解剖Claude Code泄漏源码,学工业级Agent系统设计·第一篇
解剖 Claude Code 泄漏源码,学工业级 Agent 系统设计 · 第一篇 / 共六篇
Agent 是个什么东西 从 while(true) 开始理解 AI 工程
源码:src/query.ts(68,551 字符)
2026 年 3 月 31 日,Anthropic 在发布 Claude Code 2.1.88 时,意外把调试用的 sourcemap 文件一起打包发到了 npm。这个 59MB 的文件里,藏着 Claude Code 完整的 TypeScript 源码——512,000 行代码,40+ 个工具,一套完整的 Agent 系统。
这个系列直接从这批代码里读,告诉你生产级 Agent 系统是怎么被实际工程师写出来的。今天是第一篇:Agent 的核心——主循环。
– – – – – – – – – – – – – – –
先说清楚:Agent 不是聊天程序
普通的 AI 聊天程序逻辑很简单:发一条消息,拿一条回复。Agent 不一样。
Agent 的特点是:模型可以在回复里说「我要执行一个工具」,系统真的执行,把结果告诉模型,模型继续思考,再次决定要不要再用工具……直到任务完成。这是个循环。所有 Agent 系统的心脏,都是一个循环。
Agent 系统的本质是一个循环:调用模型 → 检查是否需要执行工具 → 执行 → 喂回结果 → 继续循环。
Claude Code 主循环的状态设计
在 src/query.ts 里,主循环维护一个叫 State 的状态对象,在每次迭代开始时读取它,结束时更新它:
// src/query.ts
// 循环在每次迭代之间携带的完整状态
type State = {
messages:Message[]// 对话历史,不断追加
toolUseContext:ToolUseContext// 工具执行的上下文
autoCompactTracking:AutoCompactTrackingState | undefined
maxOutputTokensRecoveryCount:number
turnCount:number// 第几轮了
transition:Continue | undefined// 上一轮为何继续
}
然后是主体结构,一个 while (true):
// src/query.ts(简化)
while (true) {
//步骤一:调用 LLM,流式接收响应
//
//stop_reason === ‘tool_use’ is unreliable — it’s not always
//set correctly. Set during streaming whenever a tool_use block
//arrives — the sole loop-exit signal.
consttoolUseBlocks: ToolUseBlock[] = []
letneedsFollowUp = false
//…流式调用 API,遇到 tool_use block 追加到 toolUseBlocks
//步骤二:没有工具调用 = 完成了
if(!needsFollowUp) {
return{ reason: ‘completed’ }
}
//步骤三:执行所有工具
forawait (const update of runTools(toolUseBlocks, …)) {
if(update.message) {
yieldupdate.message// 流式输出给 UI
toolResults.push(…)
}
}
//步骤四:把工具结果追加到 messages,进入下一轮
state= { …state, messages: […messages, …toolResults] }
}
一个让人意外的工程决策
注意那行注释:
// src/query.ts
// stop_reason === ‘tool_use’ is unreliable — it’s not always set correctly.
API 返回的 stop_reason 字段有时候不准确,所以代码不依赖它来判断是否继续循环,而是用流式接收时直接观察到的 tool_use block 来判断。这是在生产中踩过坑之后留下的防御性注释。
不信任 API 字段,只信任实际观察到的事件。这是生产系统里被反复验证的原则。
为什么用统一的 State 对象
因为这个循环有很多「继续的原因」:工具执行完了要继续、输出超限要恢复、需要压缩时要继续……每个 continue 站点都需要携带完整状态。用统一的 State 对象,所有站点只需写 state = { …state, 需要更新的字段 },既清晰又不容易遗漏。
最小 Agent 的三个要素
●1. 消息历史(messages[]):对话的完整记录。每次调用 API 都把所有历史发过去,模型才能理解上下文。
●2. 工具调用检测:模型返回时,检测是否包含 tool_use block。有 = 继续循环;没有 = 结束。
●3. 结果追加循环:执行工具,把工具结果追加到 messages[],下一轮让模型看到结果继续推理。
这就是 Agent 的最小单元。Claude Code 在这个基础上加了权限控制、并发执行、上下文压缩、记忆系统……但核心就是这三个要素。
| 给产品经理的总结
Agent 的核心是「循环 + 工具」。循环让模型能多步骤完成复杂任务,工具让模型能操作真实世界(读文件、执行命令、搜索网络……)。构建 Agent 产品的第一步,是想清楚你的用户场景需要哪些工具。
– – – – – – – – – – – – – – –
下一篇:工具系统——40 个工具,一套统一接口。为什么并发安全性是「输入相关的」而非「工具相关的」?
夜雨聆风