Agent 的工具调用失败不是异常而是常态:一套重试与降级的工程清单
为什么失败是常态
很多团队把 Agent 的工具调用失败当成异常路径来处理:写一个 try/catch,失败就抛错给用户。但在真实生产环境里,工具调用失败恰恰是主干路径:外部 API 会超时、限流、返回 5xx;数据库会有锁冲突;第三方接口会有幂等性陷阱;连本地文件系统都可能因为权限和并发写入而出错。把失败当异常,系统就会在第一次抖动时把整条任务链路判死刑。
我们在一次多 Agent 数据聚合任务里统计过:单次任务平均发起 40 多次工具调用,其中至少 2 到 3 次会以非 2xx 结束。如果按"失败即中断"的策略,一天下来任务成功率只有七成左右;引入系统化的重试与降级后,同样的失败率下最终任务成功率可以拉到 98% 以上。差距不在模型能力,而在工程兜底。
重试设计的四个要点
第一,区分可重试与不可重试。429、502、503、超时属于可重试;400 参数错误、403 权限问题、404 资源不存在属于不可重试,重试只会放大问题。判断依据应该来自响应码和错误体结构,而不是异常堆栈的字符串匹配。
第二,指数退避加抖动。固定间隔重试在限流场景下会造成重试风暴:所有客户端在同一时刻排队重试,服务端永远缓不过来。正确的做法是指数退避(如 1s、2s、4s、8s)叠加随机抖动,并设置重试上限(一般 3 次以内),超过上限就走降级。
第三,只对幂等操作自动重试。写操作的自动重试可能造成重复下单、重复扣款。凡是带副作用的调用,要么先确认接口幂等(带请求 ID 去重),要么把重试决策交给上层业务人工确认。
第四,重试要透传上下文。常见错误是重试时丢了会话状态或请求 ID,导致服务端把它当成新请求。重试封装应该保证原请求的 headers、幂等键、trace 上下文完整保留,否则链路追踪会把同一次逻辑调用拆成多条孤立记录,排障成本剧增。
降级不是失败,而是另一种交付
重试耗尽后,Agent 不应该直接报错结束,而应按业务影响选择降级策略:返回缓存的上一次成功结果并标注数据时间;切换到备用工具或备用数据源;缩小任务范围,先交付能完成的部分,把失败子任务列入待办;或者把决策权交回给用户,附上已尝试的路径和失败原因。降级方案要在设计期就定义好,而不是故障发生时临场发挥。
观测先行
最后,所有重试与降级必须打点:哪一层重试了几次、最终是重试成功还是降级成功、降级方案被触发的频率。没有这些指标,你既无法评估下游服务的真实健康度,也说不清 Agent 的"成功率"里有多少是兜底撑起来的。工具调用的韧性不是靠运气,而是靠把失败当成一等公民来设计。
- 点赞
- 收藏
- 关注作者
评论(0)