# Claude Code 源码背后的设计哲学:51 万行代码,绝大部分都与 AI 无关
**作者**: Jason Zuo
**日期**: 2026-03-31T21:32:59.000Z
**来源**: [https://x.com/xxxjzuo/status/2039093625376645537](https://x.com/xxxjzuo/status/2039093625376645537)
---

今天 AI 圈最大的新闻,莫过于 Claude Code 的源码泄了。
51.2 万行 TypeScript,1903 个文件。很多人已经在拆里面的具体实现了,甚至是手搓了开源版本。
我更想聊的是这份源码暴露出来的一套设计哲学,作为普通非技术用户也可以复制的使用 AI agent 的底层逻辑。
Claude Code 好用,不只是因为 Opus 模型本身的能力强。51 万行代码里,真正调 LLM API 的部分可能不到 5%。剩下全是 harness:围绕模型搭建的运行环境。安全检查、权限控制、上下文管理、记忆系统、工具编排、prompt 工程。
这 95% 就是 Claude Code 的 harness 设计哲学。也是它跟其他 AI 编程工具拉开差距的地方。模型是引擎,harness 是整台车。引擎再强,没有刹车、方向盘和变速箱,你哪儿也去不了。
## 设计哲学的核心:不信任模型
读 Claude Code 的源码,最强烈的感受不是"Anthropic 工程能力真强",而是"Anthropic 对自己的模型真不信任"。
这不是哲学层面的不信任。源码注释里有大量 A/B 测试数据和故障率统计。每个 harness 组件背后,都是一个被数据验证过的"Claude 做不到这件事"。不是在吹模型多强,是在用代码承认模型的边界,然后用架构补上去。
先读后改铁律。FileEditTool 会检查你是不是已经用 FileReadTool 读过这个文件,没读过直接报错,不让改。源码里的逻辑大致是这样的:
为什么?因为 LLM 会 hallucinate 没读过的文件内容。如果不强制先读,Claude 可能凭空写一段代码覆盖你的文件。这条规则不是建议,是硬限制。代码级别的"你没看过就不许动"。
这就是为什么 Claude Code 改文件的准确率比其他工具高。不是模型更聪明,是架构不给模型犯傻的机会。

三层上下文压缩。LLM 管不好自己的 context window,对话长了就开始丢重要信息。CC 设计了三层递进式压缩:
每一层的触发阈值、预留 buffer、熔断上限,都不是拍脑袋定的,是在"保留足够上下文继续工作"和"腾出足够空间接收新消息"之间反复调出来的平衡点。
sub-agent 的身份注入。Claude 会无限递归 spawn 子 agent。源码里给子 agent 注入了一段身份声明:
翻译过来就是:"你是一个工人,不是经理。不要试着再雇人,自己干活。" Coordinator 模式下有明确的并行规则:
BashTool 安全体系。一个 BashTool,18 个文件做安全检查。prompt.ts 里有大约 350 行写给 AI 看的行为守则。这就是为什么 Claude Code 从不会擅自 git push --force。不是模型更有分寸,是 prompt 里已经把规矩讲死了。
工具工厂的默认值是整个安全体系的基石:
两个 false,一行代码。这叫 fail-closed。如果工具开发者忘了声明安全属性,系统默认它是"不安全的、会写入的"。宁可过度保守,也不漏掉一个风险。这个设计决策决定了整个系统的安全底线。
## Prompt 是编译出来的,不是写出来的
打开 src/constants/prompts.ts,会看到整个 prompt 的组装逻辑:

分界线上面是静态内容,Claude API 可以缓存,不重复计费。分界线下面是动态内容,每次对话都不一样。
Anthropic 把 prompt 当编译器的输出来优化。静态部分是编译后的二进制,动态部分是运行时参数。省钱、快、灵活,三个好处同时拿到。
缓存稳定性的维护是一场持续的保卫战。Claude API 的 prompt cache 是基于字节级前缀匹配的。不只是工具顺序,源码里追踪了十几种可能打破缓存的因素:系统 prompt、工具 schema、模型名称、beta header 列表、effort 值,任何一个变化都会导致缓存失效。CC 团队为此发明了专门的 latch 机制:某些参数一旦在会话中首次设定,即使后续状态变化也不允许修改,因为改了就会打破数万 token 的缓存。
每个工具目录下有独立的 prompt.ts,是专门写给 LLM 看的使用手册。BashTool 的 prompt.ts 大约 370 行。不是写给人看的文档,是写给 AI 看的行为守则,每次启动时注入系统提示词。
42 个工具也不是全量注入的。通过 ToolSearchTool 按需发现,需要什么加载什么。每多一个工具就多一段 prompt 描述,多花一份 token。设置 CLAUDE_CODE_SIMPLE=true,直接砍到只剩 3 个工具:Bash、读文件、改文件。连 harness 自身都在做 context management。prompt 的每一个 token 都有成本,harness 不能无节制地膨胀。
顺便说一句,CC 团队因为自家 SDK 的流式解析存在 O(n²) 性能问题,直接绕过了 Anthropic 官方 SDK,自己管理所有的流式状态累积。旗舰产品绕过自家基础设施,harness 工程的复杂度可见一斑。
## 记忆系统:精确度优先于召回率
用过 Claude Code 的人都有一个感受:它好像真的认识你。你告诉它"不要在测试中 mock 数据库",下次对话它就不会再 mock。
背后的记忆检索不是你以为的关键词匹配或向量搜索:
这个取舍很有意思:大多数系统追求"尽量多找到相关信息",CC 反过来,追求"绝不注入无关信息"。因为对 LLM 来说,context 里的噪音比缺失更致命。
源码里还有一个叫 KAIROS 的特性标志。在这个模式下,长会话中的记忆存在按日期的追加式日志中。然后有一个 /dream 技能会在低活跃期运行,把原始日志蒸馏成结构化的主题文件。AI 在"睡觉"的时候整理记忆。

## 三种安全哲学:不是好坏,是信任假设不同
为什么 Anthropic 选了最难的那条路?因为只有这样,AI 才能在你的真实环境里干活,而不是在一个干净房间里写一段代码让你复制过来。
权限系统不是 allow/deny 二态,是四态决策:
权限决策:四态模型
allow → 直接执行,不问
deny → 直接拒绝,不执行
ask → 弹窗问用户,等确认
passthrough → 低风险操作,默认放行
粒度比二态细得多。ask 让用户做即时判断,passthrough 让低风险操作直接通过。粒度决定体验,太粗用户烦,太细用户累。四态是 Anthropic 试出来的平衡点。

三种不同的信任假设。Cursor 赌人类可以一直盯着。Copilot 赌隔离就是安全。Claude Code 赌精确控制行为边界比限制接触范围更有效。51 万行代码就是这个赌注的成本。
## 内部版和外部版不一样
源码里有个 isAnthropicEmployee 分支:
Anthropic 自己就是 Claude Code 最大的用户。他们在用自己的产品开发自己的产品。内部版是实验场,外部版是稳定版。
CC 的架构不是一次性设计出来的,是在 Anthropic 自己的高强度使用中不断迭代的。每个功能从内部版毕业到外部版,都经过了实战验证。Opus 4.5 时代需要的某些限制,到 Opus 4.6 就不需要了。架构会随着模型能力的提升持续调整,有些组件会被拆掉,有些新的会加上。这也是 harness 哲学的一部分:为拆除而设计。
## 对做 Agent 产品的人意味着什么
最直接的就是社区已经大量用 Claude Code 分析了 Claude Code 源码,把核心逻辑抽出来做出了各种 agent-sdk。claude-agent-sdk 本来是 CC 套了一层壳做成 SDK,每次 query 要创建一个 CC 进程,开销大。
利用这次泄漏的内容,手搓的各种 agent-sdk 把逻辑抽成函数调用,不依赖本地 CLI 进程。这件事本身就验证了一点:CC 的价值不在调模型那一小部分代码,在于 harness 的工程实现。把 harness 逻辑抽出来,换个模型接进去,核心能力还在。
推荐 @idoubicc 做的 open-agent-sdk https://x.com/idoubicc/status/2039006326882546141?s=20
从 CC 源码能提炼出几条通用的 harness 设计原则:
Fail-closed 不是 fail-open。不确定一个操作是不是安全的?默认禁止。CC 的工具工厂就是这么做的。一行默认值,决定了整个系统的安全底线。
每个 harness 组件要有一个显式的假设。"因为 Claude 会 hallucinate 没读过的文件,所以有先读后改铁律。"说不清这个组件在补什么缺口,这个组件就不该存在。
为拆除而设计。模型升级后,有些限制就不需要了。今天你花一周搭的组件,半年后可能该拆了。如果拆不掉,说明它已经从"补模型缺口"变成了"产品本身的功能",那它就不再是 harness 组件了。
不过源码也暴露了这个原则的另一面。注释里工程师自己写了:多遍 normalization 本质上是脆弱的,每一遍清理都可能制造出前一遍本该处理的条件。原则是对的,但现实中 patch 累积的速度往往比拆除的速度快。为拆除而设计是目标,不是现状。
Harness 要管自己的开销。工具按需加载、缓存边界精确划分、固定排序维护前缀匹配。Harness 本身也是 context 的消费者,不能无节制地膨胀。
51 万行,绝大部分都是 harness。42 个工具对应系统调用,权限系统对应用户权限管理,记忆系统对应持久化存储,Agent 蜂群对应进程管理。Claude Code 不是一个套了 AI 的编程工具,是一个以 LLM 为内核的操作系统。
模型会迭代,具体的 harness 组件也会过时。但 fail-closed、先读后改、角色分离、按需加载、为拆除而设计,这些设计哲学不会。
Claude Code 好用,是因为 Anthropic 用 51 万行代码承认了一件事:再强的模型也需要一个好的运行环境。
## 相关链接
- [Jason Zuo](https://x.com/xxxjzuo)
- [@xxxjzuo](https://x.com/xxxjzuo)
- [8.8K](https://x.com/xxxjzuo/status/2039093625376645537/analytics)
- [@idoubicc](https://x.com/@idoubicc)
- [https://x.com/idoubicc/status/2039006326882546141?s=20](https://x.com/idoubicc/status/2039006326882546141?s=20)
- [Upgrade to Premium](https://x.com/i/premium_sign_up)
- [5:32 AM · Apr 1, 2026](https://x.com/xxxjzuo/status/2039093625376645537)
- [8,870 Views](https://x.com/xxxjzuo/status/2039093625376645537/analytics)
- [View quotes](https://x.com/xxxjzuo/status/2039093625376645537/quotes)
---
*导出时间: 2026/4/1 11:27:02*