乐于分享
好东西不私藏

从源码角度深度解读 Claude Code:AI 编程代理的架构之美

从源码角度深度解读 Claude Code:AI 编程代理的架构之美

Claude Code from Source — Book Cover

一个纯教育目的的 Claude Code 架构分析项目,18章、约400页,从源码层面解读 Anthropic AI 编程代理的内部设计与工程实践。


当 Anthropic 在 npm 上发布 Claude Code 时,发布包中的 .js.map 源映射文件里藏着一个秘密:每个映射条目都有一个 sourcesContent 字段,里面存储了完整的原始 TypeScript 源代码。

这给了工程师们一个前所未有的机会——在无需逆向的情况下,研究一个生产级 AI 编程代理的完整架构。

今天要介绍的这个项目,正是基于这些源码写成的技术书籍。全书18章,分为7个部分,约400页,每章都从叙事、深度解析、可迁移模式三个层次展开。它不包含任何 Claude Code 的原始代码——所有代码示例都是原创的伪代码,仅用于阐释架构模式。

六大核心抽象:整个系统的支柱

Claude Code 近两千个 TypeScript 文件,背后由 六个核心抽象 支撑一切:

1. Query Loop:异步生成器作为控制流

整个系统的核心是 query.ts(约1700行),一个 AsyncGenerator

这很关键。传统 CLI 是一个函数:接受参数、执行、退出。但 AI 代理的”程序”不是固定指令序列——而是一个运行时由语言模型生成自己指令序列的循环

// 核心模式:生成器作为 Agent 循环async functionqueryLoop(userMessage: Message) {  while (true) {    const response = await callModel(messages);    const toolCalls = extractToolCalls(response);    for (const toolCall of toolCalls) {      const result = await executeTool(toolCall);      messages.push(result); // 追加工具结果到消息历史    }    if (toolCalls.length === 0break// 模型停止调用工具 = 完成  }}

使用生成器而非回调或事件发射器,带来三个关键优势:

自然背压:UI 跟不上时,生成器自动暂停干净的取消:AbortController 可完全终止整个循环类型化的终止状态Terminal 联合类型精确编码停止原因

2. Tool System:推测性执行

Claude Code 内置40+工具——读文件、写代码、执行 Shell 命令、搜索网页……每个工具不只是函数,而是一套完整接口:身份标识、Schema、执行逻辑、权限声明、进度报告、UI渲染。

但这里最精妙的设计是:并发安全的工具,在模型流式输出的过程中就开始执行了

这就是 Speculative Execution(推测性执行)。如果模型的最终输出使该工具调用失效(极少见),结果会被丢弃。但99%的情况下,这节省了宝贵的时间。

3. 两层状态架构

Claude Code 的状态管理分为截然不同的两层:

层级
类型
作用
示例
STATE
可变单例
基础设施状态
工作目录、模型配置、成本追踪
AppState
响应式存储(Zustand风格)
UI状态驱动
消息列表、输入模式、权限提示

这是一个刻意的设计决策:基础设施状态变化稀少,不需要触发重渲染;UI状态频繁变化,必须响应式更新。分离二者,避免了不必要的计算。

4. Memory:跨会话持久化

Claude Code 的记忆系统分为三层:

关键点在于记忆召回的方式——不是关键词匹配,而是 LLM 自己决定哪些记忆与当前对话相关。启动时,一个轻量级的 Sonnet 查询会筛选出最相关的记忆片段,注入系统提示词。

5. Hooks:27个生命周期拦截点

Hooks 是在特定生命周期事件触发时执行的拦截器,跨越四种执行类型:

Shell 命令单轮 LLM 提示多轮代理对话HTTP Webhook

更妙的是,权限系统本身部分就是用 Hook 实现的——PreToolUse Hook 可以在交互式权限提示触发之前,直接拒绝危险操作。

6. Tasks:子代理与递归能力

Tasks 是后台工作单元,遵循状态机流转:

AgentTool Spawn 一个新的 query() 生成器,拥有独立的消息历史、工具集和权限模式。这意味着:代理可以委托子代理,子代理可以进一步委托——递归式的任务分解能力由此而来。

权限系统:7种模式,精密的信任边界

Claude Code 在用户机器上执行任意 Shell 命令、编辑文件、修改 Git 历史——没有权限系统,这是一场安全灾难。

Claude Code 定义了7种权限模式,按限制级别排序:

模式
行为
bypassPermissions
全部允许,仅供内部/测试
dontAsk
全部允许但记录日志,无用户提示
auto
LLM 分类器判断允许/拒绝
acceptEdits
文件编辑自动批准,其他变更需确认
default
标准交互模式,每步操作需用户批准
plan
只读模式,所有变更操作拒绝
bubble
权限请求向上冒泡到父代理

auto 模式尤其值得关注。它发起一个独立的轻量级 LLM 调用,用对话转录文本对工具调用进行分类,判断操作是否与用户意图一致。这让 Claude Code 能在半自动模式下工作——批准常规操作,标记可疑行为。

子代理默认使用 bubble 模式——它们不能自行批准危险操作,权限请求会向上冒泡到父代理,最终到达用户。

多云架构:四套基础设施,一套代码

Claude Code 通过四条不同的基础设施路径与 Claude 对话——但核心代码完全不感知这些差异。

getAnthropicClient() 工厂函数读取环境变量和配置,决定使用哪个提供商,构造相应的客户端返回。从此之后,callModel() 和其他所有消费者都将它视为通用 Anthropic 客户端——切换云服务商是配置变更,不是代码变更。

十个核心模式:AI 代理的工程精华

原文作者提炼了10个让整个系统运转的核心模式:

1.AsyncGenerator 作为 Agent Loop — yields Messages,自然背压与取消2.推测性工具执行 — 模型流式输出时就开始执行只读工具3.并发安全批处理 — 按安全性分区,读操作并行,写操作串行4.Fork 代理缓存共享 — 并行子代理共享字节级相同的提示前缀,节省约95%输入token5.四层上下文压缩 — snip → microcompact → collapse → autocompact,每层比上一层更轻量6.文件记忆 + LLM 召回 — Sonnet 副查询选择相关记忆,非关键词匹配7.两阶段技能加载 — 启动时仅加载 frontmatter,调用时才加载完整内容8.粘性锁存器 — Beta 头部一旦发送,会话期间永不取消9.槽位预留 — 默认8K输出上限,触发时升级至64K(99%请求节省上下文)10.Hook 配置快照 — 启动时冻结配置,防止运行时注入攻击

这本书是怎么写出来的?

这个项目本身就是一个 AI 工程能力的最佳案例。

36个 AI 代理协作,分四个阶段完成近2000个 TypeScript 文件的分析与写作:

从源码提取到最终修订成书,全程约6小时

最后的话

这个项目最打动我的,不是某个具体的技术实现,而是整体传达出的工程哲学:

一个生产级 AI 代理的复杂度,不在于代码量的堆砌,而在于对边界情况的精心处理、对安全性的深刻理解、对用户体验的极致追求。

从权限系统7种模式到推测性执行,从两层状态架构到四层上下文压缩——每一个设计背后,都有真实的用户场景和踩坑经验。

如果你正在构建自己的 AI Agent 系统,这本书里的10个核心模式,几乎每一个都可以直接”偷”过来用。

当然,这个项目本身也是一个提醒:源映射文件里的 sourcesContent,既是技术细节,也是安全教训

本文系根据 GitHub 开源项目 alejandrobalderas/claude-code-from-source 内容撰写,保留原始图片链接,仅供技术学习与交流使用。


相关资源

关注公众号「光影织梦」,发送口令 claude-code-from-source 获取项目地址