环境检查

  • 已有至少 2 个可调用 channel(官方 + 中转 / 多家中转 / 多 provider)
  • Python / Node.js 项目,能改后端代码
  • 决定监控存储方案(Postgres / TimescaleDB / Datadog 任选)

失败判定规则(共用)

TRIGGER_FALLBACK = {
    "http_429": True,        # 限速,等 Retry-After 再 fallback
    "http_5xx": True,        # 服务端错误立即 fallback
    "timeout_connect": True, # 连不上立即 fallback
    "timeout_read": True,    # 30s 没首字节 fallback
    "moderation_block": True,# 内容被审核拒绝可考虑 fallback
    "json_parse_fail": True, # 返回格式错误
    "stream_stall_secs": 60, # streaming 中 60s 没新数据
}

方案 A:应用层 try/catch(最简单)

import anthropic, openai
from anthropic import RateLimitError, APITimeoutError, APIStatusError

def chat_with_fallback(messages):
    try:
        return anthropic.Anthropic().messages.create(
            model="claude-3-5-sonnet-20241022",
            max_tokens=1024, messages=messages,
        )
    except (RateLimitError, APITimeoutError, APIStatusError) as e:
        log_fallback("anthropic", str(e))
        return openai.OpenAI().chat.completions.create(
            model="gpt-4o", messages=messages,
        )

50 行代码。适合 1-2 个 channel + PoC 阶段。

方案 B:LiteLLM Router(推荐)

from litellm import Router

router = Router(
    model_list=[
        {
            "model_name": "chat-main",
            "litellm_params": {
                "model": "anthropic/claude-3-5-sonnet-20241022",
                "api_key": "sk-ant-...",
            },
        },
        {
            "model_name": "chat-main",
            "litellm_params": {
                "model": "openai/gpt-4o",
                "api_key": "sk-...",
            },
        },
        {
            "model_name": "chat-main",
            "litellm_params": {
                "model": "openrouter/anthropic/claude-3-5-sonnet",
                "api_key": "sk-or-v1-...",
            },
        },
    ],
    fallbacks=[{"chat-main": ["chat-main"]}],  # 同名 group 内 fallback
    cooldown_time=30,                          # 失败 channel cool 30s
    num_retries=2,                             # 每个 channel 重试 2 次
)

resp = router.completion(model="chat-main", messages=[...])

20 行配置 + 多 channel 自动权重 + cool-down + retry。生产推荐。

方案 C:OpenRouter models 参数(最快上手)

client.chat.completions.create(
    model="anthropic/claude-3-5-sonnet",
    extra_body={
        "models": [
            "anthropic/claude-3-5-sonnet",
            "openai/gpt-4o",
            "google/gemini-2.5-flash",
        ],
    },
    messages=[...],
)

零代码改动,OpenRouter 服务端做 fallback。缺点:所有 channel 都在 OpenRouter 内,OpenRouter 自身挂了全挂。

方案 D:OneAPI 渠道权重(团队场景)

OneAPI 控制台 → 渠道 → 添加多个 channel → 设置权重与优先级。OneAPI 自动按权重轮询 + 失败时跳过。

主路 channel A:anthropic 官方,权重 5,优先级 high
备路 channel B:openrouter,权重 3,优先级 mid
兜底 channel C:中转 X,权重 2,优先级 low

适合 5+ 人团队 + 集中管理需求。

监控埋点

def log_fallback(channel_failed, reason):
    db.execute(
        "INSERT INTO llm_fallback_log (ts, channel, reason) VALUES (NOW(), %s, %s)",
        (channel_failed, reason),
    )

def log_call(channel, model, latency_ms, status):
    db.execute(
        "INSERT INTO llm_call_log (ts, channel, model, latency_ms, status) VALUES (NOW(), %s, %s, %s, %s)",
        (channel, model, latency_ms, status),
    )

每 5 分钟跑一次:

SELECT channel,
       COUNT(*) FILTER (WHERE status='success') * 1.0 / COUNT(*) AS success_rate
FROM llm_call_log
WHERE ts > NOW() - INTERVAL '5 min'
GROUP BY channel;

成功率 < 95% 的 channel 触发告警。

常见失败原因

  • 没设 cooldown:主线 429 后立刻又被打挂
  • fallback 链太长:5 级 fallback 用户等 30 秒,体验更糟
  • 不同 provider prompt 格式差异:fallback 后输出质量差
  • 监控不埋:fallback 经常触发但没人知道

安全设置

  • 每个 channel 的 key 单独存
  • fallback 链路加 request_id 透传方便排查
  • 设置月级 fallback 触发上限(超过表示主路有大问题,告警)

跨地区访问

国内访问境外多个 provider 都需要稳定网络。考虑把免外卡的 LLM API 中转线路配进 LiteLLM Router 作为最后一级 fallback,主线官方 + 备线官方都被墙时仍能服务用户。

运维备忘

Fallback 链路稳定运行后,建议记下三样东西:当前主备 channel 的配置、最近一次 fallback 触发的原因和次数、下个月要轮换的 key。多人协作时把负责人和后台入口写进一张共享表格,换人或换中转方时不会断掉保护链路。

LLM fallback 路由的落地条件

LLM fallback 路由最怕把法律主体、收款工具和产品代码混成一个问题。动手前看清现金流、工具栈和入口位置,金额较大或涉及税务时应交给专业顾问处理。

一个人运营时可以用表格压住复杂度:负责人、后台入口、到期日、费用来源和回滚动作各占一列,避免换服务商时才发现资料缺口。

涉及 Stripe、公司注册、税表或签证的内容,只能作为操作参考。当前页面没有覆盖你所在司法辖区的特殊规定时,不应把它当成法律或税务意见。

项目看什么不宜继续的信号
现金流当前后台、日志或设置页里能直接看到的字段页面提示和手头资料对不上
工具栈费用、权限、地区或设备造成的实际影响已经影响付款、审核、生产环境或家庭使用
入口位置回退入口、旧配置、官方支持材料找不到回滚方式,或责任人无法确认

相关阅读