Loop 不变量模型输出是提议,不是状态提交;只有可信控制器验证动作并原子提交后,Run 才能进入下一步。每一次迭代都必须消耗有限预算并趋向完成、等待或失败。

先定义状态,再写 while 循环

Run 表示任务,Turn 表示一次模型决策上下文,Step 表示一个可提交逻辑动作,Attempt 表示可重复执行。消息、Tool Call、Observation 和 Artifact 是记录,不等于业务状态。状态至少区分 running、waiting、completed、failed、cancelled,并定义允许的单向迁移。

业务对象与对话历史分离:订单是否退款由领域服务决定,不由最后一条 Assistant 消息决定;Prompt 可以重建,业务事实必须从权威存储读取。每次状态提交带版本,旧 Attempt 的晚到结果只能作为证据,不能覆盖新状态。

控制权:模型决定候选动作,Runtime 决定动作能否改变状态
State事实、版本、预算、待处理事项
Context对本轮必要事实的投影
Proposal回答、Tool、委派或澄清
Commit校验执行并提交下一状态

一次迭代的确定性边界

组装模型输入

从稳定指令、当前状态、选择性历史、必要 Artifact 摘要和候选 Tool 生成 Context,并记录 Context 版本/摘要。不要把完整 Trace 或所有 Tool 结果反复塞回;丢失原始证据也不能只保留不可追溯摘要。

解析模型输出

输出先进入结构解析和动作分类:最终回答、Tool Call、委派或澄清。多个 Tool Call 是否允许并行由副作用和数据依赖决定,而不是 SDK 是否支持 parallel calling。未知动作和 Schema 失败是显式错误,不应“尽量解析”。

随后执行权限/策略/预算门禁,调用 Tool,把结构化 Observation 与 Attempt 事实写入同一提交边界。只有 compare-and-swap 成功才开始下一轮;冲突后重读,不重放模型假设。

while (state.status === 'running') {
  budget.assertRemaining(state)
  const proposal = await model.decide(projectContext(state))
  const transition = await controller.evaluate(proposal, state)
  state = await store.commit(transition, { expectedVersion: state.version })
}

这是控制边界伪代码;生产实现还需持久事件、错误分类、Tool Wrapper、取消和恢复。

终止不能只依赖模型说“完成”

正常完成需要结果通过任务验收器,例如结构、引用、业务状态或测试;无 Tool Call 只表示模型本轮没调用 Tool。强制停止包括步骤、Token、费用和绝对 Deadline 用尽;保护性停止包括连续无进展、重复动作指纹、同一错误反复出现和状态振荡。策略拒绝、取消和不可恢复错误进入各自终态;等待人工或外部事件进入 waiting,不应占用 Worker。

最大步数是保险丝,不是完成定义它能阻止无限循环,但到达上限时任务仍可能未完成;必须返回可诊断原因、已有进度和恢复/人工选项。

Context 是视图,State 才是事实

Context 每轮按策略从状态投影,可摘要、裁剪和重新排序;State 保存任务事实、版本、预算、审批和 Artifact 引用。摘要是派生数据,不能覆盖原消息和工具回执的审计保留。模型输出只有经 Schema、领域和策略验证后,才能产生状态命令。

这种分离还允许模型升级或 Context 策略变更而不迁移业务事实。反例是把整个 SDK conversation 对象序列化为唯一状态:它通常混有不可移植客户端对象、敏感内容和版本相关内部结构。

中断与恢复需要可序列化检查点

检查点包含状态版本、预算余额、待审批/待事件、已提交副作用和能力/策略版本,不包含活连接、Promise 或明文短期凭据。恢复先验证代码/Schema 兼容、权限是否撤销、审批是否过期、外部状态是否漂移,再决定继续、重规划或终止。

中断前后的 Tool 调用最易产生重复:调用开始和结果提交之间必须有 Attempt/幂等记录。恢复不意味着“从最后一条消息继续”,而是从最后一个可证明的提交边界重新决策。

Loop 的关键测试不是“回答像不像”

控制器测试矩阵
注入应验证
模型重复同一 Tool指纹/进展检测停止并解释原因
Tool 晚到或重复Attempt/版本拒绝旧结果推进
提交前取消不产生新状态;已发生副作用进入对账
waiting 后恢复重新校验权限、外部状态和预算
模型声称完成任务验收器失败则继续、澄清或失败

确定性测试替换模型输出序列,验证状态转移;随机/对抗测试制造非法输出、循环和竞态;端到端 Eval 再验证任务成功。三者解决不同问题,不能只用回答评分覆盖控制正确性。

为什么对话历史不能直接充当 Run State?
它是为模型生成组织的视图,可能被摘要、裁剪和注入污染;业务事实、版本、预算与审批需要可信且可并发提交的状态。
恢复时为何要重新授权?
等待期间角色、策略、资源状态和批准有效期可能变化;旧许可不能自动授权未来副作用。

资料与事实边界

以下以官方文档、标准、论文和原始工程资料为主。厂商 API、价格、限额与模型能力会变化,落地时仍需按目标版本做能力探测和回归。

  1. OpenAI Agents SDK:Running agents — Loop、maxTurns、RunState、流式和恢复的当前 SDK 语义
  2. OpenAI Agents SDK:Human-in-the-loop — 中断、序列化状态与恢复再校验
  3. Temporal:Workflow Definition — 持久状态机、重放确定性与长任务恢复的参考边界