AI API 故障转移实战:多模型健康检查与高可用自动切换设计指南
为什么 AI API 故障转移是现在绕不过去的问题
调用单一模型厂商 API 的服务,可用性天花板由那家厂商的 SLA 决定。OpenAI 和 Anthropic 的官方承诺通常是 99.9%,折算下来每月允许宕机约 43 分钟。但实际情况更糟——高峰期限流、区域性故障、模型版本灰度导致的响应异常,都不计入官方 incident。
GPT-5.5 在 2026 年初发布后的头几周,503 错误率在部分时段超过 5%;Claude Opus 4.8 的推理延迟在高负载下有时突破 30 秒。对于 ToC 产品来说,这段时间用户看到的是白屏或报错,直接影响留存。
解法不是换一家厂商,而是设计一套 AI API 故障转移层,让请求在多个模型之间自动路由,主模型不健康时无感切换到备用模型,把整体高可用目标推到 99.95% 以上。
健康检查:判断模型是否可用的三个维度
健康检查不是简单 ping 一下端口。对 LLM API 来说,需要同时监控三件事:
1. 连通性(Connectivity)
每隔 10~15 秒发送一个极短的探针请求(如 max_tokens=1 的 "ping" prompt),只看 HTTP 状态码。延迟目标 < 500ms,超时直接标记为 degraded。
2. 错误率(Error Rate)
用滑动窗口统计最近 60 次请求中 5xx 和 429 的比例。阈值建议:
- degraded:错误率 > 10%
- unhealthy:错误率 > 30%
3. P95 延迟(Latency)
统计最近 100 次请求的 P95 响应时间。对话类应用通常设 8 秒为软阈值,流式输出场景关注的是首 token 延迟(TTFT),建议阈值 3 秒。
三个维度独立打分,任意一项触发阈值就降级该模型的权重或将其移出路由池。
from dataclasses import dataclass, field
from collections import deque
import time
@dataclass
class ModelHealth:
model_id: str
error_window: deque = field(default_factory=lambda: deque(maxlen=60))
latency_window: deque = field(default_factory=lambda: deque(maxlen=100))
last_probe: float = 0.0
status: str = "healthy" # healthy | degraded | unhealthy
def record(self, success: bool, latency_ms: float):
self.error_window.append(0 if success else 1)
self.latency_window.append(latency_ms)
self._update_status()
def _update_status(self):
if len(self.error_window) < 10:
return
error_rate = sum(self.error_window) / len(self.error_window)
p95 = sorted(self.latency_window)[int(len(self.latency_window) * 0.95)]
if error_rate > 0.30 or p95 > 8000:
self.status = "unhealthy"
elif error_rate > 0.10 or p95 > 3000:
self.status = "degraded"
else:
self.status = "healthy"
熔断器 + 优先级队列:故障转移的核心逻辑
健康检查给出状态,熔断器(Circuit Breaker)决定路由行为。经典的三态熔断器:
| 状态 | 含义 | 行为 |
|---|---|---|
| Closed | 正常 | 所有请求通过 |
| Open | 故障 | 立即返回错误或转移请求,不再调用该模型 |
| Half-Open | 恢复探测 | 放行少量请求(如 10%)验证模型是否恢复 |
Open 状态的默认持续时间建议 30~60 秒,不要设得太短,否则"抖动"期间会反复触发切换,造成雪崩。
优先级队列定义了模型的使用顺序。一个典型的生产配置:
model_pool:
- id: claude-opus-4.8
priority: 1
weight: 100
capabilities: [reasoning, long_context]
- id: gpt-5.5
priority: 2
weight: 80
capabilities: [reasoning, function_calling]
- id: deepseek-v3
priority: 3
weight: 60
capabilities: [reasoning, coding]
- id: gpt-5.4-mini
priority: 4
weight: 40
capabilities: [fast_response]
role: emergency_fallback
路由器按 priority 从低到高遍历,跳过所有 Open 状态的熔断器,选第一个 Closed 或 Half-Open 的模型。如果请求有 capability 标签(如 long_context),还要过滤掉不支持该能力的模型。
切换发生时,不要默默丢弃原始请求——把它放进重试队列,同时异步通知告警系统。Slack/PagerDuty webhook 一条消息足够,内容包含:触发模型、错误率、切换目标、时间戳。
无感切换的关键细节:上下文保持与成本控制
自动 AI API 故障转移架构还有两个经常被忽视的问题。
上下文格式兼容性
OpenAI、Anthropic、DeepSeek 的消息格式并非完全一致。Claude 系列的 system prompt 位置和 role 字段与 OpenAI 兼容格式有细微差异;工具调用(tool_calling)的 schema 差异更大。切换时需要一个 adapter 层做格式转换,不能裸传原始 payload。
推荐做法是统一用 OpenAI 消息格式作为内部标准,各模型 adapter 负责转换到目标格式。这样路由层保持干净,adapter 可以单独测试。
成本控制
备用模型往往比主模型贵(或在某些情况下反而便宜但质量低)。需要在路由配置里声明每个模型的 cost_tier,当触发 fallback 时:
- 记录哪些请求走了备用模型
- 按自然日统计 fallback token 消耗,设置预算告警(如备用模型单日消耗超过总额 20% 就报警)
一个实用的指标:fallback rate(过去 1 小时内走备用模型的请求比例)。这个数字正常应该 < 1%,超过 5% 说明主模型有持续性问题,需要人工介入而不是依赖自动切换兜底。
生产部署检查清单
把以上设计落地时,几个容易漏掉的点:
- 探针请求要计费:健康检查探针本身会消耗 token,每个模型每分钟 4 次探针,一个月下来几十万 token 不稀奇。用最短的 prompt,
max_tokens设 1。 - 不要在请求链路上做同步健康检查:健康状态应该由后台 goroutine/async task 维护,请求进来时直接读缓存状态,不额外等待。
- Claude Code / Codex / Gemini CLI 的特殊处理:这类编码 CLI 工具通常通过环境变量指定
ANTHROPIC_API_KEY或OPENAI_API_KEY,要在你的代理层暴露兼容端点,让 CLI 工具认为自己在调用官方 API,故障转移对它们完全透明。 - 日志结构化:每条调用日志至少包含
model_id、latency_ms、success、fallback_triggered,方便后期分析哪个模型是故障高发节点。
Kubernetes 环境下建议把这套路由层部署为独立的 sidecar 或专用微服务,水平扩展时健康状态用 Redis 共享,避免每个副本各自维护独立视图导致切换决策不一致。
如果你不想自建这套基础设施,我用的是 XycAi 词元平台。它用一个 OpenAI 兼容端点接入 200+ 模型,Claude Code、Codex、Gemini CLI 都能一键接入,全球 CN2 节点直连延迟低至 5ms,还支持 GPT-5.5 和 Claude Opus 4.8 等官方模型低至官方价 1.4 折。对于中小团队来说,与其花几周自建 failover 层,不如先把模型多样性和低延迟接入的问题交给它,把精力放在业务逻辑上。
一个 API 接入 200+ 全球 AI 模型
GPT · Claude · Gemini 官方模型低至 1.4 折起,持大模型算法备案号,CN2 直连低至 5ms,可开全球合规发票。
立即体验 XycAi →