Claude Code 源码深度解析

深入一个 AI 编程助手的内核实现。

你每天在终端里敲 claude,回车之后到出现提示符之间发生了什么?它凭什么敢替你改文件、跑命令,又凭什么在某些命令前停下来问你?当它同时调用三个工具时,谁来保证它们不互相踩踏?

这些问题的答案都写在源码里。本专栏以 Claude Code 完整源码(2026.3.31 泄露版本)为解剖对象——51 万行代码、40+ 工具、80+ 命令——逐层拆开它的每一个子系统。("51 万行"是整仓、含测试的口径;若只统计 src/ 一棵子树下的 .ts,实测是 379997 行——两个数不矛盾但不可互换,口径说明见第1章。)

flowchart TB
  CLI[CLI 启动<br/>三阶段 · 并行预加载 · 快速路径] --> Q
  subgraph Q [Query 引擎 · 两层架构]
    direction LR
    HI[QueryEngine.ts<br/>会话层编排] --> LO[query.ts<br/>循环状态机]
  end
  Q --> TS[工具系统<br/>自描述 · Zod 校验 · 注册表]
  TS --> PERM{权限<br/>静态规则 + 动态分类器}
  PERM -->|放行| EXEC[并发编排<br/>并发安全标记]
  PERM -->|需确认| ASK[用户确认 / 拒绝追踪]
  EXEC --> UI[终端 UI · React 渲染]
  TS -.-> MCP[MCP 集成<br/>外部工具接入]
  TS -.-> BR[Remote Control Bridge<br/>JWT · 会话 · 权限转发]
  Q -.-> SUB[多 Agent<br/>上下文隔离]

无论你是否使用 Claude Code,这些设计模式都是你构建自己的 Agent 系统时会遇到的同一批问题——区别只在于,这里有一份被大量开发者日常使用的答案可以对照。

读完你能做到什么

  1. 说清一次 Agent 循环的完整生命周期。 从 QueryEngine.ts 的会话层编排到 query.ts 的循环状态机,包括停止条件的完整图谱与 AsyncGenerator 为什么是这里的正确抽象(第4章 Query 引擎、第5章 流式消息)。
  2. 设计一套自描述、可校验、能并发的工具系统。 Tool 类型定义、Zod 运行时校验、工具注册表、渲染体系,以及那个决定谁能和谁一起跑的「并发安全标记」(第6章 工具类型系统、第7章 工具编排、第8章 核心工具)。
  3. 实现一个既安全又不烦人的权限模型。 七种权限模式(六种用户可选 + 一种仅内部使用的 bubble)、useCanUseTool 这个钩子怎么把静态规则匹配与动态分类器串起来、拒绝行为如何被追踪与分析、多 Agent 场景下权限怎么继承(第9章 权限模型、第10章 沙箱)。
  4. 把启动时间当成一个工程指标来优化。 启动的三个阶段、并行预加载、特性标志驱动的死代码消除、--bare 极简路径——「从第一个字节到交互式提示符」这段路上每一毫秒花在哪(第3章 CLI 启动)。
  5. 把 Agent 接进远端界面和外部工具生态。 MCP 服务器的生命周期、工具发现与调用、通道通知;以及 Remote Control(Bridge)的 JWT 认证、会话管理与权限对话转发(第11章 MCP 集成、第12章 Remote Control 桥接架构、第13章 LSP)。
  6. 用 React 写终端界面。 为什么是 React、它在终端里怎么协调流式输出与用户输入(第17章 终端 UI)。

这个专栏的讲法

读的是源码,不是文档。 每一章都落到具体的文件、类与函数上——useCanUseTool 怎么写的、Tool 注册表长什么样、状态机有哪几个停止条件。不是"Claude Code 支持权限管理"这种介绍性描述。

大多数章末尾有「设计决策分析」。 这是这个专栏与「源码导读」的分界线:不只说它怎么做的,还说它为什么不那样做——两层 Query 架构为什么要拆、权限为什么要静态规则加动态分类器两条腿走路、并发标记为什么放在工具自己身上。这些取舍才是能迁移到你自己系统里的东西。

从启动到收尾,覆盖一个完整的 Agent。 18 章按运行顺序排列:启动 → 循环 → 工具 → 权限 → 扩展(MCP / Remote Control / LSP / 多 Agent / Skill 与插件) → 上下文管理 → UI → 设计模式总结(第18章)。读完你手里是一张完整的架构图,不是一堆知识点。

适合谁读

不适合:找 Claude Code 使用教程的读者(这里不讲怎么用),以及没有工程背景、只想了解 AI 概念的读者。

源码版本

本专栏基于 Claude Code 2026.3.31 源码快照——对应 npm 包 @anthropic-ai/claude-code@2.1.88(2026-03-30 22:36 UTC 发布,即北京时间 3 月 31 日)随包分发的 source map(cli.js.map)所还原出的 TypeScript 源码树。这个版本随后从 npm 下架,下一版 2.1.89(2026-03-31 23:32 UTC 发布)起不再带 source map。

需要先说清楚:这份源码今天已经拿不到了,否则你会白白花时间去找。

所以本专栏引用的文件路径和行号,对照的是那一份已不可再获取的快照。这意味着你没法像读其他源码专栏那样 checkout 一棵树来逐行核对——正文因此尽量以模块职责、函数名和调用关系为锚点来讲,而不是把结论压在某个行号上。把它当作一份对已发生实现的记录来读,而不是一份可复现的实验。

但有一半是可以核的,值得说清楚边界在哪。 压缩过的 cli.js 里标识符被重命名了(BASH_SECURITY_CHECK_IDS 这类源码常量名一个都留不下),字符串字面量却原样保留——斜杠命令的 name:"…"、process.env.XXX 读的环境变量名、tengu_* 遥测事件名、工具的对外名字,都能在 npm pack @anthropic-ai/claude-code@2.1.89 解出来的那一个文件里 grep 到。2.1.89 比快照晚一天发布、是今天能拿到的最近一版,个别名字可能在这一天里有增减。所以:

目录

第一部分:开篇

第二部分:启动与核心循环

第三部分:工具系统

第四部分:权限与安全

第五部分:协议与集成

第六部分:Agent 进阶

第七部分:终端 UI 与工程实践

版权声明

本专栏内容为 杨艺韬 版权所有,保留一切权利。未经书面许可,不得全文或大段转载、改编、翻译,或用于任何商业用途(含以本专栏内容训练模型、生成衍生课程或商品)。

欢迎分享本专栏的链接。引用少量内容用于评论、教学或研究时,请署名 杨艺韬 并附上原文链接。