Skip to content

Claude Code源码分析手册:从下载到精通

3月31日泄漏的Claude Code源码是一部AI工程的百科全书——1902个文件、51.2万行TypeScript代码。本手册从下载开始,逐个模块拆解,每一步都有真实代码、动手指令和设计原理分析。

准备工作:获取源码

源码来自npm包@anthropic-ai/claude-code v2.1.88中意外发布的Source Map文件(59.8MB)。这是Anthropic第二次因.npmignore配置错误导致源码泄漏。

下载地址: https://claude.whaty.org/posts/Claude-code-source-leak.html

下载解压后你会得到一个src/目录。以下所有路径均以src/为根。

规模一览:

  • 1,902个TypeScript文件
  • 512,000+行代码
  • 44个隐藏feature flag
  • 59.8MB Source Map

第一章:全局地图——先建立整体认知

打开终端,进入源码目录,先用几个命令感受规模:

bash
cd src/

# 数文件
find . -name "*.ts" -o -name "*.tsx" | wc -l
# → 1902

# 看顶层目录
ls

1.1 顶层目录结构

src/
├── assistant/      # KAIROS主动模式(内部功能)
├── bootstrap/      # 启动状态管理
├── bridge/         # IDE桥接层(VS Code、JetBrains等)
├── buddy/          # 虚拟伙伴系统(/buddy命令)
├── cli/            # 命令行接口
├── commands/       # 103个斜杠命令(/commit、/review...)
├── components/     # 146个React组件(终端UI)
├── constants/      # 常量定义(含System Prompt)
├── context/        # React Context上下文
├── coordinator/    # 多Agent协调模式
├── entrypoints/    # 入口点定义(CLI、SDK、Agent SDK)
├── hooks/          # 87个React Hooks
├── ink/            # 终端UI渲染库
├── keybindings/    # 快捷键配置
├── memdir/         # 内存目录系统(AI的长期记忆)
├── migrations/     # 数据库迁移
├── moreright/      # 附加功能模块
├── native-ts/      # 原生绑定
├── outputStyles/   # 输出样式
├── plugins/        # 插件系统
├── query/          # 查询引擎辅助
├── remote/         # 远程执行
├── schemas/        # 数据Schema
├── screens/        # 屏幕组件
├── server/         # 内置服务器
├── services/       # 38个服务模块
├── skills/         # 技能系统
├── state/          # 应用状态管理
├── tasks/          # 6种任务类型
├── tools/          # 43个工具目录
├── types/          # TypeScript类型定义
├── upstreamproxy/  # 上游代理
├── utils/          # 331+工具函数
├── vim/            # Vim模式
├── voice/          # 语音模式

├── main.tsx          # 入口文件
├── setup.ts          # 初始化流程
├── Tool.ts           # 工具接口定义(792行)
├── Task.ts           # 任务接口定义
├── tools.ts          # 工具注册表
├── commands.ts       # 命令注册表
├── query.ts          # 核心查询逻辑(1729行)
├── QueryEngine.ts    # 查询引擎(1295行)
├── context.ts        # 上下文构建
├── cost-tracker.ts   # 成本追踪
└── costHook.ts       # 成本钩子

1.2 技术栈

动手验证:

bash
# 查看运行时
grep "bun:bundle" tools.ts
# → import { feature } from 'bun:bundle'
# 结论:用Bun打包,不是Node.js

# 查看UI框架
grep "from 'react'" main.tsx
grep "from.*ink" main.tsx
# → React + Ink(在终端中渲染React组件)

# 查看类型验证
grep "from 'zod" tools/BashTool/BashTool.tsx
# → import { z } from 'zod/v4'
# 不只是TypeScript编译时类型,还有Zod运行时验证

第一个启发: 这个项目用Bun而不是Node.js,用React渲染终端UI,用Zod做运行时类型验证。每一个选择都有工程理由——Bun启动快、React组件化思维适合复杂UI、Zod保证AI返回的工具参数符合预期。


第二章:入口追踪——程序从哪里启动

2.1 CLI入口

bash
head -30 entrypoints/cli.tsx

CLI入口会调用setup.ts初始化环境。

2.2 setup.ts——初始化的一切

bash
head -70 setup.ts

setup()函数的签名揭示了核心参数:

typescript
export async function setup(
  cwd: string,                              // 工作目录
  permissionMode: PermissionMode,           // 权限模式——核心参数
  allowDangerouslySkipPermissions: boolean, // 危险的权限跳过
  worktreeEnabled: boolean,                 // Git Worktree隔离
  worktreeName: string | undefined,
  tmuxEnabled: boolean,                     // Tmux多窗口
  customSessionId?: string | null,
  worktreePRNumber?: number,
  messagingSocketPath?: string,
): Promise<void>

setup做了什么:

  1. 检查Node.js版本(≥18)
  2. 设置项目根目录和会话ID
  3. 初始化会话内存
  4. 创建Git Worktree(如果启用)
  5. 启动文件变更监听器
  6. 预获取API Key
  7. 捕获Hook配置快照

动手: 搜索初始化过程中的所有import:

bash
grep "^import" setup.ts | wc -l
# → 50+个导入,每个都是一个子系统

2.3 查询引擎——AI的大脑循环

bash
wc -l QueryEngine.ts query.ts
# QueryEngine.ts: 1295行
# query.ts: 1729行
# 合计3024行——这是整个应用最核心的代码

核心循环:

用户输入

QueryEngine.ts
  ├── fetchSystemPromptParts()     # 获取prompt各部分
  ├── getUserContext()              # 环境上下文
  ├── getSystemContext()            # 系统上下文
  ├── buildEffectiveSystemPrompt() # 组装最终prompt(5层优先级)
  ├── normalizeMessagesForAPI()    # 规范化消息
  └── 调用 query()

query.ts
  ├── 计算Token数量
  ├── 检查是否需要Auto Compact
  ├── 追加内存文件(CLAUDE.md等)
  ├── 调用 claude.messages.create()  # API请求
  ├── 处理流式响应
  ├── 提取 tool_use / text 块
  └── 返回AssistantMessage

如果有tool_use → 权限检查 → 工具执行 → 结果回传 → 再次query()
如果只有text → 展示给用户 → 等待下一次输入

第三章:System Prompt——AI的"出厂设置"

这是最值得细读的文件。每一行都是真金白银的提示词工程经验。

3.1 文件概览

bash
wc -l constants/prompts.ts
# → 914行

3.2 五层优先级模型

打开utils/systemPrompt.ts,找到buildEffectiveSystemPrompt()函数:

优先级(高→低):
第0层:Override System Prompt(loop模式等覆盖一切)
第1层:Coordinator System Prompt(多Agent协调)
第2层:Agent System Prompt(子Agent专属指令)
第3层:Custom System Prompt(用户通过--system-prompt传入)
第4层:Default System Prompt(标准prompt + Append追加)

动手验证:

bash
grep -n "override\|coordinator\|agent.*system\|custom.*system\|default.*system" utils/systemPrompt.ts

3.3 静态/动态分区——省90%成本的关键一刀

bash
grep -n "SYSTEM_PROMPT_DYNAMIC_BOUNDARY" constants/prompts.ts

这个常量把914行prompt切成两半:

静态部分(标记之前)——被API缓存:

  • Claude Code身份介绍
  • 工具使用规范("用Read不用cat,用Edit不用sed")
  • 代码修改准则("不要添加超出要求的功能")
  • 安全操作准则("仔细考虑操作的可逆性")
  • 语调和风格("简洁、无冒号、用绝对路径")
  • 输出效率要求("直奔主题,先说答案不说过程")

动态部分(标记之后)——每次会话不同:

  • 当前工作目录和Git状态
  • CLAUDE.md内容注入
  • 模型信息和知识截止日期
  • MCP服务器列表
  • Scratchpad目录路径

为什么这很重要: Anthropic API的Prompt Cache机制——静态部分被缓存后,后续请求的输入Token只收10%。一个重度Vibe Coding会话可能100次API调用,这一刀切出来的是数十美元的成本差距。

3.4 缓存失效检测

bash
head -40 services/api/promptCacheBreakDetection.ts

这个文件对系统提示词做哈希比对,追踪每次缓存是否命中:

typescript
type PreviousState = {
  systemHash: number         // 系统提示词哈希
  toolsHash: number          // 工具定义哈希
  cacheControlHash: number   // 缓存控制哈希
  toolNames: string[]        // 工具名称列表
  perToolHashes: Record<string, number>  // 每个工具的schema哈希
  systemCharCount: number    // 字符计数
  model: string              // 模型名称
}

如果某个工具的描述变化导致缓存全线失效,这个模块会记录diff帮助诊断。注释中提到(原文):

"Per-tool schema hash. Diffed to name which tool's description changed when toolSchemasChanged but added=removed=0 (77% of tool breaks per BQ 2026-03-22)"

翻译:77%的缓存失效是因为工具描述变化,而不是工具增删。

3.5 提示词中的具体指令

动手提取所有"禁止"指令:

bash
grep -n "NEVER\|MUST NOT\|Don't\|CRITICAL\|IMPORTANT" constants/prompts.ts

你会找到这些生产级规则:

关于代码修改:

"Don't add features, refactor code, or make 'improvements' beyond what was asked. A bug fix doesn't need surrounding code cleaned up. A simple feature doesn't need extra configurability."

关于工具使用优先级:

"To read files use Read instead of cat, head, tail, or sed. To edit files use Edit instead of sed or awk. To search for files use Glob instead of find or ls."

关于安全操作:

"Carefully consider the reversibility and blast radius of actions. Generally you can freely take local, reversible actions like editing files or running tests."

关于Git安全:

"NEVER update the git config. NEVER run destructive git commands unless the user explicitly requests. NEVER skip hooks (--no-verify) unless the user explicitly requests."

关于输出效率:

"Go straight to the point. Try the simplest approach first without going in circles. Do not overdo it. Be extra concise."

启发: 如果你在写自己的AI Agent,这些指令就是最佳模板。每一条背后都是真实的生产事故——有人让AI"改进"代码结果弄崩了项目,有人让AI push --force丢了分支。


第四章:工具系统——43个工具的完整档案

4.1 工具接口定义

bash
head -100 Tool.ts

核心接口(简化版):

typescript
type Tool = {
  name: string
  userFacingName: (input) => string      // 用户可见名称
  description: (input, ctx) => string    // 动态描述
  inputSchema: ZodSchema                 // Zod运行时验证

  // 权限
  isReadOnly?: () => boolean
  canUseWithoutAsk?: boolean
  checkPermissions?: (input, ctx) => PermissionResult

  // 执行
  execute: (input, ctx) => Promise<ToolResult>

  // UI(React组件)
  renderToolUseMessage: JSX.Element
  renderToolResultMessage: JSX.Element
  renderToolUseErrorMessage: JSX.Element
  renderToolUseProgressMessage: JSX.Element
}

4.2 条件编译——feature()的魔法

bash
head -55 tools.ts

标准导入的工具(始终可用):

typescript
import { BashTool } from './tools/BashTool/BashTool.js'
import { FileEditTool } from './tools/FileEditTool/FileEditTool.js'
import { FileReadTool } from './tools/FileReadTool/FileReadTool.js'
import { FileWriteTool } from './tools/FileWriteTool/FileWriteTool.js'
import { GlobTool } from './tools/GlobTool/GlobTool.js'
import { GrepTool } from './tools/GrepTool/GrepTool.js'
import { AgentTool } from './tools/AgentTool/AgentTool.js'
import { WebSearchTool } from './tools/WebSearchTool/WebSearchTool.js'
import { WebFetchTool } from './tools/WebFetchTool/WebFetchTool.js'

条件编译的工具(通过feature gate控制):

typescript
// 仅内部员工可用
const REPLTool = process.env.USER_TYPE === 'ant'
  ? require('./tools/REPLTool/REPLTool.js').REPLTool
  : null

// KAIROS主动模式下的休眠工具
const SleepTool = feature('PROACTIVE') || feature('KAIROS')
  ? require('./tools/SleepTool/SleepTool.js').SleepTool
  : null

// 定时任务
const cronTools = feature('AGENT_TRIGGERS')
  ? [CronCreateTool, CronDeleteTool, CronListTool]
  : []

// 网页浏览器(未发布)
const WebBrowserTool = feature('WEB_BROWSER_TOOL')
  ? require('./tools/WebBrowserTool/WebBrowserTool.js').WebBrowserTool
  : null

// 工作流脚本引擎(未发布)
const WorkflowTool = feature('WORKFLOW_SCRIPTS')
  ? (() => {
      require('./tools/WorkflowTool/bundled/index.js').initBundledWorkflows()
      return require('./tools/WorkflowTool/WorkflowTool.js').WorkflowTool
    })()
  : null

// 上下文折叠检查器
const CtxInspectTool = feature('CONTEXT_COLLAPSE')
  ? require('./tools/CtxInspectTool/CtxInspectTool.js').CtxInspectTool
  : null

动手:搜索所有feature flag

bash
grep -r "feature('" tools.ts constants/ utils/ services/ --include="*.ts" | \
  grep -o "feature('[^']*'" | sort -u

完整列表:

Feature Flag功能状态
KAIROSAI主动工作模式(autoDream机制)内部测试
PROACTIVE主动执行模式内部测试
WEB_BROWSER_TOOL网页浏览器开发中
WORKFLOW_SCRIPTS可复用工作流开发中
COORDINATOR_MODE多Agent协调器内部测试
CONTEXT_COLLAPSE上下文折叠实验性
REACTIVE_COMPACT响应式压缩实验性
VOICE_MODE语音交互已上线
AGENT_TRIGGERSAgent定时触发开发中
AGENT_TRIGGERS_REMOTE远程触发开发中
TEAM_MEMORY团队内存共享开发中
TRANSCRIPT_CLASSIFIER对话安全分类实验性
HISTORY_SNIP历史裁剪实验性
UDS_INBOXUnix域套接字通信开发中
OVERFLOW_TEST_TOOL溢出测试工具测试用
TERMINAL_PANEL终端面板捕获开发中
MONITOR_TOOL监控工具开发中
KAIROS_PUSH_NOTIFICATIONKAIROS推送通知内部
KAIROS_GITHUB_WEBHOOKSGitHub Webhook订阅内部

4.3 完整工具分类

动手列出所有工具:

bash
ls tools/

按功能分类:

文件操作(6个):

  • FileReadTool — 读文件(支持图片、PDF、Jupyter Notebook)
  • FileWriteTool — 写文件
  • FileEditTool — 精确字符串替换编辑
  • GlobTool — 文件模式匹配搜索
  • GrepTool — 基于ripgrep的内容搜索
  • NotebookEditTool — Jupyter Notebook编辑

代码执行(2-3个):

  • BashTool — Bash命令执行(最复杂的工具)
  • PowerShellTool — Windows PowerShell(条件加载)
  • REPLTool — 交互式代码执行(仅Ant内部)

AI/Agent(3个):

  • AgentTool — 启动子Agent
  • SkillTool — 调用技能
  • SendMessageTool — 给队友发消息

信息获取(5个):

  • WebSearchTool — 网络搜索
  • WebFetchTool — 获取网页内容
  • MCPTool — 调用MCP服务器工具
  • ListMcpResourcesTool — 列出MCP资源
  • ReadMcpResourceTool — 读取MCP资源
  • ToolSearchTool — 搜索延迟加载的工具

任务管理(6个):

  • TaskCreateTool — 创建任务
  • TaskGetTool — 获取任务
  • TaskUpdateTool — 更新任务
  • TaskListTool — 列出任务
  • TaskStopTool — 停止任务
  • TaskOutputTool — 获取任务输出

团队协作(2个):

  • TeamCreateTool — 创建Agent团队
  • TeamDeleteTool — 删除团队

模式切换(4个):

  • EnterPlanModeTool — 进入计划模式
  • ExitPlanModeV2Tool — 退出计划模式
  • EnterWorktreeTool — 进入Git Worktree
  • ExitWorktreeTool — 退出Worktree

其他(5个):

  • ConfigTool — 修改配置
  • AskUserQuestionTool — 向用户提问
  • TodoWriteTool — 写TODO
  • LSPTool — 语言服务器协议
  • BriefTool — 简要输出工具

4.4 深度解剖BashTool

BashTool是整个工具系统中最复杂的。

动手看它的依赖数量:

bash
head -52 tools/BashTool/BashTool.tsx

50+行导入,涉及:AST安全解析、沙箱管理、命令语义解释、sed编辑解析、文件历史追踪、图片输出识别、只读约束检查、代码索引检测...

命令分类常量:

typescript
// 搜索命令(折叠显示)
const BASH_SEARCH_COMMANDS = new Set([
  'find', 'grep', 'rg', 'ag', 'ack', 'locate', 'which', 'whereis'
])

// 读取/查看命令(折叠显示)
const BASH_READ_COMMANDS = new Set([
  'cat', 'head', 'tail', 'less', 'more',
  'wc', 'stat', 'file', 'strings',
  'jq', 'awk', 'cut', 'sort', 'uniq', 'tr'
])

// 目录列表命令
const BASH_LIST_COMMANDS = new Set(['ls', 'tree', 'du'])

// 静默命令(成功时不产生输出)
const BASH_SILENT_COMMANDS = new Set([
  'mv', 'cp', 'rm', 'mkdir', 'rmdir', 'chmod', 'chown',
  'chgrp', 'touch', 'ln', 'cd', 'export', 'unset', 'wait'
])

关键常量:

typescript
const PROGRESS_THRESHOLD_MS = 2000      // 2秒后显示进度条
const ASSISTANT_BLOCKING_BUDGET_MS = 15_000  // 15秒后自动后台化

4.5 沙箱决策

bash
cat tools/BashTool/shouldUseSandbox.ts

这个文件决定哪些命令需要在沙箱中执行。沙箱通过SandboxManager实现,隔离文件系统和网络访问。

4.6 工具池装配

当启动一个子Agent时,不是简单地把所有工具都给它。assembleToolPool()会:

bash
grep -A 30 "export.*function.*assembleToolPool\|function assembleToolPool" tools.ts

流程:

  1. 获取基础工具列表
  2. 如果Agent指定了tools字段,只保留指定的工具
  3. 如果Agent指定了disallowedTools,移除这些工具
  4. 移除被权限规则全局拒绝的工具
  5. 处理特殊工具(MCP、Coordinator模式专属工具)

第五章:Agent系统——AI如何指挥AI

5.1 内置Agent完整档案

动手列出所有内置Agent:

bash
ls tools/AgentTool/built-in/

6种内置Agent:

Explore Agent(84行,最值得学习的Agent定义)

bash
cat tools/AgentTool/built-in/exploreAgent.ts

完整设计解析:

typescript
export const EXPLORE_AGENT: BuiltInAgentDefinition = {
  agentType: 'Explore',

  // 什么时候用这个Agent
  whenToUse: 'Fast agent specialized for exploring codebases...',

  // 禁用的工具——保证完全只读
  disallowedTools: [
    AGENT_TOOL_NAME,         // 不能再启动子Agent(防止套娃)
    EXIT_PLAN_MODE_TOOL_NAME,
    FILE_EDIT_TOOL_NAME,     // 不能编辑文件
    FILE_WRITE_TOOL_NAME,    // 不能写文件
    NOTEBOOK_EDIT_TOOL_NAME, // 不能编辑Notebook
  ],

  // 模型选择——这是最有启发性的设计
  // Ant内部员工用继承模型(可能是Opus/Sonnet),外部用户用Haiku
  model: process.env.USER_TYPE === 'ant' ? 'inherit' : 'haiku',
  // Haiku速度是Opus的10倍,成本是1/10

  // 跳过CLAUDE.md——Explore是只读搜索Agent,不需要项目规范
  omitClaudeMd: true,
  // 这一个配置就能省几千Token

  getSystemPrompt: () => getExploreSystemPrompt(),
}

Explore的System Prompt(第24-56行)包含严格的只读约束:

=== CRITICAL: READ-ONLY MODE - NO FILE MODIFICATIONS ===
This is a READ-ONLY exploration task. You are STRICTLY PROHIBITED from:
- Creating new files (no Write, touch, or file creation of any kind)
- Modifying existing files (no Edit operations)
- Using redirect operators (>, >>, |) or heredocs to write to files
- Running ANY commands that change system state

以及效率要求:

NOTE: You are meant to be a fast agent that returns output as quickly as
possible. In order to achieve this you must:
- Make efficient use of the tools
- Wherever possible spawn multiple parallel tool calls

Plan Agent(93行)

bash
cat tools/AgentTool/built-in/planAgent.ts

与Explore的关键区别:

  • 角色定位不同:"You are a software architect and planning specialist"
  • 输出有严格格式要求——每个Plan必须以"Critical Files for Implementation"结尾,列3-5个关键文件
  • 同样omitClaudeMd: true——Plan Agent可以自己Read CLAUDE.md,但不把它注入System Prompt,省Token

Verification Agent

动手查看:

bash
cat tools/AgentTool/built-in/verificationAgent.ts

这个Agent专门验证实现结果,输出PASS/FAIL/PARTIAL。关键设计:

  • 独立运行——不受原始Agent偏见影响
  • 可以运行测试(有Bash权限)
  • 触发条件:3+文件编辑、后端/API变更

5.2 Agent运行机制

bash
head -60 tools/AgentTool/runAgent.ts

runAgent()是所有Agent执行的核心。它负责:

  1. 构建Agent的消息历史
  2. 调用API获取响应
  3. 处理工具调用循环
  4. 管理Token预算
  5. 返回最终结果

5.3 Agent执行路径

bash
head -60 tools/AgentTool/AgentTool.tsx

AgentTool的execute()会根据情况选择不同的执行路径:

  • 本地执行 — LocalAgentTask(同机器)
  • 远程执行 — RemoteAgentTask(通过Bridge发送到远端)
  • 进程内执行 — InProcessTeammateTask(同进程的队友)
  • Fork执行 — 后台隔离运行

第六章:Harness——AI的缰绳(核心重点)

Harness是贯穿全栈的控制哲学,散布在多个模块中。

6.1 权限决策引擎——1486行的安全大脑

bash
wc -l utils/permissions/permissions.ts
# → 1486行

核心函数hasPermissionsToUseTool()实现了6层安检。每次AI调用任何工具,都经过这个函数。

动手看函数签名:

bash
grep -n "hasPermissionsToUseTool" utils/permissions/permissions.ts | head -5

六层安检详解:

AI提交工具调用

【第1层】工具级规则(5个子步骤)
  1a. getDenyRuleForTool() — 工具被整体禁止?
  1b. getAskRuleForTool() — 工具有ask规则?
  1c. tool.checkPermissions() — 工具自身安全检查
  1d. 工具deny? → 直接拒绝
  1e. 需要用户交互?
  1f. 内容特定ask规则?(如"Bash(npm publish:*)")
  1g. 安全检查失败?

  ⚠️ 1d-1g对所有模式免疫,包括bypassPermissions

【第2层】权限模式过滤
  2a. bypassPermissions → 放行(但1d-1g不可跳过)
  2b. always-allow规则匹配 → 放行

【第3层】模式转换
  如果 mode === 'dontAsk' 且 result === 'ask'
    → 自动拒绝(后台Agent不弹对话框)

【第4层】Auto模式分类器
  4a. acceptEdits快路径 — 编辑工作目录?直接放行
  4b. 安全工具白名单 — FileRead/Grep/Glob直接放行
  4c. 运行YOLO分类器 — AI评估风险

【第5层】用户钩子
  执行PermissionRequest钩子
  钩子可以allow/deny/无操作

【第6层】用户交互
  弹出权限对话框
  等待用户点击

  返回 allow / deny

6.2 五种权限模式

动手查看模式定义:

bash
grep -A 5 "PermissionMode\|PERMISSION_MODE" utils/permissions/PermissionMode.ts | head -30
模式行为适用场景风险等级
default每次操作都问日常开发最安全
plan只能看不能改方案讨论最安全
acceptEdits文件操作自动通过快速编码中等
autoAI分类器自动判断熟悉的项目中高
bypassPermissions几乎全部放行完全信任
dontAsk需确认的操作直接拒绝后台Agent特殊

6.3 YOLO分类器——52KB的AI安全大脑

bash
wc -l utils/permissions/yoloClassifier.ts
# → 1495行

动手搜索安全白名单:

bash
grep -A 15 "SAFE_YOLO_ALLOWLISTED\|allowlisted" utils/permissions/yoloClassifier.ts | head -25

白名单中的工具直接放行,不消耗API调用:

  • FileReadTool(只读)
  • GrepTool(搜索内容)
  • GlobTool(搜索文件名)
  • TaskCreateTool/TaskUpdateTool(元数据操作)
  • SendMessageTool(给队友发消息)

对于非白名单工具(尤其是Bash),分类器的处理流程:

  1. 先检查acceptEdits快路径
  2. 对Bash命令进行AST解析
  3. 检测危险模式(rm -rf、force push、权限变更等)
  4. 可能调用API进行深度评估
  5. 返回allow或deny

6.4 拒绝熔断器

bash
cat utils/permissions/denialTracking.ts

完整源码只有46行——这是教科书级的小模块设计:

typescript
export const DENIAL_LIMITS = {
  maxConsecutive: 3,    // 连续3次被拒 → 降级为人工确认
  maxTotal: 20,         // 累计20次被拒 → 整个auto模式熔断
} as const

export function recordDenial(state) {
  return { ...state,
    consecutiveDenials: state.consecutiveDenials + 1,
    totalDenials: state.totalDenials + 1,
  }
}

export function recordSuccess(state) {
  if (state.consecutiveDenials === 0) return state // 无变化
  return { ...state, consecutiveDenials: 0 }       // 重置连续计数
}

export function shouldFallbackToPrompting(state) {
  return (
    state.consecutiveDenials >= DENIAL_LIMITS.maxConsecutive ||
    state.totalDenials >= DENIAL_LIMITS.maxTotal
  )
}

设计启发:

  • 一次成功就重置连续拒绝计数(recordSuccess只重置consecutiveDenials
  • 总拒绝数不重置——这是永久记录
  • 46行4个函数,不多不少

6.5 文件系统沙箱

bash
wc -l utils/permissions/filesystem.ts
# → 1777行

动手搜索危险文件列表:

bash
grep -A 10 "DANGEROUS_FILE\|DANGEROUS_DIR" utils/permissions/filesystem.ts | head -25

不可修改的文件/目录(对所有模式免疫):

  • .gitconfig — 可被利用执行任意代码
  • .bashrc / .zshrc — Shell初始化
  • .mcp.json — MCP服务器列表
  • .git/ — 版本控制核心
  • .vscode/ / .idea/ — IDE设置
  • .claude/ — Claude配置目录

三重路径验证:

  1. 原始路径检查
  2. 符号链接解析(防止软链接逃逸)
  3. 工作目录归属检查

6.6 Hint侧通道

bash
head -70 utils/claudeCodeHints.ts

原始注释(这是最精确的设计说明):

typescript
/**
 * CLIs and SDKs running under Claude Code can emit a self-closing
 * `<claude-code-hint />` tag to stderr (merged into stdout by the shell
 * tools). The harness scans tool output for these tags, strips them before
 * the output reaches the model, and surfaces an install prompt to the
 * user — no inference, no proactive execution.
 *
 * This file provides both the parser and a small module-level store for
 * the pending hint. The store is a single slot (not a queue) — we surface
 * at most one prompt per session, so there's no reason to accumulate.
 */

关键实现:

typescript
// 标签匹配正则——只匹配独占一行的标签
const HINT_TAG_RE = /^[ \t]*<claude-code-hint\s+([^>]*?)\s*\/>[ \t]*$/gm

// 属性解析
const ATTR_RE = /(\w+)=(?:"([^"]*)"|([^\s/>]+))/g

// 支持的版本和类型
const SUPPORTED_VERSIONS = new Set([1])
const SUPPORTED_TYPES = new Set<string>(['plugin'])

设计精髓:

  • 标签必须独占一行(防止嵌入在日志语句中被误匹配)
  • 单槽存储——每会话最多一个提示(防止AI轰炸用户)
  • 不支持的版本/类型静默丢弃(向前兼容)
  • AI看到的是剥离后的输出,完全不知道标签的存在

6.7 Bash权限系统

bash
wc -l tools/BashTool/bashPermissions.ts
# → 500+行

这个文件实现了Bash命令的精细权限控制:

bash
head -60 tools/BashTool/bashPermissions.ts

包括:

  • 命令前缀匹配(npm *匹配所有npm命令)
  • 通配符模式(Bash(git push:*)
  • 环境变量白名单(HARNESS_QUIET等)
  • 输出重定向检测
  • 管道命令分析

第七章:钩子系统——可编程的AI控制权

7.1 规模

bash
wc -l utils/hooks.ts
# → 4300+行——最大的单个文件之一

7.2 八种钩子事件

bash
grep -n "PreToolUse\|PostToolUse\|PermissionRequest\|PermissionDenied\|Notification\|UserPromptSubmit\|SessionStart\|SessionEnd" utils/hooks.ts | head -20
事件触发时机输入数据
PreToolUse工具执行前工具名称、输入参数
PostToolUse工具执行后输入 + 输出结果
PostToolUseFailure工具失败后错误信息、错误类型
PermissionRequest权限请求时工具名、输入、权限建议
PermissionDenied自动拒绝后拒绝原因
Notification通知发送时通知内容
UserPromptSubmit用户输入时用户文本
SessionStart/End会话开始/结束会话信息

7.3 钩子配置

.claude/settings.json中配置:

json
{
  "hooks": [
    {
      "event": "PreToolUse",
      "matcher": "Bash(*rm*)",
      "type": "command",
      "command": "echo '⚠️ 检测到删除命令' >&2"
    },
    {
      "event": "PostToolUse",
      "matcher": "FileEditTool",
      "type": "command",
      "command": "compliance-check.sh"
    },
    {
      "event": "PermissionDenied",
      "matcher": "*",
      "type": "command",
      "command": "curl -X POST https://webhook/security -d '$REASON'"
    }
  ]
}

7.4 钩子返回值

json
{"ok": true}                    // 放行
{"ok": false, "reason": "..."}  // 拦截(AI看到reason)
// 无返回或超时                   // 旁路(当作没发生)

7.5 竞速机制

权限决策支持多条"赛道"并行:

  • 用户对话框
  • PermissionRequest钩子
  • Bash分类器

第一个返回结果的赢。如果钩子0.1秒返回allow,用户不需要手动确认。


第八章:内存系统——AI的长期记忆

8.1 CLAUDE.md优先级链

bash
head -100 memdir/memdir.ts

Claude Code从多个位置加载配置指令,近的覆盖远的:

1. .claude/CLAUDE.local.md    → 本地私有(不提交git)
2. CLAUDE.md(项目根目录)     → 项目级
3. .claude/CLAUDE.md          → 项目级(隐藏目录)
4. .claude/rules/*.md         → 可拆分的规则文件
5. ~/.claude/CLAUDE.md        → 用户全局
6. /etc/claude-code/CLAUDE.md → 系统全局(企业管理)

8.2 四种内存类型

bash
head -80 memdir/memoryTypes.ts
类型说明保存时机
user用户角色、背景、知识水平了解到用户信息时
feedback工作偏好和纠正"不要这样做"时
project项目状态、截止日期、决策了解到项目信息时
reference外部资源指针发现重要链接时

8.3 内存大小限制

bash
grep "200\|25.*KB\|truncate" memdir/memdir.ts | head -10
  • MEMORY.md索引:200行上限
  • 内容:25KB上限
  • 超限自动截断

8.4 Harness保证

bash
grep -B 2 -A 5 "Harness guarantees\|DIR_EXISTS_GUIDANCE" memdir/memdir.ts
typescript
export const DIR_EXISTS_GUIDANCE =
  'This directory already exists — write to it directly with the Write tool ' +
  '(do not run mkdir or check for its existence).'

Harness在加载内存prompt时确保目录存在,这样AI不需要浪费一个工具调用去运行mkdir


第九章:成本控制与上下文管理

9.1 成本追踪

bash
head -60 cost-tracker.ts

追踪维度:

typescript
type CostState = {
  totalCostUSD: number                    // 总花费
  totalAPIDuration: number                // API总耗时
  totalAPIDurationWithoutRetries: number  // 不含重试
  totalToolDuration: number               // 工具执行耗时
  totalLinesAdded: number                 // 新增代码行
  totalLinesRemoved: number               // 删除代码行
  modelUsage: {                           // 按模型统计
    [model]: {
      inputTokens: number
      outputTokens: number
      cacheCreationInputTokens: number    // 缓存创建Token
      cacheReadInputTokens: number        // 缓存命中Token
      cost: number
    }
  }
}

9.2 上下文压缩

bash
head -60 services/compact/autoCompact.ts
typescript
export function getEffectiveContextWindowSize(model: string): number {
  const maxOutputTokensForSummary = 20_000
  let contextWindow = getContextWindowForModel(model)

  // 允许通过环境变量覆盖
  const autoCompactWindow = process.env.CLAUDE_CODE_AUTO_COMPACT_WINDOW
  if (autoCompactWindow) {
    const parsed = parseInt(autoCompactWindow, 10)
    if (!isNaN(parsed) && parsed > 0) {
      contextWindow = Math.min(contextWindow, parsed)
    }
  }

  return contextWindow - maxOutputTokensForSummary
}

三道防线:

  • Auto Compact — Token超过阈值时总结早期对话
  • Reactive Compact(feature gate)— 根据对话节奏动态压缩
  • Context Collapse(feature gate)— 整体折叠早期上下文

9.3 成本计算公式

bash
grep -A 10 "calculateUSDCost" utils/modelCost.ts | head -15

关键经济学:

  • 输出Token价格是输入Token的3倍
  • 缓存命中Token只收输入价格的10%
  • 缓存创建Token收输入价格的25%

第十章:语音模式——完美的feature gate示例

bash
cat voice/voiceModeEnabled.ts

55行代码展示了三层feature gate的工业级实现:

typescript
// 第1层:编译时——功能关闭则代码不存在
export function isVoiceGrowthBookEnabled(): boolean {
  return feature('VOICE_MODE')
    ? !getFeatureValue_CACHED_MAY_BE_STALE(
        'tengu_amber_quartz_disabled', false
      )
    : false
}

// 第2层:认证——必须是Anthropic OAuth(不是API Key)
export function hasVoiceAuth(): boolean {
  if (!isAnthropicAuthEnabled()) return false
  const tokens = getClaudeAIOAuthTokens()
  return Boolean(tokens?.accessToken)
}

// 第3层:完整运行时检查
export function isVoiceModeEnabled(): boolean {
  return hasVoiceAuth() && isVoiceGrowthBookEnabled()
}

注释中的设计考量(原文):

"Kill-switch check... Default false means a missing/stale disk cache reads as 'not killed' — so fresh installs get voice working immediately without waiting for GrowthBook init."

翻译:默认值设计为"不关闭"——新安装的用户不需要等GrowthBook初始化就能用语音。紧急情况才把开关翻为true来关闭功能。


第十一章:多Agent协调

11.1 Coordinator模式

bash
head -60 coordinator/coordinatorMode.ts

COORDINATOR_MODE启用时,一个"领导者"AI可以:

  • TeamCreateTool创建团队
  • SendMessageTool给队友下达任务
  • 每个队友在独立环境中运行

11.2 Swarm系统

bash
ls utils/swarm/

Swarm目录包含20+个模块,实现了4种队友后端:

后端执行方式适用场景
InProcess同进程共享内存快速小任务
TmuxTmux会话需要终端的任务
iTermiTerm2窗口macOS可视化
Pane面板模式IDE集成

11.3 Buddy系统

bash
ls buddy/

虚拟伙伴系统——通过/buddy命令交互。这是一个隐藏的彩蛋功能。


第十二章:技能系统

12.1 SkillTool入口

bash
head -40 tools/SkillTool/SkillTool.tsx

技能系统允许用户通过/skillname调用预定义的多步骤工作流。

12.2 内置技能

bash
ls skills/bundled/

包括:commit(提交代码)、loop(循环执行)、schedule(定时任务)、simplify(简化代码)、updateConfig(更新配置)等。

12.3 技能预算

技能加载有Token预算限制——约占上下文窗口的1%(约8000字符),防止技能描述占用过多上下文空间。


第十三章:服务层

13.1 API客户端

bash
head -40 services/api/claude.ts

Claude API调用的底层封装。

13.2 MCP服务

bash
ls services/mcp/

Model Context Protocol客户端实现,包括:

  • client.ts — MCP客户端
  • server.ts — 本地MCP服务器
  • officialRegistry.ts — 官方注册表
  • vscodeSdkMcp.ts — VS Code集成

13.3 分析服务

bash
head -40 services/analytics/growthbook.ts

GrowthBook特性门控——远程控制feature flag的运行时开关。


动手练习清单

练习1:追踪一次Bash命令的完整生命周期

起点:tools/BashTool/BashTool.tsxexecute()函数

路径:

  1. 命令字符串 → parseForSecurity()进行AST解析
  2. bashPermissions.ts检查权限
  3. shouldUseSandbox.ts决定是否用沙箱
  4. exec()执行命令
  5. → 检查输出是否包含图片(isImageOutput()
  6. → 截断过长输出(EndTruncatingAccumulator
  7. → 检查是否有<claude-code-hint />标签
  8. → 返回ToolResult

练习2:添加一个自定义Agent

参考exploreAgent.ts(84行),理解每个字段:

  • agentType — 唯一标识符
  • whenToUse — Claude什么时候选择这个Agent
  • disallowedTools — 工具黑名单
  • model — 模型选择策略
  • omitClaudeMd — 是否跳过CLAUDE.md
  • getSystemPrompt — 系统提示词生成函数

练习3:计算Prompt Cache经济模型

  1. 打开constants/prompts.ts
  2. 找到SYSTEM_PROMPT_DYNAMIC_BOUNDARY
  3. 统计标记前后的大致字符数
  4. 用Token估算器计算Token数(约4字符=1Token)
  5. 假设:Opus输入$15/1M tokens,缓存命中$1.5/1M
  6. 计算50次会话的成本差异

练习4:绘制权限决策流程图

阅读permissions.ts中的hasPermissionsToUseTool()

  1. 画出6层决策树
  2. 标注哪些检查对所有模式免疫
  3. 标注YOLO分类器的调用位置
  4. 标注钩子的插入点
  5. 标注竞速机制的三条赛道

练习5:搜索并分类所有隐藏功能

bash
grep -rn "feature('" --include="*.ts" --include="*.tsx" | \
  grep -o "feature('[^']*'" | sort -u

对每个flag:猜测功能、找到使用它的文件、评估发布可能性。


核心文件速查表

你想了解文件路径行数难度
System Prompt全文constants/prompts.ts914★★
工具注册和条件编译tools.ts300+★★
工具接口定义Tool.ts792★★★
权限决策引擎utils/permissions/permissions.ts1486★★★★
YOLO安全分类器utils/permissions/yoloClassifier.ts1495★★★★
文件系统沙箱utils/permissions/filesystem.ts1777★★★★
拒绝熔断器utils/permissions/denialTracking.ts46
BashTooltools/BashTool/BashTool.tsx800+★★★★
Bash权限tools/BashTool/bashPermissions.ts500+★★★
Explore Agenttools/AgentTool/built-in/exploreAgent.ts84
Plan Agenttools/AgentTool/built-in/planAgent.ts93
Verification Agenttools/AgentTool/built-in/verificationAgent.ts80+★★
Agent运行器tools/AgentTool/runAgent.ts400+★★★
Hint侧通道utils/claudeCodeHints.ts194★★
钩子引擎utils/hooks.ts4300+★★★★★
内存系统memdir/memdir.ts490★★★
内存类型memdir/memoryTypes.ts271★★
成本追踪cost-tracker.ts200+★★
查询引擎QueryEngine.ts + query.ts3024★★★★★
语音模式voice/voiceModeEnabled.ts55
多Agent协调coordinator/coordinatorMode.ts200+★★★
Swarm系统utils/swarm/20+文件★★★★
缓存失效检测services/api/promptCacheBreakDetection.ts200+★★★
上下文压缩services/compact/autoCompact.ts200+★★★

总结:这份源码教给我们什么

一、提示词是资产,不是文本。 914行System Prompt经过精心设计——静态/动态分区节省90%成本,每条指令都来自生产教训。缓存失效检测精确到单个工具的schema变化。

二、控制系统比模型更重要。 6层权限安检、52KB分类器、8种钩子事件、拒绝熔断器、文件系统三重验证、Hint侧通道——这些"看不见的"代码决定了AI工具的可靠性。Harness不是限制AI,是让AI安全地发挥最大价值。

三、不是所有任务都需要最强模型。 Explore用Haiku(快10倍、省90%)、Plan跳过CLAUDE.md(省Token)、Verification独立运行(不受原Agent偏见影响)。模型选择本身就是架构决策。

四、好代码的标准是最小必要复杂度。 拒绝熔断器46行、语音模式55行、Explore Agent 84行——每个模块只做一件事,做到极致。4300行的钩子引擎是必要的复杂度,因为它支撑了整个可编程控制平台。

五、feature gate是产品策略。 同一套代码维护公开版、内部版、实验版。编译时删除不需要的功能——不只是代码不执行,连文件都不会被加载。KAIROS、WebBrowser、Workflow都在代码里,等着发布的那一天。

六、经济学决定架构。 Prompt Cache的静态/动态分区、Explore用Haiku而不是Opus、输出Token价格3倍于输入——每个技术决策背后都有成本考量。当你的应用每天处理百万请求时,一个优化可以省几百万美元。

打开源码,从第一章开始,一步一步走。


源码下载:https://claude.whaty.org/posts/Claude-code-source-leak.html本手册基于Claude Code v2.1.88源码(2026年3月31日泄漏)。

Claude Code 中文文档 - 社区翻译项目