详解 Claude Code 源码
赛博浮世绘 · 晓风乾 · 24 站拆解
回首页
详解 Claude Code 核心引擎 2.2 · queryLoop 主循环
篇章二 · 2.2

queryLoop 主循环

Agent 的本质是什么?一个循环:调模型 → 看它要用工具吗 → 用了就执行再回来调模型 → 没用就结束。Claude Code 把这个循环写到了工业级。

一个 while (true)六种重入

query.ts 里的 queryLoop() 是个 AsyncGenerator,体内就是 while (true)。源码注释里残留的 query_recursive_call 检查点暴露了它的历史:最初是递归写法,后来重构成循环——因为递归会栈溢出,循环不会。

一轮迭代的四步 点「下一迭代」走一遍
1
前置处理压缩 · 折叠 · 预取(6 道工序)
2
调用 API流式接收 · 边收边执行工具
3
判断后续有工具调用 → 执行后 continue;没有 → 收尾
4
附件与队列处理附件 · 消费排队的命令
每轮迭代由一个 State 对象驱动;点下面的按钮开始
第 1 步 · 前置处理的 6 道工序

每次把消息发给 API 之前,先过六道「瘦身」工序——按成本从零到高排列,能省一层是一层:

aSkill 预取异步预载可能用到的技能
bContent replacement工具结果的预算管理
cSnip compact裁掉最老的消息段
dMicrocompact清空旧 tool_result 内容
eContext collapse把工具调用折叠成摘要
fAutocompact超阈值 → 全量压缩

d/e/f 三道是篇章六的主角,这里先记住它们的位置:在循环里、每轮 API 调用之前

State.transition · 六种「为什么又转一圈」
transition触发场景性质
next_turn模型调了工具,执行完接着来正常流
reactive_compact_retryAPI 返回 413(上下文超限),压缩后重试救火
max_output_tokens_recovery单次输出超长,调整后续发救火
stop_hook_blockingStop hook 拦住了收尾,重试救火
collapse_drain_retry上下文折叠后排空重试救火
token_budget_continuationtoken 预算续发救火

设计味道:与其写 6 个异常分支函数,不如把「重新进循环」统一成一个带原因标记的 State——循环体自己看原因决定怎么处理。

救火队挑战 · 你来扳道岔
已处理:0 起
① 前置处理 ② API ③ 判断 ④ 附件
点「接收警情」——警情在环轨上炸响,你选一条岔路把循环救回来。
本站要点:Agent = 循环,但工业级 Agent 的循环里长满了「救火通道」——5/6 的重入原因都是异常恢复。下一站下沉一层,看循环第 2 步调用的 API 层:它为什么敢放弃官方 SDK,以及那只 90 秒的看门狗。