⚠️ 学习声明 :本文档基于 Claude Code 2.1.88 源码分析整理,仅供个人学习研究使用,不做任何商业用途。
前言: 之前的13篇文档偏重”架构骨架”——启动流程、循环管线、UI框架、状态管理等TypeScript工程代码。 本文深入分析真正让Claude Code”智能”的那些代码——它们不是普通的程序逻辑,而是 用代码驱动LLM做决策 的系统。 这些机制才是Claude Code区别于一个普通chat wrapper的核心竞争力。
一、总论:智能化的六大支柱 ┌─────────────────────────────────────────────────────────┐ │ Claude Code Intelligence │ ├──────────────┬──────────────┬──────────────────────────┤ │ ① 灵魂注入 │ ② LLM安全网 │ ③ 投机执行引擎 │ │ System │ Auto-Mode │ Speculation │ │ Prompt │ Classifier │ Engine │ │ (prompts.ts)│ (yoloCls.ts) │ (speculation.ts) │ ├──────────────┼──────────────┼──────────────────────────┤ │ ④ 上下文 │ ⑤ 记忆系统 │ ⑥ 多Agent智能体 │ │ 压缩与窗口 │ CLAUDE.md & │ Fork/Subagent/ │ │ 管理 │ Memory Files │ Swarms │ │ (compact/) │ (claudemd.ts)│ (AgentTool/) │ └──────────────┴──────────────┴──────────────────────────┘
核心洞察 : Claude Code的TypeScript代码本身并不”思考”——它是一个精密的LLM编排系统 。智能来自三个层面:
Prompt Engineering : 用精心设计的系统提示词塑造LLM行为
LLM-as-Judge : 用另一个LLM调用来做安全/权限决策(side-query分类器)
Speculative Execution : 预测用户意图并预执行,用Copy-on-Write隔离保证安全
二、灵魂注入:系统提示词工程 (constants/prompts.ts, 915行) 2.1 这是什么 prompts.ts 是Claude Code的”灵魂文件”。它定义了一个精密的系统提示词(System Prompt),决定了Claude在terminal环境中的一切行为模式 。这不是简单的”你是一个编码助手”,而是一份400+行的行为规范手册 。
2.2 提示词的分层架构 getSystemPrompt() 输出结构: ┌──────────────────────────────────────────────┐ │ [静态部分 - 可被Prompt Cache全局缓存] │ │ │ │ ① getSimpleIntroSection() │ │ - 角色定义: "you are Claude, an AI..." │ │ - 安全指令: cyber risk prevention │ │ │ │ ② getSimpleSystemSection() │ │ - 系统行为规则 (不主动停止除非明确要求) │ │ - 工具使用纪律 │ │ │ │ ③ getSimpleDoingTasksSection() │ │ - 代码风格规则 (极其详细) │ │ - 安全漏洞警告 │ │ │ │ ④ getActionsSection() │ │ - 操作可逆性/爆炸半径分级 │ │ - 具体命令示例 │ │ │ │ ⑤ getUsingYourToolsSection() │ │ - 工具优先级: 专用工具 > Bash │ │ - 并发策略 │ │ │ │ ⑥ getOutputEfficiencySection() │ │ - ant内部: 详细散文式输出 │ │ - external: "be concise" 极简输出 │ │ │ │ ──── SYSTEM_PROMPT_DYNAMIC_BOUNDARY ──── │ │ [动态部分 - 每次请求可能不同] │ │ │ │ ⑦ getSessionSpecificGuidanceSection() │ │ - Agent工具引导 │ │ - Skill发现指令 │ │ - 验证Agent指南 │ │ - 环境详情 (OS/Shell/CWD/时间) │ └──────────────────────────────────────────────┘
2.3 关键的Prompt Cache优化 export const SYSTEM_PROMPT_DYNAMIC_BOUNDARY = '<!-- SYSTEM_PROMPT_DYNAMIC_BOUNDARY -->'
原理 : Anthropic API的Prompt Cache按系统提示词的前缀进行匹配(1小时TTL)。将提示词分为:
静态区 : 角色定义、行为规则、代码风格——所有session共享,全局缓存命中
动态区 : 当前工作目录、时间、session特定配置——每次不同
这意味着你的第2次、第3次…第N次API调用,系统提示词的输入token费用接近0 (cache hit)。
2.4 你不知道的行为规则细节 代码风格强制 (getSimpleDoingTasksSection):
- "Don't add features beyond what is requested" (不要做超出要求的事——这就是为什么Claude Code不会擅自"改进"你没提的东西) - "Don't create separate helper functions for operations used in only one place" (不要为只用一次的操作创建辅助函数) - "Avoid leaving TODO/FIXME comments in code" (不要留下TODO注释) - "NEVER generate response with security vulnerabilities: hardcoded secrets, SQL injection, XSS, path traversal..." (绝对不生成包含安全漏洞的代码)
操作分级规则 (getActionsSection):
高风险(需确认): rm -rf, 修改.bashrc, 修改crontab, git push --force 中等风险(谨慎): git commit, 写入新文件 低风险(自动): 读文件, grep, ls, git status, git diff
Ant内部 vs 外部用户的差异 :
ant (Anthropic员工): 输出可以详细、有分析过程
external (外部用户): “be concise”——极简输出,不浪费token
2.5 Proactive模式的灵魂 当启用主动模式时,系统提示词追加一段完全不同的行为规范:
- 像自驱动的开发者一样工作 - 有自主决策权去修复bug、改进代码 - 使用sleep工具等待,而不是退出 - 终端失去焦点时继续工作
三、LLM安全网:Auto-Mode分类器 (utils/permissions/yoloClassifier.ts, 1496行) 3.1 这是什么 这是Claude Code最复杂的智能机制之一。当用户开启Auto Mode(自动批准操作)时,不能真的什么都自动批准——否则恶意提示词注入可能让Claude执行 rm -rf /。
解决方案 : 用另一个独立的Claude API调用 来判断每个操作是否安全。这就是”LLM-as-Judge”模式。
3.2 分类器的工作流 Claude主循环产生一个tool_use (例如 Bash: "rm -rf ./build") ↓ ┌───────────────────────┐ │ isAutoModeAllowlisted?│ ←── classifierDecision.ts │ (读取/搜索类工具?) │ 有25+个白名单工具 └───────┬───────────────┘ │ 不在白名单 ↓ ┌───────────────────────┐ │ buildYoloSystemPrompt │ ←── 加载.txt模板文件: │ │ auto_mode_system_prompt.txt │ │ permissions_external.txt │ │ (或 permissions_anthropic.txt) └───────┬───────────────┘ │ ┌───────────────────────┐ │ buildTranscriptEntries│ ←── 将对话历史压缩为紧凑格式 │ (JSONL or text-prefix)│ {"Bash":"rm -rf ./build"} └───────┬───────────────┘ {"user":"clean up the project"} │ ┌───────────────────────┐ │ sideQuery() API调用 │ ←── 独立的Claude API请求 │ temperature: 0 │ model: 与主循环相同 │ max_tokens: 64/4096 │ 用prompt cache共享前缀 └───────┬───────────────┘ │ ┌───────────────────────┐ │ 解析分类结果 │ shouldBlock: true/false │ <block>yes/no</block> │ reason: "为什么" └───────────────────────┘
3.3 两阶段XML分类器(核心创新) 这是yoloClassifier.ts最精巧的设计——两阶段分类 ,平衡速度与准确性:
Stage 1 (Fast) :
max_tokens=64, stop_sequences=['</block>'] 追加后缀: "Err on the side of blocking. <block> immediately."
目标:在不到100ms内做出快速判断
如果判断为”允许”(no) → 直接放行(快速路径)
如果判断为”阻止”(yes) 或无法解析 → 进入Stage 2
Stage 2 (Thinking) :
max_tokens=4096 追加后缀: "Review the classification process carefully... explicit user confirmation is required to override blocks. Use <thinking> before responding with <block>."
目标:通过Chain-of-Thought推理减少误报
给分类器更多空间思考,避免把安全操作误判为危险
为什么这样设计?
Stage 1 处理90%的简单case (读文件、grep) → 几乎零延迟
Stage 2 只在Stage 1拿不准时触发 → 减少假阳性(本该允许却被阻止)
3.4 分类器的安全性设计 对话历史投影 (Transcript Projection) :
CLAUDE.md 上下文注入 :
"The following is the user's CLAUDE.md configuration. These are instructions the user provided to the agent and should be treated as part of the user's intent when evaluating actions."
这意味着如果你在CLAUDE.md里写 “你可以自由删除./build目录”,分类器会把这视为用户意图的一部分。
3.5 安全白名单 (classifierDecision.ts) const SAFE_YOLO_ALLOWLISTED_TOOLS = new Set ([ 'Read' , 'Grep' , 'Glob' , 'LSP' , 'TaskGet' , 'TodoRead' , 'Sleep' , 'PlanModeRespond' , ])
这些工具跳过分类器,直接放行——因为它们在设计上就是只读/无副作用的。
四、投机执行引擎 (services/PromptSuggestion/speculation.ts, 992行) 4.1 这是什么 这是Claude Code最”炫酷”的智能机制。当Claude完成一个回合后,系统会:
预测用户的下一步操作 (Prompt Suggestion)
在用户确认之前就开始执行 (Speculative Execution)
如果用户确认 → 直接展示结果(省去等待时间)
如果用户拒绝 → 丢弃投机结果,无副作用
4.2 投机执行的安全隔离(Copy-on-Write) 正常文件系统: /project/src/main.ts ↓ 投机执行引擎: /tmp/claude/speculation/{pid}/{id}/src/main.ts ↑ 投机写入到overlay目录,不触碰真实文件
canUseTool : async (tool, input) => { if (isWriteTool) { if (!canAutoAcceptEdits) { updateBoundary ({ type : 'edit' , toolName, filePath }) abort () return deny (...) } if (!writtenPaths.has (rel)) { await copyFile (join (cwd, rel), join (overlayPath, rel)) writtenPaths.add (rel) } input = { ...input, file_path : join (overlayPath, rel) } } if (isSafeReadOnlyTool) { if (writtenPaths.has (rel)) { input = { ...input, path : join (overlayPath, rel) } } } if (tool.name === 'Bash' ) { if (checkReadOnlyConstraints (command).behavior !== 'allow' ) { updateBoundary ({ type : 'bash' , command }) abort () return deny (...) } } }
4.3 投机边界 (Speculation Boundary) 投机执行不是无限的。它在以下时刻停止并等待用户确认 :
边界类型
触发条件
原因
edit
文件写入操作 + 非auto权限模式
需要用户确认文件修改
bash
非只读Bash命令
可能有副作用
denied_tool
未知/不安全的工具
安全防线
complete
投机执行自然完成
模型认为任务完成
4.4 投机接受流程 用户看到prompt suggestion: "继续修复剩余的3个test" ↓ 按Tab接受 ↓ acceptSpeculation(): 1. copyOverlayToMain() ← 将overlay的文件复制回真实文件系统 2. prepareMessagesForInjection() ← 清理投机消息(去除thinking块、失败的tool结果) 3. mergeFileStateCaches() ← 合并投机期间的文件状态缓存 4. 将投机消息注入到主对话历史 5. 清理overlay目录
4.5 流水线化 (Pipelined Suggestion) 投机完成后,系统还会再生成一个prompt suggestion ,为下一轮投机做准备:
投机完成 → 后台生成下一个suggestion → 用户接受投机 → 立即展示下一个suggestion → 新投机开始
这形成了一个连续执行的流水线 ,用户只需不停按Tab,Claude就持续工作。
五、SideQuery:轻量级LLM旁路调用 (utils/sideQuery.ts) 5.1 这是什么 SideQuery是Claude Code中所有”用LLM做判断”场景的统一基础设施 。它不是主对话循环的一部分,而是一个独立的API调用包装器。
5.2 使用场景
调用方
querySource
用途
yoloClassifier
auto_mode
安全分类
compact
compact
对话压缩(生成摘要)
session_search
session_search
搜索历史session
prompt_suggestion
suggestion
生成下一步建议
speculation
speculation
投机执行
permission_explainer
permission_explainer
解释权限决策
model_validation
model_validation
验证模型可用性
5.3 关键技术细节 export async function sideQuery (opts : SideQueryOptions ): Promise <BetaMessage > { const fingerprint = computeFingerprint (messageText, MACRO .VERSION ) const attributionHeader = getAttributionHeader (fingerprint) const cliSyspromptPrefix = getCLISyspromptPrefix (...) const betas = getModelBetas (model) let thinkingConfig = thinking === false ? { type : 'disabled' } : { type : 'enabled' , budget_tokens : ... } const response = await client.beta .messages .create ({ model : normalizeModelStringForAPI (model), max_tokens, system : systemBlocks, messages, ...tools, ...tool_choice, ...output_format, ...temperature, ...stop_sequences, ...thinkingConfig, metadata : getAPIMetadata (), }) logEvent ('tengu_api_success' , { querySource, model, tokens... }) }
六、上下文窗口管理与智能压缩 6.1 自动压缩触发 (autoCompact.ts) 有效上下文窗口 = 模型上下文窗口 - max(模型最大输出token, 20000) 自动压缩阈值 = 有效上下文窗口 - 13000 (buffer) 当 tokenCountWithEstimation(messages) > 阈值 时触发
6.2 压缩提示词工程 (compact/prompt.ts) 这是另一个精心设计的提示词。它要求LLM:
1. 先写 <analysis> 分析块(草稿纸,最终会被删除) - 按时间顺序分析每条消息 - 识别用户意图、技术决策、代码模式 - 记录文件名、代码片段、函数签名 - 记录遇到的错误和修复方法 2. 再写 <summary> 摘要块(保留在上下文中) 包含9个章节: - 主要请求和意图 - 关键技术概念 - 文件和代码段(含完整代码片段) - 错误和修复 - 问题解决 - 所有用户消息(非工具结果) - 待完成任务 - 当前工作 - 可选下一步
块为什么存在? 它是一个”思考草稿纸”——让LLM先做详细分析,然后在summary中产出高质量摘要。最后 formatCompactSummary() 会删除analysis块 ,只保留summary。
6.3 部分压缩 (Partial Compact) 保留最近N条消息不变,只压缩更早的消息 → 减少信息丢失,保持当前工作的完整上下文 → 两种方向: 'from': 压缩旧消息,摘要放在保留消息之前 'up_to': 压缩前半段,摘要独立存在
6.4 反激进压缩保护 const MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES = 3
七、Thinking/Ultrathink 思维控制 7.1 三种Thinking模式 type ThinkingConfig = | { type : 'adaptive' } | { type : 'enabled' ; budgetTokens : number } | { type : 'disabled' }
7.2 Ultrathink触发 当用户输入包含 ultrathink 关键词时:
function hasUltrathinkKeyword (text : string ): boolean { return /\bultrathink\b/i .test (text) }
需要 build-time feature('ULTRATHINK') 和 runtime GrowthBook tengu_turtle_carbon 双重开启
UI会显示彩虹色渐变效果(7种颜色 + shimmer版本)
7.3 Adaptive Thinking 从Claude 4.6模型开始支持”自适应思考”——模型自己决定需要思考多少:
八、记忆系统:CLAUDE.md与上下文组装 8.1 记忆文件层级 层级1: 管理员记忆 /etc/claude-code/CLAUDE.md (系统级) 层级2: 用户记忆 ~/.claude/CLAUDE.md (用户级) 层级3: 项目记忆 项目根/CLAUDE.md (项目级) 项目根/.claude/CLAUDE.md 项目根/.claude/rules/*.md 层级4: 嵌套记忆 子目录/CLAUDE.md (cd到子目录时加载)
8.2 上下文组装的复杂性 (attachments.ts, 3998行) attachments.ts 是Claude Code中最大的单个文件之一 (近4000行),它处理:
每次API调用前,需要组装的上下文: ├── CLAUDE.md内容 (多层级合并) ├── 条件规则 (conditional rules) ├── @include 引用的文件 ├── IDE选择区域 ├── 文件附件(拖拽/粘贴的文件) ├── 图片附件(调整大小/降采样) ├── PDF引用 ├── TODO列表提醒 (每10轮提醒一次) ├── Plan模式提醒 (每5轮提醒一次) ├── Auto模式提醒 ├── 日期变更通知 ├── 诊断信息 (LSP lints/errors) ├── 任务状态 (Task system) ├── Agent列表 (可用的子agent) ├── 工具搜索说明 (MCP tool delta) ├── MCP指令增量 ├── Hook响应 ├── 队友邮箱消息 (Swarm模式) ├── 自动记忆 (memdir, 20KB/turn上限) ├── Skill发现信号 ├── Kairos session transcript └── Token预算管理
8.3 自动记忆 (Memdir) const MAX_MEMORY_LINES = 200 const MAX_MEMORY_BYTES = 4096 const MAX_SESSION_BYTES = 60 *1024
九、多Agent与Fork子代理 9.1 ForkedAgent (utils/forkedAgent.ts) ForkedAgent是Claude Code运行”子任务”的统一基础设施:
type ForkedAgentParams = { promptMessages : Message [] cacheSafeParams : CacheSafeParams canUseTool : CanUseToolFn querySource : QuerySource maxTurns ?: number maxOutputTokens ?: number skipTranscript ?: boolean onMessage ?: (msg ) => void }
Prompt Cache共享机制 :
父agent: [system_prompt + tools + model + context_messages] ← cache key ↓ cache hit! 子agent: [system_prompt + tools + model + context_messages + child_prompt]
子agent故意保持与父agent完全相同的系统提示词、工具集和模型 ,这样API的prompt cache可以被共享——子agent的输入token成本几乎为0。
Fork是一种特殊的子agent模式——它继承父agent的完整对话上下文 :
"STOP. READ THIS FIRST. You are a forked worker process. You are NOT the main agent. RULES (non-negotiable): 1. Your system prompt says 'default to forking.' IGNORE IT 2. Do NOT converse, ask questions, or suggest next steps 3. USE your tools directly: Bash, Read, Write, etc. 4. Stay strictly within your directive's scope 5. Keep your report under 500 words 9. Your response MUST begin with 'Scope:' Output format: Scope: <echo back your assigned scope> Result: <key findings> Key files: <relevant paths> Files changed: <list with commit hash> Issues: <list>"
Fork消息构建 :
const FORK_PLACEHOLDER_RESULT = 'Fork started — processing in background'
9.3 SubagentContext隔离 createSubagentContext (parentContext, overrides?): readFileState : clone (parent) abortController : child (parent) toolDecisions : undefined nestedMemoryPaths : new Set () shareSetAppState : true shareAbortController : true
十、Prompt Suggestion 提示建议 10.1 工作流 Claude完成回合 → executePromptSuggestion(): 1. 检查是否满足条件: - assistantTurnCount >= 2 (至少2轮对话) - 非API错误回复 - 非plan模式 - 非限速状态 2. generateSuggestion(): 使用 runForkedAgent() 运行一个子agent cacheSafeParams = 与主循环相同(cache共享) → 输出: 一个简短的"用户可能想说的下一句话" 3. 过滤/显示suggestion 4. 如果投机执行开启 → startSpeculation(suggestionText)
10.2 投机与建议的流水线 回合完成 ├→ generateSuggestion() [后台] │ ↓ suggestion ready │ ├→ 显示给用户 │ └→ startSpeculation(suggestion) [后台] │ ↓ speculation complete │ └→ generatePipelinedSuggestion() [后台] │ ↓ next suggestion ready │ └→ 用户接受投机时立即显示 │ └→ 用户思考中... (Claude已经在后台工作了)
11.1 问题 MCP可以注册数十甚至数百个外部工具。将所有工具定义全部发送给API会浪费大量token。
启动时: 所有MCP工具 + shouldDefer工具 → 标记为 defer_loading: true API只收到: 核心工具 + ToolSearchTool 运行时: 模型发现需要某个工具 → 调用 ToolSearch(query: "xxx") ToolSearch返回匹配的deferred工具 → 动态加入工具池 自动开启条件: deferred工具的token总量 > 上下文窗口的10%
十二、Token Budget 自动续命 12.1 机制
十三、总结:真正的智能在哪里?
机制
文件
行数
智能类型
系统提示词
prompts.ts
915
Prompt Engineering
Auto-Mode分类器
yoloClassifier.ts
1496
LLM-as-Judge
投机执行
speculation.ts
992
Predictive Execution
上下文压缩
compact/prompt.ts
375
LLM Summarization
Prompt建议
promptSuggestion.ts
524
LLM Prediction
上下文组装
attachments.ts
3998
Context Engineering
Fork子代理
forkedAgent.ts
690
Agent Orchestration
SideQuery
sideQuery.ts
~300
LLM Infrastructure
Thinking控制
thinking.ts
~200
Model Capability Tuning
最终答案:
Claude Code的”智能”不在TypeScript代码本身——TypeScript只是一个精密的编排系统。真正的智能来自:
Prompt Engineering — 系统提示词定义了Claude的行为边界和风格
LLM-as-Judge — 用独立的LLM调用做安全决策
Speculative Execution + Copy-on-Write — 预测+预执行+安全隔离
Context Engineering — 4000行的上下文组装代码,精确控制LLM看到什么信息
Prompt Cache优化 — 通过精心的参数对齐,让子agent几乎免费共享父agent的cache
这些机制的共同特点是:用代码控制LLM,而不是代码自身做智能决策。 TypeScript负责”orchestration”(编排),Claude负责”cognition”(认知)。
涉及源文件
services/PromptSuggestion/speculation.ts
src/main.ts
tools/AgentTool/forkSubagent.ts
utils/forkedAgent.ts
utils/permissions/yoloClassifier.ts
utils/sideQuery.ts