先定义状态,再写 while 循环
Run 表示任务,Turn 表示一次模型决策上下文,Step 表示一个可提交逻辑动作,Attempt 表示可重复执行。消息、Tool Call、Observation 和 Artifact 是记录,不等于业务状态。状态至少区分 running、waiting、completed、failed、cancelled,并定义允许的单向迁移。
业务对象与对话历史分离:订单是否退款由领域服务决定,不由最后一条 Assistant 消息决定;Prompt 可以重建,业务事实必须从权威存储读取。每次状态提交带版本,旧 Attempt 的晚到结果只能作为证据,不能覆盖新状态。
一次迭代的确定性边界
组装模型输入
从稳定指令、当前状态、选择性历史、必要 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、价格、限额与模型能力会变化,落地时仍需按目标版本做能力探测和回归。
- OpenAI Agents SDK:Running agents — Loop、maxTurns、RunState、流式和恢复的当前 SDK 语义
- OpenAI Agents SDK:Human-in-the-loop — 中断、序列化状态与恢复再校验
- Temporal:Workflow Definition — 持久状态机、重放确定性与长任务恢复的参考边界