Anthropic 官方 AI 编程 CLI 工具的完整架构分析 —— 从入口到渲染、从 Query 循环到工具系统的全链路拆解
Claude Code 是 Anthropic 官方出品的 AI 驱动的命令行编程助手,基于 TypeScript + React (Ink) 构建。本分析基于构建产物反编译版本。
Claude Code 是一个在终端中运行的 AI 代理,能够读取/编辑文件、执行 Shell 命令、搜索代码、管理 Git、调用外部服务等。它不是简单的聊天机器人,而是一个拥有完整工具系统、权限系统、会话管理、多代理协作能力的智能编程平台。
| 技术 | 用途 | 说明 |
|---|---|---|
TypeScript | 核心语言 | 全量 TypeScript 编写,类型安全 |
React + Ink | 终端 UI | 自定义 React 渲染器,将 JSX 渲染到终端 |
Yoga Layout | 布局引擎 | Facebook 的 Flexbox 布局引擎,用于终端排版 |
Zod | Schema 验证 | 运行时类型校验,用于工具输入/输出验证 |
Bun | 打包构建 | Feature Flag 门控 + Dead Code Elimination |
Commander.js | CLI 解析 | 命令行参数和选项解析 |
Anthropic SDK | API 调用 | 与 Claude 模型通信 |
Claude Code 采用清晰的分层架构,从入口到渲染层层递进
从 CLI 输入到第一次渲染,Claude Code 执行了一系列精心编排的初始化步骤
12 个核心文件共约 11,259 行代码,构成 Claude Code 的骨架
4,683 行 — 整个应用的入口和 CLI 编排器
Deferred Prefetches — 首次渲染后才启动 System Prompt 和 MCP 资源的加载。大量使用 feature() 门控,实现构建时 Dead Code Elimination。
1,729 行 — 核心对话循环,Claude Code 的「心脏」
export async function* query(
params: QueryParams
): AsyncGenerator<StreamEvent | Message>
使用 Generator 实现流式输出,UI 层可逐步接收消息。
1,295 行 — 高层 Query 编排,SDK/Headless 模式的封装
792 行 — 工具接口定义,所有工具的基础类型
type Tool = {
name: string
call(input, context, msg) // 执行工具
prompt() // 系统 Prompt 片段
checkPermissions(input, ctx) // 权限检查
inputSchema / outputSchema // Zod Schema 验证
isConcurrencySafe() // 是否可并行
isReadOnly() / isDestructive() // 读写属性
renderToolUseMessage() // 渲染调用消息
renderToolResultMessage() // 渲染结果消息
shouldDefer // 是否延迟加载
...
}
约 300 行的上下文对象,传递给所有工具调用,包含:会话状态、权限上下文、通知系统、文件缓存、归因追踪等。
754 行 — 命令注册中心
type Command = {
type: 'local' | 'prompt' | 'jsx'
name: string
description: string
source: 'builtin' | 'plugin' | 'skill' | 'mcp'
}
389 行 — 工具注册表,组装 40 个核心工具 + Feature Gate 扩展工具
189 行 — 构建每次对话的系统/用户上下文
预初始化:终端恢复、Worktree 创建、Hooks 快照、安全校验、UDS 消息服务
按模型追踪 Token 用量和 USD 成本,支持会话恢复时的成本还原
命令历史持久化到 ~/.claude/history.jsonl,大粘贴内容哈希存储
任务类型定义:local_bash、local_agent、remote_agent、in_process_teammate 等 7 种
理解 Query 循环是理解 Claude Code 工作原理的关键
type State = {
messages: Message[]
toolUseContext: ToolUseContext
autoCompactTracking: AutoCompactTrackingState
maxOutputTokensRecoveryCount: number
hasAttemptedReactiveCompact: boolean
pendingToolUseSummary: Promise<...>
stopHookActive: boolean
turnCount: number
transition: Continue | undefined
}
| 场景 | 恢复策略 |
|---|---|
max_output_tokens | 保留部分响应,继续生成下一轮 |
| Token 超限 | Reactive Compact(快速压缩) |
| 上下文过长 | Auto Compact(自动摘要压缩) |
| API 错误 | Retry with backoff |
| 工具失败 | 返回错误结果,模型自行处理 |
async function* 实现,每个 Token、每个工具调用结果都通过 yield 逐步发送给 UI 层。这保证了实时的流式输出体验,不需要等待整个响应完成。
工具是 Claude Code 的「手和脚」,每个工具都遵循统一的接口规范
inputSchema + outputSchema,运行时验证工具输入输出。支持 lazySchema 延迟求值。
Ask / Allow / Deny 三级。规则支持路径通配符、命令前缀、域名匹配、正则表达式。
isConcurrencySafe() 标记是否可并行。Bash 工具串行队列执行。
标准化 onProgress 回调,UI 实时显示工具执行进度。
shouldDefer 标记的工具通过 ToolSearch 按需加载,减少初始 Prompt 大小。
每个工具有独立的 JSX 渲染组件,显示调用中、结果、错误、拒绝四种状态。
| 配置位置 | 说明 |
|---|---|
.claude/settings.json | 用户设置:hooks、permissions、behaviors |
global.json | 全局设置:theme、model、voice |
| Permission Rules | Behavior: deny/ask/allow,Content: 路径通配符、命令前缀、域名 |
| 默认模式 | ask(用户控制默认行为) |
| 特殊保护 | SSH/UNC 路径阻止(防止凭据泄露)、Secret 模式检测 |
Claude Code 内置 40 个工具(42 个目录含 shared/testing),覆盖文件操作、搜索、执行、任务管理等领域
| 工具 | 功能 | 关键特性 |
|---|---|---|
FileReadTool | 读取文件内容 | 编码检测、PDF 提取、图片处理、Token 大小限制、设备文件阻止 |
FileEditTool | 字符串替换编辑 | 陈旧检测(Staleness)、引号规范化、原子读写锁、LSP 通知、Git Diff |
FileWriteTool | 创建/覆盖文件 | 自动创建父目录、文件历史备份、行尾保留、VSCode 通知、Skill 发现 |
NotebookEditTool | 编辑 Jupyter Notebook | Cell 级修改、保留 Cell 结构、多类型 Cell 支持 |
| 工具 | 功能 | 关键特性 |
|---|---|---|
GrepTool | 内容搜索(ripgrep 后端) | 正则、多行匹配、VCS 目录排除、分页、默认 250 行限制 |
GlobTool | 文件名模式搜索 | 最多返回 100 文件、相对路径输出 |
WebSearchTool | 网络搜索 | API 提供商检测、每次最多 8 次搜索、流式进度 |
WebFetchTool | 网页内容提取 | HTML → Markdown、预批准域名缓存、LLM 内容提取 |
ToolSearchTool | 搜索可用工具 | 帮助模型发现相关工具 |
| 工具 | 功能 | 关键特性 |
|---|---|---|
BashTool |
执行 Shell 命令 |
安全:AST 解析命令验证、UNC 路径保护、Sed 编辑预览 执行:沙箱支持、后台任务、15 秒自动后台化 语义:检测搜索/读取/列表命令、Git 操作追踪 输出:Stdout/Stderr 捕获、图片渲染、大输出持久化 |
PowerShellTool | PowerShell 命令(Windows) | Cmdlet 规范化、同 Bash 安全模型 |
| 工具 | 功能 |
|---|---|
TaskCreateTool | 创建任务(subject + description + activeForm 形式) |
TaskListTool | 列出所有任务及状态和依赖关系 |
TaskGetTool | 获取单个任务详情(含 metadata) |
TaskUpdateTool | 更新任务状态/所有者/依赖(pending → in_progress → completed) |
TaskStopTool | 停止后台运行的任务 |
TaskOutputTool | 读取后台任务的输出文件 |
| 工具 | 功能 | 关键特性 |
|---|---|---|
AgentTool |
生成子代理 |
隔离类型:Worktree / Remote(CCR) / CWD 模型选择:sonnet / opus / haiku 团队协作:多代理 Swarm 团队 后台运行:120 秒自动后台化 |
SkillTool | 执行技能 | 本地/内置/市场 Skill、Frontmatter 元数据解析、隔离执行 |
SendMessageTool | 团队消息 | 向 Teammate 发送消息、邮箱投递 |
Language Server Protocol:goToDefinition、findReferences、hover、documentSymbol 等
创建隔离的 git worktree 并切换会话
进入计划模式(所有工具需审批)
定时调度:Cron 表达式 + 一次性/循环任务
运行时配置 theme/model/voice 等
MCP 工具包装器:Slack、GitHub、Twitter 等外部服务
向用户提问并等待回答
管理远程代理触发器(CCR)
暂停执行(轮询间隔场景)
100+ 个斜杠命令(内置 + 插件 + MCP + Skills),支持 local、prompt、jsx 三种类型
| 类型 | 说明 | 示例 |
|---|---|---|
local | 同步/异步函数,返回 LocalCommandResult | /compact、/branch |
local-jsx | React 组件,交互式 UI 体验 | /model、/help、/config |
prompt | 发送 Prompt 给 Claude 执行 | /commit、/review |
/commit | 安全的 Git 提交(检查 secret、HEREDOC 格式) |
/review | PR 本地代码审查(正确性、规范、安全) |
/diff | 显示会话中的代码变更 |
/branch | Git 分支操作 |
/compact | 压缩对话历史 |
/rewind | 回退到之前的消息 |
/plan | 启用计划模式或查看当前计划 |
/ultraplan | 高级扩展计划模式 |
/tasks | 管理任务列表 |
/init | 8 阶段项目初始化(CLAUDE.md + skills + hooks) |
/model | 选择/切换模型(Opus、Sonnet、Haiku) |
/config | 打开设置配置界面 |
/theme | 切换终端主题 |
/permissions | 管理工具权限 |
/hooks | 配置事件钩子 |
/keybindings | 管理键盘快捷键 |
/memory | 编辑 CLAUDE.md 记忆文件 |
/plugin | 管理插件(发现、安装、启用/禁用) |
/skills | 管理自定义技能 |
/mcp | 管理 MCP 服务器连接 |
/agents | 管理代理配置 |
/install-github-app | 10 步安装 GitHub App 集成 |
/ide | IDE 集成(VSCode/JetBrains) |
/voice | 语音输入控制 |
/help | 显示所有命令的帮助菜单 |
/context | 显示当前 Context 使用和 Token 统计 |
/cost | 显示成本信息 |
/stats | 会话统计 |
/login / /logout | 认证管理 |
/resume | 恢复之前的会话 |
/export | 导出对话记录 |
/doctor | 环境诊断 |
/ultrareview | 远程 Bug 查找与验证(10-20 分钟) |
/session | 显示远程会话信息 + QR 码 |
/remote-setup | 配置远程模式 |
/sandbox-toggle | 切换沙箱模式 |
/upgrade | 检查/安装升级 |
/release-notes | 显示发行说明 |
Claude Code 使用自定义的 React 终端渲染引擎,43 个文件实现了完整的终端 UI 框架
| 组件 | 说明 |
|---|---|
Box | Flex 容器(类似 HTML div) |
Text | 文本渲染 + 样式 |
ScrollBox | 可滚动容器 + 滚动 API |
Button | 按钮组件 |
Link | 超链接 |
RawAnsi | 原始 ANSI 直通 |
AlternateScreen | 备用屏幕模式 |
键盘输入监听
访问 Stdin 流
动画帧计时
终端尺寸响应
文本选择状态
光标位置管理
113 个 React 组件文件,从布局容器到消息渲染器,构建完整的终端交互界面
App.tsx | 顶层包装器(FPS、Stats、AppState 提供者) |
FullscreenLayout.tsx | 主布局(636 行):滚动区、底部固定、模态框、浮层、药丸通知 |
VirtualMessageList.tsx | 虚拟滚动消息列表(1081 行) |
StatusLine.tsx | 状态栏:模型、权限、Context、Token、会话信息 |
MessageResponse.tsx | 助手回复包装(⎿ 缩进) |
Markdown.tsx | Markdown 渲染器 |
PromptInput/ | 复杂输入子系统(8 个文件) |
PromptInput.tsx | 主输入组件 |
PromptInputFooter.tsx | 底部栏(建议、模式指示器) |
PromptInputHelpMenu.tsx | 帮助菜单 |
TextInput.tsx | 通用文本输入 |
| 类别 | 组件 |
|---|---|
| 用户消息 | UserPromptMessage、UserTextMessage、UserBashInputMessage |
| 助手消息 | AssistantTextMessage、AssistantThinkingMessage、AssistantRedactedThinkingMessage |
| 工具消息 | AssistantToolUseMessage |
| 结果消息 | UserToolSuccessMessage、UserToolErrorMessage、UserToolRejectMessage、UserToolCanceledMessage |
| 系统消息 | SystemTextMessage、HookProgressMessage、ShutdownMessage、RateLimitMessage |
| 协作消息 | PlanApprovalMessage、TaskAssignmentMessage、UserAgentNotificationMessage |
QuickOpenDialog | 快速打开/搜索对话框 |
ExportDialog | 导出对话框 |
BackgroundTasksDialog | 后台任务管理 |
ShellDetailDialog | Shell 输出详情 |
MCPServerApprovalDialog | MCP 服务器审批 |
Settings/ | 设置界面(3 个文件) |
83 个自定义 Hook 文件,管理从状态订阅到远程连接的所有副作用
useAppState | 订阅 AppState 切片(Selector 模式) |
useSettings | 只读访问设置 |
useCommandQueue | 命令排队与处理 |
useCanUseTool | 工具权限检查 |
useInput | 原始终端输入处理 |
useTextInput | 文本输入状态管理 |
useVimInput | Vim 模式键绑定 |
usePasteHandler | 剪贴板粘贴处理 |
useArrowKeyHistory | 上下箭头历史导航 |
useDoublePress | 双击检测(Ctrl+C/D) |
useGlobalKeybindings | 全局快捷键注册 |
useRemoteSession | 远程执行会话 |
useDirectConnect | 直连配置 |
useSSHSession | SSH 会话管理 |
useReplBridge | REPL 协议桥接 |
useIDEIntegration | IDE 连接集成 |
useTasksV2 | 后台任务状态 |
useSwarmInitialization | 多代理 Swarm 初始化 |
useVoiceIntegration | 语音输入集成 |
notifs/ | 12 个通知 Hook(启动、限速、插件更新等) |
20+ 个专业服务,处理 API 通信、Token 管理、MCP 协议、OAuth、语音等
services/api/ — 20 个文件
claude.ts — Anthropic API 核心通信层client.ts — SDK 客户端初始化与配置withRetry.ts — API 失败重试逻辑errors.ts — 错误处理与转换usage.ts — Token 使用追踪grove.ts — Grove API 集成(Anthropic 内部服务)services/compact/ — 11 个文件
compact.ts — 主压缩算法autoCompact.ts — 自动触发系统microCompact.ts — 轻量内联压缩sessionMemoryCompact.ts — 持久记忆压缩prompt.ts — 压缩 Prompt 生成services/mcp/ — 23 个文件
MCPConnectionManager.tsx — MCP 生命周期管理client.ts — MCP 客户端实现config.ts — 配置解析与验证channelPermissions.ts — Telegram/Channel 访问控制officialRegistry.ts — 官方 MCP 注册表voice.ts | Push-to-talk 录音(native + SoX) |
voiceStreamSTT.ts | 流式语音转文字 |
tokenEstimation.ts | Token 计数(多 Provider) |
claudeAiLimits.ts | 限速追踪(5h/7d 窗口) |
oauth/ | OAuth2 流程(GitHub、Google) |
lsp/ | Language Server Protocol |
analytics/ | GrowthBook Feature Flag + Datadog |
SessionMemory/ | 会话内记忆注入与检索 |
基于 Zustand 思想的轻量状态管理,单一数据源 + 不可变更新
settings, verbose, mainLoopModel, statusLineText
expandedView, isBriefOnly, focusedButtonInDialog
tasks (索引), viewingAgentTaskId, selectedIPAgentIndex
messages[], unreadCount, dividerIndex
promptSuggestion, userInput, promptInputMode
toolPermissionContext, denialTracking
分层设计:平台默认 → 用户自定义,支持 Chord(组合键序列)
| Context | 快捷键 | 功能 |
|---|---|---|
| Global | Ctrl+C | 中断当前操作 |
| Global | Ctrl+D | 退出 |
| Global | Ctrl+L | 重绘终端 |
| Global | Ctrl+T | 打开 Todos |
| Global | Ctrl+R | 历史搜索 |
| Chat | Enter | 提交输入 |
| Chat | Escape | 取消 |
| Chat | Ctrl+Shift+K | 终止所有代理 |
| Chat | Shift+Tab | 循环切换模式 |
支持 Chord 绑定,如 Ctrl+K Ctrl+S(两步组合)。Ctrl+C 和 Ctrl+D 为保留键,不可重新绑定。
31 个文件实现远程控制通信层,支持 Claude Code 作为远程代理运行
| 模式 | 说明 |
|---|---|
single-session | 单会话模式 |
worktree | 隔离 Git Worktree |
same-dir | 同目录模式 |
Model Context Protocol — 连接外部工具和服务的标准协议
技能是原子化的 Prompt 扩展,插件是多能力集合体
~/.claude/skills/ 目录// BundledSkillDefinition
{
name: string
description: string
hooks?: HookDef[]
files?: string[]
// Frontmatter: model, triggers
}
| Skill | Plugin | |
|---|---|---|
| 粒度 | 单一 Prompt | 多能力集合 |
| 包含 | Prompt + 文件 | Skills + Hooks + MCP Servers |
| 管理 | /skills | /plugin(启用/禁用 UI) |
| 来源 | 本地/内置/MCP | 内置/市场 |
{name}@builtin 或 {name}@{marketplace}
Claude Code 中反复出现的架构设计模式总结
query.ts 和 QueryEngine.ts 使用 async function* 实现流式输出。每个 Token、每个工具结果都通过 yield 逐步发送给 UI 层,实现实时体验。
async function* query(params) {
while (shouldContinue) {
yield* streamAPIResponse()
yield* executeTools()
}
}
使用 Bun 的 feature() 系统实现构建时代码消除。不同的构建产物包含不同的功能集。
if (feature('KAIROS')) {
tools.push(SleepTool, CronCreateTool)
}
if (feature('REPL_TOOL')) {
tools.push(REPLTool)
}
context.ts、commands.ts 等使用 memoize 缓存昂贵计算结果,一次计算,全程复用。支持手动失效。
SessionId 和 AgentId 使用 TypeScript 品牌类型,编译时防止 ID 混用。
type SessionId = string & { __brand: 'SessionId' }
type AgentId = string & { __brand: 'AgentId' }
全局状态通过 React Context Provider 注入,组件通过 useXxx Hook 订阅。避免 Prop Drilling。
Provider 层级:AppState → Keybinding → Modal → Notifications → Theme
所有工具通过 buildTool() 工厂函数创建,自动补充安全默认值。工具只需实现关心的方法。
非关键模块使用动态 require() 延迟加载。系统 Prompt、MCP 资源在首次渲染后后台预取。
history.jsonl、config.json 等共享文件使用文件级锁防止竞态条件。
记忆压缩、摘要生成等操作在子进程中运行,不阻塞主线程。使用 CacheSafeParams 共享 Prompt 缓存。
query 循环实现多级错误恢复:max_output_tokens 继续 → Reactive Compact → Auto Compact → Stop Hook → 用户通知。
Anthropic 近期力推的核心理念:Harness(编排层)与模型同等重要。Claude Code 的代码中处处体现了这一设计哲学。
Harness(直译「线束/缰绳」)是包裹在 AI 模型外层的编排运行时。它不是模型本身,而是控制模型行为的一整套机制:
文件:constants/prompts.ts
System Prompt 不是简单的「你是一个 AI 助手」,而是一份精心编写的行为规范文档,包括:
文件:utils/hooks.ts, query/stopHooks.ts
Hooks 允许用户在模型行为的关键节点注入确定性 Shell 命令:
| Hook 事件 | 触发时机 | 用途示例 |
|---|---|---|
PreToolUse | 工具执行前 | 阻止危险操作 |
PostToolUse | 工具执行后 | 自动格式化代码 |
Stop | 轮次结束 | 运行测试验证 |
PreCompact | 压缩前 | 保存关键上下文 |
UserPromptSubmit | 用户提交 | 输入预处理 |
SessionStart | 会话开始 | 环境初始化 |
PermissionRequest | 权限检查时 | 自动审批策略 |
Notification | 通知触发 | 外部通知转发 |
PostToolUse Hook 配置 prettier --write $FILE,每次文件修改后必然执行格式化,模型无法绕过。
文件:utils/permissions/filesystem.ts
权限系统定义了模型的硬能力边界,独立于模型的判断:
.gitconfig、.bashrc、.ssh/、.git/ 等敏感路径硬编码保护harness-controlled,自动放行读取// filesystem.ts line 1153
// 7. Allow reads from internal harness paths
// (session-memory, plans, tool-results)
// filesystem.ts line 1763
// this subtree is harness-controlled.
文件:services/PromptSuggestion/speculation.ts
Harness 可以在模型不知情的情况下,将执行切换到沙箱模式:
/tmp/speculation/{pid}/)文件:utils/claudeCodeHints.ts
工具可以通过特殊 XML 标签与 Harness 直接通信,不经过模型:
// 工具 Stderr 输出
<claude-code-hint v="1" type="plugin" value="name@marketplace" />
// Harness 处理:
// 1. 扫描工具输出中的 hint 标签
// 2. 从输出中剥离(模型看不到)
// 3. 以 UI 提示形式展示给用户
源码注释明确指出:"hints are a harness-only side channel"(hints 是仅 harness 可见的侧信道)
文件:memdir/memdir.ts
Harness 保证记忆目录始终存在,模型无需检查:
// memdir.ts line 114
// Harness guarantees the directory exists
// via ensureMemoryDirExists().
// The model can write directly without mkdir.
这意味着 System Prompt 可以告诉模型「直接写入,不要运行 mkdir」,因为 Harness 已经在启动时创建好了目录。这是一个微小但典型的 Harness-Model 协作模式:Harness 处理基础设施,模型专注推理。
文件:entrypoints/cli.tsx line 16
// Harness-science L0 ablation baseline.
if (feature('ABLATION_BASELINE') &&
process.env.CLAUDE_CODE_ABLATION_BASELINE) {
// 关闭所有 Harness 增强功能:
// CLAUDE_CODE_SIMPLE → 简化 System Prompt
// DISABLE_THINKING → 关闭 Extended Thinking
// DISABLE_COMPACT → 关闭自动压缩
// DISABLE_INTERLEAVED_THINKING → 关闭交错思维
// ...
}
文件:services/tools/toolOrchestration.ts
模型通过 API 发出工具调用请求,但Harness 控制实际执行:
canUseTool() 在执行前检查,可阻止maxResultSizeChars 自动持久化到磁盘| Harness 能力 | 代码实现 | 没有它会怎样? |
|---|---|---|
| 定义行为规范 | System Prompt 宪法 | 模型行为不一致,违反安全策略 |
| 强制安全边界 | Permission Rules + 危险路径列表 | 模型可能误写 .bashrc 或 SSH 密钥 |
| 确定性拦截 | 10 种 Hook 事件 | 无法在模型之外强制执行策略 |
| 上下文管理 | Token 预算 + 自动压缩 + 推测沙箱 | 上下文爆炸、未验证的状态变更 |
| 验证输出 | Post-sampling hooks + Stop hooks | 无法拒绝或修改模型的不良输出 |
| 状态保证 | Memory 目录 + Temp 隔离 + Overlay | 文件系统混乱、状态损坏 |
| 工具安全并发 | 工具编排 + 并发分区 | 竞态条件、不安全的并行执行 |
| 独立评估 | Feature Gate + 消融基线 | 无法区分模型改进 vs Harness 改进 |
| 用户可配置 | settings.json + Hooks + Permissions | Harness 是黑盒,团队无法定制策略 |
| 带外通信 | Claude Code Hints 侧信道 | 工具无法直接与 Harness 通信 |
ABLATION_BASELINE)更是直接证据 — Anthropic 把 Harness 的价值当作可量化的科学指标来追踪。
一张图看懂 Claude Code 的完整架构