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

取消后迟到的工具结果不能把运行改回成功。队列的 at-least-once 投递也意味着同一调用可能到达多次,call_id 和幂等记录必须参与判断。

本章自测

send_email 超时后能不能重试?不要回答“模型说可以”。你要先问:邮件服务是否支持幂等发送,是否能按业务 ID 查询结果,当前 deadline 是否还允许等待。

下一章:多工具和流式调用怎样不乱?

进入 keel 阅读