演示时一切顺利的 Agent,一上线就状况百出:接口超时、模型服务限流、工具返回意外格式、网络抖动。这一篇讲如何让 Agent 在出错时依然可靠运行。
一、Agent 中的错误来源
| 来源 | 举例 |
|---|---|
| 模型 API | 限流、服务过载、请求超时、网络中断 |
| 工具执行 | 下游接口超时、数据库连接失败、参数错误、权限不足 |
| 模型输出 | 输出格式错误、调用了不存在的工具、参数不合法 |
| 任务层面 | 陷入死循环、超出预算、长时间没有进展 |
不同来源的错误,处理方式不同。
二、工具错误:交给模型处理
第 05 篇提过:工具出错时,把错误作为工具结果返回给模型,而不是让程序崩溃。模型看到错误后,往往能自己调整:
- 参数错了,换个参数重试;
- 某个数据源不可用,换一个数据源;
- 实在解决不了,告诉用户哪一步失败了、为什么。
前提是错误信息要写得好:
| 差 | 好 |
|---|---|
| Error 500 | 订单服务暂时不可用(连接超时),已自动重试 3 次仍失败。可以稍后再试,或改用 query_orders_cache 查询缓存数据(可能延迟 10 分钟)。 |
| Invalid input | 参数 start 格式错误:收到 “昨天”,需要 YYYY-MM-DD HH:MM 格式。 |
不要把完整的异常堆栈返回给模型,它占用大量上下文,对模型也没什么帮助。
三、重试策略
1. 先区分能不能重试
| 可以重试 | 不应重试 |
|---|---|
| 超时、网络中断 | 参数错误 |
| 限流(HTTP 429) | 权限不足(HTTP 401、403) |
| 服务暂时不可用(HTTP 502、503) | 资源不存在(HTTP 404) |
对不可重试的错误反复重试,只会浪费时间,甚至触发对方的封禁。这类错误应该直接返回给模型,让它换个思路。
2. 指数退避
重试时不要立刻重发,等待时间逐次加倍:1 秒、2 秒、4 秒、8 秒……并加上一点随机抖动,避免大量请求在同一时刻一起重试。
import random, time
def call_with_retry(fn, max_retries=4, base=1.0):
for attempt in range(max_retries + 1):
try:
return fn()
except RetryableError:
if attempt == max_retries:
raise
wait = base * (2 ** attempt) + random.uniform(0, 0.5)
time.sleep(wait)
如果对方返回了建议的等待时间(比如 Retry-After 头),优先按它等待。
3. 分层重试,避免叠加
注意不要在多个层面同时重试。如果 HTTP 客户端重试 3 次、工具函数重试 3 次、模型又决定重新调用 3 次,最坏情况下一个请求会被发送 27 次。约定好由哪一层负责重试。
四、幂等:重试的前提
查询类操作重试多少次都没关系。但有副作用的操作,比如发送通知、创建订单、扣款,如果第一次其实已经成功、只是响应丢了,重试就会造成重复执行。
解决方法是让操作幂等:同一个操作执行多次,效果和执行一次一样。常用做法:
- 幂等键:每个操作生成唯一 ID,执行前检查这个 ID 是否已经处理过;
- 先查后做:发送通知前先检查是否已发送;
- 设计成「设置状态」而不是「增量变化」:「把库存设为 100」可以安全重复,「库存加 10」不行。
五、超时
- 单次工具调用超时:每个工具设置合理的超时时间,查询类几秒到几十秒,超时就作为错误返回给模型。
- 单次模型调用超时:模型生成长内容时可能比较慢,超时时间要留够,或者使用流式输出。
- 整个任务超时:一个任务总共允许运行多久。到时间后让模型基于已有信息做总结,而不是直接中断。
六、熔断与降级
如果某个下游服务已经持续失败,继续调用只是浪费时间,还可能加重对方的负担。熔断的做法是:
- 统计某个工具最近的失败率;
- 失败率超过阈值时,暂时停止调用,直接返回「服务暂不可用」;
- 过一段时间后,放少量请求试探,恢复正常再重新开放。
降级则是准备备选方案:实时数据查不到就用缓存数据,主模型不可用就切换到备用模型,自动处理失败就转人工。降级时要明确告诉用户结果的局限,比如「以下数据来自 10 分钟前的缓存」。
七、任务层面的保护
第 04 篇讲过的保护机制,在这里再强调一次:
- 最大步数、最大 token、最大费用;
- 重复调用检测,识别死循环;
- 长时间无进展检测:连续多步没有获得新信息,提醒模型换思路或结束任务;
- 任务中断时保存状态,支持从中断处恢复,而不是从头再来。
本篇小结
- 工具错误作为结果回填给模型,错误信息要具体、能指导下一步。
- 区分可重试与不可重试错误,使用指数退避加随机抖动,避免多层重试叠加。
- 有副作用的操作必须幂等,重试才安全。
- 设置工具、模型调用、整体任务三级超时。
- 持续失败时熔断,准备降级方案并告知用户。
思考与练习
- 一个「发送告警通知」的工具,重试时如何避免用户收到重复通知?
- 你的 Agent 依赖的每个外部服务,如果宕机了,降级方案分别是什么?
上一篇:AI Agent原理篇16:Agent 间通信:A2A 等协议
下一篇:AI Agent原理篇18:安全:Prompt 注入、权限边界与人在回路
返回系列总目录