别再为每家大模型改代码了:一个降级链客户端,Python/Node 双实现,成本省一半

0 阅读3分钟

跑过 DeepSeek、GPT 系多家的都知道痛点:每家 SDK 略有差异、限流各有节奏、价格差好几倍。今天分享一个我踩坑后收敛出来的方案:一份 OpenAI 兼容代码 + 按成本自动降级的调用链。附真实倍率对比表。

一、问题:多模型接入的三个真实坑

坑 1:改不完的 SDK。 想对比 A 家和 B 家的效果,代码要改一遍、Key 要管两套。其实所有主流模型厂商(以及 new-api/one-api 这类聚合网关)都兼容 OpenAI 的 /v1/chat/completions 格式——统一用这一种协议就够了。

坑 2:单点故障。 只用一家,赶上高峰限流或者宕机,应用直接挂。我的做法是降级链:便宜模型在前,失败/超时自动切下一档,全挂才报错。

坑 3:成本失控。 大模型按 token 计费,不同模型差价能到 5 倍以上。摘要、改写、格式化这类任务用便宜模型完全够,推理、写代码才值得上高档模型。把"什么任务用什么档"写成代码,成本立刻降一半。

二、核心代码:50 行 Python

import requests

class SmartClient:
    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 = timeout
                                    
                                        def chat(self, prompt, **kw):
                                                errors = []
                                                        for m in self.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()
                                                                                                                                                                                                    if r.status_code == 200 and data.get("choices"):
                                                                                                                                                                                                                        return data["choices"][0]["message"]["content"], m
                                                                                                                                                                                                                                        errors.append(f"{m}: HTTP {r.status_code}")
                                                                                                                                                                                                                                                    except (requests.Timeout, requests.ConnectionError) as e:
                                                                                                                                                                                                                                                                    errors.append(f"{m}: {type(e).__name__}")
                                                                                                                                                                                                                                                                            raise RuntimeError("全链路失败:\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"],
                                                                                                                                                                                                                                                                                        )
                                                                                                                                                                                                                                                                                        text, used_model = c.chat("用一句话介绍快速排序")
                                                                                                                                                                                                                                                                                        ```
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        Node.js 版本(原生 fetch 无依赖)和流式版本放在文末仓库里。
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        ## 三、真实成本对比(2026-11 抓取)
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        倍率来自某聚合站公开 pricing 接口(你自己的站以自己为准):
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        | 模型 | 输入倍率 | 输出倍率 |
                                                                                                                                                                                                                                                                                        | --- | --- | --- |
                                                                                                                                                                                                                                                                                        | deepseek-v4.1-flash(低价线) | 0.25 | 4× |
                                                                                                                                                                                                                                                                                        | deepseek-v4.1-flash | 0.4 | 4× |
                                                                                                                                                                                                                                                                                        | deepseek-v4-pro | 1.125 | 3× |
                                                                                                                                                                                                                                                                                        | gpt-6.1-sol | 0.1495 | 5× |
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        **算笔账**:一段 2k 输入 + 1k 输出的任务,flash 系比 v4-pro 便宜 10-15%,比"闭着眼全用高档模型"的写法便宜得更多。日调用量上去之后差距很明显。
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        **我的选型口诀**:
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        1. 默认便宜档,不对再升级
                                                                                                                                                                                                                                                                                        2. 输入长、输出短 → 输入倍率低的模型
                                                                                                                                                                                                                                                                                        3. 推理/代码 → 高档模型
                                                                                                                                                                                                                                                                                        4. 把这套规则写进降级链,就不用人盯了
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        ## 四、踩坑提醒(都是真踩过的)
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        1. **超时要设**。不带 timeout,一个卡死的请求能把整个服务拖住。降级的前提是"快速失败"。
                                                                                                                                                                                                                                                                                        2. **别用异常做流程控制太重**。Timeout 和 ConnectionError 分开抓,限流(429)和宕机(5xx)处理策略不同。
                                                                                                                                                                                                                                                                                        3. **流式输出别自动降级**。已经吐出去一半的文字没法撤回,流式请求失败就直接报错让前端重试。
                                                                                                                                                                                                                                                                                        4. **倍率表会过期**。抓自己站的 pricing 接口做成定时任务,别抄别人的表。
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        ## 五、完整代码
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        GitHub 仓库(Python + Node 双实现、流式、降级演示、成本表):
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        **https://github.com/chenduosheng1/multi-model-switcher**
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        MIT 许可,直接抄。觉得有用给个 star,有问题开 issue 附报错原文,我看到就修。
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        ---
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        *我是独立开发者,在做一个多模型聚合接入的工具站,踩坑记录会持续写。下一篇预告:《流式输出的降级策略:为什么流式不能自动切模型》*