乐于分享
好东西不私藏

解剖Claude Code泄漏源码,学工业级Agent系统设计·第一篇

解剖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 个工具,一套统一接口。为什么并发安全性是「输入相关的」而非「工具相关的」?