🔄 Agent Retry Patterns

失败是正常的,怎么优雅地失败才是技术

"世界上没有不会翻车的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"

最佳实践

  1. 所有外部调用都加重试 - 没有任何API是100%可靠的
  2. 区分可重试和不可重试 - 429/5xx可重试,400/401/403不可
  3. 设置全局超时 - 防止单次调用卡住整个Agent
  4. 记录重试日志 - 追踪哪些工具经常失败
  5. 定期审查降级策略 - 备选方案本身也可能失效

相关资源