AI Agent 工具调用为什么要幂等?防止重复下单、重复发信的设计方法
幂等的意思是:同一个操作执行一次和执行多次,结果一样。 对 Agent 来说这很重要,因为网络超时、框架自动重试、模型在下一轮又决定「再调用一次」都很常见。只要工具会产生外部影响(下单、扣款、发消息、创建工单),就应该设计成幂等,或者在调用前检查是否已经做过。
重复调用是怎么发生的
- 超时重试:工具其实执行成功了,但响应没及时返回,框架或模型又调一次。
- 模型重复决策:上下文很长时,模型没注意到上一步已经完成。
- 流程中断后恢复:Agent 从中间步骤重新开始,前面的步骤又跑了一遍。
- 多个 Agent 并行:两个子任务都认为自己该发通知。
哪些工具需要幂等
| 类型 | 例子 | 是否需要 |
|---|---|---|
| 只读 | 查询订单、搜索文档 | 天然幂等,不需要特别处理 |
| 覆盖写 | 把状态设为“已完成” | 通常天然幂等 |
| 追加写 | 创建订单、发送邮件、新增记录 | 必须处理 |
| 涉及金额 | 退款、付款 | 必须处理,并加人工确认 |
方法一:幂等键
每次「业务意图」生成一个唯一的键,工具执行前检查这个键是否已经处理过。
- 键由业务内容决定,而不是每次调用随机生成。例如「给工单 1023 发送关闭通知」可以用
close-notice:1023作为键。 - 工具端保存已处理的键和结果;再次收到同一个键时,直接返回上次的结果,不再执行。
- 很多支付和消息服务的 API 本身支持幂等键参数,具体以服务商文档为准。
方法二:执行前检查状态
不方便用幂等键时,在工具内部先查再做:
- 发邮件前查「这个工单是否已发过关闭通知」。
- 创建记录前查「同一来源 ID 的记录是否已存在」。
注意并发:两个调用同时检查、同时发现「没做过」,仍会重复。需要数据库唯一约束或锁来兜底。
方法三:拆成“准备”和“确认”两步
对高风险操作,Agent 先调用「准备」工具生成草稿(比如退款申请),由人或规则确认后再调用「执行」。草稿可以重复生成,执行只发生一次。
在提示词里配合
工具设计是根本,提示词可以减少重复决策:
调用任何会产生外部影响的工具(发送、创建、付款)之前,先检查对话记录和工具返回结果中
是否已经有同一操作的成功记录。如果有,不要再次调用,直接引用之前的结果。
如果工具返回超时或不确定是否成功,先调用查询工具确认状态,不要直接重试。
怎么测试
- 模拟超时:让工具执行成功但延迟返回,看 Agent 是否重试,以及重试后是否产生重复结果。
- 重放:把同一段工具调用序列重复执行两遍,检查外部系统里的记录数。
- 恢复测试:在流程中间中断,再从头运行,确认前面的步骤没有重复产生影响。
常见坑
- 幂等键每次随机生成,等于没有。
- 只在 Agent 层做检查,工具本身没保护,换个调用方就失效。
- 重试没有上限,失败时无限循环。
相关阅读:Function Calling 入门、Agent 重试预算 SOP,也可以看看 Agent 常见失败模式。