Claude Code Harness 深度教程
Claude Code Harness 深度教程
15 章拆解 Claude Code 的架构设计与实现 —— 一个 1902 个源文件、51 万行 TypeScript、把 prompt 当预算管理的 agent(智能体)运行外壳
本教程的定位(2026-08-25)
同目录下已有三份 harness 拆解,它们是同一道题的三种答案:
- Pi-Agent 教程 —— 减法:4 个包,刻意不做 MCP / 子 Agent / 权限弹窗
- DeepSeek Harness 教程 —— 全插件化:185 个包,连 agent loop 都是配置里的一行
- Codex Harness 教程 —— 工程化:102 个 crate,四套沙箱实现,一个用模型守模型的安全层
Claude Code 是第四种答案,而且和前三种都不在一个坐标轴上:它既不最小、也不最可替换、更不是"把该有的全做出来塞进二进制"。它的组织原则只有一条——
上下文窗口是稀缺资源,prompt cache 是真金白银,所以每一个设计决定都要先回答"这会不会破坏缓存前缀"。
从系统提示词的动静边界、到子 agent 的 fork 路径、到工具 schema 的延迟加载、到把动态信息从 system prompt 挪进消息尾部的 attachment —— 全是同一条主线。第 15 章有完整的四方对照。
版本基线与取证方法
本教程基于 tvytlx/claude-code-deep-dive 仓库中的 extracted-source/ 快照(git 提交 d2bab20,2026-03-31)。这份源码是从 npm 包 @anthropic-ai/claude-code 的 cli.js.map 里的 sourcesContent 字段还原出来的——不是反编译,是原始 TypeScript 源码本身,注释、TODO、内部 PR 编号、A/B 实验名全在。
快照的年代:提示词常量里的前沿模型是 Claude Opus 4.6(prompts.ts:118),模型 ID 表只到 claude-opus-4-6 / claude-sonnet-4-6 —— 也就是 Claude 5 家族发布之前。所以它比本机运行的 2.1.241 略旧。凡是标 [源码] 的结论都指快照;凡是标 [实测] 的都出自本机 2.1.241 的运行痕迹(48 个会话的 transcript、3336 条附件记录),两者交叉验证过的地方会明说。
与另外三份教程的取证等级对照:Pi 教程是转载 + 补全,dsh 教程读的是打包产物(lib/index.js),Codex 教程读的是公开 Git 仓库。本教程读的是从 sourcemap 还原的闭源产品源码——保真度接近 Codex(有注释有 TODO),但没有 git 历史,所以本教程不做时间线考古,只做横截面解剖。
一条硬边界:这份 sourcemap 来自外部构建,被 feature() 开关关掉的模块在打包时已被物理删除,sourcesContent 里根本没有它们(详见第 2 章 §2.4 的实证)。受影响最大的是第 7 章的五层压缩——其中四层的实现代码不在,只能从调用点、类型标注和注释还原设计意图。那一章会逐条标明哪些看得见、哪些是推断。
一、这套教程解决什么问题
如果你读过前三份 harness 教程,会带着这些问题来看 Claude Code:
- 一个"闭源产品"的 harness 长什么样? —— Codex 是在公开仓库里持续开发的开源产品,Claude Code 不是。但它的 sourcemap 里带着完整源码注释,包括 // 3P default: false — verification agent is ant-only A/B 这种内部实验标记。本教程能读到的东西,某种意义上比读开源仓库还多。
- prompt cache 命中率能变成一条架构主线吗? —— 能。系统提示词有一个叫 SYSTEM_PROMPT_DYNAMIC_BOUNDARY 的哨兵字符串,边界前后是两套缓存策略;给一个 section 加"每轮重算"的能力,函数名叫 DANGEROUS_uncachedSystemPromptSection 且强制要求传一个理由字符串。
- 上下文压缩做几层才够? —— Claude Code 做了五层:snip / microcompact / context-collapse / autocompact / reactive compact,并且它们在主循环里有严格的执行顺序和"谁先把上下文压下去就轮不到下一层"的短路逻辑。
- 多 agent 怎么做到既并行又不烧钱? —— fork 路径会构造逐字节相同的对话前缀,让所有 fork 子进程共享父进程的 prompt cache。占位符 'Fork started — processing in background' 之所以是个常量,就是为了这个。
- "好行为"能被制度化吗? —— 系统提示词里那些"不要过度抽象""不要假装测试过""被拒绝的工具调用不要原样重试",加上一个专门被 prompt 成"你的工作不是确认它能跑,是想办法弄坏它"的验证 agent。
如果你没读过前三份教程,本教程也是自洽的:从第 2 章的工程骨架讲起,不预设你了解任何一个具体 harness,也不要求你精通 TypeScript(所有代码片段都有中文解读)。
二、章节结构
text
第一部分 · 骨架
ch01 开篇总览 → ch02 工程骨架 → ch03 Agent Loop
↓
第二部分 · 上下文(本教程的主线)
ch04 模型调用与缓存经济学 → ch05 系统提示词装配
↓
ch06 附件与 system-reminder → ch07 五层压缩
↓
第三部分 · 工具与治理
ch08 工具系统 → ch09 工具执行链 → ch10 权限模型 → ch11 钩子系统
↓
第四部分 · Agent 与扩展
ch12 Agent 调度 → ch13 内建 Agent → ch14 扩展面 → ch15 设计精华
| 章节 | 主题 | 核心问题 | 难度 |
|---|
| 第 1 章 | 开篇总览 | Claude Code 是什么?和另外三个 harness 的本质区别在哪? | 入门 |
| 第 2 章 | 工程骨架 | 1902 个源文件怎么塞进一个 npm 包?89 个编译期开关是干什么的? | 入门 |
| 第 3 章 | Agent Loop | 一个 while(true) 里为什么有 7 个 continue、10 个终止原因? | ★ 核心 |
| 第 4 章 | 模型调用与缓存经济学 | 为什么"会不会破坏缓存"是这个系统的第一性问题? | ★ 核心 |
| 第 5 章 | 系统提示词装配 | 那份真实的生产系统提示词是怎么拼出来的? | ★ 核心 |
| 第 6 章 | 附件与 system-reminder | 为什么动态信息不进 system prompt,而是走消息尾部? |
阅读建议:第 1–4 章是骨架,建议顺序通读——不理解第 4 章的缓存经济学,后面每一章都会觉得"这里为什么要绕这么一大圈"。第 5 章起可按需跳读。第 7 章(五层压缩)、第 12 章(fork)、第 15 章即使不读源码也值得单独看。
每一章回答三个层次的问题:是什么(概念)、怎么做(源码取证)、为什么这样做(设计取舍)。
三、素材基线:本教程的每个数字从哪来
| 素材 | 位置 | 规模 |
|---|
| 还原源码 | claude-code-deep-dive/extracted-source/src/ | 1902 个文件(1332 .ts + 552 .tsx + 18 .js)/ 512685 行 |
| 主循环 | src/query.ts | 1729 行 |
| 系统提示词装配 | src/constants/prompts.ts | 914 行 |
| 工具执行链 | src/services/tools/toolExecution.ts | 1745 行 |
| 钩子系统 | src/utils/hooks.ts | 5022 行 / 27 个事件 |
| 权限系统 | src/utils/permissions/ | 24 个文件 / 9409 行 |
| Agent 调度 | src/tools/AgentTool/ | 20 个文件 / 6782 行 |
自己动手复核
每章末尾都有「动手复核」小节,给出可直接运行的命令。教程正文里凡标注 [源码] 的结论都给了 文件:行号,凡标注 [实测] 的数字都出自本机 transcript。
起手式:
bash
git clone https://github.com/tvytlx/claude-code-deep-dive.git
cd claude-code-deep-dive/extracted-source && ls src/
想验证你自己那台机器上的运行时行为:
bash
ls ~/.claude/projects/*/ | head # 会话 transcript
claude --version # 对照本教程的 2.1.241
原始资料索引见 00-资料索引,研究背景与结论摘要见 Claude Code Harness 研究摘要。
四、和另外三份 harness 教程的关系
| 维度 | Pi 教程 | dsh 教程 | Codex 教程 | 本教程 |
|---|
| 拆解对象 | pi-agent SDK | DeepSeek Harness | OpenAI Codex CLI | Claude Code |
| 语言 | TypeScript | TypeScript | Rust | TypeScript |
| 设计哲学 | 减法:核心极简 | 全插件化:一切可替换 | 工程化:产品该有的全做 | 上下文经济学:一切服从缓存前缀 |
| 规模 | 4 个核心包 | 185 个包 | 102 个 crate / 147 万行 | 1902 个文件 / 51 万行 |
| 交付形态 | npm 库 | npm 运行时 + 插件树 |
第 15 章会把这张表展开成完整的哲学对照,汇总全书可迁移的设计判断,并给出对本仓(Obsidian 知识库 + 大量自定义 skill)的具体启示。
- Pi-Agent 深度教程 —— 减法哲学的对照组
- DeepSeek Harness 深度教程 —— 全插件化的对照组
- Codex Harness 深度教程 —— 工程化的对照组
- Harness Engineering 研究报告 —— harness 工程的行业方法论背景
- Claude Code Harness 研究摘要 —— 本教程的调研过程与核心结论
- 00-资料索引 —— 原始资料清单