有人把 Claude Code 的源码反编译了。花了一晚上通读,发现它远不只是一个"会用工具的 chatbot"——而是一套完整的 多 Agent 协作操作系统。
这篇文章拆解 Claude Code 的 7 大核心系统。每个系统是什么、怎么工作、为什么这么设计。
1. Agent Team — 多 Agent 协作
这是 Claude Code 最复杂的系统。它让一个 Coordinator(协调者)管理多个 Teammate(队友)并行工作,共享一个任务列表。
工作流
Coordinator
├── TeamCreate → 创建团队 + 共享任务列表
├── TaskCreate → 拆分任务
├── Agent(team_name, name) → 生成队友
├── SendMessage → 给队友发指令
└── TaskStop → 停止出错的队友
每个队友自动从 ~/.claude/tasks/{team-name}/ 领取任务,完成后标记,检查下一个。消息自动投递,不需要轮询。
Coordinator 模式的精髓
Coordinator 模式下,主 Agent 只有 4 个工具:Agent、SendMessage、TaskStop、SyntheticOutput。它不碰代码,只做一件事:理解 + 指挥。
核心原则:Never delegate understanding.
不许写 "based on your findings, fix the bug"——这是在把理解的责任推给 worker。Coordinator 必须综合研究结果,写出包含具体文件路径、行号、修改内容的实现规格。
任务分四个阶段:Research(worker 并行调查)→ Synthesis(coordinator 综合理解) → Implementation(worker 实现)→ Verification(worker 验证)。Synthesis 是 coordinator 存在的理由。
2. Agent Tree — 层级与分叉
Claude Code 有一棵完整的 Agent 类型树:
| 类型 | 特点 | 用途 |
|---|---|---|
| Explore | 只读,不能编辑文件 | 代码搜索、架构分析 |
| Plan | 只读 | 实现方案规划 |
| Verification | 独立对抗性验证(内部版) | 证明代码能用,不是橡皮图章 |
| Fork | 继承父上下文,后台运行 | 研究、实现 |
| Custom | .claude/agents/*.md | 用户自定义 |
| Worker | Coordinator 模式下的执行者 | 全工具集 |
Fork Subagent:最聪明的设计
省略 subagent_type → 隐式分叉。子进程继承父进程的完整对话上下文和 system prompt。
精妙之处在于 prompt cache 优化:所有 fork 子进程的 tool_result 替换为相同占位符 "Fork started — processing in background",确保不同子进程的 API 请求前缀字节完全相同,最大化缓存命中。
Fork 子进程有严格规则:
- 不能递归 fork(通过检测
<fork-boilerplate>标签防止) - 不能偷看进度(不要 Read output_file)
- 不能伪造结果(完成通知由系统生成,不是模型自己写的)
- 输出必须结构化:Scope → Result → Key files → Files changed → Issues
自定义 Agent 格式
用 Markdown + frontmatter 定义,支持精细控制:
# .claude/agents/my-agent.md
---
description: "Code reviewer"
tools: ["Read", "Bash", "Grep"]
model: "inherit"
permissionMode: "bubble"
isolation: "worktree"
maxTurns: 200
memory: "project"
---
You are a code reviewer that...
3. Tool Server — MCP 双向桥接
Claude Code 同时是 MCP server 和 MCP client。
作为 Server
claude-code mcp 启动一个标准 MCP 服务器(名称 claude/tengu),通过 StdioTransport 暴露所有内部工具——Read、Edit、Write、Bash、Glob、Grep 等。其他 AI 工具可以直接调用 Claude Code 的能力。
作为 Client
连接外部 MCP server,获取额外工具和技能:
- MCP server 的
instructions注入 system prompt - 支持指令增量模式:MCP 指令通过 attachment 增量传递,避免连接/断开时破坏 prompt cache
- MCP 工具可标记
_meta['anthropic/alwaysLoad']跳过延迟加载 - MCP server 可以提供 Skill(prompt 技能),被技能系统自动发现
4. Skill System — 技能即 Prompt
Skill 本质上是带 frontmatter 的 Markdown 文件,调用时展开为完整指令注入当前上下文。
技能来源
- 内置:/commit、/verify、/simplify、/debug、/remember、/stuck、/batch 等 13+ 个
- 用户定义:
.claude/commands/*.md或~/.claude/commands/*.md - MCP 提供:外部 MCP server 暴露的 prompt 技能
- 动态发现:DiscoverSkillsTool 根据当前任务自动搜索(实验特性)
Skill vs Agent
| 维度 | Skill | Agent |
|---|---|---|
| 执行位置 | 主上下文内 | 子进程 |
| 上下文 | 共享主对话 | 独立/继承 |
| 并行 | 不能 | 可以 |
| 本质 | Prompt 注入 | 独立推理循环 |
预算控制
技能列表占 context window 的 1%(约 8000 字符)。每条描述最多 250 字符,超预算时 bundled 技能优先保留完整描述,其余截断。极端情况下只显示技能名。
5. Async Tool — 后台执行
"Async" 在 Claude Code 中有两个层面:
层面 1:Bash run_in_background
命令立即返回,后台跑完后系统自动发 <task-notification>。不需要轮询、不需要 sleep、不需要 &。适合构建、测试、部署等长时间任务。
层面 2:Agent 后台模式
Fork subagent 始终后台运行,普通 agent 可选 run_in_background: true。Coordinator 模式下所有 worker 都是后台异步的。
后台 Agent 工具白名单
后台 Agent 不能用所有工具。被禁的:
Agent— 防递归AskUserQuestion— 后台不能弹交互TaskStop— 需要主线程状态MCP 工具— 尚未实现
6. Sequential Tool — 并行与顺序
这不是一个独立系统,而是贯穿所有工具执行的编排策略。
并行
System prompt 明确指导:"独立的工具调用放在同一条消息中并行执行。" 例如 git status + git diff 可以并行,多个研究 agent 可以并行启动。
顺序
"有依赖的工具调用必须顺序执行。" 例如先 Read 再 Edit,先 commit 再 status。Bash 中用 && 串联有依赖的命令。
并发安全
每个工具定义 isConcurrencySafe(input),返回 false 的工具系统会强制串行。对同一文件的两个 Edit 不是并发安全的。
Coordinator 层面的策略更清晰:
- Research(只读)→ 自由并行
- Implementation(写)→ 同一文件集一次一个
- Verification → 可与不同文件区域的 implementation 并行
7. Harness — 运行时框架
Harness 是连接 AI 推理和工具执行的中间层,是整个系统的"壳"。
Prompt Cache 管理
这是 harness 最精妙的部分。System prompt 分为静态和动态两部分,用 SYSTEM_PROMPT_DYNAMIC_BOUNDARY 分隔:
[Static — cacheScope: 'global', 跨用户/跨组织共享]
Intro → System rules → Doing Tasks
→ Actions → Using Tools → Tone → Output
[=== BOUNDARY (Blake2b hash) ===]
[Dynamic — 每轮可变]
Session guidance → Memory → Env info
→ Language → MCP → Scratchpad
设计目标:静态部分字节完全相同才能命中全局缓存。所以任何运行时条件判断(如 agent list、MCP 连接状态)都必须放在动态部分——否则会指数级增加缓存变体(2^N 问题)。
上下文自动压缩
对话接近上下文限制时自动压缩历史消息。模型被告知 "write down important information" 因为旧的 tool results 可能被清除(Cached MicroCompact 特性)。理论上上下文无限。
工具延迟加载
不是所有工具都在第一轮就展开 schema——核心工具(Read、Edit、Bash)始终加载,其余通过 ToolSearch 按需加载。减少初始 prompt 大小。
Claude Code Hints 协议
Harness 扫描 Bash 输出中的特殊标签:
<claude-code-hint v="1" type="plugin"
value="eslint@marketplace" />
标签从输出中剥离(模型看不到),harness 解析后弹出安装提示。纯侧通道,不经过 AI 推理。
其他 Harness 职责
- 权限系统:sandbox 沙箱(文件系统 + 网络白名单)、权限冒泡(bubble)、中断行为(cancel/block)
- Interrupt Behavior:用户发新消息时,工具可选择取消或继续
- System Reminder:
<system-reminder>标签在 tool result 中注入系统信息 - Hook 系统:shell 命令响应事件(如 tool call 前后),反馈等同于用户输入
Bonus:内部版 vs 外部版
源码中 process.env.USER_TYPE === 'ant' 区分 Anthropic 内部版和公开版,差异很大:
| 维度 | 内部版 (ant) | 外部版 |
|---|---|---|
| 沟通风格 | 散文体、倒金字塔、≤25 词/≤100 词 | "be concise" 一句话 |
| 注释哲学 | 默认不写,只写 WHY 不明显的 | 无规定 |
| 诚实报告 | 禁止谎报测试结果 | 无 |
| 验证 Agent | 3+ 文件改动必须独立验证 | 无 |
| Explore 模型 | inherit(Opus) | Haiku |
| Agent 嵌套 | 允许 | 禁止 |
| Agent 隔离 | worktree + remote | 仅 worktree |
| Undercover | 隐藏未发布模型名 | 无 |
启发
读完整个源码,几个印象最深的设计决策:
- Cache 是一等公民。从 static/dynamic 边界到 fork 占位符到 MCP 指令增量,所有设计都在保护 prompt cache。这是成本控制的核心。
- Coordinator 模式是多 agent 的答案。不让一个 agent 既思考又干活。分开后 coordinator 专注综合,worker 专注执行,质量显著提升。
- "Never delegate understanding"——这句话值得刻在每个 agent 开发者的桌上。最常见的多 agent 失败模式就是把理解外包出去。
- Fork 的 prompt cache 共享是一个非常工程化的创新。同一段上下文被多个子进程复用,边际成本几乎为零。
- 内部版比外部版严格得多。Anthropic 自己用的是"不能撒谎、不能偷懒、必须验证"的版本。这说明他们知道模型的弱点在哪。
Claude Code 不是一个 CLI 工具。它是一个 agent operating system。