Claude Code源码深度技术解析:AnthropicAI编程助手的架构全貌

从启动编排、工具执行到权限治理的 Claude Code实现原理解剖

Posted by 爱折腾的工程师 on Wednesday, April 1, 2026

一、引言:一次意外的源码曝光

2026年3月31日,安全研究者 @Fried_rice 发现 Claude Code 的 npm 发布包中残留了 .map 文件(Source Map),该文件指向了 Anthropic 存储在 R2 桶中的未混淆 TypeScript 源码。这一构建产物泄露事件,让我们得以窥见这款当前最热门 AI 编程 CLI 工具的完整内部实现。

声明:本文基于公开可获取的源码快照进行纯技术架构分析,仅用于学习和研究目的。

本文导读

  • 先建立全局认知:第二节先用一张总览图,把 Claude Code 的 CLI 入口、QueryEngine、工具系统、Bridge 与权限/插件体系串起来。
  • 再抓主执行链路:第三到第六节依次拆解启动流程、Agentic Loop、工具系统与权限系统,这是 Claude Code 最核心的工程主线。
  • 最后看扩展能力:第八到第十二节重点分析终端 UI、IDE Bridge、多 Agent 协作以及插件/技能系统。
  • 适合阅读人群:如果你关心 AI Coding Agent、终端 UI、权限治理或 CLI 工程化,这篇文章会比较有参考价值。

项目概貌

指标 数据
语言 TypeScript (strict mode)
运行时 Bun
终端 UI React + Ink (深度定制 fork)
工程特征 多模块分层、强工具化、重状态管理
CLI 解析 Commander.js (extra-typings)
Schema 验证 Zod v4
代码搜索 ripgrep
协议支持 MCP SDK, LSP
遥测 OpenTelemetry + gRPC
特性开关 GrowthBook
认证 OAuth 2.0, JWT, macOS Keychain

二、整体架构概览

如果你只想先建立 Claude Code 的整体心智模型,先看下面这张总览图。

Claude Code 整体架构

看图重点:从上到下依次是 CLI 入口、REPL 终端 UI、QueryEngine、工具系统,以及命令/服务/Bridge 三组外围能力;最底层则是状态、权限、插件与技能这些基础支撑层。

2.1 高层架构

Claude Code 的架构可以分为以下核心层次:

  • CLI 入口层main.tsx 基于 Commander.js 完成参数解析、命令路由和启动编排。
  • 交互层REPL + 自定义 Ink 渲染器负责终端 UI、消息流和输入体验。
  • 推理层QueryEngine 负责上下文组装、模型调用、流式输出与工具调用循环。
  • 执行层:40+ 工具组成 Claude Code 的动作面,包括文件读写、命令执行、搜索、网络访问和 Agent 调度。
  • 外围能力层:命令系统、服务层和 Bridge 共同提供 CLI 工作流、外部集成与 IDE 协作能力。
  • 基础支撑层:状态管理、权限系统、插件系统与技能系统构成整套运行时底座。

2.2 目录结构

src/
├── main.tsx                 # 入口编排 (Commander.js CLI)
├── commands.ts              # 命令注册中心
├── tools.ts                 # 工具注册中心
├── Tool.ts                  # 工具类型定义
├── QueryEngine.ts           # LLM 查询引擎核心
├── context.ts               # 系统/用户上下文收集
├── cost-tracker.ts          # Token 费用追踪
├── commands/                # 斜杠命令实现
├── tools/                   # Agent 工具实现
├── components/              # Ink UI 组件
├── hooks/                   # React Hooks
├── services/                # 外部服务集成
├── screens/                 # 全屏 UI (Doctor, REPL, Resume)
├── utils/                   # 工具函数库
├── bridge/                  # IDE 远程控制桥接
├── coordinator/             # 多 Agent 协调器
├── plugins/                 # 插件系统
├── skills/                  # 技能系统
├── keybindings/             # 快捷键配置
├── vim/                     # Vim 模式
├── voice/                   # 语音输入
├── remote/                  # 远程会话
├── memdir/                  # 持久化记忆目录
├── tasks/                   # 后台任务管理
├── state/                   # 全局状态管理
├── ink/                     # Ink 渲染器深度定制 Fork
└── entrypoints/             # 各种入口点逻辑

三、启动流程深度剖析

启动链路是理解 Claude Code 性能优化思路的最好切口,下面这张图把主流程压缩成了四个阶段。

Claude Code 启动流程

看图重点:真正影响冷启动体验的,不只是 main.tsx 本身,而是它在重量级模块评估之前就并行发起了配置预读、Keychain 预取和 API 预连接。

3.1 入口点:main.tsx

main.tsx 是整个应用的启动编排入口,它承担了:

  1. Commander.js CLI 解析:定义所有命令行参数和子命令
  2. 并行预取优化:在模块加载之前就开始预取关键数据
  3. React/Ink 渲染器初始化:启动终端 UI

把这条链路拆开来看,可以进一步归纳为四个启动阶段:

  1. 并行预取阶段:提前触发 startMdmRawRead()startKeychainPrefetch()apiPreconnect(),把耗时 I/O 往前挪。
  2. CLI 解析阶段:通过 program.option()program.action() 完成参数定义、命令路由与入口分发。
  3. 环境引导阶段:进入 bootstrap/state.ts,加载配置、认证状态、GrowthBook 特性开关和 MCP 连接。
  4. 终端渲染阶段:最终执行 render(<App />),把运行时状态装配到 REPL 主界面上。

并行预取是 Claude Code 的一个重要性能优化模式。在任何重量级模块被评估之前,就已经通过副作用启动了 MDM 设置读取、Keychain 预取和 API 预连接:

// main.tsx — 在其他 import 之前作为副作用触发
startMdmRawRead()
startKeychainPrefetch()

3.2 环境引导:bootstrap/state.ts

bootstrap/state.ts 更像一个“启动状态机”,核心不是简单加载配置,而是把信任建立、环境生效和外部依赖初始化排成一条有先后顺序的链路:

  • 先启用配置系统:打开多层配置解析能力,但在信任建立前只应用“安全环境变量”。
  • 尽早处理 TLS 前置条件:例如把 NODE_EXTRA_CA_CERTS 这类证书配置提前注入进程环境,避免首次握手后再改配置失效。
  • 异步预热非关键能力:如一方事件日志、OAuth 账户信息、JetBrains 检测、仓库识别、远程设置加载 Promise,尽量不阻塞首屏。
  • 收拢运行时状态:在真正进入 REPL 前,把认证状态、GrowthBook 特性开关、MCP 连接和权限模式统一收敛到可消费状态。

3.3 延迟加载策略

重量级模块(OpenTelemetry、gRPC、分析引擎、特性门控子系统)通过动态 import() 延迟到实际需要时才加载:

// 条件加载示例
import { feature } from 'bun:bundle'

const voiceCommand = feature('VOICE_MODE')
  ? require('./commands/voice/index.js').default
  : null

已知的特性开关包括:PROACTIVEKAIROSBRIDGE_MODEDAEMONVOICE_MODEAGENT_TRIGGERSMONITOR_TOOL。这些开关通过 Bun 的 bun:bundle 实现编译时死代码消除,未激活的功能代码会在构建时被完全剥离。


四、查询引擎:QueryEngine.ts

4.1 核心职责

QueryEngine.ts 是 Claude Code 与 LLM 交互的核心引擎,处理:

  1. 接收输入:读取用户消息,并准备本轮推理所需的上下文。
  2. 组装上下文:把 context.tsCLAUDE.md 规则、memdir 记忆、MCP 资源等拼进请求体。
  3. 调用模型:通过 services/api/claude.ts 发起流式 API 请求,并处理 thinking mode、prompt cache、重试和错误恢复。
  4. 分叉处理结果:如果返回的是文本,就直接渲染到终端;如果返回的是工具调用,就进入权限检查、执行工具、结果回灌,再继续下一轮推理。

4.2 工具调用循环(Agentic Loop)

在 Claude Code 里,真正把“聊天”变成“编程代理”的,并不是模型本身,而是下面这个持续运转的执行循环。

Agentic Loop 工作流程

看图重点:一次看似简单的对话,底层往往会经历“模型输出 → 工具执行 → 结果回灌 → 再次推理”的多轮迭代,直到产出最终文本结果。

这是 Claude Code 最核心的机制 — 工具调用循环(也称 Agentic Loop):

  1. 将用户消息 + 系统提示 + 对话历史发送给 Claude API。
  2. 如果 Claude 返回工具调用请求(如 BashToolFileEditTool):
    • 先检查该工具是否真的可用,以及当前输入是否通过权限与安全校验。
    • 再根据工具特性决定并发执行还是串行执行:只读、可并发的调用会被批量调度;带副作用的调用则按顺序执行,避免上下文互相污染。
    • 工具执行过程中,结果消息与上下文修改器会被持续收集,并在合适时机回写到消息历史与运行时上下文。
    • 工具结果回灌后,重新调用 API,形成下一轮推理。
  3. 如果 Claude 返回纯文本响应,循环结束。

4.3 API 客户端:services/api/claude.ts

这是与 Anthropic API 通信的核心客户端,它的实现重点不在“把请求发出去”,而在于把模型调用改造成可恢复、可缓存、可观测的运行链路:

  • 流式响应处理:逐 token 接收并实时渲染,让终端交互具有持续反馈感。
  • Prompt Cache 感知:通过 promptCacheBreakDetection.ts 识别哪些上下文变动会打断缓存命中,从而减少无谓的重复计算。
  • 重试与恢复withRetry.ts 负责指数退避与失败恢复,把瞬时网络问题从“整轮失败”降成“局部重试”。
  • 错误分层errors.ts 区分限流、认证失败、网络错误等异常类型,避免所有失败都落到同一套处理路径里。
  • 预算控制tokenEstimation.ts 在请求发出前做 token 估算,让上下文裁剪和模型选择更可控。

4.4 上下文压缩:services/compact/

当对话上下文过长时,Claude Code 有一套精密的压缩机制:

compact/
├── compact.ts              # 核心压缩逻辑
├── autoCompact.ts          # 自动压缩触发器
├── microCompact.ts         # 微压缩 — 轻量级摘要
├── apiMicrocompact.ts      # API 级微压缩
├── sessionMemoryCompact.ts # 会话记忆压缩
├── prompt.ts               # 压缩提示词
└── grouping.ts             # 消息分组策略

压缩流程:对话历史 → 分组 → 生成摘要 → 替换原始消息 → 保留关键上下文。用户可通过 /compact 命令手动触发。


五、工具系统深度解析

工具系统决定了 Claude Code 能做什么,也决定了它为什么能从“回答问题”走向“直接改代码”。

工具系统架构

看图重点:可以把工具看作 QueryEngine 的“手脚”,其中 BashToolFileEditToolAgentTool 分别对应命令执行、文件修改和多 Agent 协作三类关键能力。

5.1 工具架构

每个工具都是一个自包含模块,但它们并不是一堆平铺的脚本,而是共享同一套运行时约定:

  • 输入层:每个工具都通过 Zod Schema 声明输入边界,先做结构校验,再进入执行逻辑。
  • 权限层:工具既可以复用统一权限管线,也可以在自身实现里追加更细粒度的安全判断。
  • 执行层:真正的执行逻辑与 UI 展示分离,方便在终端、IDE 桥接层和自动模式之间复用。
  • 上下文层:工具不仅返回结果消息,还可能回写上下文修改器,影响后续轮次的可见状态。

从职责上看,工具目录里最关键的几类实现包括:

  • BashTool/:负责 shell 命令执行,同时内置命令语义分析、权限规则、路径校验和沙箱策略。
  • FileEditTool/:负责局部文件修改,核心难点在于字符串替换、diff 展示和编辑安全边界。
  • AgentTool/:负责生成和调度子 Agent,把复杂任务拆成可并行或可验证的子问题。
  • 其他基础工具:包括文件读取、写入、搜索、网络获取、LSP 集成、MCP 调用、计划模式与任务列表管理等。

5.2 Tool 基类型:Tool.ts

Tool.ts 定义了所有工具共享的抽象接口,核心包括:

  • 输入 Schema:约束模型传入的数据结构。
  • 权限模型:声明哪些操作需要用户批准、哪些操作可自动放行。
  • 执行入口:把工具输入映射为实际行为。
  • 进度状态:让终端与 IDE 能持续展示工具执行状态。
  • UI 组件:让工具结果不只是文本,还能带有差异视图、进度条或结构化展示。

5.3 关键工具类型

工具 作用 实现重点
BashTool Shell 命令执行 命令安全分析、规则匹配、路径校验、沙箱执行
FileReadTool 文件读取 支持文本、图片、PDF、Notebook 等多种输入
FileWriteTool 文件创建/覆盖 负责一次性写入和落盘边界控制
FileEditTool 局部文件修改 基于字符串替换与 diff 展示实现最小改动
GlobTool / GrepTool 文件和内容搜索 为模型提供低成本、高命中率的代码检索能力
WebFetchTool / WebSearchTool Web 获取 连接外部文档与实时信息源
AgentTool 子 Agent 调度 任务拆解、上下文隔离、结果汇总
SkillTool / MCPTool / LSPTool 外部能力扩展 把技能、MCP 服务和语言服务统一接入工具层
TodoWriteTool / TeamCreateTool / SendMessageTool 协作编排 支撑多 Agent 协作、任务追踪和消息传递

5.4 BashTool 安全机制深度分析

如果说 Claude Code 的工程壁垒在哪里,BashTool 的安全设计大概率是最有代表性的一个点。

BashTool 五层安全模型

看图重点:这不是单点拦截,而是“命令分析 + 权限规则 + 只读判定 + 路径校验 + Sandbox”叠加起来的组合防线。

BashTool 是 Claude Code 中实现最重、边界最多的工具之一,其安全机制值得单独分析:

  1. Layer 1 — bashSecurity.ts:负责命令黑名单检测、危险模式识别、网络操作审计,以及密码/密钥相关操作拦截。
  2. Layer 2 — bashPermissions.ts:负责基于规则的权限匹配、路径白名单/黑名单校验、只读操作自动批准,以及危险操作的显式确认。
  3. Layer 3 — readOnlyValidation.ts:从命令语义、参数副作用和环境变量修改三个角度判断这次调用是否真的“只读”。
  4. Layer 4 — pathValidation.ts:负责工作区边界检查、符号链接跟随检测,以及 ~/.ssh/etc/passwd 这类敏感路径保护。
  5. Layer 5 — sedValidation.ts:专门处理 sed 这类内联编辑命令的解析与验证,防止“看起来像读操作,实际上带写入”的绕过场景。

此外还有 Sandbox 模式shouldUseSandbox.ts),可以在容器化环境中执行不可信命令。

5.5 AgentTool:子 Agent 生成

AgentTool 是实现多 Agent 协作的核心工具:

它的运行模型可以概括成三层:

  • 主 Agent:直接与用户交互,负责拆分任务、下发子任务和汇总结果。
  • 子 Agent:按目标拿到不同工具集,例如只读探索型 Agent 更偏向 Read/Grep,执行型 Agent 更偏向 Bash
  • 结果回流层:子 Agent 完成工作后把结果回传给主 Agent,再由主 Agent 生成最终答复或继续调度下一轮任务。

内置 Agent 类型:

  • exploreAgent:专门用于代码库探索,只配备只读工具
  • planAgent:专注于制定执行计划
  • verificationAgent:验证代码变更的正确性
  • generalPurposeAgent:通用子 Agent

六、权限系统

Claude Code 真正难做的不是“能不能调用工具”,而是“调用工具时如何把风险控制在工程上可接受的范围内”。

权限系统决策流程

看图重点:这里不是简单的弹窗确认,而是把 bypassPermissionsautoplandefault 四种模式与规则匹配、YOLO 分类器和用户确认机制编排成一条完整决策链。

6.1 权限模式

Claude Code 实现了一个精密的分层权限系统:

  • bypassPermissions:跳过所有确认,直接执行,适合完全受信任环境。
  • auto(YOLO 模式):交给 yoloClassifier.ts 自动判断当前操作是安全还是危险。
  • plan:先提交计划,待用户审批后再执行。
  • default:每次工具调用都要经过用户确认。

6.2 权限规则引擎

权限规则存储在 .claude/settings.json 中,支持:

  • 工具级规则:针对特定工具(如 BashTool)设置策略
  • 路径级规则:针对特定目录/文件设置读写权限
  • 命令级规则:针对特定 shell 命令设置允许/拒绝
  • Glob 匹配:支持通配符路径模式

权限决策流程可以概括为五步:

  1. 接收工具调用请求:先判断当前会话运行在哪种 PermissionMode 下。
  2. 检查显式规则:优先匹配 .claude/settings.json 中已有的 allow/deny 规则。
  3. 快速放行特殊模式:如果是 bypassPermissions,则直接跳过确认流程。
  4. 进入自动判断或人工确认:在 auto 模式下交给 YOLO 分类器评估风险;若不满足自动批准条件,则弹出确认对话框。
  5. 执行工具:只有在规则、分类器或用户确认三者之一给出“允许”之后,工具才会真正执行。

6.3 YOLO 分类器

yoloClassifier.ts 实现了 auto 模式下的命令安全分类器。它的关键价值不只是“替用户点一次允许”,而是把规则系统、上下文状态和历史拒绝信息一起纳入判断:

  • 命令语义:区分读操作、写操作和执行操作。
  • 操作范围:区分单文件修改和全局性动作。
  • 路径敏感度:区分项目内路径与系统目录、敏感目录。
  • 历史批准模式:结合已有拒绝/允许历史,避免在连续高风险场景下过度乐观。
  • 规则净化:在进入 auto 模式前,系统还会主动剥离那些可能绕过分类器的危险 allow 规则,避免“规则先放行、分类器失效”的情况。

七、命令系统

7.1 命令注册:commands.ts

所有斜杠命令通过 commands.ts 注册和管理,支持条件加载。按职责来看,大致可以分成五类:

  • 开发工作流/commit/review/diff/branch/plan
  • 上下文管理/compact/context/memory/resume/files
  • 系统配置/config/model/theme/vim/permissions
  • 扩展集成/mcp/skills/plugin/hooks/agents
  • 运维诊断/doctor/cost/stats/login/export

7.2 特色命令:ultraplan

ultraplan.tsx 本质上不是一个“在本地生成计划”的普通命令,而是把复杂任务切到远端 plan mode 的调度器。它的实现链路大致分成四步:

  • 前置校验:先通过 checkRemoteAgentEligibility() 检查远端执行资格,避免在登录态、策略或环境不满足时盲目启动。
  • 远端建会话:调用 teleportToRemote({ permissionMode: 'plan', ultraplan: true }),把当前任务描述和可选 seedPlan 打包发到 Claude Code on the web。
  • 本地注册后台任务:成功建会话后,本地立即注册 RemoteAgentTask,并用 startDetachedPoll() 在后台轮询远端状态。
  • 扫描审批结果:轮询逻辑最终进入 pollForApprovedExitPlanMode(),从远端事件流里识别 ExitPlanModetool_use / tool_result,再根据结果分成两条路径:
    • 用户选择继续在 web 端执行:本地只负责跟踪状态,远端继续编码。
    • 用户选择teleport 回终端:通过 ULTRAPLAN_TELEPORT_SENTINEL 把批准后的计划回传本地,再由 REPL 弹层接管后续动作。

所以,ultraplan 真正有意思的地方不在“计划文本长不长”,而在它把远程规划、人工审批、执行位置切换做成了一套可恢复的状态机。

7.3 特色命令:insights

insights.ts 也不是一个简单的“统计报表命令”,而是一条先离线聚合,再用模型做结构化解释的数据分析流水线:

  • 轻量扫描阶段scanAllSessions() 先扫本地会话目录,只读取文件系统元数据,不急着解析整份日志。
  • 缓存优先阶段:优先命中 loadCachedSessionMeta() / loadCachedFacets(),只对未命中的会话批量解析 jsonl,降低首次分析以外的重复成本。
  • 数据净化阶段:过滤 /insights 自己生成的 meta-session,并按 session_id 去重 conversation branches,避免同一会话分叉把统计结果放大。
  • 结构化洞察阶段:将会话聚合数据、facet 摘要、friction 细节和用户指令拼成 fullContext,再用 Promise.all(...) 并行生成多个 section 的 JSON 结果。
  • 报告输出阶段:最终把结构化结果渲染成 HTML,并写入 report.html,而不是只在终端吐一段文本。

这说明 insights 的重点并非“统计了多少字段”,而是把会话扫描、缓存利用、特征提取、模型归纳和报告生成串成了一条完整分析链路。


八、终端 UI 系统:React + Ink 深度定制

很多人第一次看到 Claude Code,都容易把它理解成“一个命令行聊天壳”;但从 UI 实现上看,它其实更像一套运行在终端里的轻量 IDE。

终端 UI 系统架构

看图重点:最上层是 REPL.tsx 主界面,中间是输入、消息、状态与设计系统,最底层则是 Anthropic 深度改造过的 Ink 渲染栈和终端 I/O 抽象。

8.1 自定义 Ink Fork

Claude Code 没有直接把社区版 Ink 当黑盒来用,而是维护了一套 深度定制 Fork。从源码看,它主要补了六类能力:

  • 渲染主干ink/ink.tsxrender-node-to-output.ts 负责终端节点树到字符缓冲区的落地过程。
  • 屏幕控制ink/screen.tsink/selection.ts 让终端界面具备更强的屏幕管理与文本选择能力。
  • 组件重写App.tsxScrollBox.tsxButton.tsxText.tsx 等高频组件都做了终端场景适配。
  • 事件系统click-event.tskeyboard-event.tsterminal-focus-event.ts 把鼠标、键盘和焦点事件统一成可消费的输入模型。
  • 终端协议处理parser.tstokenize.tssgr.tscsi.tsosc.ts 负责 ANSI/CSI/OSC 等序列解析。
  • 布局系统ink/layout/yoga.ts 把 Flexbox 风格布局迁移到了终端字符坐标系里。

8.2 REPL 主界面:screens/REPL.tsx

如果只看产品形态,REPL.tsx 像“聊天主屏”;但从实现上看,它更像 Claude Code 的终端运行时容器

  • 消息状态编排messagesRef + setMessages() 采用 eager apply 方式,确保 React 状态尚未完成渲染时,逻辑层也能立即读到最新消息数组。
  • 历史按需加载useAssistantHistory() 在滚动上翻时才加载更旧历史,而不是一开始把全部消息塞进内存。
  • Hook 延迟注入useDeferredHookMessages() 允许 REPL 先渲染,再把 SessionStart hook 结果补进消息流,同时保证首次真正发起 query() 前这些上下文已经到位。
  • 查询流消费onQueryImpl() 组装 systemPromptuserContexttoolUseContext,随后 for await ... of query(...) 持续消费模型输出与工具事件。
  • 并发守卫QueryGuard 让 REPL 能在已有轮次运行时拦截并排队新的用户输入,避免多轮推理并发污染同一份状态。
  • 弹层与工作流汇合点:权限确认、MCP elicitation、ultraplan 启动/回传选择、退出流程等都由同一套 focusedInputDialog / overlay 机制统一驱动。
  • 桥接入口useReplBridge() 把远程控制、权限回执、中断信号和会话状态同步接到 REPL 主循环上。

8.3 关键 UI 组件

从职责划分看,REPL 周围最关键的组件并不是“谁最大”,而是谁承担了哪些交互责任:

  • PromptInput.tsx:负责输入、自动补全、引用粘贴、语音相关状态与提交前处理。
  • Messages.tsx / VirtualMessageList.tsx:负责消息渲染、分组、折叠以及长对话下的虚拟滚动。
  • ScrollKeybindingHandler.tsx:把终端里的滚动与快捷键导航统一成一套可预测行为。
  • LogSelector.tsx / Stats.tsx:承担诊断、筛选和可观测性相关 UI。
  • Feedback.tsx:承接用户反馈与产品内回流机制。

8.4 设计系统

Claude Code 还内建了一套终端设计系统(components/design-system/),把常见交互原语统一起来:

  • ThemeProvider.tsx:主题管理
  • Dialog.tsx:模态对话框
  • Tabs.tsx:标签页交互
  • FuzzyPicker.tsx:模糊搜索选择器
  • ProgressBar.tsx:进度可视化
  • ThemedBox / ThemedText:主题化布局与文本抽象

九、Bridge 桥接系统:IDE 集成

Bridge 是 Claude Code 从“纯 CLI 工具”走向“可嵌入 IDE 的协作编程环境”的关键转折点。

Bridge 桥接系统架构

看图重点:上层是 VS Code / JetBrains 扩展,中间是 Bridge 主循环、消息协议与安全/传输层,下层才回到 CLI REPL 本体,三层之间通过 WebSocket + JWT 维持双向同步。

9.1 架构总览

Bridge 不是单纯的“IDE 消息转发器”,而是一套在 IDE 与本地 REPL 之间维持会话状态一致性的协议层。

可以从三条链路来理解:

  • REPL 接入层useReplBridge.tsx 在 React 侧把 onInboundMessageonPermissionResponseonInterruptonSetPermissionMode 这些回调接入 REPL。
  • 初始化层initReplBridge.ts 负责运行时 gate、OAuth 检查、组织策略校验、title 推导以及选择走旧桥还是新桥。
  • 核心传输层
    • replBridge.ts 是旧的 env-based 路线:先注册环境,再轮询 work item,拿到 ingress token 后接入消息流。
    • remoteBridgeCore.ts 是新的 env-less 路线:直接 POST /v1/code/sessions 创建会话,再 POST /bridge 换取 worker_jwt,随后建立 SSE + CCR 写通道。

消息层则由 bridgeMessaging.ts 统一负责:既要过滤哪些消息适合桥接,也要处理 control_request / control_response、初始化请求、权限模式切换和中断指令。

9.2 关键能力

从源码看,Bridge 最关键的工程点有四个:

  • 历史与实时消息顺序保证FlushGate 会在初始历史 flush 期间暂存 live writes,避免“旧消息还没补完,新消息先到”的乱序问题。
  • 回声与重放去重BoundedUUIDSet 用于处理 echo/replay,避免本地刚发出的消息又被服务端回放成一条“新消息”。
  • 权限回执与控制协议:远端客户端回复 control_response 后,Bridge 侧会同步调用 reportState('running'),让服务端知道这一轮可以继续推进。
  • 重连与令牌刷新:env-less 路线通过 createTokenRefreshScheduler() 定时刷新 JWT;如果 SSE 因 401 关闭,则重建 transport,而不是直接让会话失效。

因此,Bridge 真正难的地方不是“能连上 IDE”,而是如何在消息顺序、鉴权刷新、状态恢复和双向控制之间保持一致性。


十、多 Agent 协作系统

如果说 Agentic Loop 解决的是“单个代理如何工作”,那多 Agent 系统解决的就是“多个代理如何并行协作”。

多 Agent 协作架构

看图重点:主 Agent 更像一个协调器,它通过 TeamCreateToolSendMessageTool、共享记忆和邮箱轮询机制,把多个子 Agent 组织成一套可通信的团队。

10.1 协调器:coordinator/coordinatorMode.ts

coordinatorMode.ts 的重点并不是实现一个复杂调度器,而是在 prompt 层显式约束主 Agent 的职责

  • isCoordinatorMode() 用特性开关 + 环境变量决定是否进入协调器模式。
  • getCoordinatorUserContext() 会把 worker 可用工具、MCP 服务器和 scratchpad 路径注入上下文,让主 Agent 清楚“手下的人”能做什么。
  • getCoordinatorSystemPrompt() 则把主 Agent 限定为 orchestration 角色:能启动 worker、继续 worker、停止 worker,但不应把 trivially answerable 的问题滥发出去。
  • worker 的结果不会伪装成普通模型输出,而是以 <task-notification> XML 形式回到主线程,再由主 Agent 继续综合、追问或二次调度。

这意味着 Claude Code 的多 Agent 协作,核心首先是职责收窄与消息协议设计,其次才是后台任务执行。

10.2 子 Agent 与任务执行

真正把“协调器模式”落到 runtime 的关键,在 runAgent.ts 和任务系统本身:

  • 上下文分叉runAgent.ts 会为子 Agent 生成独立 agentId,fork 当前上下文消息,并在需要时过滤不完整工具调用。
  • 缓存与权限继承:它会克隆或新建 read-file cache,同时根据 agent 定义覆盖 permission mode、effort 等运行参数。
  • 子上下文构建:通过 createSubagentContext() 生成独立执行环境,再把 prompt、工具池和系统提示装配进去。
  • 持久化观测面recordSidechainTranscript()writeAgentMetadata() 会把 sidechain transcript 和 agent 元数据落盘,方便恢复与调试。
  • 任务抽象:后台执行单元又被拆成 LocalAgentTaskRemoteAgentTaskLocalShellTaskInProcessTeammateTaskDreamTask 等类型,各自对应本地子 Agent、远端子 Agent、本地 shell 和进程内协作者等场景。
  • 周期性摘要startAgentSummarization() 会大约每 30 秒 fork 一次无工具子上下文,只生成 3–5 个词的进度摘要,持续刷新 UI 中的 worker 状态。

10.3 记忆系统:memdir/

多 Agent 并发之后,真正的问题就不再是“能不能多开几个 worker”,而是这些 worker 如何共享长期上下文

memdir/ 负责这件事:

memdir/
├── memdir.ts                  # 记忆目录核心
├── memoryTypes.ts             # 记忆类型定义
├── findRelevantMemories.ts    # 相关记忆检索
├── memoryScan.ts              # 记忆扫描
├── paths.ts                   # 存储路径管理
├── teamMemPaths.ts            # 团队记忆路径
└── teamMemPrompts.ts          # 团队记忆提示词

services/extractMemories/
├── extractMemories.ts         # 自动记忆提取
└── prompts.ts                 # 记忆提取提示词

它既承担跨会话知识沉淀,也承担团队模式下的共享记忆路径约定,让主 Agent 与多个 worker 在不同时间点仍能围绕同一批长期信息继续协作。


十一、服务层深度解析

11.1 MCP 集成:services/mcp/

MCP(Model Context Protocol)是 Claude Code 连接外部工具和数据源的核心协议:

  • 客户端核心client.ts 负责 MCP 客户端的主逻辑。
  • 配置与认证config.ts 负责配置管理,auth.ts 处理 OAuth 与认证接入。
  • 连接管理useManageMCPConnections.ts 负责连接状态管理。
  • 安全与通道治理channelPermissions.tschannelAllowlist.ts 负责通道级权限控制。
  • 交互与企业认证elicitationHandler.ts 负责交互式数据收集,xaa.ts / xaaIdpLogin.ts 负责 XAA 认证集成。

11.2 LSP 集成:services/lsp/

Language Server Protocol 提供代码智能能力:

  • 客户端与实例管理LSPClient.tsLSPServerManager.tsLSPServerInstance.ts 负责客户端连接与服务实例生命周期。
  • 诊断与配置LSPDiagnosticRegistry.tsconfig.ts 负责诊断信息与配置管理。
  • 管理与反馈manager.ts 负责整体调度,passiveFeedback.ts 用于被动反馈收集。

11.3 分析和遥测:services/analytics/

- `growthbook.ts`:GrowthBook 特性开关管理
- `metadata.ts`:运行时元数据收集
- `firstPartyEventLogger.ts`:一方事件日志记录
- `datadog.ts`:Datadog 集成
- `sink.ts`:事件汇聚
- `index.ts`:统一出口

11.4 OAuth 认证:services/oauth/

- `client.ts`:OAuth 客户端
- `auth-code-listener.ts`:授权码监听
- `crypto.ts`:加密工具
- `getOauthProfile.ts`:获取用户信息
- `index.ts`:统一出口

十二、插件和技能系统

Claude Code 的长期可扩展性,不在某一个巨型核心模块里,而在它把“可扩展点”系统化地拆成了插件、技能、Agent、Hooks 等多种层次。

插件与技能扩展系统

看图重点:插件偏向分发与安装,技能偏向复用工作流,两者又都能挂接到 Claude Code 统一的执行引擎上,这就是它扩展生态的基本骨架。

12.1 插件系统

Claude Code 的插件系统支持通过 npm 分发和安装第三方扩展。

它的实现重点不在“装多少文件”,而在如何把扩展点收束成稳定装载链路

  • 插件装载链路:从 plugins/builtinPlugins.ts 出发,进入 utils/plugins/pluginLoader.ts,再依次解析 plugin.json,装载 commandshooksskillsagentsMCP serversoutput styles
  • 装载稳定性loadAllPlugins 使用 memoize,避免同一进程内重复扫描与重复初始化。
  • 插件管理链路marketplaceManager.tsinstalledPluginsManager.tspluginInstallationHelpers.tsvalidatePlugin.ts 分别负责市场管理、已装插件维护、安装辅助与合法性校验。

12.2 技能系统

技能(Skills)是可复用的工作流定义。

从实现看,技能系统主要由三部分组成:

  • 加载入口loadSkillsDir.ts 负责技能目录扫描,按目录约定和 SKILL.md 发现技能描述;bundledSkills.ts / bundled/index.ts 负责内置技能注册。
  • 构建能力mcpSkillBuilders.ts 负责把 MCP 能力包装成可调用技能,让“外部服务能力”也能以统一技能形态接入。
  • 内置技能集合bundled/ 中沉淀了 batchdebuglooprememberskillifyverify 等基础工作流,说明 Claude Code 在把“高频操作流程”产品化,而不只是暴露底层工具。

十三、工具函数库:utils/

src/utils/ 真正重要的地方,不在于“文件很多”,而在于这里沉淀了 Claude Code 最难复用的工程细节。最值得关注的几块如下:

13.1 Shell 命令解析器

utils/bash/
├── bashParser.ts            # Bash 解析器
├── ast.ts                   # AST 定义
├── commands.ts              # 命令分析
├── heredoc.ts               # Heredoc 解析
├── shellQuote.ts            # Shell 引用处理
└── treeSitterAnalysis.ts    # Tree-sitter 集成

Claude Code 内置了一个完整的 Bash 命令解析器,可以把 shell 命令解析成 AST 再做安全分析;这也是 BashTool 能实现“命令理解”而非“纯字符串黑名单”的基础。

13.2 权限系统工具

utils/permissions/
├── permissions.ts           # 权限核心逻辑
├── permissionSetup.ts       # 权限配置与模式切换
├── filesystem.ts            # 文件系统权限边界
├── yoloClassifier.ts        # auto 模式分类器
├── pathValidation.ts        # 路径校验
└── permissionRuleParser.ts  # 规则解析

这部分代码共同决定了 Claude Code 如何把“模式、规则、路径和分类器”合并成一套统一决策过程。

13.3 会话存储

utils/sessionStorage.ts 负责会话的完整生命周期管理:创建、保存、恢复、搜索、清理,以及 sidechain transcript、背景任务和恢复态元数据的持久化。

13.4 配置管理

  • utils/config.ts:多层配置解析与合并
  • utils/claudemd.tsCLAUDE.md 规则文件解析
  • utils/hooks.ts:SessionStart / SessionEnd / UserPromptSubmit 等 Hook 系统核心

这些模块共同决定了 Claude Code 如何把“用户配置、仓库规则、会话钩子”变成可持续演化的运行时约束。


十四、通信传输层

14.1 CLI 传输

cli/transports/
├── ccrClient.ts                # CCR 客户端
├── WebSocketTransport.ts       # WebSocket 传输
├── SSETransport.ts             # SSE 传输
├── HybridTransport.ts          # 混合传输
├── SerialBatchEventUploader.ts # 批量事件上传
└── WorkerStateUploader.ts      # Worker 状态上传

这里体现的是 Claude Code 的传输分层:上层是统一事件模型,下层则根据场景选择 WebSocket、SSE 或混合传输。

14.2 上游代理

upstreamproxy/
├── upstreamproxy.ts            # 代理配置
└── relay.ts                    # 请求中继

这部分让 CLI 能在企业网络、代理环境和中继场景下维持可用性。


十五、设计模式与工程亮点

15.1 并行预取(Parallel Prefetch)

启动时间优化的核心策略 — 在重模块评估之前并行预取多种数据:

  • MDM 配置读取
  • Keychain 凭证获取
  • API 预连接(TCP + TLS 握手)
  • GrowthBook 特性开关获取

15.2 编译时特性消除

利用 Bun 的 bun:bundle 在编译时消除未启用的特性代码,显著减小发布包体积。

15.3 自定义 Ink 渲染引擎

没有简单依赖社区 Ink 框架,而是维护了一个深度定制的 Fork,包含:

  • 自定义事件系统(鼠标点击、终端焦点)
  • 虚拟滚动(处理超长对话)
  • 文本选择支持
  • 自定义 Yoga 布局引擎绑定
  • ANSI 解析和渲染优化

15.4 多层安全模型

BashTool 的五层安全模型是业界标杆:

  1. 命令安全分析(黑名单 + 模式匹配)
  2. 权限规则匹配(用户自定义规则)
  3. 只读验证(自动识别安全操作)
  4. 路径安全校验(防止越界访问)
  5. Sandbox 隔离(容器化执行)

15.5 上下文压缩

会话上下文管理的三级压缩策略:

  1. 微压缩(Micro-compact):轻量级,保留关键信息
  2. 标准压缩(Compact):中等力度,替换工具输出
  3. 会话记忆压缩(Session Memory Compact):最激进,提取核心记忆

十六、推荐阅读路径:如何啃这份源码

如果你的目标不是“数文件”,而是快速理解 Claude Code 的实现原理,我更推荐按能力链路阅读源码。

16.1 建议的阅读顺序

  1. 启动链路:先看 main.tsxbootstrap/state.tsentrypoints/init.ts,理解配置、认证、预热和首屏渲染是怎样排顺序的。
  2. 主推理循环:再看 query.tsQueryEngine.tsservices/api/claude.ts,理解一轮输入如何进入模型、工具、再回到模型。
  3. 工具与权限:继续看 toolOrchestration.tstoolExecution.tspermissions.tspermissionSetup.ts,这是 Claude Code 最核心的行动能力与安全边界。
  4. 终端运行时:然后看 screens/REPL.tsx 以及 PromptInputMessagesuseDeferredHookMessages 等周边模块,理解状态、输入、消息和弹层如何汇合。
  5. IDE 桥接:接着看 useReplBridge.tsxinitReplBridge.tsreplBridge.tsremoteBridgeCore.tsbridgeMessaging.ts,理解 IDE 与 CLI 如何保持双向同步。
  6. 多 Agent 协作:最后读 coordinatorMode.tsrunAgent.tsagentSummary.tsmemdir/,你会更容易看懂它的 orchestrator 思路。

16.2 最值得重点看的模块

模块 为什么值得重点看
bootstrap/state.ts 能看清 Claude Code 如何把配置、信任、TLS、认证和特性开关排成有先后关系的启动状态机
query.ts / QueryEngine.ts 能看清 AI Coding Agent 最核心的“模型 ↔ 工具 ↔ 上下文”闭环
toolOrchestration.ts / toolExecution.ts 能看清只读工具为何可并发、带副作用工具为何必须串行
permissions.ts / permissionSetup.ts 能看清规则优先、auto 模式、危险规则剥离和人工确认是如何组合的
screens/REPL.tsx 能看清终端 UI 如何承接消息流、输入流、后台任务和各种弹层工作流
remoteBridgeCore.ts / bridgeMessaging.ts 能看清远程控制场景下的顺序保证、去重、令牌刷新与协议恢复
runAgent.ts / agentSummary.ts 能看清子 Agent 的上下文分叉、持久化和进度可观测性是如何落地的

十七、技术栈总结

类别 技术选型
运行时 Bun
语言 TypeScript (strict)
终端 UI React + Ink (深度定制 Fork)
CLI 解析 Commander.js (extra-typings)
Schema 验证 Zod v4
代码搜索 ripgrep
布局引擎 Yoga (Flexbox)
Shell 解析 自研 Bash Parser + Tree-sitter
协议 MCP SDK, LSP
API Anthropic SDK
遥测 OpenTelemetry + gRPC
特性开关 GrowthBook
认证 OAuth 2.0, JWT, macOS Keychain
分析 Datadog
传输 WebSocket, SSE, HTTP

十八、总结与启示

18.1 工程复杂度

Claude Code 的复杂度,并不只是因为它“代码很多”,而是因为它实际上已经长成了一套完整的终端 IDE + Agent 运行时,具备:

  • 深度定制的 UI 渲染引擎
  • 完整的 Bash 命令解析器
  • 多层安全模型
  • 多 Agent 协作框架
  • 插件和技能扩展系统
  • IDE 双向通信桥接
  • 复杂的上下文管理和压缩

18.2 架构启示

  1. 安全第一:BashTool 的五层安全模型展示了 AI 工具执行的安全防线应有多深
  2. 可扩展设计:工具、命令、插件、技能四大扩展点,各司其职
  3. 性能优化:并行预取、编译时特性消除、延迟加载三管齐下
  4. 上下文管理:三级压缩策略是长上下文 AI 应用的工程最佳实践
  5. 用户体验:深度定制 Ink 框架打造了真正的终端级 IDE 体验

18.3 关于源码泄露

这次源码泄露本质上是一个构建产物管理失误 — npm 发布包中包含了 Source Map 文件,而 Source Map 又指向了可公开访问的源码存储桶。这提醒我们:

  • 发布流程需要包含 Source Map 剥离检查
  • 存储桶访问策略需要与构建产物生命周期对齐
  • CI/CD 管道中应增加产物安全扫描

本文仅用于技术学习和架构研究。Claude Code 源码版权归 Anthropic 所有。


参考资料

「真诚赞赏,手留余香」

爱折腾的工程师

真诚赞赏,手留余香

使用微信扫描二维码完成支付