雨天小六

读懂 Codex(3.13):一次 Turn 内多次模型采样的循环条件

· 更新于 2026-08-02 · 专栏:读懂 Codex

#Codex#Agent Runtime#生命周期#软件架构

一次 Turn 继续采样的总条件是 model_needs_follow_up OR has_pending_input,但这个布尔值还会被 compact、Stop Hook 和 Mailbox 策略改写。只写“模型调用工具后再请求一次”覆盖不了当前 Runtime。

模型侧 follow-up 从哪里来

完成的工具调用经 ToolRouter 解析后将 needs_follow_up=true;Runtime 等工具 future 生成 output,下一次请求把 call 与 output 一起交给模型。无法正常路由但可向模型解释的 RespondToModel 也写入 synthetic output 并继续。Responses completed 若显式 end_turn=false,即使没有工具也要求继续。

一次采样后继续模型请求的各种条件
图 3.13-1:工具、provider end_turn、pending input、Stop Hook 和 mailbox 都可能延长同一个 Turn。
model_needs_follow_up = (
    response.contains_executable_tool_call
    or response.contains_model_recoverable_tool_error
    or response.end_turn is False
)

needs_follow_up = model_needs_follow_up or input_queue.has_pending_input(turn)

模型只返回最终 assistant message、没有 pending input、end_turn 未要求继续时,基础循环可以结束。Reasoning item 本身不必然继续;决定权来自 response completed 汇总结果。

pending input 怎样加入条件

Steer 或允许投递的 mailbox 在采样结束后使 has_pending_input=true。下一轮开始前 Runtime 排空并记录这些输入,再重新捕获 Step。初始用户 input 在第一轮已直接记录,因此 can_drain_pending_input 初值取决于 input 是否为空;自动 compact 后也可能暂缓 drain,让 tool continuation 先恢复,避免 steer 被插到 call/output 之间。

Mailbox 还有抢占优化:流正在输出 reasoning 或 commentary 时,如果 mailbox 已有消息,可以提前结束当前 response 处理并返回 needs_follow_up=true,让新信息尽快进入下一请求。最终回答类 message 则可把非 trigger mail 推迟到下一 Turn,避免已经结束语义的答复被无条件重开。

Token rollover 是继续条件的变换器

只有 needs_follow_up 为真且收到 new-context-window 请求或 Token limit reached,才执行 mid-turn auto compact。压缩成功后仍在同一 Turn 继续,但会重建 continuation Step/world baseline。

should_roll_over = needs_follow_up and (
    take_new_context_window_request() or token_limit_reached
)
if should_roll_over:
    await run_auto_compact(reason="context_limit", phase="mid_turn")
    await rebuild_continuation_context()
    can_drain_pending = not model_needs_follow_up
    continue

若已经不需要 follow-up,即使 Token 已到阈值也不为一个已经结束的 Turn 强行采样;后续 Turn 的预采样 compact 会处理。这样 compact 服务于“还必须继续工作”的请求,而不是无意义延长终态。

follow-up 与 Token limit 联合触发 mid-turn compact
图 3.13-2:达到 Token 阈值本身不够;只有 Turn 仍需继续时才 rollover,压缩后回到下一次采样而不是发 TurnComplete。

Stop Hook 可以把“完成”改成“继续”

基础条件为 false 后才运行 turn-stop hooks。若 hook 返回 block 且提供 continuation fragments,Runtime 把它们组成 hook prompt message、写入历史、允许 mailbox 当前轮投递,并设置 stop_hook_active 后继续。若 block 却没有 prompt,只发 Warning 并忽略该阻止请求,避免空循环。

因此循环没有一个孤立的 if tool_call。完整决策顺序是:采样汇总 → pending input → Token rollover → Stop Hook → legacy after-agent hook → break。

评论


← 返回文章列表