"世界上没有不会翻车的Agent。区别在于——有些翻车了就趴那了,有些翻车了还能自己爬起来继续跑。后者就是我们今天要讲的重试模式。"
为什么Agent需要重试?
AI Agent面对的现实世界充满了不确定性:API限流、网络超时、模型过载、工具返回异常。据统计,一个生产级Agent每天至少会遇到3-5次失败调用。没有重试策略的Agent,就像没有安全带的汽车——跑得再快也没意义。
| 失败类型 | 概率 | 典型原因 |
|---|---|---|
| API限流 (429) | 15% | 请求频率过高 |
| 超时 | 10% | 网络延迟、模型处理慢 |
| 模型过载 (529) | 8% | OpenAI/Anthropic服务繁忙 |
| 格式错误 | 5% | 模型输出不符合预期格式 |
| 工具失败 | 7% | 外部服务不可用 |
六种重试模式
模式1:固定间隔重试(Fixed Interval)
# 最简单的重试——每次间隔相同时间
retry:
strategy: "fixed"
max_attempts: 3
interval: 2000 # 固定2秒间隔
# 适用场景:简单工具调用
# 缺点:可能导致"惊群效应"(多个Agent同时重试)
模式2:指数退避(Exponential Backoff)
# 最推荐的策略——间隔指数增长
retry:
strategy: "exponential"
max_attempts: 5
base_delay: 1000 # 初始1秒
max_delay: 60000 # 最大60秒
multiplier: 2 # 每次翻倍
jitter: true # 添加随机抖动
# 重试时间:1s → 2s → 4s → 8s → 16s
# 抖动后:1.3s → 2.7s → 3.1s → 9.4s → 15.2s
💡 关键:一定要加Jitter(抖动)!否则多个Agent在API恢复后会同时重试,造成新的拥堵。就像红绿灯变绿后,不是所有车同时冲出去,而是有一个自然的启动间隔。
模式3:断路器模式(Circuit Breaker)
# 连续失败到阈值后"断路"——不再尝试
circuit_breaker:
failure_threshold: 5 # 连续失败5次触发断路
recovery_timeout: 30000 # 30秒后尝试恢复
half_open_max: 1 # 半开状态最多允许1个请求
states:
- closed: "正常工作,允许所有请求"
- open: "断路中,直接拒绝(快速失败)"
- half-open: "试探性允许少量请求"
模式4:超时策略(Timeout)
# 不同操作设置不同超时
timeouts:
# 快速操作
tool_call: 10000 # 工具调用10秒
web_search: 15000 # 搜索15秒
# 慢速操作
llm_generation: 60000 # LLM生成60秒
browser_action: 30000 # 浏览器操作30秒
# 超时后的处理
on_timeout:
action: "fallback" # 降级到备选方案
log: true
notify: true
模式5:优雅降级(Graceful Degradation)
# 主方案失败时使用备选方案
fallback_chain:
primary:
model: "gpt-4o"
fallback:
- model: "gpt-4o-mini"
trigger: "rate_limit"
- model: "claude-3.5-sonnet"
trigger: "overloaded"
- model: "local-llama3"
trigger: "all_failed"
# 搜索降级
search_fallback:
primary: "brave_search"
alternatives:
- "duckduckgo"
- "bing_search"
- "local_cache"
模式6:幂等重试(Idempotent Retry)
# 确保重复执行不会产生副作用
idempotency:
enabled: true
key_generator: "request_hash"
cache_ttl: 300 # 5分钟内相同请求返回缓存
# 幂等操作示例
safe_operations:
- web_search # 搜索——查多少次结果一样
- web_fetch # 抓取——内容不变
- read # 读取——文件不变
unsafe_operations:
- write # 写入——重复写入有问题
- message_send # 发消息——重复发送是灾难
- api_post # POST请求——非幂等
⚠️ 红线:发送消息(message)和写入操作(write)绝对不能简单重试!必须使用幂等键或"先查后写"模式避免重复执行。
实战:生产级重试配置
# ~/.openclaw/agents/my-agent/RESILIENCE.yaml
# 全局重试策略
retry:
default:
strategy: "exponential"
max_attempts: 3
base_delay: 1000
jitter: true
# 断路器配置
circuit_breaker:
default:
failure_threshold: 5
recovery_timeout: 30000
# 各工具独立配置
tool_resilience:
llm:
retry: { max_attempts: 5, base_delay: 2000 }
circuit_breaker: { failure_threshold: 3 }
fallback: ["model_b", "model_c"]
web_fetch:
retry: { max_attempts: 3 }
timeout: 15000
cache: true # 缓存成功响应
message:
retry: { max_attempts: 1 } # 消息只重试1次!
idempotency: true
browser:
retry: { max_attempts: 2 }
timeout: 30000
on_failure: "screenshot_and_report"
最佳实践
- 所有外部调用都加重试 - 没有任何API是100%可靠的
- 区分可重试和不可重试 - 429/5xx可重试,400/401/403不可
- 设置全局超时 - 防止单次调用卡住整个Agent
- 记录重试日志 - 追踪哪些工具经常失败
- 定期审查降级策略 - 备选方案本身也可能失效