单次工具调用通常有清楚的输入和输出:调用搜索,得到结果;调用计算,得到数值。把多个调用串成一个会根据中间结果继续行动的流程后,系统需要面对新的问题:某一步超时是否该重试?重试会不会重复写入?何时应该停止?上下文越来越长时,早先的约束还在不在?

这篇文章是一份工程分析与验证顺序,不描述我已经实现或跑过某个 Agent 基准。讨论从一个常见业务场景开始:收到审批事件后,读取详情、核验状态、创建业务记录并回写处理结果。

把流程表示成状态,而不是一串提示词

可以先将任务拆为显式状态:收到事件、读取详情、验证条件、创建记录、关联记录、完成。每一步定义输入、输出、可重试条件和副作用。

这种表示让控制流可检查。模型可以帮助选择下一步或整理非结构化文本,但“是否允许创建记录”“当前记录是否已经存在”等业务不变量应由确定性代码和数据库约束保证。把约束只写在提示词里,无法防止超时重放或并发执行。

超时后重试,可能意味着第一次已经成功

网络超时说明调用方没有及时拿到响应,并不代表服务端没有完成操作。如果创建请求已提交,而响应在返回途中丢失,直接重试可能重复创建。多步 Agent 也会遇到同样的问题:工具调用的结果没能写回上下文,但副作用已经发生。

因此,有副作用的步骤需要稳定的业务键或幂等保护。再次执行时,系统应能查回第一次的结果。若一个流程包含“创建主体”和“建立关联”两个步骤,还要分别记录它们的状态;主体创建成功、关联失败时,恢复逻辑应继续补关联,而不是再创建一个主体。

失败恢复需要明确分类

不同错误不能统一处理成“再试一次”:

  • 暂时性错误:网络抖动、限流或服务暂时不可用,可以有限次数退避重试。
  • 业务拒绝:审批未通过、必填字段缺失,不应自动重试,应该要求补充或等待状态变化。
  • 结果不确定:调用超时但副作用可能已完成,先按稳定键查询状态,再决定是否重放。
  • 输出不合约:工具返回缺字段或无法解析,进入可观察的失败状态,避免把不完整结果传给下一步。

重试策略要有上限、间隔和可观测记录。否则一个局部错误可能变成重复调用或无限循环。

上下文不是可靠的状态存储

对话上下文方便模型理解任务,却不适合作为业务流程的唯一事实来源。上下文可能被压缩,模型也可能忽略较早的信息。关键标识、已完成步骤、工具结果摘要和待执行动作,应写入结构化的流程状态。每一步都从状态存储恢复必要数据,而不是期待模型记住完整对话。

同时应给工具设置最小权限和明确参数范围。流程只需要读取审批详情时,不应获得任意写入能力;需要创建记录时,也应限制可写字段和可访问对象。人工确认应放在高影响、不可轻易回滚的动作之前,而不是在流程每一步都增加确认摩擦。

一个不依赖框架的验证顺序

验证多步流程时,可以构造以下场景,并记录每个步骤的状态变化和副作用次数:

  1. 正常完成,确认流程只创建并关联一次。
  2. 在工具响应返回前模拟超时,再次投递同一事件,观察是否读回已有结果。
  3. 创建成功后让关联步骤失败,恢复执行时确认只补关联。
  4. 返回缺字段或无效状态,确认流程停止并提供可恢复信息。
  5. 连续返回暂时性错误,确认重试有上限并最终进入明确状态。
  6. 输入要求越权的参数,确认工具层拒绝并保留审计记录。

这是一份建议的测试矩阵,不是已经完成的实验结果。实际验证还应明确运行环境、故障注入方式和记录字段。至少需要观察每步开始与结束时间、尝试次数、业务键、工具返回状态和人工介入点,同时避免把敏感内容写入日志。

什么时候需要 Agent,什么时候普通工作流更合适

如果步骤固定、条件明确、失败路径有限,普通状态机或任务队列往往更容易测试和运维。Agent 的价值在于需要根据材料选择工具、归纳开放式结果或在有限范围内规划后续步骤。即使引入模型,也可以把它限制在“提出下一步建议”的位置,由确定性控制器验证动作是否允许。

从简单工作流开始,先列出状态、幂等键、失败分类和恢复入口,再判断哪一步需要模型推理。这样可以把模型带来的灵活性放在确实需要灵活性的环节,同时让副作用、权限和完成条件继续保持可验证。

参考

  • OpenAI Agents SDK: Tools:工具超时和失败如何被呈现给模型的一个 SDK 实例。文中的状态、幂等与恢复建议是通用工程分析,不代表该 SDK 自动提供业务级事务保证。
相关项目查看AI 招聘助手的实现与交互