Agent 重试前,先判断错误是否可恢复
文章讨论 AI Agent 调用外部 API 失败时,如何按错误类型设计重试与异常处理。盲目立即重试可能放大局部故障并增加 API 开销,编排层应区分不同失败原因。
AI 深度解读
AI Agent 调用外部 API 失败后,最容易加上的补丁就是重试。但原文的核心判断是:不分原因地反复请求,可能把一次短暂故障放大成连锁失败,还会增加 API 和模型调用成本。
作者给出了一套基础处理顺序:先判断错误能否恢复,再用指数退避和随机抖动安排重试,最后用熔断器停止无效调用。它适合拿来检查现有工作流,但文章没有提供代码、实测数据或完整的生产配置。
先判断失败原因,再决定要不要重试
原文首先区分两类错误。
HTTP 400 段错误通常指向请求自身的问题,例如缺少必填参数、JSON schema 不合法、认证 token 过期。请求没有修正,再发送多少次也不会自动变好。作者用一个直观例子说明:同样的错误载荷重试 50 次,只会反复失败、消耗资源并塞满日志。
HTTP 500 段错误或网络超时,则可能来自服务过载、重启或短暂的基础设施故障。这类情况才有等待后重试的理由。
重试应当建立在「故障可能自行恢复」的判断上。
对 Agent 编排层而言,这个区分尤其有用。工具调用失败后,下一步可能是补参数、修正结构、更新凭证,也可能是稍后再试。它们需要不同的处理路径,不能全部塞进同一个重试循环。
不过,原文的分类只是起点,不能直接当成完整的状态码策略,后面还需要结合具体 API 的约定细化。
为什么等得更久,还要等得不一样
遇到暂时性错误,也不能立即连续请求。
原文举例,如果 Agent 每隔 100 毫秒就再发一次请求,会继续给已经吃紧的服务增加压力。指数退避(exponential backoff)的做法是逐步拉长等待时间:第一次重试前等 1 秒,第二次等 2 秒,第三次等 4 秒。
等待给了下游恢复的机会,但固定节奏仍然存在问题。
假设多个工作流同时触发 API 限制,它们又采用同样的退避算法,就可能同时等待、同时重试,再次制造流量尖峰。单个请求已经变慢,整个请求群体却仍然挤在一起。
随机抖动(jitter)解决的是这种同步问题。原本固定等待 2 秒,可以随机变为 2.1 秒或 1.8 秒,让请求分散到不同时间发出。
这里有两个不同作用:指数退避降低持续请求的频率,随机抖动分散并发请求的到达时间。文章解释了原理,但没有给出随机分布、最大等待时间和最大尝试次数,因此还不能直接照着配置上线。
熔断器负责承认「现在继续试没有用」
退避和抖动只能调整请求节奏,无法修好已经停机的服务,也不能让被撤销的 API key 恢复有效。
熔断器(circuit breaker)的任务,是在失败持续发生时暂停调用。原文描述的机制是:按工具或 API 端点监测失败情况,如果短时间内失败达到设定次数,就进入打开状态。打开期间,工作流停止调用这个工具,转向备用流程,或者通知人工处理。
它与重试处理的是不同层面的问题。重试决定某次失败后何时再尝试;熔断则让后续执行也避开已经持续失败的依赖。
对多步骤工作流,这能减少无效等待和费用,让其他可执行路径继续运行。但原文没有说明熔断后何时恢复、如何试探服务是否恢复,也没有给出阈值。作者讲清了停止条件的作用,恢复策略仍需另外设计。
我的判断
这套顺序是合理的:先分类,再安排重试,持续失败时停止调用。它提醒开发者把故障处理放进编排设计,而不是出错后只加一个循环。
但状态码不能机械二分。例如 HTTP 429 属于 400 段,却通常需要按限流规则等待;认证过期可能需要先刷新凭证。这是对原文分类的补充,原文没有展开这些例外。
网络超时也不等于操作没有成功。对于会产生副作用的工具调用,还得确认重复执行是否安全。原文没有讨论幂等性,直接重试可能重复提交同一项操作。
与固定间隔重试相比,退避加抖动的机制解释更充分;至于实际能节省多少费用、改善多少成功率,作者没有对照数据,不能替它补上效果承诺。文章更适合作为设计检查表,具体参数仍要依据服务约定和运行记录确定。
能拿来做什么
- 在 Node 工具调用层区分参数错误、认证错误、限流和暂时性服务故障,让每类错误进入明确的处理路径。
- 为适合重试的外部 API 配置指数退避和随机抖动,并补齐原文未给出的最大尝试次数与最大等待时间,避免工作流无限等待。
- 为反复失败的工具设置熔断后的备用路径,例如返回可处理的失败结果,或转入人工处理,同时明确恢复调用的条件。
- 检查 AI 编程工作流中的工具是否会产生副作用,对超时后的重试先确认重复执行是否安全。