Claude Code 源码深度分析报告

基于 1,332 个 TypeScript 文件的全面分析


引言

Claude Code 是 Anthropic 推出的终端 AI 编程助手,使用 TypeScript 开发,Bun 作为运行时。本报告基于其开源泄露的完整源码,从整体架构核心执行流程核心模块设计模式工程实践五个维度进行深度分析,为学习和借鉴这一企业级 TypeScript 项目提供参考。

说明:本文档基于公开泄露的源码进行分析,内容仅用于学习和研究目的。


一、整体架构分析

1.1 项目规模

指标 数值
TypeScript 文件 1,332 个
核心模块代码行数 6,766+ 行
工具实现 45+ 个
CLI 命令 100+ 个
React 组件 146 个
React Hooks 87+ 个

1.2 顶级目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
src/
├── main.tsx # 应用入口 (803KB)
├── query.ts # 查询引擎核心 (1,729 行)
├── QueryEngine.ts # 查询引擎类 (1,295 行)
├── Tool.ts # 工具基础定义 (792 行)
├── commands.ts # 命令注册表 (754 行)
├── tools.ts # 工具注册表 (389 行)
├── setup.ts # 会话初始化 (477 行)
├── context.ts # 上下文构建 (189 行)

├── tools/ # 45 个工具实现
├── commands/ # 100+ CLI 命令
├── services/ # 核心服务 (38 个子目录)
├── hooks/ # React hooks (87+ 个)
├── components/ # React UI 组件 (146 个)
├── utils/ # 工具函数库 (330+ 个)
├── ink/ # 终端 UI 引擎 (50 个文件)
├── bridge/ # 远程会话系统
└── types/ # 类型定义

1.3 技术栈

  • 运行时: Bun
  • 语言: TypeScript
  • UI框架: React + Ink (终端 UI 库)
  • 包管理: 无 package.json (源码提取目录)

二、核心执行流程(Agent Loop)

2.1 应用启动序列

Claude Code 的启动流程设计精巧,充分利用了异步 I/O 的并行性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// main.tsx - 启动序列

// 第1阶段:性能关键点 - 并行预热
profileCheckpoint('main_tsx_entry')
startMdmRawRead() // macOS MDM 读取
startKeychainPrefetch() // Keychain 读取

// 第2阶段:重型模块导入(借助上述并行预热)
import { feature } from 'bun:bundle'
import { Command, ... } from '@commander-js/extra-typings'

// 第3阶段:CLI 命令解析和初始化
const commands = getCommands() // 从 commands.ts 加载
await init(...) // 初始化会话
launchRepl() // 启动 REPL

关键设计

  • 启动前缀优化:在主模块导入前启动 MDM/Keychain 读取,利用 I/O 等待时间
  • 特性开关:使用 feature()bun:bundle 进行死代码消除

2.2 Agent Loop 核心逻辑(query.ts)

Claude Code 采用双层生成器架构实现流式处理:

1
2
3
4
5
6
7
8
9
// query.ts - 双层生成器架构
export async function* query(params: QueryParams)
└─> async function* queryLoop(params, consumedCommandUuids)
└─> while (true) // 主循环
├─> API 调用(模型采样)
├─> 工具执行
├─> 消息合并和上下文管理
├─> 恢复策略(自动紧缩、上下文折叠、Snip 等)
└─> 继续条件判断或退出

2.3 查询循环状态机

1
2
3
4
5
6
7
8
9
10
type State = {
messages: Message[]
toolUseContext: ToolUseContext
autoCompactTracking: AutoCompactTrackingState | undefined
maxOutputTokensRecoveryCount: number
hasAttemptedReactiveCompact: boolean
pendingToolUseSummary: Promise<ToolUseSummaryMessage | null> | undefined
turnCount: number
transition: Continue | undefined // 继续原因
}

2.4 主循环流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
1. [初始化] API 链追踪、查询配置、预取内存

2. [上下文管理]
├─ Snip 紧缩(HISTORY_SNIP 特性)
├─ 微紧缩(缓存编辑)
├─ 上下文折叠(CONTEXT_COLLAPSE 特性)
├─ 自动紧缩(如果超过令牌阈值)
└─ 令牌预算检查(硬阻止限制)

3. [API 流式传输]
├─ 调用 deps.callModel() 获取 Claude 响应
├─ 在流式传输期间处理工具使用块
├─ StreamingToolExecutor 并发执行工具
└─ 处理流式降级(回退模型)

4. [工具执行和结果处理]
├─ 权限检查(canUseTool)
├─ Hook 执行(pre/post 工具)
├─ 消息存储(工具结果存储层)
└─ 分析事件记录

5. [错误恢复]
├─ 提示太长 (413) → 上下文折叠/反应式紧缩/截断重试
├─ 媒体尺寸错误 → 反应式紧缩(剥离)
├─ 最大输出令牌 → 截断恢复
└─ 流式降级 → 创建新执行器

6. [停止条件]
├─ 无工具使用块 (needsFollowUp === false)
├─ 用户中断 (abortController.signal.aborted)
└─ 令牌预算耗尽

7. [后采样]
├─ Stop Hooks 执行
├─ 权限钩子清理
└─ 分析事件

8. [返回或继续]
根据转换原因继续循环或返回终端信号

三、核心模块详细解读

3.1 工具系统(/tools - 45个工具)

工具注册架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// tools.ts - 单一真实源(SSOT)
export function getAllBaseTools(): Tools {
return [
AgentTool,
TaskOutputTool,
BashTool,
FileReadTool, FileEditTool, FileWriteTool,
GlobTool, GrepTool,
WebFetchTool, WebSearchTool,
SkillTool,
EnterPlanModeTool, ExitPlanModeV2Tool,
...(isTodoV2Enabled()
? [TaskCreateTool, TaskGetTool, TaskUpdateTool, TaskListTool]
: []),
...(feature('KAIROS') ? [SendUserFileTool, PushNotificationTool, ...] : []),
]
}

工具定义接口(Tool.ts)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
export type Tool<
Input extends AnyObject = AnyObject,
Output = unknown,
P extends ToolProgressData = ToolProgressData,
> = {
name: string
aliases?: string[]
searchHint?: string

call(
args: z.infer<Input>,
context: ToolUseContext,
canUseTool: CanUseToolFn,
parentMessage: AssistantMessage,
onProgress?: ToolCallProgress<P>,
): Promise<ToolResult<Output>>

description(input, options): Promise<string>
inputSchema: Input
inputJSONSchema?: ToolInputJSONSchema
isEnabled(): boolean
}

工具执行流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1. [工具发现] 流式传输到达工具使用块

2. [权限检查]
├─ Hook 权限检查(pre 工具)
├─ 分类器决策(TRANSCRIPT_CLASSIFIER)
├─ 权限模式评估(default/plan/auto/bypassPermissions)
└─ 用户询问/自动批准

3. [并发调度](StreamingToolExecutor)
├─ 并发安全工具 → 立即执行
├─ 非并发工具 → 排队,等待独占访问
└─ 以原始工具接收顺序缓冲结果

4. [工具执行](runToolUse)
├─ 输入验证(Zod/JSON Schema)
├─ 分析记录
├─ Telemetry 追踪(OpenTel 跨度)
├─ 调用 tool.call(args, context, canUseTool)
└─ 错误分类和结果存储

5. [结果处理]
├─ 成功 → UserMessage with tool_result block
├─ 权限拒绝 → 拒绝消息
└─ 错误 → 带 is_error=true 的工具结果

3.2 命令系统(/commands - 100+命令)

命令注册(commands.ts)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
export function getCommands(): Command[] {
return [
// 核心命令
addDir, commit, commitPushPr, clear, config, branch,

// 高级命令
agent, agents, plan, fast, compact,

// 诊断命令
cost, status, doctor,

// 条件性(feature gates)
...(feature('PROACTIVE') ? [proactive] : []),
...(feature('KAIROS') ? [assistantCommand] : []),
...(feature('UDS_INBOX') ? [peersCmd] : []),

// 过滤远程模式
...filterCommandsForRemoteMode(allCommands),
]
}

命令类型定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
export type Command = {
name: string
slashCommand?: string
description: string

execute(
context: ProcessUserInputContext,
args: string[],
): Promise<void>

isAvailable?: (context) => boolean
isJSX?: boolean
isLocalJSX?: boolean
}

3.3 上下文构建(context.ts)

系统提示构建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 缓存贯穿整个对话
export const getSystemContext = memoize(async (): Promise<{
[k: string]: string
}> => {
const gitStatus = await getGitStatus()
const injection = getSystemPromptInjection()

return { gitStatus, cacheBreaker: ... }
})

export const getUserContext = memoize(async (): Promise<{
[k: string]: string
}> => {
// CLAUDE.md 自动发现
const claudeMd = shouldDisableClaudeMd
? null
: getClaudeMds(filterInjectedMemoryFiles(await getMemoryFiles()))

return { claudeMd, currentDate: "今天的日期是..." }
})

3.4 MCP 服务(/services/mcp)

MCP 客户端架构

1
2
3
4
5
6
7
8
9
10
11
12
13
export class MCPClient {
// 生命周期
connect(serverConfig: McpServerConfig)
disconnect()

// 工具管理
listTools(): Promise<MCPTool[]>
callTool(toolName: string, input: Record<string, unknown>): Promise<MCPToolResult>

// 资源管理
listResources(): Promise<ServerResource[]>
readResource(uri: string): Promise<ResourceContent>
}

工具适配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function createMcpToolAdapter(mcpTool, client): Tool {
return {
name: `mcp__${serverName}__${toolName}`,

async call(args, context, canUseTool, parentMessage) {
const result = await client.callTool(toolName, args)

return {
data: result,
newMessages: result.messages,
mcpMeta: result.meta,
}
}
}
}

3.5 权限系统(/utils/permissions)

权限模式

1
2
3
4
5
6
7
export type PermissionMode =
| 'default' // 提示用户
| 'plan' // 计划模式(只读)
| 'auto' // 自动分类(TRANSCRIPT_CLASSIFIER)
| 'bypassPermissions' // 跳过检查
| 'dontAsk' // 拒绝所有
| 'acceptEdits' // 允许编辑

权限决策流程

1
2
3
4
5
6
7
8
9
1. 权限规则检查(SSOT)

2. Hook 权限检查(提前拒绝)

3. 分类器决策(TRANSCRIPT_CLASSIFIER)

4. 用户询问(如需要)

5. 记录分析

四、设计模式与工程实践

4.1 设计模式识别

模式 应用场景
生成器模式 query.ts 的异步生成器实现流式处理
工具链模式 权限检查 → Hook 执行 → 工具执行
策略模式 多种紧缩策略可互换
工厂模式 工具和命令的动态创建
适配器模式 MCP 工具转换为内置工具接口
观察者模式 进度回调和事件监听
状态模式 查询循环的状态机
缓存模式 系统提示和上下文缓存
功能开关模式 条件编译和死代码消除

4.2 工程实践

代码组织

  • 单一真实源(SSOT):tools.ts、commands.ts 是工具/命令的 SSOT
  • 导入循环破坏:用懒加载和类型中心破坏循环
  • 特性开关feature() 进行编译时条件编译

类型系统

  • 深度类型安全:大量泛型和精确的 Zod 模式
  • 类型中心架构:类型定义在 /types 中心化

错误处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 1. 输入验证
try {
const validated = toolSchema.parse(input)
} catch (error) {
formatZodValidationError(error)
}

// 2. API 错误分类
categorizeRetryableAPIError(error)

// 3. 工具错误分类
classifyToolError(error)

// 4. 恢复策略
if (isPromptTooLongMessage(error)) {
// 触发上下文折叠 → 反应式紧缩 → 截断重试
}

性能优化

  • 启动优化:MDM/Keychain 并行预热、懒加载、死代码消除
  • 流式优化:StreamingToolExecutor 在模型流式传输期间执行工具
  • 上下文优化:自动紧缩、Snip 紧缩、上下文折叠
  • 缓存:系统提示缓存、文件读取 LRU、内存预取

五、可借鉴学习的特点

5.1 架构设计

  1. 生成器流式架构:使用 async generator 实现实时流式处理,是 AI Agent 的理想选择
  2. 工具注册模式:单一真实源(SSOT)+ 条件加载,便于扩展
  3. 并发调度:安全的工具并行运行,非安全工具排队

5.2 工程质量

  1. 类型安全:深度泛型和 Zod 模式确保运行时安全
  2. 错误恢复:多层嵌套的恢复策略(3层:上下文折叠 → 反应式紧缩 → 截断重试)
  3. 遥测完善:详细的事件记录和 OpenTel 跟踪

5.3 权限设计

多层权限检查(规则 → Hook → 分类器 → 用户询问),平衡安全性和用户体验。

5.4 性能优化

  • 启动时并行 I/O 预热
  • 令牌预算管理和自动紧缩
  • 工具结果缓存和内存预取

5.5 可扩展性

  • MCP 协议支持扩展外部服务
  • 技能系统(SkillTool)支持用户自定义
  • Hook 系统允许扩展权限、工具执行等行为

六、总结

Claude Code 是一个企业级的 AI 编程助手,其源码体现了高质量的 TypeScript 工程实践:

维度 评价
模块化 工具、命令、服务清晰分离
流式架构 生成器实现实时反馈和并发执行
可扩展性 工具/命令通过简单接口易于扩展
权限管理 多层权限检查和灵活配置
性能优化 自动上下文紧缩、缓存、流式工具执行
类型安全 深度泛型和 Zod 验证

核心是一个高效的 Agent Loop(query.ts),由以下层次支撑:

  • 工具执行层:45+ 工具、MCP 集成、并发执行
  • 权限层:多模式权限管理和 Hook 系统
  • 上下文层:自动紧缩、上下文折叠、Snip 压缩
  • 服务层:Claude API、分析、MCP、OAuth 等
  • UI 层:React + Ink 终端 UI

这个项目是学习大型 TypeScript AI 应用架构的绝佳参考。


文档生成时间:2026-04-01
基于 Claude Code 源码泄露版本分析