给 Agent API 设置可见的重试预算
作者为 Agent 调用的 API 按端点和时间窗口限制重试次数,并加入指数退避、抖动和熔断。实践中,明确返回 Retry-After 和剩余预算,比仅返回 500 更能引导调用方停止密集重试。
AI 深度解读
Agent 调 API 失败后立刻重试,看起来是在努力完成任务,也可能是在放大故障。作者遇到过:下游一次 30 秒的短暂抖动,被连续重试变成了对自家服务的小型拒绝服务攻击。
他的处理办法是给重试设预算,并把等待时间、剩余额度一起告诉调用方。核心判断是:重试会消耗资源,API 不能只告诉 Agent「失败了」,还得说明接下来允许怎么做。这对正在把后端接口封装成 AI 工具的开发者很有参考价值。
为什么一次短暂故障会被重试放大
作者暴露了一批供 Agent 自主调用的 API,反复看到同一种失败模式:下游出现问题,Agent 马上再次发送相同请求,然后继续重试。
单次重试未必有问题,但连续、密集的重复请求会占用服务容量。依赖尚未恢复,新请求又压了上来,原本只持续 30 秒的抖动,反而让自家服务承受额外压力。
作者因此把重试看成资源分配问题。每次尝试都要消耗上游容量、下游服务的承受余量,以及 Agent 自身的上下文窗口。原文没有量化这些成本,但提醒了一个容易遗漏的事实:
重试次数增加,不等于任务成功的机会会等比例增加。
如果失败原因是依赖暂时不可用,立即重复同一操作,很可能只是为同一个错误继续付费。
重试预算怎样让 Agent 知道该停了
作者的方案包含三层控制。
第一层是限制次数:按照「每个 Agent、每个 endpoint、每个时间窗口」分配有上限的重试额度。它控制的是一段时间内允许投入多少次尝试,而不只是某次调用最多循环几遍。
第二层是拉开间隔:使用指数退避(exponential backoff)与随机抖动(jitter)。前者让连续失败后的等待时间逐步增加,后者给等待时间加入随机偏移,避免调用方整齐地同时重试。
第三层是熔断器(circuit breaker):当依赖已经处于异常状态时,直接告诉调用方暂停、稍后再来,减少继续消耗尝试次数的机会。
这些控制还需要配合清楚的反馈。作者观察到,收到明确的 Retry-After 和剩余预算响应头时,Agent 会较平稳地退让;只收到一个裸 500 时,它们反而会更猛烈地重试。他最终把这套机制放进自己运营的服务,让每次失败调用同时返回错误和剩余重试空间。
错误描述当前发生了什么,预算与等待信号则约束下一步怎么行动。
不过,原文没有给出剩余预算响应头的名称,也没有公开额度、时间窗口、退避参数和熔断阈值。这里能借鉴的是设计思路,还不是可以直接照搬的完整协议。
我的判断
我认同把重试当作预算管理。对于供 Agent 调用的工具,只在客户端写一个固定次数的重试循环,很难控制多个调用方叠加后的压力。服务端按照调用身份、接口和时间窗口限制额度,能把资源约束落到具体请求上。
指数退避、随机抖动和熔断也各有用途:它们分别处理重试间隔、请求扎堆和依赖持续异常。单纯提高最大重试次数,解决不了这些问题。
但作者关于 Agent 行为的结论仍属于经验观察。原文没有说明使用了哪些模型、Agent 框架,也没有提供请求量、成功率或加入响应头前后的对照数据。不能据此断言所有 Agent 都会理解并遵守 Retry-After,更不能假设一个自定义预算响应头天然就会被执行。
更稳妥的做法,是让调用端代码明确处理这些信号,服务端继续执行硬性额度限制。模型是否愿意等待,不应成为服务能否承受流量的唯一保障。
能拿来做什么
- 给 Node API 或 AI 工具服务增加重试预算时,可以先按 Agent 身份、endpoint 和时间窗口划分额度,并在失败响应中提供剩余空间。
- 检查现有工具调用代码,找出收到错误后立即重复请求的循环,加入指数退避和随机抖动,并明确处理
Retry-After。 - 用依赖短暂异常的场景验证整条调用链,观察请求是否逐步减少、预算耗尽后是否停止,以及熔断后调用方是否等待,别只验证接口返回了正确的错误码。