Claude Code from Source:18章深度拆解Anthropic最畅销AI编程工具的架构精髓
posts posts 2026-04-12T18:03:00+08:001,552 Stars的Claude Code from Source,通过npm源码地图逆向分析Anthropic Claude Code的完整架构。36个AI Agent历时6小时写成,涵盖Agent循环、工具执行、多Agent编排、内存系统、性能工程等10大核心架构模式。技术笔记Claude Code, Anthropic, AI Agent, 架构分析, MCP目录
Claude Code from Source:18章深度拆解Anthropic最畅销AI编程工具的架构精髓
📋 学习目标
- 理解Claude Code的六大核心抽象与数据流
- 掌握Agent循环的4层压缩机制与错误恢复策略
- 理解14步工具执行管道的设计与实现
- 学会多Agent编排中的Fork模式与95%成本节省秘诀
- 理解文件式内存系统与LLM召回机制
- 掌握10大可迁移的架构模式,应用到自己的Agent系统
📖 项目概述
什么是Claude Code from Source
Claude Code from Source是一本揭示Anthropic Claude Code内部架构的深度技术书籍。
核心信息来源:
Claude Code发布到npm时,源码地图(source maps)也随之打包。通过读取每一个
.js.map文件中的sourcesContent字段,获得了完整的原始TypeScript源码。近2000个文件,构成了完整架构图景。
项目数据
| 指标 | 数值 |
|---|---|
| 源仓库 | alejandrobalderas/claude-code-from-source |
| 章数 | 18章 |
| 参与Agent | 36个AI Agent |
| 创作耗时 | 6小时(从源码提取到最终修订) |
| 产出 | 494KB原始技术文档→叙事化书籍 |
创作方法论
这本书的诞生本身就是一场AI生产力的演示:
| 阶段 | Agent数量 | 任务 |
|---|---|---|
| 探索 | 6个并行Agent | 阅读源码树的每一个文件 |
| 分析 | 12个Agent | 产出494KB原始技术文档 |
| 写作 | 15个Agent | 从零开始重写为叙事化章节 |
| 审核修订 | 3个Reviewer Agent | 产出900行反馈;3个Agent应用所有修复 |
关键约束:最终审计确保没有直接复制源码——每个代码块都改写为伪代码,使用不同变量名,仅用于说明架构模式。
🏗️ 六大核心抽象
Claude Code的架构由六个核心抽象支撑:
┌─────────────────────────────────────────────────────┐
│ Claude Code 核心抽象 │
├─────────────────────────────────────────────────────┤
│ 1. AsyncGenerator → Agent循环(流式输出+背压) │
│ 2. Message → 类型化通信单元 │
│ 3. ToolDefinition → 工具声明与执行分离 │
│ 4. PermissionSystem → 安全边界与权限控制 │
│ 5. PromptCache → 前缀共享与成本优化 │
│ 6. HookSystem → 生命周期扩展点 │
└─────────────────────────────────────────────────────┘🔄 Agent循环:异步生成器的力量
核心模式
Claude Code的Agent循环是一个AsyncGenerator:
async function* agentLoop(query: Query): AsyncGenerator<Message> {
// 1. 流式输出:模型边输出边流式返回
for await (const token of model.stream(query)) {
yield { type: 'token', value: token };
}
// 2. 工具执行:流式过程中预启动只读工具
const speculativeReads = await executeReadToolsSpeculatively(query);
// 3. 错误恢复:自动重试与上下文压缩
if (error) {
await recoverAndCompact();
}
// 4. 上下文压缩:4层压缩机制
await compressContextIfNeeded();
}4层上下文压缩
| 层级 | 触发条件 | 压缩效果 | 用途 |
|---|---|---|---|
| Snip | 输出超长 | 截断中间轮次 | 保留首尾 |
| Microcompact | Token超50% | 合并相邻消息 | 轻量压缩 |
| Collapse | Token超70% | 摘要合并 | 中度压缩 |
| Autocompact | Token超90% | 深度摘要+重放 | 极致压缩 |
每层都比上一层更彻底,但计算代价也更高。
🛠️ 工具执行:14步管道
完整执行管道
用户请求
↓
1. 工具定义解析
↓
2. 权限检查(PermissionSystem)
↓
3. 安全分类(Read/Write/Dangerous)
↓
4. 依赖分析
↓
5. 推测执行(Speculative Execution)
↓
6. 并发分组(按安全分类分区)
↓
7. 并行执行(只读工具)
↓
8. 序列化写入
↓
9. 结果聚合
↓
10. 错误处理
↓
11. 上下文更新
↓
12. 流式输出
↓
13. 缓存更新
↓
14. 返回结果推测执行(Speculative Execution)
核心创新:在模型流式输出的同时,预启动只读工具。
// 模型还在输出thinking,工具已经开始执行
async function speculativeExecute(query: Query) {
const plan = await model.plan(query); // 首次token到达即规划
// 只读工具可以立即执行
const readResults = await Promise.all(
plan.readTools.map(tool => tool.execute())
);
// 写工具等待模型确认
if (plan.writeTools.length > 0) {
await model.confirm(); // 等待完整响应
await executeWrites(plan.writeTools);
}
return { readResults, writeResults };
}并发安全分组
// 按安全分类分区
const partitions = {
read: tools.filter(t => t.safety === 'read'),
write: tools.filter(t => t.safety === 'write'),
dangerous: tools.filter(t => t.safety === 'dangerous')
};
// 只读工具完全并行
const readResults = await Promise.all(
partitions.read.map(t => t.execute())
);
// 写工具串行执行
for (const tool of partitions.write) {
await tool.execute();
}🔀 多Agent编排:Fork与协作
Fork Agent的Prompt Cache秘诀
Claude Code的多Agent系统最核心的创新:父子Agent共享字节完全相同的Prompt前缀。
// 主Agent的Prompt结构
const mainPrompt = [
systemPrompt, // 系统级前缀(不变)
projectContext, // 项目上下文(不变)
taskHistory, // 任务历史(不变)
// ↑ 这三部分 = 可缓存前缀 ↑
currentTask // 当前任务(每次不同)
];
// Fork Agent继承相同前缀
const forkedPrompt = [
systemPrompt, // 共享,0额外Token
projectContext, // 共享,0额外Token
taskHistory, // 共享,0额外Token
forkedTask // Fork特有任务
];
// 结果:~95%输入Token节省
Agent生命周期(15步)
| 步骤 | 阶段 | 核心行为 |
|---|---|---|
| 1-3 | 初始化 | 加载技能、解析任务、构建上下文 |
| 4-6 | 规划 | 分解任务、识别依赖、预算Token |
| 7-9 | 执行 | 并发工具、推测执行、结果聚合 |
| 10-12 | 评估 | 判断完成度、检测循环、触发重试 |
| 13-15 | 交付 | 汇总结果、更新内存、清理状态 |
💾 内存系统:文件式记忆
4类内存分类
| 类型 | 存储形式 | 召回方式 | 用途 |
|---|---|---|---|
| SystemPrompt | 静态文件 | 启动时加载 | 角色定义 |
| ProjectContext | 项目文件 | LLM选择 | 代码结构 |
| ConversationHistory | 消息文件 | 时间+相关度 | 对话记忆 |
| ** LearnedPrinciples** | 增量文件 | LLM召回 | 经验积累 |
LLM召回 vs 嵌入搜索
Claude Code选择LLM召回而非嵌入向量搜索:
// 传统嵌入搜索
const results = await embeddingSearch(query, memories);
// Claude Code的LLM召回
async function recallMemories(query: Query, context: Context) {
// 用Sonnet做side-query
const relevantMemories = await sonnet.query(
`Given the current task: ${query}
And context: ${context}
Which memories from past sessions are relevant?
List them verbatim.`
);
return relevantMemories;
}为什么LLM召回更好:
- 理解语义关联,而非关键词匹配
- 可处理模糊、多层次、隐含的查询
- 不需要额外的嵌入模型和向量数据库
⚡ 性能工程:每一毫秒都有意义
启动优化:240ms冷启动
// 并行I/O最大化
async function bootstrap() {
const [
config, // 配置加载
skills, // 技能加载
model, // 模型初始化
memory, // 内存恢复
ui // UI初始化
] = await Promise.all([
loadConfig(),
loadSkills(),
initModel(),
restoreMemory(),
initUI()
]);
return { config, skills, model, memory, ui };
// 总耗时 = max(各阶段) 而非 sum(各阶段)
}Slot Reservation(槽位预留)
// 默认8K输出上限
const OUTPUT_SLOT = 8 * 1024;
// 当输出命中上限时,自动扩展到64K
async function handleOutputOverflow(output: string) {
if (output.length >= OUTPUT_SLOT) {
await escalateOutputSlot(64 * 1024);
// 节省策略:在99%的请求中,8K足够
}
}Bitmap预过滤
模糊搜索使用Bitmap索引:
// 预计算的Bitmap索引
const fileIndex = {
content: new Bitmap(), // 内容位图
path: new Bitmap(), // 路径位图
symbol: new Bitmap() // 符号位图
};
// 先用Bitmap过滤候选文件
const candidates = fileIndex.content.and(queryBitmap);🔌 可扩展性:技能与钩子
两阶段技能加载
| 阶段 | 加载内容 | 时机 |
|---|---|---|
| 启动时 | 技能元数据(YAML frontmatter) | Claude Code启动 |
| 调用时 | 完整技能内容 | 实际使用技能 |
// 阶段1:启动时只加载元数据
const skillMeta = {
name: 'git操作',
triggers: ['git commit', 'git push'],
permissions: ['read:repo', 'write:repo'],
// 完整内容不加载
};
// 阶段2:触发时才加载完整内容
async function invokeSkill(skill: SkillMeta) {
if (!skill.isLoaded) {
skill.content = await loadSkillContent(skill.path);
skill.isLoaded = true;
}
return execute(skill.content);
}27个生命周期钩子
| 钩子类型 | 数量 | 用途 |
|---|---|---|
| PreToolUse | 4个 | 工具执行前拦截 |
| PostToolUse | 4个 | 工具执行后处理 |
| PreCompact | 2个 | 上下文压缩前快照 |
| SessionStart | 2个 | 会话恢复 |
| … | … | … |
配置快照安全
// 启动时冻结所有配置
const frozenConfig = deepFreeze(loadConfig());
// 运行时无法修改,防止注入攻击
function preventInjection(attemptedChange: any) {
// 任何尝试修改冻结配置的都会被拒绝
throw new SecurityError('Config is immutable after startup');
}📚 18章目录详解
Part 1: foundations
| 章 | 标题 | 核心内容 |
|---|---|---|
| 1 | The Architecture of an AI Agent | 6大关键抽象、数据流、权限系统、构建系统 |
| 2 | Starting Fast — The Bootstrap Pipeline | 5阶段初始化、模块级I/O并行、信任边界 |
| 3 | State — The Two-Tier Architecture | Bootstrap单例、AppState存储、粘性门闩、成本追踪 |
| 4 | Talking to Claude — The API Layer | 多提供商客户端、Prompt Cache、流式输出、错误恢复 |
Part 2: The Core Loop
| 章 | 标题 | 核心内容 |
|---|---|---|
| 5 | The Agent Loop | query.ts深度分析、4层压缩、错误恢复、Token预算 |
| 6 | Tools — From Definition to Execution | 工具接口、14步管道、权限系统 |
| 7 | Concurrent Tool Execution | 分区算法、流式执行器、推测执行 |
Part 3: Multi-Agent Orchestration
| 章 | 标题 | 核心内容 |
|---|---|---|
| 8 | Spawning Sub-Agents | AgentTool、15步runAgent生命周期、内置Agent类型 |
| 9 | Fork Agents and the Prompt Cache | 字节相同前缀技巧、缓存共享、成本优化 |
| 10 | Tasks, Coordination, and Swarms | 任务状态机、Coordinator模式、Swarm消息传递 |
Part 4: Persistence and Intelligence
| 章 | 标题 | 核心内容 |
|---|---|---|
| 11 | Memory — Learning Across Conversations | 文件式内存、4类分类、LLM召回、陈旧警告 |
| 12 | Extensibility — Skills and Hooks | 两阶段技能加载、生命周期钩子、快照安全 |
Part 5: The Interface
| 章 | 标题 | 核心内容 |
|---|---|---|
| 13 | The Terminal UI | 自定义Ink分支、渲染管道、双缓冲、池化 |
| 14 | Input and Interaction | 键解析、键绑定、和弦支持、Vim模式 |
Part 6: Connectivity
| 章 | 标题 | 核心内容 |
|---|---|---|
| 15 | MCP — The Universal Tool Protocol | 8种传输协议、MCP OAuth、工具包装 |
| 16 | Remote Control and Cloud Execution | Bridge v1/v2、CCR、上游代理 |
Part 7: Performance Engineering
| 章 | 标题 | 核心内容 |
|---|---|---|
| 17 | Performance — Every Millisecond | 启动优化、上下文窗口、Prompt Cache、渲染、搜索 |
| 18 | Epilogue — What We Learned | 5大架构赌注、可迁移性、Agent的未来 |
🎯 10大可迁移架构模式
| # | 模式 | 核心原理 | 可迁移场景 |
|---|---|---|---|
| 1 | AsyncGenerator驱动 | yields Messages,天然背压和取消 | 所有流式Agent系统 |
| 2 | 推测执行 | 模型流式输出时预启动只读工具 | 低延迟工具调用 |
| 3 | 并发安全分组 | 按安全分类分区,读并行写串行 | 多工具并发系统 |
| 4 | Fork缓存共享 | 父子共享字节相同前缀 | 多Agent协作系统 |
| 5 | 4层上下文压缩 | snip→microcompact→collapse→autocompact | 长上下文管理 |
| 6 | LLM召回内存 | Sonnet side-query选择记忆 | 长期记忆系统 |
| 7 | 两阶段技能加载 | 启动元数据+调用时内容 | 动态技能平台 |
| 8 | 粘性门闩 | Beta头一旦发送,永不在会话中撤销 | 缓存稳定性 |
| 9 | 槽位预留 | 8K默认→64K升级 | 输出管理 |
| 10 | 钩子配置快照 | 启动时冻结,运行时防注入 | 安全边界 |
💡 适用读者
适合谁读
| 读者类型 | 阅读方式 | 收获 |
|---|---|---|
| 构建Agent系统的工程师 | 精读+ Apply This练习 | 直接应用架构模式 |
| 评估架构的技术负责人 | 浏览叙事,跳过代码块 | 理解决策背后的原因 |
| 对生产AI工具好奇的任何人 | 通读+重点章节 | 理解Claude Code如何工作 |
每章结尾的 Apply This
每章结尾都有"Apply This"——5个可迁移的带具体适应建议的模式。
🔒 安全与隐私
权限系统设计
const permissionMatrix = {
// 默认拒绝
default: 'deny',
// 明确允许
allow: [
'Read:repo', // 读取代码库
'Write:repo', // 修改代码
'Execute:shell', // 执行Shell命令
],
// 明确拒绝
deny: [
'Execute:sudo', // 禁止提权
'Read:/etc/*', // 禁止读取系统配置
'Write:~/.ssh', // 禁止修改SSH配置
]
};快照安全原则
- 所有敏感配置在启动时冻结
- 运行时配置不可变
- 任何运行时修改尝试都被拒绝
🌐 MCP:通用工具协议
Claude Code内置对MCP的支持,支持8种传输协议:
| 传输类型 | 说明 | 适用场景 |
|---|---|---|
| stdio | 标准输入输出 | 本地开发 |
| HTTP+SSE | 长连接+服务端推送 | Web应用 |
| WebSocket | 双向通信 | 实时应用 |
| Streamable HTTP | 可流式HTTP | 大文件传输 |
| Server-Sent Events | 单向事件流 | 简单推送 |
| WebRTC | 浏览器P2P | 复杂Web应用 |
| stdio (local) | 本地进程通信 | CLI工具 |
| Docker | 容器化MCP | 隔离环境 |
✅ 总结
Claude Code from Source是一本揭示生产级AI编程工具架构的深度技术书籍:
- 架构深度:18章覆盖从启动到性能的完整架构
- 源码可信:基于npm实际源码地图,非逆向或推测
- 模式可迁移:10大架构模式可直接应用到自己的Agent系统
- 实践导向:每章都有Apply This,提供具体适应建议
- 教育纯粹:所有代码都是伪代码,仅用于说明架构,无版权问题
核心收获:
- 理解AsyncGenerator如何驱动整个Agent系统
- 掌握14步工具执行管道的推测执行优化
- 学会Fork模式+Prompt Cache实现95%成本节省
- 理解4层上下文压缩如何管理Token预算
- 掌握两阶段技能加载+钩子系统实现可扩展性
🦞