乐于分享
好东西不私藏

Claude Code 源码深度解读(一):总览与架构哲学

Claude Code 源码深度解读(一):总览与架构哲学

系列导读:本系列共7篇,源自对 Claude Code 51万行 TypeScript 源码的逆向解读。目标不仅是「看懂 Claude Code」,更是为构建你自己的 Agentic 系统提供可迁移的设计模式和工程经验。


一、Claude Code 是什么?

Claude Code 是 Anthropic 官方的 命令行 AI 编码助手,于 2025 年初推出。它不是一个 IDE 插件,而是一个直接运行在终端中的、完全自主的 AI Agent。

用一句话概括它的定位:

一个能在你的代码库里「自由行动」的 AI 工程师,它能读代码、写代码、运行命令、搜索文件、管理 Git,甚至能生成子代理来并行工作。

1.1 项目基本指标

指标
数据
代码语言
TypeScript (strict mode)
运行时
Bun

(不是 Node.js!)
总代码行数
~512,000+ 行
源文件数量
~1,900 个
终端 UI 框架
React + Ink(React for CLI)
CLI 框架
Commander.js
构建系统
bun:bundle(原生打包)

让你惊讶的第一个事实:终端里运行的程序居然用 React 写 UI。这不是噱头——Ink 是一个将 React 组件渲染为终端输出的框架,意味着 Claude Code 的「界面层」和 Web App 共享同一套组件化思想。


二、一张图看懂整体架构

┌─────────────────────────────────────────────────────────────┐│                   CLI 入口层 (main.tsx)                       ││  Commander.js 解析命令行 → React/Ink 渲染终端 UI              ││  启动时并行预取:MDM设置 + Keychain + API预连接               │├─────────────────────────────────────────────────────────────┤│                查询引擎层 (QueryEngine.ts)                    ││  会话管理 │ 消息生命周期 │ 系统Prompt组装 │ 使用量跟踪        │├─────────────────────────────────────────────────────────────┤│                核心查询循环 (query.ts)                         ││  while(true) 主循环 │ 五层上下文压缩 │ 五重错误恢复            ││  流式API调用 │ StreamingToolExecutor 并行工具执行              │├───────────────────────┬─────────────────────────────────────┤│   工具系统 (tools/)    │   命令系统 (commands/)               ││  ~40 个内置工具        │  ~80+ 个斜杠命令                     ││  MCP 外部工具          │  技能/插件/工作流命令                 ││  Feature Flag 条件加载 │  可用性门控                           │├───────────────────────┴─────────────────────────────────────┤│                    服务层 (services/)                         ││  API │ MCP │ OAuth │ Compact(压缩) │ Analytics │ Session     │├─────────────────────────────────────────────────────────────┤│                    基础设施层                                  ││  State(状态) │ Bridge(IDE桥接) │ Hooks │ Permissions          ││  Memory(记忆) │ Skills(技能) │ Coordinator(协调器)            │└─────────────────────────────────────────────────────────────┘

这个六层架构有一个核心设计原则:每一层只依赖下面的层,不向上依赖。这意味着你可以独立替换任何一层——比如把终端 UI 换成 Web UI(Bridge 模式做的正是这件事)。


三、架构哲学:七个核心设计决策

3.1 哲学一:「循环」而非「链」

很多 AI Agent 框架(如 LangChain)喜欢用链式思维:输入 → 处理1 → 处理2 → 输出。

Claude Code 的核心选择不同——它是一个 while(true) 无限循环

while (true) {  压缩上下文 → 调用模型 → 执行工具 → 收集结果 → 注入附件      ↓                                           ↓  如果模型说"我还没做完" ─────────────────────→ 继续循环      ↓  如果模型说"我做完了" ──→ 检查Stop Hooks ──→ 退出}

为什么是循环而不是链?

因为真实的编码任务是不可预测的。模型可能需要调用 1 个工具就完成,也可能需要调用 50 个。链式架构需要预定义步骤数量,而循环架构是自适应的。

💡 给你的启发:如果你的 Agent 系统面对的任务复杂度变化很大,优先选择循环架构而非链式架构。循环给模型最大的「自主权」来决定什么时候停下来。

3.2 哲学二:Feature Flag 驱动的渐进式发布

Claude Code 大量使用 bun:bundle 的 feature() 函数实现编译时特性开关

// 只有启用了 PROACTIVE 特性,SleepTool 才会被编译进最终产物const SleepTool = feature('PROACTIVE') || feature('KAIROS')  ? require('./tools/SleepTool/SleepTool.js').SleepTool  : null// 内部员工专用的 REPL 工具const REPLTool = process.env.USER_TYPE === 'ant'  ? require('./tools/REPLTool/REPLTool.js').REPLTool  : null

这不是普通的运行时 if/else,而是编译时死代码消除。当 feature('PROACTIVE') 为 false 时,整个 SleepTool 的代码不会出现在最终构建中。

已知的重要 Feature Flags:

Flag
功能
状态
PROACTIVE
主动模式(AI 主动发起对话)
实验中
KAIROS
助手模式(推送/通知/订阅)
实验中
COORDINATOR_MODE
多代理协调器
可用
CONTEXT_COLLAPSE
上下文折叠压缩
可用
HISTORY_SNIP
历史裁剪
可用
REACTIVE_COMPACT
反应式压缩(413 时触发)
可用
CHICAGO_MCP
Computer Use(操控桌面)
实验中
WEB_BROWSER_TOOL
浏览器工具(代号 Bagel)
实验中
VOICE_MODE
语音输入
实验中
TOKEN_BUDGET
Token 预算控制
可用
BUDDY
伴侣精灵彩蛋
彩蛋

💡 给你的启发:即使你的系统不需要编译时消除,也应该为每个新能力设计 Feature Flag。这允许你「安全地向前冲」——代码先合入主干,flag 控制谁能看到。

3.3 哲学三:流式一切 (Stream Everything)

Claude Code 的核心数据流全部使用 AsyncGenerator(异步生成器):

// QueryEngine.submitMessage 返回的是 AsyncGeneratorasync *submitMessage(prompt): AsyncGenerator<SDKMessage, void, unknown> {  // ...  for await (const message of query(...)) {    yield message  // 逐条吐出,不是全部算完再返回  }}// query() 本身也是 AsyncGeneratorasync function* query(params): AsyncGenerator<Message> {  while (true) {    for await (const message of callModel(...)) {      yield message  // 模型返回一个 token 就吐一个    }    // ...  }}

这种设计意味着:

  1. 1. 用户立即看到输出——不用等整个工具执行完
  2. 2. 可以在任意点中断——Ctrl+C 能即时停止
  3. 3. 内存友好——不需要把所有消息存在内存里

💡 给你的启发:在设计 Agentic 系统时,用 AsyncGenerator(Python 里是 async def ... yield)作为核心数据管道。它天然支持流式、取消和背压。

3.4 哲学四:工具是一等公民

在 Claude Code 里,工具不是模型的附属品,工具是架构的核心

整个系统围绕「模型决定调用什么工具 → 系统执行工具 → 结果反馈给模型」的循环运转。工具有自己的:

  • • 类型系统(Zod Schema 验证输入输出)
  • • 权限模型(每个工具独立的权限检查)
  • • 并发声明(声明自己是否线程安全)
  • • 渲染系统(每个工具自定义 UI 展示)
┌──────────────────────────────────────────┐│              Tool 接口                    │├──────────────────────────────────────────┤│ name         │ 工具名称                  ││ inputSchema  │ Zod 输入验证              ││ call()       │ 执行逻辑                  ││ checkPerms() │ 权限检查                  ││ isReadOnly() │ 是否只读                  ││ isEnabled()  │ 当前是否可用              ││ isConcSafe() │ 是否并发安全              ││ render*()    │ 各种渲染钩子              │└──────────────────────────────────────────┘

💡 给你的启发:不要把工具当作「函数列表」。给每个工具设计完整的元数据(权限、并发性、只读性),系统才能智能地调度和管控它们。

3.5 哲学五:五层韧性(永远不崩)

Claude Code 对错误处理的执念到了偏执的程度。在核心查询循环中,实现了五重恢复机制

                       API 调用                          │                    ┌─────▼─────┐              ┌─ NO─┤ 调用成功? ├─ YES ──→ 继续              │     └───────────┘              ▼    ┌─────────────────┐    │ FallbackTriggered│──→ 自动切换到备用模型    │    Error         │    清理残留消息,重试    └────────┬────────┘             │ 还是失败?             ▼    ┌─────────────────┐    │ Context Collapse │──→ 释放已折叠的上下文    │   Drain Retry    │    减小 prompt 体积,重试    └────────┬────────┘             │ 还是 413?             ▼    ┌─────────────────┐    │ Reactive Compact │──→ 紧急全量摘要压缩    │    Retry         │    用压缩后的对话重试    └────────┬────────┘             │ 输出截断?             ▼    ┌─────────────────┐    │ Max Output Tokens│──→ 注入「继续」指令    │   Recovery (×3)  │    最多重试3次    └────────┬────────┘             │ 图片太大?             ▼    ┌─────────────────┐    │  Media Size      │──→ 裁剪超大图片    │  Recovery        │    重试    └─────────────────┘

最妙的是:这些恢复机制对用户是透明的。用户看到的只是「AI 正在思考」,背后可能已经经历了模型回退、上下文压缩、重试等一系列操作。

💡 给你的启发:Agentic 系统必须像潜水艇一样设计多层水密舱。每一层失败都有下一层兜底。用户不应该感知到任何内部故障恢复。

3.6 哲学六:可组合的「大系统」

Claude Code 不是一个单一的 Agent,它是一个可组合的 Agent 运行时

┌─────────────────────────────────────────┐│              组合方式                     │├────────────┬────────────────────────────┤│ CLI 模式    │ 终端直接使用               ││ SDK 模式    │ 被其他程序调用             ││ Bridge 模式 │ 被 IDE 插件调用            ││ 协调器模式  │ 管理多个子代理             ││ 远程模式    │ 运行在云端服务器           ││ 无头模式    │ 无 UI,纯 API             │└────────────┴────────────────────────────┘

同一份代码,通过不同的入口和配置,变成完全不同的产品形态。

3.7 哲学七:极致的启动性能

Claude Code 的启动流程令人印象深刻——在所有 import 语句执行之前就开始了并行 I/O:

// main.tsx 的前几行(在 import 之前!)import { profileCheckpoint } from &#x27;./utils/startupProfiler.js&#x27;;profileCheckpoint(&#x27;main_tsx_entry&#x27;);  // 标记启动时间import { startMdmRawRead } from &#x27;./utils/settings/mdm/rawRead.js&#x27;;startMdmRawRead();  // 立即启动 MDM 设置读取import { startKeychainPrefetch } from &#x27;./utils/secureStorage/keychainPrefetch.js&#x27;;startKeychainPrefetch();  // 立即启动 Keychain 预取// 此时模块加载还要 ~135ms,MDM 和 Keychain 读取在这 135ms 里并行完成

时间线:

0ms          50ms         100ms        135ms        200ms│             │             │            │            │├─ import ────────────────────────────────┤├─ MDM read ──────────┤                  │├─ Keychain ──────────────┤              ││                                        ├─ 真正开始 ─→

在模块加载的「死时间」里做并行 I/O,这种优化思路值得学习。

💡 给你的启发:用户感知的「启动速度」= 串行路径上最长的那条链。把所有无依赖的 I/O 操作提前到最早可能的时刻并行执行。


四、核心数据流:一次完整的对话

让我们追踪一次用户输入 "帮我重构 utils.ts" 的完整旅程:

用户输入 "帮我重构 utils.ts"    │    ▼┌─ 1. QueryEngine.submitMessage() ─────────────────────┐│  · 组装系统 Prompt(CLAUDE.md + 项目上下文 + Git状态)  ││  · 加载记忆(MEMORY.md + 嵌套记忆目录)               ││  · 创建 ToolUseContext(工具上下文)                   │└───────────────────────┬───────────────────────────────┘                        ▼┌─ 2. query() 主循环 ──────────────────────────────────┐│                                                       ││  ┌─ 2a. 预处理 ─────────────────────────────────┐    ││  │ · Skill Discovery Prefetch(异步预取技能发现) │    ││  │ · Tool Result Budget(工具结果预算裁剪)       │    ││  │ · Snip + Microcompact(历史和工具结果压缩)    │    ││  │ · Context Collapse(上下文折叠)               │    ││  │ · Autocompact(Token 超限全量压缩)            │    ││  └───────────────────────────────────────────────┘    ││                        ▼                              ││  ┌─ 2b. 模型调用 ───────────────────────────────┐    ││  │ callModel() 流式调用 Claude API               │    ││  │ StreamingToolExecutor 边收边执行工具           │    ││  │ → 模型返回: "我需要先读取 utils.ts"            │    ││  │ → tool_use: ReadFileTool("utils.ts")          │    ││  └───────────────────────────────────────────────┘    ││                        ▼                              ││  ┌─ 2c. 工具执行 ───────────────────────────────┐    ││  │ ReadFileTool.call("utils.ts")                  │    ││  │ → 返回文件内容                                 │    ││  └───────────────────────────────────────────────┘    ││                        ▼                              ││  ┌─ 2d. 附件注入 ───────────────────────────────┐    ││  │ · 文件变更通知                                 │    ││  │ · 记忆预取结果                                 │    ││  │ · 技能发现结果                                 │    ││  │ · 队列命令/通知                                │    ││  └───────────────────────────────────────────────┘    ││                        ▼                              ││  needsFollowUp = true  → 回到 2a 继续循环             ││  ...(可能循环 5-20 次,读文件、写文件、运行测试等)     ││  ...                                                  ││  needsFollowUp = false → Stop Hooks 检查 → 退出循环   │└───────────────────────────────────────────────────────┘                        ▼┌─ 3. 结果返回 ────────────────────────────────────────┐│  · 记录使用量和成本                                    ││  · 持久化会话记录                                      ││  · 更新 Git Attribution                               ││  · 等待用户下一次输入                                  │└───────────────────────────────────────────────────────┘

五、22 个可直接应用的设计模式

架构模式

  1. 1. 六层蛋糕架构 — 每层只依赖下层,可独立替换
  2. 2. AsyncGenerator 核心管道 — 流式、可取消、背压
  3. 3. 循环 vs 链 — 自适应任务复杂度
  4. 4. Feature Flag 驱动发布 — 安全地向前冲

错误处理模式

  1. 5. 五层韧性 — 多层恢复机制对用户透明
  2. 6. Tombstone 消息 — 回退时清理已发出的”脏消息”

多代理模式

  1. 7. 渐进式代理复杂度 — 6 个级别可混合使用
  2. 8. Fork + Prompt Cache 共享 — 统一占位符确保字节一致
  3. 9. 自动后台化 — 120秒超时自动转后台
  4. 10. Scratchpad 跨代理共享 — 文件系统即消息队列
  5. 11. Schema 动态裁剪 — 编译时防止模型误用

记忆模式

  1. 12. 四类记忆分类法 — 约束驱动的有效记忆
  2. 13. 索引+明细分层 — MEMORY.md 是索引,详细内容在子目录
  3. 14. 双维度限制 — 200行 AND 25KB 独立检查
  4. 15. 推测执行 — 在用户输入时就开始工作

状态管理

  1. 16. DeepImmutable + Mutable 分层 — 渲染性能 + 灵活性
  2. 17. Promise 记忆化 — 并发安全的一次性操作

工具系统

  1. 18. 工具元数据声明 — isReadOnly / isDestructive / isConcurrencySafe
  2. 19. 阻塞限制前置检查 — 在调用 API 之前先检查 token 预算

性能优化

  1. 20. 启动时并行 I/O — 在模块加载的”死时间”里做并行操作
  2. 21. 流式一切 — AsyncGenerator 作为核心数据管道
  3. 22. 死代码消除 — 编译时 feature() 条件加载

六、结语

Claude Code 的出现标志着 AI 编码助手进入了一个新的阶段——从「问答式」向「自主式」转变。它的架构设计告诉我们:构建一个可靠的 Agentic 系统,需要的不仅是 LLM API,还需要:

  • • 一个健壮的核心循环
  • • 精细的上下文管理
  • • 灵活的工具框架
  • • 纵深防御的安全模型
  • • 持久化的记忆系统
  • • 以及无处不在的工程纪律

这个系列将逐层深入 Claude Code 的每一个子系统,希望能为你构建自己的 Agentic 系统提供启发。


📚 系列文章目录

本系列共7篇,系统性地拆解 Claude Code 的架构设计:

篇目
标题
核心内容
原文链接
01 总览与架构哲学
六层架构、七大设计哲学、核心数据流
阅读原文[1]
02
查询循环与上下文管理
while(true)循环、五层压缩、错误恢复
阅读原文[2]
03
工具系统设计
buildTool工厂、工具注册、MCP集成
阅读原文[3]
04
多代理架构
Agent Swarm、Fork、Coordinator、Worktree
阅读原文[4]
05
权限与安全
三层防御、四种模式、ResolveOnce
阅读原文[5]
06
记忆与状态管理
四类记忆、推测执行、DeepImmutable
阅读原文[6]
07
工程实践启示录
22个设计模式、Feature Flag、实战清单
阅读原文[7]

参考资料:

  • • 项目地址:https://github.com/aga-j/claude-code-deep-dive
  • • 作者:Wyman Wu (AI Product Manager)
  • • 源码基础:Claude Code ~512K 行 TypeScript 源码

本系列基于开源项目源码解读,仅供学习研究使用。

引用链接

[1] 阅读原文: https://github.com/aga-j/claude-code-deep-dive/blob/main/01-architecture-overview.md[2] 阅读原文: https://github.com/aga-j/claude-code-deep-dive/blob/main/02-query-loop-and-context.md[3] 阅读原文: https://github.com/aga-j/claude-code-deep-dive/blob/main/03-tool-system.md[4] 阅读原文: https://github.com/aga-j/claude-code-deep-dive/blob/main/04-multi-agent-architecture.md[5] 阅读原文: https://github.com/aga-j/claude-code-deep-dive/blob/main/05-permissions-and-security.md[6] 阅读原文: https://github.com/aga-j/claude-code-deep-dive/blob/main/06-memory-and-state.md[7] 阅读原文: https://github.com/aga-j/claude-code-deep-dive/blob/main/07-engineering-insights.md