LiteLLM 多模型网关:统一接入与成本路由

LiteLLM 是一个把 OpenAI、Anthropic、通义千问、DeepSeek 等几十家模型统一成一套兼容接口的开源网关。接入后业务代码只认一个 client,模型随时可换、成本可追踪、一家挂了还能自动降级,是吃掉多家大模型后最该补的中间层。

一、为什么业务需要一个多模型网关

公司早期只接一家模型时,很少有人会想到后面会接第三家、第五家。等真接了才发现:每加一家就要改一套 SDK、读一遍对方的鉴权与错误码;想做 A/B 比价得在代码里写满 if-else;某家突发限流时只能手工切流量。这些问题单靠业务代码补不出来,需要一层统一的「翻译 + 路由」。

1.1 直连 vs 网关:四个维度的差距

下面这张表是我带团队做选型时反复强调的对比,结论很直接:只要模型数量超过一家,网关就是净收益。

维度直连各家走 LiteLLM 网关
接入成本每接一家改一套 SDK 与错误码一处 client,model 字段切换
切换成本改代码 + 改测试 + 发版改配置或路由权重
成本归因各云账单割裂,难对账统一账本、按 key 设预算
容灾单点,挂了只能人工切fallback 自动降级

补充一点动机:当你的提示词组织得越复杂、上下文越大,切换模型带来的行为差异越难评估——这正是大模型上下文工程实战里强调的「改动要可验证」。网关让「换模型」变成一行配置,评估才做得起来。

二、五分钟跑通:一套接口调通不同模型

LiteLLM 最核心的价值就是让所有模型对齐 OpenAI 的 messages / response schema。下面这段 Python 只用切换 model 字段,就把同一句提问先后打给了海外与国内两家模型,业务代码一行都不用改。

from litellm import completion

# 海外模型,请求/响应结构与 OpenAI 完全对齐
resp = completion(
    model='gpt-4o-mini',
    messages=[{'role': 'user', 'content': '用一句话解释什么是 Token'}],
)
print(resp.choices[0].message.content)

# 换成通义千问,业务代码无需任何改动
resp2 = completion(
    model='qwen-plus',
    messages=[{'role': 'user', 'content': '用一句话解释什么是 Token'}],
    api_key='sk-dashscope-xxx',
)
print(resp2.choices[0].message.content)

注意 key 的管理:不要把各家 api_key 硬编码进代码,统一从环境变量或密钥服务注入。LiteLLM 支持在配置里写 os.environ/XXX,运行时自动读取,避免密钥进仓库。

2.1 用代理模式把网关跑成服务

上面是 SDK 直调,适合脚本与批量任务。线上服务更常见的形态是把 LiteLLM 跑成一个常驻代理:应用把 base_url 指向网关,就当它是「另一家 OpenAI」来用,对业务零侵入。配置用一个 yaml 描述模型清单。

model_list:
  - model_name: my-gpt
    litellm_params:
      model: gpt-4o-mini
      api_key: os.environ/OPENAI_API_KEY
  - model_name: my-qwen
    litellm_params:
      model: qwen-plus
      api_key: os.environ/DASHSCOPE_API_KEY

litellm_settings:
  drop_params: true          # 厂商不支持的参数自动剔除,避免 400
  num_retries: 2             # 限流时自动退避重试

启动后应用侧的改动极小:只换 base_url 与 api_key,请求体保持 OpenAI 格式不变。自部署模型也可以挂进来——比如你用 vLLM 部署实战 起的私有推理服务,只要暴露 OpenAI 兼容端口,就能以同样的 model 字段被网关纳管。

三、路由与自动降级:一家挂了不影响业务

网关真正的杀手锏是 Router。你可以把同一个逻辑名(如 primary)映射到多个物理模型,并声明 fallback 顺序。主模型返回 429/500/超时,LiteLLM 在后台透明切到备用模型,调用方完全无感——这对在线服务可用性提升是立竿见影的。

from litellm import Router

router = Router(
    model_list=[
        {'model_name': 'primary', 'litellm_params': {'model': 'gpt-4o-mini'}},
        {'model_name': 'primary', 'litellm_params': {'model': 'qwen-plus'}},
    ],
    # 主模型失败时自动切到 qwen-plus,对调用方透明
    fallbacks=[{'primary': ['qwen-plus']}],
    num_retries=2,
    timeout=20,
    retry_after=3,
)

resp = router.completion(
    model='primary',
    messages=[{'role': 'user', 'content': '帮我总结这段日志'}],
)
print(resp.choices[0].message.content)

降级策略要配合业务语义:闲聊类请求可以随便降级,但涉及结构化抽取、要求严格 schema 的请求,降级到能力更弱的模型可能直接解析失败。对这类请求建议保留强模型、只做超时重试而非跨模型降级,相关约束输出的做法见 大模型结构化输出实战

四、成本跟踪:把每次调用折算成钱

多模型最头疼的是算账。各家账单格式不同、出账周期不同,月底想看「哪个功能花了多少」几乎不可能。LiteLLM 内置了主流模型的价目表,只要 model 名匹配就自动算成本,还能按虚拟 key、tag、模型维度聚合。

import litellm
from litellm.integrations.prometheus import PrometheusLogging

# 启用 Prometheus 指标,成本与延迟自动暴露给现有监控
litellm.callbacks = [PrometheusLogging()]

# 或按实例设硬预算,超支直接拒绝,防刷与防死循环
litellm.max_budget = 10.0          # 美元
litellm.budget_duration = '1d'

更精细的做法是给每个业务方、每个环境发一个虚拟 key,各自带预算上限。下面这条命令生成一个每天最多花 5 美元的 key,只能调网关里登记的两个模型:

curl -X POST http://localhost:4000/key/generate \
  -H 'Authorization: Bearer sk-litellm-master' \
  -H 'Content-Type: application/json' \
  -d '{"models": ["my-gpt","my-qwen"], "max_budget": 5.0, "budget_duration": "1d"}'

预算告警要接进既有值班体系,而不是另起一套。成本突增往往是「被刷接口」或「Agent 死循环」的信号,应当复用你已经建好的告警治理流程,而不是让网关自己发邮件。成本优化的整体思路在 大模型推理成本优化里有系统拆解,网关只是把「按调用粒度采集花费」这一步变得真正可行。

五、与现有可观测体系打通

网关不是监控,它只负责路由与记账。真正的可观测要把网关产生的数据接到你已有的链路系统上:用 Prometheus 指标做大盘与告警,把每次请求带上业务 trace_id,必要时再叠加 LLM 语义层的链路追踪。三者分工清晰,别让网关越界去做它不擅长的事。

一个容易忽视的点:网关把模型「抽象」掉之后,线上出问题会更难定位——你看到的是 primary 失败,但不知道背后是哪个物理模型、哪条提示词导致的。因此务必让网关在日志和 metrics 里透出实际 model 名与 provider,否则排查会退回到「盲猜」。排障的通用方法论可以回看 On-call 值班与告警治理实战

六、生产落地的五个坑

下面五条都是真踩过的,按发生频率排序,建议上线前逐条对照。

表现处置
参数不兼容切模型后 400,说参数不支持开 drop_params,或按模型收敛参数集
降级救活了但答错了fallback 到弱模型,结构化解析失败强 schema 请求只重试不跨模型降级
成本算不准用了别名 internal-chat,落到 unknownmodel 名对齐官方,或显式上报 cost
预算被绕过有人用 master key 直发,绕过虚拟 key生产环境禁用 master 写权限,仅网关机持有
雪崩一家限流,重试风暴打垮另一家限流时退避 + 全局并发上限

最后一条最隐蔽:fallback 本来是容灾,但如果主模型限流时你不做退避就疯狂重试,流量会瞬间灌到备用模型,把它也打挂,变成连锁雪崩。正确的姿势是退避 + 全局并发上限 + 最坏情况下快速失败(返回降级提示),而不是无脑重试。

七、在 RAG / Agent 体系里的位置

如果你的应用是 RAG 或 Agent,网关处在「模型调用」这一层最合适。检索、重排、工具调用这些逻辑继续留在你的业务里,只把「最终调哪家风模型」这件事交给网关。这样 RAG 进阶实战 里打磨的检索质量、Function Calling 里的工具编排都不受影响,模型层却获得了可替换、可降级、可计费的弹性。这也是把「模型」从硬编码依赖变成可配置资源的关键一步。

小结

接多家大模型不是难点,难点是接完之后代码不乱、账算得清、挂了有人顶。LiteLLM 用一套 OpenAI 兼容接口把几十家模型收编:SDK 直调适合脚本,代理模式适合线上,Router 负责自动降级,虚拟 key + 预算负责成本围栏。落地顺序我的建议是:先接通用接口跑通,再上路由做容灾,最后按 key 设预算接告警。

它不该替代你的监控与链路系统,而是把「模型可替换、可计费、可降级」这三件事变成基础设施。做到这一步,换模型与比价才第一次从「改代码发版」降级成「改一行配置」,多模型架构的弹性才算真正落地。

上一篇 Langfuse 实战:LLM 应用链路与成本可观测
下一篇 推测解码实战:让大模型推理提速 2 倍