Fallback / Retry

降级与重试

主模型超时?降到备选模型;可重试错误?指数退避。

详解

Fallback(降级)与 Retry(重试)是 LLM 调用失败时的两层应对策略。重试针对"短暂性"错误:限流(429)、服务器繁忙(529)、网络抖动——等一会儿通常自己就好了,策略是指数退避(首次等 1s,下次 2s、4s、8s……)加上随机抖动(jitter),防止所有客户端同时重试造成"雪崩"。降级针对"持久性"失败:主模型连续重试仍报错,或延迟已超用户可接受阈值——此时切换到备选模型(如从大模型降到小模型)或备选 API 端点,保证服务不中断。Python 里用 tenacity 库可以用装饰器声明式地配置重试次数、等待策略和重试条件,避免手写大量 try/except 循环。关键原则:只对可恢复错误重试;对 4xx 认证/参数错误直接抛出,不要无谓重试。

一个类比
就像打出租车:叫车失败(重试)先等一分钟再叫,再失败等两分钟,再等四分钟——给司机一点时间接单(指数退避)。如果连续失败五次,就换个打车 App(降级),总比一直在同一个 App 反复点单强。不管走哪条路,目标都是让你到达目的地,而不是堵在叫车页面上。
举个例子
import anthropic
from tenacity import (
    retry, stop_after_attempt,
    wait_exponential_jitter, retry_if_exception_type
)

client = anthropic.Anthropic()

@retry(
    stop=stop_after_attempt(4),
    wait=wait_exponential_jitter(initial=1, max=30),  # 1→2→4→8s + 随机抖动
    retry=retry_if_exception_type(
        (anthropic.RateLimitError, anthropic.InternalServerError)
    ),
)
def call_primary(prompt: str) -> str:
    resp = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=128,
        messages=[{"role": "user", "content": prompt}]
    )
    return resp.content[0].text

def call_with_fallback(prompt: str) -> str:
    try:
        return call_primary(prompt)  # 主模型:带重试
    except Exception:
        # 重试耗尽后降级到小模型
        resp = client.messages.create(
            model="claude-haiku-4-5",
            max_tokens=128,
            messages=[{"role": "user", "content": prompt}]
        )
        return "[降级] " + resp.content[0].text

print(call_with_fallback("用一句话解释指数退避"))
PYTHON 示例
相关概念