AI Agent 工具超时:用业务状态选择重试、补偿与回滚
2026/9/2 17:48:16 网站建设 项目流程

工具超时最危险的误判,是把“没收到结果”当成“没有执行”。对会扣费、建单或发消息的 Agent,这个误判可能直接制造第二次业务动作。

OpenAI Agents SDK 0.20.0 的官方变更说明写明:重试策略可以读取稳定的重放安全信息,并显式决定是否批准一次不安全重放;这种批准仍可能重复提供方一侧的工作。

这看似是一个 SDK 更新,背后却是所有工具型 Agent 都绕不过去的问题:超时不等于没执行,失败也不等于可以再来一次。

一个只生成文字的 Agent 答错了,人可以忽略。一个会调用工具的 Agent 如果重复扣费、重复建单或重复发消息,恢复动作本身就可能制造第二次事故。

所以,工具调用失败以后,第一反应不该是“重试几次”,而应该是:上一次到底有没有生效?

先判断状态,再选择恢复动作

把失败分成四种状态,处理会清楚很多:

  • 明确未执行:满足幂等和次数限制时,可以考虑重试;
  • 结果未知:先查询状态或对账,不能直接假设失败;
  • 已经错误生效:执行批准的补偿,或者交给人处理;
  • 新版本持续制造错误:停止相关动作并回滚版本,同时处理已经产生的业务后果。

这也是“安全重放”四个字的重要性。模型请求、工具请求、业务动作并不是同一层。即使 SDK 能判断一次模型调用是否适合重放,也不代表本地工具已经产生的副作用可以自动再做一遍。

重试解决“这一次没完成”

重试适合短暂超时、网络中断、上游暂时不可用等情况。但只有再次执行不会产生重复业务后果时,它才安全。

假设 Agent 提交创建工单请求。第一次请求超时,不代表工单没有创建;它也可能已经成功,只是响应没有回来。如果系统看见超时就再发一次,最终会出现两张工单。

重试之前至少回答三个问题:

  1. 同一业务请求有没有稳定的幂等标识?
  2. 上游能不能查询第一次请求的状态?
  3. 再次提交时会返回原结果,还是重新执行?

权限错误、参数不合法、业务规则拒绝,通常也不会因为多试一次自动变好。把所有错误放进同一个循环,只会拖慢人工接管,并让日志充满重复噪声。

把评审问题落成可检查材料时,可以先对照生产就绪检查项逐项写清数据、工具、验收和人工接管,再决定是否扩大动作范围。

补偿解决“已经生效,但要抵消后果”

有些动作发生以后,无法把时间倒回去,但可以用另一笔业务动作抵消结果。这就是补偿。

例如,错误工单可以再创建关闭记录;已经占用的名额可以释放;错误预留的库存可以解除。补偿不是删除历史,而是在审计链里明确写入一笔反向动作。

补偿路径必须和主动作一起设计。只有“成功接口”、没有“撤销或对冲接口”的工具,不适合被 Agent 直接调用。

即使存在补偿,也要写清谁批准、补偿失败由谁接、原动作和补偿动作如何关联。退款、撤销对外承诺、恢复删除数据,可能需要更高权限,甚至根本无法完全恢复。

回滚解决“版本或系统状态整体退回”

回滚通常针对部署版本、配置或可恢复的系统状态。例如一版新规则持续造成误判,可以切回上一版;一组配置漂移,可以恢复到已验证快照。

它和补偿的区别在于:回滚让系统整体回到已知状态,补偿处理已经发生的具体业务后果。

代码版本回去了,不代表错误创建的工单自动消失;那部分仍然要逐项补偿或人工处理。

上线方案如果只写“支持回滚”,还不够。还要演练回滚需要多久、哪些数据不会随版本恢复、回滚以后如何确认服务真的回到安全状态。

一张失败表,比统一写“自动重试”更有用

为每个工具动作补一张失败表,至少写四项:失败信号、是否可能已生效、恢复动作、人工接管点。

举个最小版本:

  • 网络超时:状态未知 → 先查单,不直接重试;
  • 参数错误:明确未执行 → 修正参数或转人工,不循环重试;
  • 重复结果:已经生效 → 阻断后续动作,进入补偿;
  • 新版本异常率持续升高:系统性问题 → 停止动作、回滚版本、核对已产生后果。

有人会担心,这么设计会把一个简单工具调用变复杂。确实会。Agent 从“建议”走到“执行”,复杂度本来就不只多一个 API。它同时接手了重复动作风险、业务补偿和审计责任。

更合理的起点,是把自动执行限制在低风险、可查询、可补偿的动作上。对于不可逆或责任重大的动作,让 Agent 准备参数、让人确认提交,往往已经能省掉大量操作成本。

可直接带进评审的材料

观察到的状态先做什么禁止动作
明确未执行核对幂等后重试无限制循环
结果未知查询状态或对账直接再次提交
错误已生效执行批准的补偿删除审计历史
系统性异常停止动作并回滚版本只回滚代码不核对后果

恢复逻辑要消费业务状态,而不是直接消费 HTTP 错误。下面是一个最小状态机示例:

typeOutcome="not_executed"|"unknown"|"wrong_effect"|"systemic";functionrecovery(outcome:Outcome){switch(outcome){case"not_executed":return"retry_with_idempotency_key";case"unknown":return"query_upstream_state";case"wrong_effect":return"approved_compensation";case"systemic":return"stop_then_rollback_and_reconcile";}}

这里的关键不是switch,而是Outcome从哪里来。调用记录要保存稳定的业务请求标识、上游返回标识和后续查询结果;只有传输层的 timeout,无法证明业务层是not_executed

工具适配层应该把传输错误和业务状态分开记录。HTTP 超时只是一条传输信号,不能直接映射成“业务未执行”。调用记录至少要保存稳定的业务请求标识、工具名、参数摘要、开始与结束状态、上游返回标识,以及后续查询或补偿动作。

状态查询接口和写接口同样重要。若上游无法按业务请求标识查询结果,自动重试就很难证明安全;若补偿动作不能关联原动作,审计时也无法确认后果是否已经抵消。对于这类工具,更稳妥的权限是让 Agent 准备参数,由人确认提交。

回滚也要拆成版本回滚和业务后果处理。切回旧版本只能阻止继续产生同类错误,已经创建的工单、已经发送的消息或已经改变的状态仍需要逐项查询、补偿或人工接管。

工具放行前,先证明失败能被识别、状态能被查询、后果能被补偿;做不到的动作应停在建议或人工确认层。

官方文档核对:OpenAI Agents SDK 0.20.0 官方变更说明。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询