Claude Code 源码解析:Anthropic 官方 AI 编程助手的架构设计

Claude Code 源码解析:Anthropic 官方 AI 编程助手的架构设计

深入剖析 Anthropic 官方的 AI 编程助手——Claude Code 的架构设计、核心模块与运行机制

项目简介

Claude Code 是 Anthropic 推出的 AI 编程助手 CLI 工具,基于 TypeScript + React (Ink) 构建。它不仅仅是一个简单的命令行聊天工具,而是一个功能完备的编程代理系统

核心特性

  • 🤖 交互式 REPL 对话:流畅的终端交互体验
  • 🔧 40+ 内置工具:文件操作、命令执行、搜索、代理等
  • 📋 斜杠命令系统:70+ 命令,覆盖会话、配置、代码操作等
  • 🔌 MCP 支持:Model Context Protocol 标准化工具扩展
  • 🧩 插件系统:第三方工具、命令、技能包扩展
  • 👥 多代理协作:支持创建代理团队、并行执行
  • 🔒 多层安全机制:细粒度权限控制、沙箱隔离

技术栈

  • 语言:TypeScript + React (Ink 终端 UI)
  • 运行时:Node.js 18+ / Bun
  • 构建:esbuild
  • 核心依赖@anthropic-ai/sdkcommanderinkzod

目录结构

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
src/
├── main.tsx # 主入口文件(803KB)
├── QueryEngine.ts # 查询引擎核心(46KB)
├── query.ts # 查询循环实现(68KB)
├── tools.ts # 工具注册与管理(17KB)
├── commands.ts # 命令注册与路由(25KB)
├── Tool.ts # 工具基类定义(29KB)
├── context.ts # 上下文管理
├── history.ts # 会话历史管理
├── cost-tracker.ts # 成本追踪

├── bootstrap/ # 启动引导
├── cli/ # CLI 处理器
│ ├── print.ts # 非交互式输出(212KB)
│ └── structuredIO.ts # 结构化输入输出

├── commands/ # 斜杠命令(1774 个文件)
│ ├── add-dir/
│ ├── commit/
│ ├── config/
│ ├── mcp/
│ ├── review/
│ └── ... (70+ 命令)

├── tools/ # 内置工具(1412 个文件)
│ ├── AgentTool/ # 代理工具
│ ├── BashTool/ # 命令执行
│ ├── FileEditTool/ # 文件编辑
│ ├── FileReadTool/ # 文件读取
│ ├── FileWriteTool/ # 文件写入
│ ├── GrepTool/ # 搜索工具
│ ├── WebFetchTool/ # 网页抓取
│ └── ... (40+ 工具)

├── services/ # 服务层
│ ├── api/ # API 调用封装
│ ├── mcp/ # MCP 协议实现
│ ├── analytics/ # 遥测与分析
│ ├── compact/ # 上下文压缩
│ ├── plugins/ # 插件管理
│ └── policyLimits/ # 策略限制

├── state/ # 状态管理
│ ├── AppState.tsx
│ ├── AppStateStore.ts
│ └── store.ts

├── utils/ # 工具函数(9542 个文件)
│ ├── permissions/ # 权限管理
│ ├── model/ # 模型管理
│ ├── settings/ # 配置管理
│ ├── hooks/ # 钩子系统
│ └── ... (300+ 工具模块)

├── components/ # React 组件(UI)
├── context/ # React Context
├── hooks/ # React Hooks
├── types/ # TypeScript 类型定义
└── entrypoints/ # 入口点
├── cli.tsx # CLI 入口
└── init.ts # 初始化逻辑

这个规模令人印象深刻——仅 utils/ 目录就有 9542 个文件,commands/ 有 1774 个文件,tools/ 有 1412 个文件。


启动流程

入口点:src/main.tsx

Claude Code 的启动流程经过精心设计,通过并行预取减少启动延迟:

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
┌─────────────────────────────────────────────────────────┐
1. 性能追踪启动 │
profileCheckpoint('main_tsx_entry') │
├─────────────────────────────────────────────────────────┤
2. 并行预取(减少启动延迟) │
│ - startMdmRawRead() - MDM 配置读取 │
│ - startKeychainPrefetch() - 密钥链预取 │
├─────────────────────────────────────────────────────────┤
3. 加载 135+ 模块依赖 │
│ - 命令、工具、服务、工具函数 │
├─────────────────────────────────────────────────────────┤
4. CLI 参数解析(Commander) │
│ - 解析命令行参数 │
│ - 加载配置文件 │
├─────────────────────────────────────────────────────────┤
5. 初始化核心服务 │
│ - GrowthBook(特性开关) │
│ - 遥测系统 │
│ - 策略限制 │
│ - MCP 服务器 │
├─────────────────────────────────────────────────────────┤
6. 认证与授权 │
│ - OAuth / API Key 验证 │
│ - 权限模式初始化 │
├─────────────────────────────────────────────────────────┤
7. 启动模式分支 │
│ ├─ 交互模式 → launchRepl() │
│ ├─ 非交互模式 → print.ts
│ └─ SDK 模式 → QueryEngine │
└─────────────────────────────────────────────────────────┘

启动优化策略

并行预取机制

1
2
3
4
// 在模块加载的同时并行执行 I/O 操作
startMdmRawRead(); // 启动 MDM 子进程
startKeychainPrefetch(); // 预取 macOS 密钥链
prefetchAwsCredentialsAndBedRockInfoIfSafe();

延迟加载

1
2
3
4
// 使用 feature flag 实现死代码消除
const SleepTool = feature('PROACTIVE') || feature('KAIROS')
? require('./tools/SleepTool/SleepTool.js').SleepTool
: null

这种设计非常巧妙——在等待模块加载的同时,并行执行 I/O 操作,显著减少启动时间。


核心架构

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
┌──────────────────────────────────────────────────────────────┐
│ 用户界面层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ REPL │ │ CLI │ │ SDK │ │ IDE │ │
│ │ (Ink) │ │ (print) │ │ (API) │ │ (Ext) │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
└───────┼──────────────┼──────────────┼──────────────┼────────┘
│ │ │ │
└──────────────┴──────────────┴──────────────┘

┌──────────────┴──────────────┐
│ QueryEngine │
│ ┌─────────────────────┐ │
│ │ 消息管理 │ │
│ │ 工具编排 │ │
│ │ 权限控制 │ │
│ │ 上下文压缩 │ │
│ └─────────────────────┘ │
└──────────────┬──────────────┘

┌──────────────┴──────────────┐
│ 服务层 │
│ ┌──────┐ ┌──────┐ │
│ │ API │ │ MCP │ │
│ └──────┘ └──────┘ │
│ ┌──────┐ ┌──────┐ │
│ │插件 │ │遥测 │ │
│ └──────┘ └──────┘ │
└──────────────┬──────────────┘

┌──────────────┴──────────────┐
│ 工具 & 命令 │
│ ┌──────┐ ┌──────┐ │
│ │工具 │ │命令 │ │
│ │(40+) │ │(70+) │ │
│ └──────┘ └──────┘ │
└─────────────────────────────┘

QueryEngine:查询引擎核心

文件src/QueryEngine.ts (46KB)

QueryEngine 是整个系统的”大脑”,负责:

  • 管理会话状态(消息历史、文件缓存、使用量)
  • 协调查询生命周期
  • 处理工具执行和权限检查
  • 支持多轮对话和上下文压缩

核心接口

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
export type QueryEngineConfig = {
cwd: string // 工作目录
tools: Tools // 可用工具列表
commands: Command[] // 可用命令列表
mcpClients: MCPServerConnection[] // MCP 连接
agents: AgentDefinition[] // 代理定义
canUseTool: CanUseToolFn // 权限检查函数
getAppState: () => AppState // 状态获取
setAppState: (f) => void // 状态更新
initialMessages?: Message[] // 初始消息
readFileCache: FileStateCache // 文件缓存
userSpecifiedModel?: string // 模型覆盖
thinkingConfig?: ThinkingConfig // 思考配置
maxTurns?: number // 最大轮次
maxBudgetUsd?: number // 预算限制
}

export class QueryEngine {
private config: QueryEngineConfig
private mutableMessages: Message[]
private abortController: AbortController
private permissionDenials: SDKPermissionDenial[]
private totalUsage: NonNullableUsage
private readFileState: FileStateCache

constructor(config: QueryEngineConfig)
submitMessage(userMessage: string): AsyncGenerator<Message>
abort(): void
}

查询循环(Agent Loop)

文件src/query.ts (68KB)

查询循环是整个系统的”心脏”,实现了 LLM 调用与工具执行的交替进行:

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
┌──────────────┐
│ 初始状态 │
└──────┬───────┘

┌──────────────┐
│ API 调用 │ ← 流式接收响应
└──────┬───────┘

┌──────────────┐
│ 检查工具调用 │
└──────┬───────┘

┌──────────────┐
│ 权限检查 │ → 拒绝 → 返回错误
└──────┬───────┘

┌──────────────┐
│ 执行工具 │
└──────┬───────┘

┌──────────────┐
│ 结果处理 │ → 需要继续 → 回到 API 调用
└──────┬───────┘

┌──────────────┐
│ 结束状态 │
└──────────────┘

核心实现

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
40
41
42
43
44
async function* queryLoop(params, consumedCommandUuids) {
let state: State = {
messages: params.messages,
toolUseContext: params.toolUseContext,
autoCompactTracking: undefined,
maxOutputTokensRecoveryCount: 0,
hasAttemptedReactiveCompact: false,
turnCount: 0,
}

while (true) {
// 1. 检查终止条件
if (shouldTerminate(state)) {
return { terminal: true }
}

// 2. 调用 API
const response = yield* callAPI(state)

// 3. 处理响应
for await (const event of response) {
yield event // 流式输出

if (event.type === 'assistant') {
state.messages.push(event)

// 4. 检查工具调用
const toolUses = extractToolUses(event)
if (toolUses.length > 0) {
// 5. 执行工具
const results = yield* executeTools(toolUses, state)
state.messages.push(...results)
}
}
}

// 6. 自动压缩检查
if (shouldCompact(state)) {
state = yield* compactContext(state)
}

state.turnCount++
}
}

关键特性

  • 自动压缩:检测上下文过长时自动压缩
  • 错误恢复:处理 API 错误和重试
  • 工具编排:支持并发工具执行
  • 令牌预算:跟踪和控制 token 使用

工具系统

工具基类

文件src/Tool.ts (29KB)

1
2
3
4
5
6
7
8
9
10
11
12
13
export interface Tool {
name: string
description: string
inputSchema: ToolInputJSONSchema

// 核心方法
isEnabled(): boolean
call(input: any, context: ToolUseContext): Promise<ToolResult>

// 可选方法
validate?(input: any): ValidationResult
getPromptAddendum?(): string
}

工具上下文

1
2
3
4
5
6
7
8
9
10
11
12
export type ToolUseContext = {
cwd: string
readFileState: FileStateCache
messages: Message[]
toolPermissionContext: ToolPermissionContext
canUseTool: CanUseToolFn
setToolJSX?: SetToolJSXFn
addNotification?: (notif: Notification) => void
agentId?: AgentId
agentType?: string
// ... 更多上下文
}

工具分类

文件操作工具

工具名 功能 权限要求
FileReadTool 读取文件内容 读取权限
FileEditTool 编辑文件(精确替换) 写入权限
FileWriteTool 写入/创建文件 写入权限
NotebookEditTool 编辑 Jupyter Notebook 写入权限

命令执行工具

工具名 功能 权限要求
BashTool 执行 Bash 命令 命令权限
PowerShellTool 执行 PowerShell(Windows) 命令权限

搜索工具

工具名 功能 实现方式
GrepTool 内容搜索 ripgrep
GlobTool 文件名搜索 glob 模式
WebSearchTool 网络搜索 Tavily API
WebFetchTool 网页抓取 HTTP 请求

代理工具

工具名 功能 特性
AgentTool 创建子代理 支持并行执行
SendMessageTool 代理间通信 消息传递
TeamCreateTool 创建代理团队 多代理协作

工具执行流程

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
┌─────────────────────────────────────────┐
1. Claude 返回 tool_use 块 │
└──────────────┬──────────────────────────┘

┌─────────────────────────────────────────┐
2. 查找工具实现 │
│ findToolByName(name) │
└──────────────┬──────────────────────────┘

┌─────────────────────────────────────────┐
3. 输入验证 │
│ tool.validate(input) │
└──────────────┬──────────────────────────┘

┌─────────────────────────────────────────┐
4. 权限检查 │
│ canUseTool(tool, input) │
│ ├─ 允许 → 继续 │
│ ├─ 拒绝 → 返回拒绝结果 │
│ └─ 询问 → 显示权限对话框 │
└──────────────┬──────────────────────────┘

┌─────────────────────────────────────────┐
5. 执行工具 │
│ tool.call(input, context) │
└──────────────┬──────────────────────────┘

┌─────────────────────────────────────────┐
6. 处理结果 │
│ - 添加 tool_result 消息 │
│ - 更新状态 │
│ - 应用上下文修改 │
└─────────────────────────────────────────┘

并发工具执行

文件src/services/tools/StreamingToolExecutor.ts

1
2
3
4
5
6
7
8
class StreamingToolExecutor {
// 并发执行多个工具调用
async executeTools(toolUses: ToolUseBlock[]): Promise<ToolResult[]> {
// 检查工具是否支持并发
// 分组执行并发安全的工具
// 按顺序执行有依赖的工具
}
}

并发策略

  • 读写操作互斥
  • 多个读操作可以并发
  • 命令执行默认串行

命令系统

命令注册

文件src/commands.ts (25KB)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
export type Command = {
name: string
description: string
type: 'local' | 'prompt' | 'jsx'

// 本地命令(不发送给 AI)
callLocal?(args: string, context: CommandContext): Promise<void>

// 提示命令(生成 AI 提示)
getPromptForCommand?(args: string, context: CommandContext): Promise<string>

// JSX 命令(显示 UI)
getJSXForCommand?(args: string, context: CommandContext): Promise<React.ReactNode>
}

命令分类

会话管理

命令 功能
/clear 清除对话历史
/compact 压缩上下文
/resume 恢复会话
/session 会话信息
/exit 退出程序

配置管理

命令 功能
/config 配置设置
/model 切换模型
/effort 设置努力程度
/fast 快速模式
/theme 主题设置

代码操作

命令 功能
/commit 提交更改
/review 代码审查
/security-review 安全审查
/diff 查看差异

工具集成

命令 功能
/mcp MCP 服务器管理
/plugin 插件管理
/skills 技能管理
/hooks 钩子管理

状态管理

AppState 架构

文件src/state/AppState.tsx

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
export type AppState = {
// 会话状态
messages: Message[]
sessionId: UUID
conversationId: UUID

// 模型配置
mainLoopModel: string
thinkingConfig: ThinkingConfig
effort: 'low' | 'medium' | 'high'

// 权限状态
toolPermissionContext: ToolPermissionContext
permissionDenials: SDKPermissionDenial[]

// UI 状态
verbose: boolean
spinnerMode: SpinnerMode
hasInterruptibleToolInProgress: boolean

// 文件状态
readFileState: FileStateCache
fileHistoryState: FileHistoryState

// 工具状态
inProgressToolUseIDs: Set<string>
toolDecisions: Map<string, ToolDecision>

// 成本追踪
totalUsage: Usage
totalCost: number

// 代理状态
currentAgentId?: AgentId
agentType?: string

// 推测执行
speculationState: SpeculationState
}

状态存储

文件src/state/store.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
export function createStore(initialState: AppState, onChange?: OnChange) {
let state = initialState
const listeners = new Set<() => void>()

return {
getState: () => state,

setState: (updater: (prev: AppState) => AppState) => {
const oldState = state
state = updater(state)

// 通知订阅者
listeners.forEach(l => l())

// 调用 onChange 回调
onChange?.({ newState: state, oldState })
},

subscribe: (listener: () => void) => {
listeners.add(listener)
return () => listeners.delete(listener)
}
}
}

React 集成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Context Provider
export function AppStateProvider({ children, initialState }) {
const [store] = useState(() => createStore(initialState))

return (
<AppStoreContext.Provider value={store}>
<MailboxProvider>
<VoiceProvider>
{children}
</VoiceProvider>
</MailboxProvider>
</AppStoreContext.Provider>
)
}

// 状态选择 Hook
export function useAppState<T>(selector: (state: AppState) => T): T {
const store = useContext(AppStoreContext)
return useSyncExternalStore(
store.subscribe,
() => selector(store.getState())
)
}

权限与安全机制

权限模式

1
2
3
4
5
export type PermissionMode =
| 'default' // 默认模式(询问)
| 'auto' // 自动模式(AI 决定)
| 'bypass' // 绕过模式(全部允许)
| 'plan' // 计划模式(只读)

权限规则

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
export type ToolPermissionContext = {
mode: PermissionMode
additionalWorkingDirectories: Map<string, AdditionalWorkingDirectory>
alwaysAllowRules: ToolPermissionRulesBySource
alwaysDenyRules: ToolPermissionRulesBySource
alwaysAskRules: ToolPermissionRulesBySource
isBypassPermissionsModeAvailable: boolean
isAutoModeAvailable?: boolean
}

// 权限规则来源
type ToolPermissionRulesBySource = {
global?: PermissionRule[] // 全局配置
project?: PermissionRule[] // 项目配置
session?: PermissionRule[] // 会话配置
}

// 权限规则
type PermissionRule = {
toolName: string
rule: 'allow' | 'deny' | 'ask'
condition?: {
path?: string // 文件路径匹配
command?: string // 命令匹配
}
}

权限检查流程

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
┌─────────────────────────────────────────┐
│ 工具调用请求 │
│ tool.call(input, context) │
└──────────────┬──────────────────────────┘

┌─────────────────────────────────────────┐
1. 检查权限模式 │
if (mode === 'bypass') return allow │
└──────────────┬──────────────────────────┘

┌─────────────────────────────────────────┐
2. 检查 alwaysAllow 规则 │
if (matchesAllowRule(tool, input)) │
return allow │
└──────────────┬──────────────────────────┘

┌─────────────────────────────────────────┐
3. 检查 alwaysDeny 规则 │
if (matchesDenyRule(tool, input)) │
return deny │
└──────────────┬──────────────────────────┘

┌─────────────────────────────────────────┐
4. 检查 auto 模式安全工具 │
if (mode === 'auto' && │
│ safeTools.includes(tool)) │
return allow │
└──────────────┬──────────────────────────┘

┌─────────────────────────────────────────┐
5. 显示权限对话框 │
│ await showPermissionDialog(tool) │
│ ├─ 允许 → return allow │
│ ├─ 拒绝 → return deny │
│ └─ 记住 → 添加规则 + return
└─────────────────────────────────────────┘

安全检查

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
// 危险命令检测
function isDangerousCommand(command: string): boolean {
const dangerousPatterns = [
/rm\s+-rf/i,
/mkfs\./i,
/dd\s+if=/i,
/>\s*\/dev\/[sh]d/i,
/chmod\s+-R\s+777/i,
/curl.*\|\s*sh/i,
]

return dangerousPatterns.some(p => p.test(command))
}

// 文件路径验证
function validateFilePath(path: string): ValidationResult {
// 1. 检查路径遍历
if (path.includes('..')) {
return { result: false, message: '路径遍历不允许' }
}

// 2. 检查工作目录
if (!isWithinWorkingDir(path)) {
return { result: false, message: '路径超出工作目录' }
}

// 3. 检查符号链接
if (isSymlink(path)) {
return { result: false, message: '符号链接不允许' }
}

return { result: true }
}

服务层架构

API 服务

目录src/services/api/

1
2
3
4
5
6
services/api/
├── claude.ts # Claude API 封装
├── bootstrap.ts # 启动数据获取
├── errors.ts # 错误分类
├── withRetry.ts # 重试逻辑
└── logging.ts # 使用量记录

重试策略

1
2
3
4
5
6
7
// 重试策略
function categorizeRetryableAPIError(error: Error): RetryStrategy {
// 网络错误 → 立即重试
// 速率限制 → 延迟重试
// 服务器错误 → 指数退避
// 客户端错误 → 不重试
}

MCP 服务

目录src/services/mcp/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// MCP 服务器连接
interface MCPServerConnection {
name: string
config: McpServerConfig
client: MCPClient

// 工具发现
listTools(): Promise<Tool[]>

// 资源访问
listResources(): Promise<Resource[]>
readResource(uri: string): Promise<Content>

// 提示模板
listPrompts(): Promise<Prompt[]>
}

插件服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 插件定义
interface Plugin {
name: string
version: string
commands: Command[]
tools?: Tool[]
skills?: Skill[]
}

// 插件加载
async function loadPlugins(): Promise<Plugin[]> {
// 1. 扫描插件目录
// 2. 验证插件签名
// 3. 加载插件模块
// 4. 注册命令和工具
}

关键运行机制

上下文压缩

文件src/services/compact/autoCompact.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 压缩触发条件
function shouldCompact(state: State): boolean {
const tokenCount = countTokens(state.messages)
const contextWindow = getContextWindowForModel(model)

// 超过 80% 上下文窗口时触发
return tokenCount > contextWindow * 0.8
}

// 压缩策略
async function compactContext(state: State) {
// 1. 保留最近的消息
// 2. 压缩历史消息为摘要
// 3. 保留关键工具调用结果
// 4. 更新消息列表
}

文件状态缓存

文件src/utils/fileStateCache.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
export class FileStateCache {
private cache: Map<string, FileState>
private maxSize: number

// LRU 缓存
get(path: string): FileState | undefined
set(path: string, state: FileState): void
invalidate(path: string): void

// 批量操作
getMany(paths: string[]): Map<string, FileState>
clear(): void
}

type FileState = {
content: string
lastModified: number
hash: string
size: number
}

钩子系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 钩子类型
type HookEvent =
| 'pre_tool_use' // 工具调用前
| 'post_tool_use' // 工具调用后
| 'pre_api_call' // API 调用前
| 'post_api_call' // API 调用后
| 'on_error' // 错误发生
| 'on_stop' // 停止时

// 钩子注册
function registerHook(event: HookEvent, handler: HookHandler): void

// 钩子执行
async function executeHooks(event: HookEvent, context: any): Promise<void> {
const hooks = getHooks(event)
for (const hook of hooks) {
await hook.handler(context)
}
}

推测执行

文件src/state/AppStateStore.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
type SpeculationState = {
enabled: boolean
pendingSpeculation?: {
toolUseId: string
predictedResult: string
timestamp: number
}
speculationResults: Map<string, SpeculationResult>
}

// 推测执行流程
function speculateToolExecution(toolUse: ToolUse): void {
// 1. 预测工具执行结果
// 2. 提前准备后续操作
// 3. 实际执行后验证预测
// 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
// 成本追踪
type Usage = {
inputTokens: number
outputTokens: number
cacheCreationInputTokens: number
cacheReadInputTokens: number
}

// 成本计算
function calculateCost(usage: Usage, model: string): number {
const pricing = getModelPricing(model)

return (
usage.inputTokens * pricing.input +
usage.outputTokens * pricing.output +
usage.cacheCreationInputTokens * pricing.cacheCreation +
usage.cacheReadInputTokens * pricing.cacheRead
)
}

// 预算检查
function checkBudget(usage: Usage, budget: number): boolean {
const cost = calculateCost(usage, currentModel)
return cost <= budget
}

关键文件索引

文件 大小 功能
main.tsx 803KB 主入口、CLI 解析、初始化
query.ts 68KB 查询循环、工具执行
QueryEngine.ts 46KB 查询引擎、会话管理
commands.ts 25KB 命令注册、路由
Tool.ts 29KB 工具基类、类型定义
tools.ts 17KB 工具注册表
cli/print.ts 212KB 非交互式输出

架构设计亮点

1. 模块化设计

清晰的分层架构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
┌─────────────────────────────────────┐
│ UI 层 (React/Ink) │
│ - 组件、Hooks、Context │
├─────────────────────────────────────┤
│ 应用层 (Commands, Tools) │
│ - 业务逻辑、工具实现 │
├─────────────────────────────────────┤
│ 服务层 (Services) │
│ - API、MCP、插件、遥测 │
├─────────────────────────────────────┤
│ 核心层 (QueryEngine, State) │
│ - 查询引擎、状态管理 │
├─────────────────────────────────────┤
│ 基础设施层 (Utils) │
│ - 工具函数、配置、权限 │
└─────────────────────────────────────┘

2. 可扩展性

  • 插件系统:第三方工具扩展、自定义命令、技能包、主题和样式
  • MCP 协议:标准化工具接口、跨平台兼容、动态工具发现

3. 性能优化

启动优化

  • 并行预取(MDM、密钥链、凭证)
  • 延迟加载(feature flag 死代码消除)
  • 模块缓存

运行时优化

  • 文件状态缓存(LRU)
  • 工具并发执行
  • 流式响应处理
  • 上下文压缩
  • 推测执行

4. 安全设计

多层防护

  1. 权限系统:细粒度的工具权限控制
  2. 沙箱隔离:命令执行安全检查
  3. 路径验证:防止路径遍历攻击
  4. 输入验证:Zod schema 校验
  5. 审计日志:完整的操作记录

5. 用户体验

  • 渐进式披露:简单的默认配置,高级选项可配置
  • 反馈机制:实时进度显示、成本透明展示、错误恢复建议

总结

Claude Code 是一个设计精良、架构清晰、功能完备的 AI 编程助手,几个亮点:

  1. 模块化架构:清晰的分层设计,易于扩展和维护
  2. 强大的工具系统:40+ 内置工具,支持 MCP 和插件扩展
  3. 灵活的状态管理:基于 React 的状态管理,支持多种运行模式
  4. 完善的安全机制:多层权限控制,细粒度的安全检查
  5. 优秀的性能:并行预取、缓存优化、流式处理、推测执行
  6. 良好的用户体验:渐进式披露、实时反馈、错误恢复
  7. 成本控制:透明的成本追踪和预算管理

Claude Code 的源码规模令人印象深刻——仅 main.tsx 就有 803KB,utils/ 目录有 9542 个文件。这反映了 Anthropic 在工程化上的投入。

对于想要构建生产级 AI 编程工具的开发者来说,Claude Code 的源码是一个极好的学习素材——尤其是它的权限系统、查询引擎、工具编排和状态管理设计。


项目地址https://github.com/anthropics/claude-code
版本:v2.1.88
文档https://docs.anthropic.com/en/docs/claude-code


Claude Code 源码解析:Anthropic 官方 AI 编程助手的架构设计
https://tingfeng347.github.io/2026/08/02/Claude Code 源码解析:Anthropic 官方 AI 编程助手的架构设计/
作者
Tingfeng
发布于
2026年8月2日
许可协议