海外模型不可用时的国产兜底方案
海外大模型受制于跨境链路质量,出现超时、限流或服务中断时,如果没有兜底方案,整个依赖该模型的功能会直接不可用。国产模型兜底是生产级接入海外模型必须考虑的高可用设计。
为什么需要兜底方案
海外模型在国内使用时面临两类可用性风险:
- 网络层故障:跨境链路抖动、丢包,导致请求超时或连接失败
- 服务层故障:海外模型服务商自身的故障、计划维护、区域性中断
这两类问题的发生概率远高于国内 API 服务,且难以通过重试完全规避。对于 ToC 产品或关键业务流程,设计兜底逻辑是负责任的工程实践。
我见过最典型的一次事故是这样的:某天凌晨海外某模型服务商所在区域的骨干网出问题,国内到海外的请求成功率掉到不到一半,但没掉到 0——这是最麻烦的情况。如果服务全挂了,监控一眼能看出来;可它只是”偶尔超时、偶尔正常”,重试几次总能碰上一次成功,于是表面看起来”还活着”,实际上用户那边的平均响应时间已经从 2 秒涨到了 25 秒,客服工单量翻了三倍才被人发现。这种”半死不活”的状态,比彻底宕机更容易被漏掉,也正是兜底方案要重点覆盖的场景——你不能靠”服务是否完全不可用”来判断要不要切换,得靠超时率和错误率的滑动窗口统计。
再举一个真实会遇到的报错:Python 的 anthropic SDK 在跨境网络抖动时,抛出的往往不是超时异常,而是 anthropic.APIConnectionError: Connection error.,根因是 TCP 握手或 TLS 握手阶段就失败了,连请求都没发出去;而如果是海外那边限流,你会看到 anthropic.RateLimitError: Error code: 429,这种情况恰恰不该马上切兜底,应该先按官方建议的退避策略重试。搞混这两类错误,是很多团队兜底逻辑上线后依然”偶发卡死”的根源——把该重试的当成该切换的,或者反过来,都会让系统行为跟预期不符。
兜底架构选择
方案一:客户端熔断 + 自动切换
在业务代码层实现:主路调用海外模型,超时或错误达到阈值后触发熔断,自动切换至国产模型。
import anthropic
from openai import OpenAI # 以 OpenAI 兼容格式的国产模型为例
OVERSEAS_TIMEOUT = 30 # 秒
FALLBACK_MODEL = "deepseek-chat" # 国产兜底模型
def call_with_fallback(prompt: str) -> str:
# 主路:Claude
try:
client = anthropic.Anthropic()
resp = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[{"role": "user", "content": prompt}],
timeout=OVERSEAS_TIMEOUT,
)
return resp.content[0].text
except Exception as e:
print(f"海外模型失败,切换国产兜底: {e}")
# 兜底:国产模型(OpenAI 兼容格式)
fallback_client = OpenAI(
api_key="your-domestic-key",
base_url="https://api.deepseek.com/v1",
)
resp = fallback_client.chat.completions.create(
model=FALLBACK_MODEL,
messages=[{"role": "user", "content": prompt}],
)
return resp.choices[0].message.content
上面这段代码看着简单,但有三个容易踩的坑,值得展开说说。
第一,timeout=OVERSEAS_TIMEOUT 这个参数一定要显式传,不要用 SDK 默认值。anthropic SDK 的默认超时通常是几分钟级别,如果你不设置,遇到网络抖动时请求会一直挂着不返回,用户前端转圈转到天荒地老,比直接报错体验还差。30 秒是一个折中值:太短(比如 5 秒)会把海外模型正常的长回复也误判为超时;太长(比如 60 秒)又会让用户等太久才切到兜底。具体数值要结合你自己接口的 P95 响应时间来定,一般设成正常响应时间的 3~5 倍比较稳妥。
第二,except Exception as e 这种写法在生产代码里其实偷了懒——它会把所有异常都当成”该切兜底”,包括你自己代码里的 bug(比如 prompt 拼接时的 TypeError)。更严谨的做法是只捕获网络类和服务端类异常,比如 anthropic.APIConnectionError、anthropic.APITimeoutError、anthropic.InternalServerError,让业务逻辑错误正常抛出并被日志系统捕获,而不是被兜底逻辑悄悄吞掉。吞掉自己的 bug 是最难排查的一类线上问题,因为表面上”服务正常”(用户拿到了兜底模型的回复),实际上主路模型可能一直在因为你的代码问题而失败。
第三,这个函数里的 fallback 客户端每次调用都新建了一个 OpenAI(...) 实例,高并发场景下建议把它做成模块级单例(放在函数外初始化一次),避免重复创建连接池带来的额外开销。
优点:逻辑简单,不依赖外部组件,适合团队规模小、接入模型数量少(1~2 个)的早期阶段。
缺点:每个服务都需要重复实现这套 try/except 逻辑,熔断状态不跨实例共享——如果你有 10 个 Pod 在跑,每个 Pod 都要自己摸索一遍”海外模型是不是又挂了”,没法共享判断结果,也容易出现有的 Pod 已经切换、有的还在傻等的不一致状态。
方案二:API 网关层故障切换(推荐生产环境)
在 API 网关(如 LiteLLM、One API、合规聚合平台)层配置主备路由,业务代码无感知。
# LiteLLM 配置示例
model_list:
- model_name: chat # 统一对外暴露的模型名
litellm_params:
model: anthropic/claude-sonnet-4-5
timeout: 30
- model_name: chat # 同名第二条,自动作为 fallback
litellm_params:
model: openai/deepseek-chat
api_base: https://api.deepseek.com/v1
api_key: your-domestic-key
router_settings:
routing_strategy: latency-based-routing
enable_pre_call_checks: true
这段 YAML 里有两个配置项经常被人直接抄走却不理解含义,简单拆一下。routing_strategy: latency-based-routing 的意思是:当同名的 chat 有多条路由时,网关会按最近一段时间各路由的实际响应延迟动态调整流量分配,而不是固定顺序”先试第一条,挂了再试第二条”。这对兜底场景其实是把双刃剑——如果海外模型只是”变慢了”但没有完全挂,网关可能会自动把一部分流量导向国产模型,你不需要等它彻底超时;但如果你的诉求是”只有主路完全失败才切换,绝不主动分流”,就得改成 simple-shuffle 或显式设置 fallbacks 字段,而不是用延迟路由。enable_pre_call_checks: true 则是让网关在真正发起请求前先做一次轻量校验(比如上下文长度是否超限、模型是否处于已知不可用状态),提前失败比等请求打过去再超时要省时间,尤其是海外模型这种单程网络延迟就有一两百毫秒的场景。
优点:业务代码不感知切换逻辑,熔断状态集中管理在网关里,支持更复杂的路由策略(延迟路由、权重路由、按错误码分类处理),新增模型或调整兜底顺序只改配置不改代码。
缺点:引入网关组件,需要你自己维护网关本身的高可用(网关挂了,主备模型再稳也没用),团队里得有人熟悉网关的运维和排障。
两种方案怎么选,我一般按团队和接入规模给建议:
| 维度 | 客户端熔断(方案一) | API 网关(方案二) |
|---|---|---|
| 接入模型数量 | 1~2 个,逻辑简单 | 3 个以上,或未来会持续增加 |
| 团队规模 | 1~3 人小团队,快速验证阶段 | 有专职后端/运维,能维护网关 |
| 多实例部署 | 熔断状态不共享,各实例各判断 | 状态集中,行为一致 |
| 改动成本 | 改代码、发版 | 改配置、热更新 |
| 适合阶段 | MVP、早期验证 | 生产环境、多模型矩阵 |
简单说:如果你现在只接了 Claude 一个海外模型加一个国产兜底,方案一半天就能上线,没必要为了”架构好看”上网关组件;但只要你的模型矩阵超过 3 个,或者预期未来会持续扩展,网关层的配置化管理会在半年后帮你省下大量重复劳动。
详见 API 网关故障切换配置。
国产兜底模型选型(截至 2026-06,以官方为准)
| 模型 | 适合兜底的场景 | OpenAI 兼容格式 |
|---|---|---|
| DeepSeek(deepseek-chat) | 代码生成、通用问答、长文档 | 是 |
| Qwen(通义千问) | 中文内容、多轮对话 | 是 |
| 文心一言(ERNIE) | 中文业务场景、百度生态内 | 是(部分版本) |
| 月之暗面(Kimi) | 长上下文场景兜底 | 是 |
具体模型能力对比见 国产模型横向对比。
关键设计原则
- 超时要短,不要无限等待:海外模型超时建议设 15–30 秒,不要等到连接自然超时(可能 120 秒+)。判断标准很直接:拿你线上最近一周的正常响应时间做个 P95 统计,超时阈值设成这个数字的 3 倍左右,既不会误伤慢响应的正常请求,也不会让用户干等太久。
- 区分错误类型:
429 Rate Limit应重试(配合指数退避,比如首次等 1 秒,失败再等 2 秒、4 秒,最多重试 3 次),5xx或网络超时才触发兜底切换。把这两类混在一起处理,最常见的后果是:明明只是短暂限流,稍等一下就能正常调用,却被直接切到了国产模型,白白浪费了海外模型这次调用的额度和你为它付的费用。 - 熔断要有恢复探测:切换到国产模型后,定期(如 60 秒)发一个探测请求测试海外模型是否恢复,而非永久切换。这里有个实践细节:探测请求最好用一个极短的 prompt(比如”你好”),而不是真实业务请求,一是省成本,二是避免探测请求本身因为超长上下文又触发一次误判。
- 记录切换日志:每次切换都应记录原因(超时/限流/连接失败/5xx)、时间、切换前后的模型名,便于监控海外模型的可用率,也便于月底核算”这个月因为兜底多花了多少国产模型的调用费”。
- 国产模型也要有备份:国产模型的账期、配额管理同样重要,不能成为单点。见过团队把国产模型当”永远不会挂”的兜底,结果国产模型自己也遇到限流,两条腿一起瘸——建议至少准备两家国产模型互为备份,或者在网关里配成一个 fallback 链而不是单一目标。
进阶:异步/并发场景下怎么做兜底
如果你的服务是用 asyncio 或者要处理高并发请求,同步版本的 try/except 会阻塞事件循环,这时候该用 asyncio.wait_for 包一层超时控制,逻辑和同步版本一致,但不会卡住其他协程:
import asyncio
import anthropic
async def call_with_fallback_async(prompt: str) -> str:
client = anthropic.AsyncAnthropic()
try:
resp = await asyncio.wait_for(
client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[{"role": "user", "content": prompt}],
),
timeout=15, # 异步场景可以设更短,因为不阻塞其他请求
)
return resp.content[0].text
except (asyncio.TimeoutError, anthropic.APIConnectionError, anthropic.InternalServerError) as e:
print(f"海外模型失败,切换国产兜底: {e}")
# 兜底逻辑同上,此处省略
return await call_domestic_fallback(prompt)
这里故意只捕获 asyncio.TimeoutError、APIConnectionError、InternalServerError 三类,而不是笼统的 Exception——原因前面讲过,笼统捕获会把你自己代码的 bug 也吞掉。异步场景下超时可以设得比同步版本更短(比如 15 秒而不是 30 秒),因为异步不阻塞其他请求处理,切换更激进一点对整体吞吐反而有利,代价是极少数本来能在 20 秒内正常返回的海外请求会被提前切到兜底,这个取舍要结合你业务对”准确率 vs 速度”的偏好来定。
如果单个请求需要极高的可用性(比如金融场景的关键判断),还可以做”双发”——同时向海外和国产模型发请求,谁先成功用谁的结果,牺牲一部分成本换取延迟和可用性,但要注意这样两边的调用费都会产生,只适合小流量、高价值的关键路径,不建议全量请求都这么干。
常见问题
兜底模型的输出和主路模型一样吗?
不完全一样。不同模型的风格、格式遵循程度有差异。建议在设计 prompt 时尽量使用通用格式约束(如 JSON 输出),减少对特定模型风格的依赖,提高兜底时的输出一致性。
兜底切换会让用户感知到吗?
如果切换时机是在请求失败后(已有等待时间),用户会感到延迟增加。更好的体验是设置较短的超时(如 10 秒),超时后立即切兜底,总响应时间反而可能比等海外模型重试更短。
用聚合平台做兜底,需要自己写代码吗?
使用支持故障切换的聚合接入层(如力达云等候名单中的方案),通常只需在控制台配置主备模型,业务代码无需改动。具体能力以平台文档为准。
国产模型兜底时,之前的对话历史能带过去吗?
可以,只要在切换时将完整的 messages 数组传给国产模型 API 即可(多数支持 OpenAI 格式的国产模型兼容相同的消息格式)。注意:不同模型对超长历史的处理方式不同,需做截断保护。
本文仅作技术科普,不构成法律意见。企业接入海外模型须通过合规渠道,遵守数据出境相关规定。具体产品能力以各服务商官方文档为准。
相关阅读:海外模型合规接入指南(Pillar) · 海外模型合规接入专题 · API 网关故障切换 · 国产模型横向对比
如需了解企业合规聚合接入方案(含多模型自动兜底),欢迎访问 力达云等候名单。