最简单的 Agent 是一个不断执行模型和工具的 while 循环。它适合演示,不适合长期任务。真实任务会遇到上下文耗尽、测试失败、用户打断、预算耗尽、并发 worker、进程崩溃和“模型说完成但其实没完成”。因此 Agent Loop 的核心不是 while,而是围绕 while 建立一套状态机。

本文以 Codex 当前 goal/turn 机制、Claude Code 的 session/stop 机制、Ralph、OMC、SWE-agent、OpenHands、LangGraph、Temporal、CrewAI 和 AutoGen 的公开实现为参照。

01 Loop 的完整模型

Agent Loop Engineering Layers

一个生产级 loop 至少有七个状态:

Goal -> Plan -> Attempt -> Observation -> Verification -> Transition -> Recovery

其中 Attempt 可以重复,Recovery 可以回到 Plan,也可以进入 blocked、paused、failed 或 complete。完成不是模型返回一句“好了”,而是目标状态满足外部验收条件。

02 Codex Goal 与 Claude Goal:目标放在哪里

Codex Goal vs Claude Goal

Codex 的长期目标更接近线程级账本:目标、进度、阻塞、预算和继续条件由宿主状态管理,Agent 可以跨多个 turn 继续推进。Goal 是控制面状态,不是 prompt 里的一句话。

Claude Code 的 goal 类机制更接近 session/stop 时刻的完成审计:当 Agent 想停止时,系统检查目标是否满足,必要时再让模型继续。它的优势是侵入小,缺点是外层长期调度和多日恢复需要更多宿主设施。

两者的共同点是把完成条件外部化;差异是 Codex 更偏“目标运行时”,Claude 更偏“停止时的质量门”。

03 Ralph:最小外层循环为何有效

Ralph 的基本思想很朴素:

读取 PRD / tasks
  -> 调用 coding agent
  -> 运行测试与检查
  -> 记录进度
  -> 下一轮继续

它把任务状态放在文件或 git 工作树,外层脚本拥有循环,内层 Agent 只负责一次尝试。优点是透明、可替换、容易部署;缺点是状态一致性、重复工作、预算、并行和恢复语义都由脚本自行承担。

Ralph 适合把一个可拆分的 PRD 转成多个小任务,不适合没有明确验收条件的开放式探索。

04 OMC 与 OpenHands:从脚本变成运行时

Agent Loop Project Landscape

OMC 将 worker、allocation policy、事件和团队状态引入 loop;OpenHands 则把对话、动作、观察、sandbox 和应用状态组织成 runtime。两者都说明一个事实:一旦存在多 worker 或真实环境,loop 就必须拥有 action/observation 事件、worker 生命周期、并发与取消、任务依赖与结果合并、独立验证者和可恢复持久化。

从 done 文件升级到事件流,不是为了“架构更高级”,而是为了避免轮询看不到中间状态,也无法区分“没完成”“执行中”“已失败”和“等待用户”。

05 SWE-agent:环境是 loop 的一等对象

SWE-agent 的 action/observation loop 很适合说明 coding agent 的本质:

issue + repo state
  -> agent action
  -> SWEEnv observation
  -> trajectory
  -> patch / test / retry

环境不是执行器的附属物。它决定 shell、文件、测试、补丁和反馈是否一致。RetryAgent 一类机制则说明失败不是异常终点,而是一次新的 attempt,应该记录失败原因并改变下一次上下文。

06 通用编排框架的不同取舍

框架核心抽象强项代价
LangGraph状态图、checkpoint、持久化有状态 loop 和人工介入需要显式建图
Temporaldurable workflow崩溃恢复、长时间运行工作流边界更严格
CrewAI角色、任务、crew快速搭建角色协作精细状态治理较弱
AutoGenAgent 对话与终止条件多 Agent 交互灵活终止和共享状态需自行设计

它们不是互斥方案。Temporal 可以作为 durable substrate,LangGraph 可以表达任务图,CrewAI/AutoGen 可以提供角色层,具体 Agent 仍要自己设计工具策略和验收。

07 关键工程问题

目标状态

目标应有 id、描述、验收条件、当前阶段、预算、负责人、阻塞原因、更新时间和证据链接。自然语言目标必须转成可观测状态。

停止判定

停止条件至少包括 success、blocked、paused、budget_exhausted、user_cancelled、failed 和 max_iterations。只靠模型自报完成会产生大量假阳性。

验证闭环

验证可以是测试、lint、类型检查、diff review、浏览器截图、人工批准或领域评测。验证结果必须写回状态,不能只在终端打印。

恢复语义

崩溃恢复需要知道最后一个 durable event、正在执行的副作用、是否可以重试、是否需要补偿。工具调用最好有 idempotency key,避免恢复时重复发送消息或重复迁移数据库。

预算与无进展

token、时间、工具调用次数和并发 worker 都应有预算;连续多轮没有文件、状态或验证变化时,应触发无进展保护,而不是继续烧钱。

08 内外两层 Loop

一个 coding agent 往往有两层循环:

外层 Goal Loop:拆任务、重试、验证、恢复、汇总
    内层 Agent Loop:模型 -> 工具 -> 结果 -> 模型

把两层混在一起,会导致“模型自己决定是否完成全部任务”,也会让外层无法插入 review、预算和人工审批。合理做法是让内层专注单个 attempt,外层拥有目标和生命周期。

09 选型与实现顺序

个人脚本可以先用 Ralph 式文件状态;需要 session 恢复时引入 append-only event;需要复杂依赖时使用 LangGraph;需要跨天和崩溃恢复时考虑 Temporal;需要多 Agent 时再加入 worker runtime。

不要一开始就做“无限自主”。最小可用版本应该先具备:目标对象、一次 attempt、外部验证、失败状态、可读日志和人工停止。之后再加并行、记忆、计划自动修正和自我改进。

10 最后判断

Agent Loop 的演化方向很明确:从“重复调用模型”变成“管理一项可验证、可恢复、可审计的工作”。模型能力决定单次 attempt 的上限,loop 工程决定系统能否把多个 attempt 组织成可靠结果。

参考资料