多模型API接入降级链实战(Python+Node双实现+真实成本表)
场景
做 AI 应用的团队普遍接了不止一家模型:DeepSeek 跑日常、GPT 系跑推理。但接入越多,问题越多:
- 每家 SDK/参数差异,代码改来改去
- 一家限流全家卡壳
- Token 成本没有闸门,月底账单吓人
本文给出一套OpenAI 兼容协议统一接入 + 成本导向降级链的实战方案,Python/Node 双实现,直接能跑。
- Token 成本没有闸门,月底账单吓人
原理:三个决定
决定 1:只说 OpenAI 方言。DeepSeek、通义、豆包以及 new-api/one-api/OpenRouter 这类聚合网关全部兼容/v1/chat/completions。统一协议,换模型=改一个字符串。
决定 2:降级链而不是单点。模型按"便宜→贵"排队,请求失败或超时自动切下一个。对用户无感,对成本最优。
决定 3:超时是降级的前提。没有超时就没有降级。60 秒起步视场景调整。
代码(Python 完整实现)
importrequestsclassSmartClient:def__init__(self,base_url,api_key,chain,timeout=60):self.base_url=base_url.rstrip("/")self.api_key=api_key self.chain=list(chain)# 便宜在前self.timeout=timeoutdefchat(self,prompt,**kw):errors=[]forminself.chain:try:r=requests.post(f"{self.base_url}/chat/completions",headers={"Authorization":"Bearer "+self.api_key},json={"model":m,"messages":[{"role":"user","content":prompt}],**kw},timeout=self.timeout)data=r.json()ifr.status_code==200anddata.get("choices"):returndata["choices"][0]["message"]["content"],m errors.append(f"{m}: HTTP{r.status_code}")except(requests.Timeout,requests.ConnectionError)ase:errors.append(f"{m}:{type(e).__name__}")raiseRuntimeError("全链路失败:\n"+"\n".join(errors))``` 测试降级: ```python c=SmartClient(base_url="https://你的网关/v1",# new-api / one-api / openrouter 均可api_key="sk-xxx",chain=["deepseek-v4.1-flash","deepseek-v4-pro"],)# 故意放一个不存在的模型在链头, 观察自动跳过:c2=SmartClient(c.base_url,c.api_key,["not-exist-xxx","deepseek-v4.1-flash"])print(c2.chat("一句话介绍二分查找"))# 自动落到第二个``` Node.js 版(原生 fetch,零依赖)见文末仓库。## 成本数据(实测抓取 2026-11)|模型|输入倍率|输出倍率|适用||---|---|---|---||低价 flash 线|0.25|4×|摘要/改写/格式化||flash 标准线|0.4|4×|日常任务||v4-pro|1.125|3×|推理/代码||gpt-6.1-sol|0.1495|5×|长输入短输出|同任务(2k入+1k出)flash 系比 pro 省10-15%+;做"默认便宜、失败升级"的链路后,整体账单通常降一半左右。## 踩坑清单|坑|解法||---|---||不设超时,卡死整个服务|每请求必带 timeout||429和 5xx 混为一谈|分开处理:429可等重试,5xx 直接降级||流式输出自动降级|流式不能降级(已吐出的字收不回),失败直接报错||抄别人的倍率表|倍率会变,定时抓自己站 pricing 接口|## 完整仓库GitHub:**https://github.com/chenduosheng1/multi-model-switcher**含:Python+Node 双实现/流式示例/降级演示/成本表。MIT 许可。issue 附报错原文,看到就回。---下一篇:《流式输出的降级策略》。有具体场景问题评论区聊。