Agent X-Ray
RuntimeNotesAbout
Notes/源码拆解/Claude Code Harness/README

Claude Code Harness 深度教程

7 分钟 · 更新于 2026-09-01

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-codecli.js.map 里的 sourcesContent 字段还原出来的——不是反编译,是原始 TypeScript 源码本身,注释、TODO、内部 PR 编号、A/B 实验名全在。

快照的年代:提示词常量里的前沿模型是 Claude Opus 4.6prompts.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:

  1. 一个"闭源产品"的 harness 长什么样? —— Codex 是在公开仓库里持续开发的开源产品,Claude Code 不是。但它的 sourcemap 里带着完整源码注释,包括 // 3P default: false — verification agent is ant-only A/B 这种内部实验标记。本教程能读到的东西,某种意义上比读开源仓库还多。
  2. prompt cache 命中率能变成一条架构主线吗? —— 能。系统提示词有一个叫 SYSTEM_PROMPT_DYNAMIC_BOUNDARY 的哨兵字符串,边界前后是两套缓存策略;给一个 section 加"每轮重算"的能力,函数名叫 DANGEROUS_uncachedSystemPromptSection强制要求传一个理由字符串
  3. 上下文压缩做几层才够? —— Claude Code 做了五层:snip / microcompact / context-collapse / autocompact / reactive compact,并且它们在主循环里有严格的执行顺序和"谁先把上下文压下去就轮不到下一层"的短路逻辑。
  4. 多 agent 怎么做到既并行又不烧钱? —— fork 路径会构造逐字节相同的对话前缀,让所有 fork 子进程共享父进程的 prompt cache。占位符 'Fork started — processing in background' 之所以是个常量,就是为了这个。
  5. "好行为"能被制度化吗? —— 系统提示词里那些"不要过度抽象""不要假装测试过""被拒绝的工具调用不要原样重试",加上一个专门被 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,而是走消息尾部?★ 核心
第 7 章上下文压缩五层压缩各管什么?顺序为什么不能换?★ 核心
第 8 章工具系统一个 Tool 接口凭什么有 47 个成员?工具太多喂不下怎么办?进阶
第 9 章工具执行链从模型吐出 tool_use 到真正执行,中间隔着什么?★ 核心
第 10 章权限模型六种权限模式怎么和规则、钩子、分类器叠加?进阶
第 11 章钩子系统27 个钩子事件能干预到什么程度?边界在哪?进阶
第 12 章Agent 调度fork 和 fresh subagent 到底差在哪?为什么 fork 便宜?★ 核心
第 13 章内建 Agent六个内建 agent 各自被裁成了什么形状?进阶
第 14 章扩展面四条扩展通道分别解决什么?为什么模型"知道"自己有哪些扩展?进阶
第 15 章设计精华哪些设计该抄,哪些不该?总结

阅读建议:第 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.ts1729 行
系统提示词装配src/constants/prompts.ts914 行
工具执行链src/services/tools/toolExecution.ts1745 行
钩子系统src/utils/hooks.ts5022 行 / 27 个事件
权限系统src/utils/permissions/24 个文件 / 9409 行
Agent 调度src/tools/AgentTool/20 个文件 / 6782 行
压缩子系统src/services/compact/11 个文件 / 3960 行
会话存储src/utils/sessionStorage.ts5105 行
工具目录src/tools/*/42 个
命令src/commands/ + src/commands.ts101 个目录 / 76 个内建命令项
编译期特性开关feature('...')89 个唯一值
附件类型src/utils/attachments.ts45 个 type 变体 / 3997 行
本机运行痕迹 [实测]~/.claude/projects/-home-chenkun-.../48 个会话 / 28 MB / 3336 条附件记录

自己动手复核 每章末尾都有「动手复核」小节,给出可直接运行的命令。教程正文里凡标注 [源码] 的结论都给了 文件:行号,凡标注 [实测] 的数字都出自本机 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 SDKDeepSeek HarnessOpenAI Codex CLIClaude Code
语言TypeScriptTypeScriptRustTypeScript
设计哲学减法:核心极简全插件化:一切可替换工程化:产品该有的全做上下文经济学:一切服从缓存前缀
规模4 个核心包185 个包102 个 crate / 147 万行1902 个文件 / 51 万行
交付形态npm 库npm 运行时 + 插件树单个静态二进制单个 npm 包(含 sourcemap)
前端TUIWeb GUI + CLITUI / IDE / 桌面 / MCP / 云端TUI / IDE / 桌面 / Web / SDK / MCP server
扩展方式TS 扩展文件cordis 插件 + 四层 patchMCP / Skills / Hooks / Plugins / CodeModeSkills / Plugins / Hooks / MCP / Commands / Output Styles
沙箱无(明确不做)seam + 多后端三套操作系统原生实现(自研)外包给独立包 @anthropic-ai/sandbox-runtime
钩子事件数无正式钩子插件事件总线6 个事件点27 个
上下文压缩层数1(摘要)1(摘要)2(本地 + 远端)5
子 agent明确不做subagent / workflow / ralph子进程 + 协作图fork(共享缓存)+ 6 个内建专家 + teammate
内容来源转载 + 补全本机取证(打包产物)原始源码取证(开源仓库)sourcemap 还原源码 + 本机 transcript 实测

第 15 章会把这张表展开成完整的哲学对照,汇总全书可迁移的设计判断,并给出对本仓(Obsidian 知识库 + 大量自定义 skill)的具体启示。


  • Pi-Agent 深度教程 —— 减法哲学的对照组
  • DeepSeek Harness 深度教程 —— 全插件化的对照组
  • Codex Harness 深度教程 —— 工程化的对照组
  • Harness Engineering 研究报告 —— harness 工程的行业方法论背景
  • Claude Code Harness 研究摘要 —— 本教程的调研过程与核心结论
  • 00-资料索引 —— 原始资料清单

本章目录
一、这套教程解决什么问题二、章节结构三、素材基线:本教程的每个数字从哪来四、和另外三份 harness 教程的关系Related Documents
苏ICP备2025204887号-2