Claude Code 架构综合分析报告
1. 执行摘要
Claude Code 是一个基于 Bun 运行时 + React/Ink 终端 UI 的 AI 编程助手,源码规模约 1900 个文件、512K 行代码。系统采用经典的分层架构,从入口层到基础设施层共六个主要层次,通过编译时 Feature Flag(Bun 宏 + 死代码消除)和运行时动态 import 实现模块的条件加载。核心代理循环在 query.ts(1729 行)中实现,以 while(true) 驱动多轮工具调用,配合 43 个内置工具和 MCP 外部工具构成完整的 AI 执行引擎。整个系统设计体现了强烈的安全优先理念——从 BashTool 的 7 层命令分析到 buildTool() 的 fail-closed 默认值,安全性贯穿每一层。
2. 整体架构
2.1 分层架构图
2.2 核心数据流
3. 关键架构层职责
3.1 入口层
| 模块 | 职责 | 关键特性 |
|---|---|---|
entrypoints/cli.tsx | 快速路径分流 | 9 条快速路径(--version 零模块加载) |
main.tsx (4684 行) | Commander.js 配置、会话启动 | MDM/Keychain 并行预取、50+ CLI 选项 |
entrypoints/init.ts | 系统初始化 | memoized 单次执行 |
setup.ts | 会话设置 | UDS 消息、worktree、session memory |
3.2 表现层
| 模块 | 职责 | 关键特性 |
|---|---|---|
components/ (144 个) | UI 组件 | 消息展示 · 权限对话框 · 输入系统 · 设计系统 |
hooks/ (85 个) | React hooks | useTextInput(529行)、useCanUseTool、useGlobalKeybindings |
ink/ (48 个) | 自定义 Ink 引擎 | 自定义 reconciler、Yoga 布局、差量渲染 |
screens/ (3 个) | 顶层屏幕 | REPL(5006行)、Doctor、ResumeConversation |
3.3 业务逻辑层
| 模块 | 职责 | 关键特性 |
|---|---|---|
query.ts (1729 行) | Agent 循环核心 | State 模式、多级上下文压缩、流式工具执行 |
QueryEngine.ts (1295 行) | 会话生命周期管理 | submitMessage() AsyncGenerator、headless 模式 |
tools/ (43 个) | AI 工具定义 | buildTool() 工厂、fail-closed 默认值、Zod schema |
commands/ (101 个) | 斜杠命令 | 三层类型(prompt/local/local-jsx)、五层源合并 |
services/ (36 个) | 后端服务 | API 客户端、MCP、OAuth、Analytics、LSP |
3.4 状态与数据层
| 模块 | 职责 | 关键特性 |
|---|---|---|
state/store.ts | 轻量级响应式 Store | 34 行实现,Object.is 浅比较 |
bootstrap/state.ts | 全局可变状态 | 1758 行,"DO NOT ADD MORE STATE HERE" |
AppStateStore.ts | 应用状态类型 | ~90 个顶级字段,DeepImmutable 包装 |
cost-tracker.ts | 成本追踪 | 按模型分类用量、跨会话持久化 |
3.5 远程与桥接层
| 模块 | 职责 | 关键特性 |
|---|---|---|
bridge/ (31 个文件) | Remote Control | 轮询式任务获取、子会话 spawn、JWT 刷新 |
remote/ | CCR WebSocket | 远程权限桥接、viewer-only 模式 |
server/ | 直连管理 | WebSocket 直连会话 |
4. 模块依赖总览
entrypoints/cli.tsx
└──> main.tsx (动态 import)
├──> bootstrap/state.ts (全局可变状态)
├──> entrypoints/init.ts (初始化,memoized)
│ ├──> utils/config.ts, utils/managedEnv.ts
│ ├──> utils/gracefulShutdown.ts
│ ├──> services/analytics/*
│ └──> utils/proxy.ts
├──> commands.ts --> commands/* (101 个)
├──> tools.ts --> tools/* (43 个)
├──> context.ts --> utils/git.ts, utils/claudemd.ts
├──> setup.ts --> utils/worktree.ts, services/SessionMemory
├──> ink.ts --> ink/root.ts (Ink 引擎)
├──> state/store.ts, state/AppStateStore.ts, state/AppState.tsx
├──> services/mcp/client.ts (MCP 客户端, 3348 行)
├──> services/api/bootstrap.ts
├──> services/analytics/growthbook.ts (Feature Flags)
├──> replLauncher.tsx --> components/App.tsx --> screens/REPL.tsx
│ ├──> QueryEngine.ts --> query.ts
│ ├──> hooks/* (85 个)
│ └──> components/* (144 个)
└──> QueryEngine.ts (headless 模式)
循环依赖处理:多处使用 require() 懒加载打破循环——teammate.ts 与 AppState.tsx、TeamCreateTool/SendMessageTool 与 tools.ts、feature-gated 命令与 commands.ts。
5. 技术栈总结
| 层面 | 技术选择 |
|---|---|
| 运行时 | Bun(利用 bun:bundle 宏实现编译时 DCE) |
| 终端 UI | React + 自定义 Ink 实现(48 个文件的 forked Ink) |
| CLI 框架 | Commander.js + @commander-js/extra-typings |
| 类型校验 | Zod v4(运行时 schema 验证) |
| 状态管理 | 自定义轻量 Store (34 行) + useSyncExternalStore |
| API 通信 | Anthropic SDK(支持 Bedrock/Vertex/Foundry 多 provider) |
| 命令解析 | tree-sitter-bash WASM(安全 AST 解析) |
| MCP 协议 | @modelcontextprotocol/sdk(Stdio/SSE/HTTP/WebSocket) |
| 认证 | OAuth 2.0 + PKCE、macOS Keychain、XAA 跨应用访问 |
| 分析 | GrowthBook/Statsig feature gates、Datadog RUM、1P 事件日志 |
| LSP | Language Server Protocol 集成 |
| 插件 | Git 仓库市场 + 自动安装/更新 |
| 包管理 | npm(推测,Bun 构建) |
6. 最重要的设计决策
6.1 Bun 宏 + 编译时死代码消除
选择 import { feature } from 'bun:bundle' 而非运行时 feature flag 服务。feature('KAIROS') 在外部构建时返回 false,Bun bundler 自动消除不可达代码块。全代码库 138 个文件使用此机制,40+ 个活跃 feature flags。这使得 CLI 启动时无需加载未启用功能的任何代码。
代码引用: src/tools.ts:16-19, src/commands.ts:62-122
6.2 自定义 Ink 引擎而非标准 ink 包
实现完整的自定义 React reconciler(src/ink/reconciler.ts),包括 Yoga 布局引擎、差量渲染优化器、屏幕缓冲区、焦点管理、文本选择、鼠标支持。这提供了对渲染管线的完全控制,但代价是维护 48 个文件的自定义渲染层。
代码引用: src/ink/ink.tsx (1723 行)
6.3 buildTool() 工厂 + Fail-Closed 默认值
所有工具通过 buildTool() 构造,TOOL_DEFAULTS 将 isReadOnly 和 isConcurrencySafe 默认设为 false——未显式声明为安全的工具被视为不安全。isDestructive 默认 false 且可选,只有标记为破坏性的工具才需要特别注意。
代码引用: src/Tool.ts:757-792
6.4 激进的并行预取启动策略
启动时 4 个阶段的并行化:① MDM + Keychain 与 import 阶段并行 ② API preconnect fire-and-forget ③ bootstrap data 并行拉取 ④ 首次渲染后延迟预取。performance.mark() 精确追踪各阶段耗时。
代码引用: src/main.tsx:13-20, src/main.tsx:388-431
6.5 三层上下文压缩流水线
每次 query 迭代前执行:Tool Result Budget → Snip → Microcompact → Context Collapse → Auto Compact。支持响应式压缩(413 错误时触发)和微压缩(压缩冗余工具调用),最后兜底全量压缩。
代码引用: src/query.ts:365-447
6.6 流式工具执行 (StreamingToolExecutor)
启用 tengu_streaming_tool_execution2 时,在 API 流式接收过程中并行执行已到达的 tool_use blocks,而非等待完整响应后再执行。极大缩短了多工具调用场景的总延迟。
代码引用: src/query.ts:562-568
6.7 权限与验证的严格分离
validateInput() 是纯逻辑校验(格式、路径存在性),失败直接返回错误给模型。checkPermissions() 是权限决策(用户是否允许),可弹出 UI 确认。两阶段完全独立,职责清晰。
代码引用: src/Tool.ts:489-503
6.8 MCP 工具的原型模式
MCPTool 是一个"空壳",mcpClient.ts 在运行时克隆它并填充真实的 name、schema、call。避免为每个 MCP 服务器创建独立工具类,是一种 prototype 模式。
代码引用: src/tools/MCPTool/MCPTool.ts:27-77, src/services/mcp/client.ts:188-210
6.9 零依赖的分析入口
services/analytics/index.ts 无任何 import,事件入队直到 attachAnalyticsSink() 被调用。使用 phantom type 标记 PII 安全类别,_PROTO_* 前缀的 key 只路由到内部系统。彻底避免了循环依赖问题。
代码引用: src/services/analytics/index.ts:1-173
6.10 Headless (SDK) 模式的一等公民地位
通过 -p/--print 标志触发非交互模式:跳过 Ink 渲染、信任对话框、预取,直接通过 QueryEngine.ts 执行查询。支持 stream-json 输出格式,使 Claude Code 可以作为 SDK 嵌入其他工具。
代码引用: src/main.tsx:800-803, src/QueryEngine.ts:1186-1295
7. 强势与值得注意的模式
7.1 性能工程意识
- 启动时间优化:并行子进程预取、快速路径分流(
--version零模块加载)、首屏后延迟加载 - 渲染性能:虚拟消息列表(VirtualMessageList)、差量渲染(optimizer.ts)、React Compiler 自动 memoization
- Token 管理:Prompt Cache 断点(
addCacheBreakpoints)、工具结果大小管理(超限持久化到磁盘) - 连接优化:API preconnect、MCP auth cache (15 min TTL)、keychain prefetch
7.2 安全优先的设计哲学
- BashTool 拥有 7+ 层命令安全分析:AST 解析 → 语义检查 → 沙箱 → 精确匹配 → LLM 分类器 → 管道拆分 → 子命令检查
- Fail-closed 默认值:未声明安全的工具默认为不可读且不可并发
- 环境变量剥离策略:allow 规则用白名单,deny 规则用全量剥离
- 受信设备机制:Bridge 会话的额外安全层
7.3 渐进增强与优雅降级
- 流式工具执行 → 串行工具执行(feature gate 控制)
- tree-sitter AST 解析 → shell-quote 正则解析(legacy 回退)
- macOS Keychain → 明文存储(平台降级)
- OAuth 自动回调 → 手动粘贴 auth code
- 流式 API → 非流式降级
7.4 多层抽象的统一接口
- Tool 系统:
buildTool()工厂 +ToolDef部分定义 → 完整Tool - 命令系统:
prompt(注入模型) /local(本地执行) /local-jsx(渲染 UI) - 传输层:Stdio / SSE / StreamableHTTP / WebSocket 统一抽象
- 存储层:macOS Keychain / 明文 / Fallback 统一接口
7.5 代码组织的工程纪律
- 标准目录结构:每个工具/命令一个目录,统一包含主入口、prompt.ts、UI.tsx
- 懒加载贯穿全栈:命令的
load()、工具的条件require()、组件的dynamic import - Memoize 缓存:
getSystemContext、getUserContext、COMMANDS()、loadAllCommands() - 依赖注入:
QueryDeps让核心循环可测试