Skip to content

Agent Loop

Abstract

Agent Loop 是 Coding Agent 的心跳:接收输入 → 调用 LLM → 执行工具 → 回填结果 → 继续推理 → 直到完成

  • Codex CLI 更像一个基于 turn 的状态机,每轮都有明确输入、配置、工具结果和事件输出
  • Claude Code 更像一个持续流式执行的产品化 Agent loop,通过工具调用、权限确认和上下文更新不断推进任务

基本循环

无论具体实现如何变化,Coding Agent 的核心循环都围绕同一件事:让模型在 推理(reasoning)行动(action) 之间反复切换。

flowchart LR
    Input[用户输入] --> Model[调用 LLM]
    Model --> Decision{是否需要工具?}
    Decision -->|否| Done[完成回答]
    Decision -->|是| Tool[执行工具]
    Tool --> Result[工具结果]
    Result --> Model

真正的差异不在“有没有循环”,而在循环如何被组织

状态放在哪里、工具何时执行、结果如何回填、权限如何确认、上下文溢出时如何恢复。


Codex:Turn-Based State Machine

Codex 更适合理解为 turn-based state machine。每一轮 turn 都会携带一组相对固定的配置,例如模型、沙箱策略、审批模式、会话历史和工具定义。模型在当前 turn 中流式输出文本、推理片段或工具调用;工具执行完成后,结果会写回历史,再进入下一轮。

用户输入
    ↓
创建 TurnContext(模型、配置、沙箱策略、权限)
    ↓
构建 Prompt(基础指令 + 历史 + 工具 schema)
    ↓
流式接收模型响应(SSE 或 WebSocket)
    ↓
从响应中解析工具调用
    ↓
对每个工具调用:
    ├── 检查审批
    ├── 应用沙箱策略
    ├── 在沙箱中执行
    └── 收集结果
    ↓
将结果追加到历史
    ↓
向 UI 发送事件
    ↓
下一轮 Turn(若模型需要继续)

关键设计

Codex 的 turn 边界让执行过程更容易推理:一轮 turn 有明确的输入、上下文、工具调用、工具结果和事件输出。即使中间存在流式输出和异步工具执行,turn 仍然是状态同步的重要边界。

关键组件

并发模型

Codex 基于 Tokio 做异步 I/O,模型流、工具执行和 UI 事件可以通过异步任务协同推进。ToolOrchestrator 负责调度工具调用,并处理审批请求与结果回填。

优缺点总结

优势在于每一轮具有清晰的边界:当某一轮失败时,可以围绕该 turn 实现取消、重试或错误恢复,便于系统内状态管理和错误控制。
但这也带来一定复杂性:系统必须细致处理 turn 内部的流式事件管理、工具 futures 的并发调度、审批请求的等待,以及结果顺序的正确还原。


Claude Code:Streaming Agent Loop

Claude Code 更适合从用户可观察行为上理解为 streaming agent loop。用户提交请求后,系统会持续向模型发送上下文、接收流式响应、发现工具调用、执行工具、追加工具结果,并在需要时继续请求模型。

用户输入
    ↓
组装 System Prompt(cached sections + dynamic context)
    ↓
规范化消息以适配 API
    ↓
从 Claude API 流式接收响应
    ↓
处理 stop_reason:
    ├── "tool_use" → 提取 tool blocks
    │   ├── 检查权限(canUseTool)
    │   ├── 执行工具(读取类并行,写入类串行)
    │   ├── 追加工具结果
    │   └── 回到 API 调用
    │
    ├── "end_turn" → 返回文本响应,结束
    │
    ├── "max_tokens" → 自动压缩上下文,继续
    │
    └── "stop_sequence" → 处理 stop hooks

关键设计

Claude Code 的循环更强调连续体验:工具调用、权限确认、进度展示、上下文压缩和最终输出都可以作为流式事件不断反馈给用户。它的边界不一定像 Codex turn 那样硬,而更像一个持续推进的执行管线。

关键组件

  • Conversation / Query Orchestrator:维护一次会话中的消息、模型调用、工具结果和执行状态
  • Stream Event:向 UI 或调用方持续输出文本、工具调用、权限请求、进度和错误等事件
  • Permission System:决定工具是否可以执行,是否需要用户确认,或是否应该拒绝
  • Tool Executor:执行文件读取、搜索、命令、编辑、MCP 等工具,并把结果回填给模型

并发模型

Claude Code 的工具执行需要区分只读操作和有副作用操作:

  • 只读工具:例如搜索、文件读取等,通常更适合并发执行
  • 写入或命令类工具:例如编辑文件、执行命令等,需要更谨慎的权限确认和顺序控制
  • 结果回填:工具结果需要以模型可理解的形式追加回上下文,供下一轮推理使用

优缺点总结

体验细腻:用户可以更早看到事件、进度、权限提示和部分结果。 代价是控制流更复杂,状态可能分散在会话、工具执行器、权限系统和 UI 事件之间。


重要性

Agent Loop 决定了 Coding Agent 的工程性格。

Codex 的 turn-based 模型更像一个可审计的执行单元:每轮都能看到模型拿到了什么上下文、发起了什么工具调用、工具返回了什么结果,以及下一轮为什么继续。这种结构适合强调边界、沙箱和可恢复性的系统。

Claude Code 的 streaming loop 更像一个持续运行的交互产品:它可以自然地展示进度、暂停等待权限确认、继续执行工具、处理上下文压缩,并把这些状态转化成用户可感知的体验。这种结构适合强调交互流畅性和工具权限控制的产品。


核心差异

维度 Codex(Turn-Based) Claude Code(Streaming)
边界 每轮迭代有明确的 TurnContext 对用户更像连续事件流,边界感更弱
状态 每轮配置和上下文边界更明确 会话状态持续更新,和工具、权限、UI 事件交织
流式 模型输出、工具进度和事件可流式展示,但 turn 仍是重要结构 文本、工具、权限和进度更自然地组成连续事件流
恢复 适合围绕当前 turn 做取消、重试和错误恢复 适合在执行过程中处理权限等待、上下文压缩和继续执行
取消 更容易以 turn 为单位管理取消 更容易在事件流中暂停或中止任务

Auto-Continuation

Coding Agent 通常不会在第一次模型输出后就停止。如果模型决定调用工具,系统会执行工具并把结果追加回上下文,让模型继续推理。

  • Codex CLI:如果模型输出工具调用,工具结果会写回历史,并进入下一轮 turn,直到模型不再需要继续调用工具。
  • Claude Code:如果模型返回工具调用,循环会继续执行工具并再次请求模型;如果上下文过长,则可能先压缩上下文再继续。

从用户角度看,这些 continuation 往往被包装成一次完整任务:用户发出请求,Agent 在后台经历多轮“思考-行动-反馈”,最后返回结果。

Context Overflow

当会话历史超过模型上下文窗口时,Agent Loop 必须处理上下文溢出,否则模型无法继续可靠工作。

  • Codex CLI:更适合把上下文管理看作 history 的压缩、摘要和裁剪问题,目标是在保留关键任务状态的同时降低 token 占用。
  • Claude Code:更强调在连续执行过程中触发压缩和恢复,让用户感知到的任务流尽量不中断。

上下文管理会直接影响 Agent 的长期任务能力:如果压缩过度,模型会丢失关键约束;如果压缩不足,任务会被上下文窗口打断。