KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
06. 工具失败时为什么不能急着重试? — keel 龙骨
最危险的失败是结果未知:请求已经发出,但客户端没有收到响应。创建工单可能已经成功,立刻重试会产生第二张工单。
最危险的失败是结果未知:请求已经发出,但客户端没有收到响应。创建工单可能已经成功,立刻重试会产生第二张工单。
先按恢复动作分类
unknown_tool -> 拒绝
invalid_arguments -> 受控错误,可有限修正
business_error -> 告知用户或补充输入
policy_denied -> 终止,不绕过权限
tool_unavailable -> 按策略退避重试
tool_timeout -> 先查询副作用是否发生
outcome_unknown -> 查询状态或人工确认
错误分类是恢复策略的输入,不是日志里的装饰词。
Effect 决定重试风险
| Effect | 默认策略 |
|---|---|
| read | 暂时性错误可有限重试 |
| write | 需要幂等键或确认未生效 |
| external | 默认不自动重试,先查状态/审批 |
幂等保护业务效果
idempotency_key = tenant + tool + stable_business_request_id
服务端需要持久化 key、参数摘要和第一次结果。相同 key 配不同参数必须冲突,不能悄悄复用旧结果。
运行确定性实验
python courses/foundation/tool-calling/course/project/examples/04_idempotency.py
同一个 key 调用两次创建工单,第二次应该得到第一次的结果;同一个 key 换标题,应该得到参数冲突。这个实验不需要真实模型,因为幂等是业务和执行器的责任。
Timeout、Deadline、Cancellation
- Timeout:一次工具最多等待多久;
- Deadline:整次 Agent 运行最晚结束时间;
- Cancellation:用户或系统主动停止。
取消后迟到的工具结果不能把运行改回成功。队列的 at-least-once 投递也意味着同一调用可能到达多次,call_id 和幂等记录必须参与判断。
本章自测
send_email 超时后能不能重试?不要回答“模型说可以”。你要先问:邮件服务是否支持幂等发送,是否能按业务 ID 查询结果,当前 deadline 是否还允许等待。