☰
litellm大模型API网关:统一多模型接入、路由与成本治理
2026/10/13 17:10:15 网站建设 项目流程

做后端服务这几年,我接过大大小小十几个和 AI 相关的项目,最烦的从来不是模型效果不好,而是对接模型供应商的那一层胶水代码。

今天想聊的是一个大模型 API 网关项目,名字叫litellm。我用它大概半年了,从最开始只是想在本地统一调几个模型,到后来把整个团队的模型入口、密钥、预算、日志全部收口到这一个服务里,越用越觉得这套思路值得好好说清楚。如果你也在做 AI 应用的后端,或者团队里好几个人各调各的模型、各写各的适配层,那这篇文章应该能帮你省下不少重复劳动。

litellm 解决的核心问题:任何模型供应商的 API,都可以用同一套 OpenAI 风格的接口来调用;路由、重试、预算、密钥管理、日志追踪,配置化完成。不管你是只想本地少写点代码,还是想在公司级网关里收口所有 AI 调用,都能对得上。

1. 为什么需要 litellm:多模型接入的痛点

1.1 模型供应商一多,适配代码就失控

先还原一个很常见的场景。你负责的一个产品想同时接入好几个大模型,有的擅长中文、有的便宜、有的响应快,业务上还希望做兜底切换。于是最朴素的做法出现了:在业务代码里写一个LLMClient类,里面接上各家 SDK。

一开始只有一两家,问题不大。但模型供应商超过三家以后,事情开始变味:

  • 每家 API 的请求结构不一样,有的是messages,有的是prompt;
  • 流式输出的格式不同,有的返回text/event-stream,有的是普通 JSON;
  • 出错信息、重试参数、鉴权方式全都不一样;
  • 各家 SDK 版本升级频繁,依赖冲突、接口变动是常事。

我见过最典型的例子是某小组的代码里塞了五个if provider ==分支,每个分支里又套着好几层异常处理。业务逻辑还没写几行,光适配代码就几百行。这不是个例,只要团队里每个人按自己的习惯接一遍供应商,代码库就离“模型适配屎山”不远了。

1.2 网关思路:把模型调用统一成一种协议

解决这类问题,业界早就有一套成熟思路:加一层代理。把所有供应商的真实 API 藏在后面,对外只暴露一个统一接口。litellm 做的就是这件事。

它的对外接口长得很像 OpenAI 的接口格式,也就是目前生态最通用的协议。你原来用某个 SDK 的chat.completions.create,在 litellm 代理下,只需要把base_url指向 litellm 的地址,模型名换成你在配置文件里定义的名称即可。内部怎么把请求翻译成各家协议、怎么处理鉴权、怎么重试、怎么计费,代理层全部处理掉。

用生活里的例子类比,它就是手机充电头的转换插座。你家里的插座孔型可能不一样,但只要带上转换头,任何设备都能插。litellm 就是那个转换头,把乱七八糟的插座孔型给你统一了。

选 litellm 而不是自己写适配层,我当时的判断有三点:

  1. 生态兼容性,OpenAI 协议是事实标准,团队里几乎所有现成代码不用大改;
  2. 社区更新快,新模型一发布,基本不用自己手动研究 API 细节;
  3. 部署简单,一个 Docker 容器就能跑起来,配置全部集中在 YAML 文件里。

1.3 从“够用”到“网关”,还是一个渐进过程

一开始你可能只想少写点适配代码,这个工具在个人项目里也能用。但真正让它发光的是团队级场景。因为一旦所有请求都经过网关,你就可以在网关这一层做全局的密钥治理、预算控制、访问日志、模型可用性监控。

我所在的项目组最初就是个人工具起家,后来逐步收敛到中心化网关,整个切换过程不到半天。这个渐进路径,我觉得很适合大多数中小团队:先用起来,再逐步把权限、预算、观测能力加进去。

2. litellm 到底做了什么:核心能力拆解

2.1 统一入口:一个接口连接所有供应商

litellm 对外提供的核心端点主要是/chat/completions和/embeddings,也就是对话补全和向量化两个最常用能力。配置好以后,你在任何语言里用 HTTP 调用即可,不需要关心背后的供应商是谁。

一个典型的请求长这样:

curl -X POST 'http://localhost:4000/chat/completions' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer sk-1234' \ -d '{ "model": "provider-a/gpt-style-model", "messages": [ {"role": "user", "content": "你好,请介绍一下你自己"} ] }'

注意model字段的值不是供应商内部的模型 ID,而是配置文件里定义的模型别名。网关拿到请求后,根据别名查配置,再决定转发给哪家供应商、用哪个模型、什么参数。

这种设计的巧妙之处在于:业务代码里只依赖一个虚拟的模型命名空间。将来想从 A 模型切到 B 模型,只需要改配置文件里model_name对应的litellm_params,业务代码一行不用动。我实际切过几次模型,改完配置、刷新网关配置,调用方完全无感。

2.2 模型路由:权重、兜底、限流一套配置搞定

网关真正厉害的地方不在“转发”,而在“路由策略”。litellm 支持几类非常实用的模式:

按权重分发。比如某两个模型,你想让 80% 流量走主力贵一点的模型,20% 流量走便宜模型做对比,在配置里给每个模型加rpm(每分钟请求数)权重,或者配成simple-shuffle这种轮询策略,就能做到。

故障转移。这是我最常用的能力。给一个模型别名配置多个候选供应商,当主供应商返回 5xx 错误、限流、超时时,网关自动尝试下一个供应商。用户端感知不到切换,顶多延迟多几百毫秒。

配置上一个简单的兜底长这样:

model_list: - model_name: chat-main litellm_params: model: provider-a/model-x api_key: os.environ/PROVIDER_A_KEY fallbacks: - provider-b/model-y - provider-c/model-z

这个机制帮我扛过好几次上游服务抖动。前一阵某个模型服务商频繁限流,我在网关配了一个便宜的备用模型,高峰期自动降级,业务的可用性数据比之前好了一大截。

限流控制。网关层可以做请求级别的限流,防止某个调用方的突发流量打爆上游配额。对团队内部共享网关的场景来说,这几乎是刚需。

2.3 密钥治理:不再把供应商 Key 散落在各处

没上网关之前,各家供应商的 API Key 分布在环境变量、代码仓库、同事的本地配置里,基本处于“失控”状态。换个 Key 要通知所有人,还总有人漏改,结果线上突然 401。

litellm 引入了虚拟密钥机制。你只配置一个主 Key(Master Key),然后用它去签发多个虚拟 Key。每个虚拟 Key 可以绑定:

  • 允许访问的模型列表;
  • 每分钟请求数(rpm)、每分钟 Token 数(tpm)限制;
  • 最大预算额度;
  • 可选的到期时间。

签发的流程也很简单:

curl -X POST 'http://localhost:4000/key/generate' \ -H 'Authorization: Bearer sk-master-key' \ -H 'Content-Type: application/json' \ -d '{ "models": ["chat-main"], "max_budget": 20, "rpm_limit": 60 }'

这样各业务线只拿自己的虚拟 Key 调用,互不干扰。某个服务 Key 泄露了,直接在网关撤销,几秒钟生效,不需要去上游供应商重新生成 Key。比起把真 Key 藏来藏去,这个机制在生产环境里非常省心。

2.4 日志与成本追踪:每一块钱花在哪都看得见

网关的另一大价值是自带日志与指标能力。默认情况下,litellm 会把每次请求的模型、Token 数、延迟、状态码、花费记录下来。

如果你接入了数据库,这些信息会写入专门的数据表,配合管理面板可以按时间、按项目、按密钥维度查看成本。某次功能上线后,我就是通过网关日志发现某个模型调用量异常飙升,最后定位到是某个定时任务死循环了,及时止损。

在成本敏感的项目里,“看得见”本身就是一种治理能力。预算上限、异常消耗预警这些,都能在网关层做到,不用等账单来了才后知后觉。

3. 部署与首次接入全流程

3.1 准备基础环境和配置文件

litellm 对部署环境的要求很低,本地开发只需 Python 3.8+ 或者 Docker。我更推荐直接用 Docker 起服务,省去 Python 依赖管理的问题,尤其适合团队标准化环境。

启动前先准备一个config.yaml,定义你的模型列表。拿我们一个很早期的配置举例:

model_list: - model_name: provider-a/gpt-style-model litellm_params: model: provider-a/gpt-style-model api_key: os.environ/PROVIDER_A_KEY - model_name: provider-b/claude-style-model litellm_params: model: provider-b/claude-style-model api_key: os.environ/PROVIDER_B_KEY api_base: https://api.provider-b.example.com/v1 - model_name: local-embedding litellm_params: model: hosting/embedding-model api_base: http://localhost:11434

有几个细节值得注意:

  • api_key推荐用os.environ/XXX的写法,Key 不要直接写进 YAML 文件,避免配置泄漏;
  • provider-a/gpt-style-model这种命名是 litellm 识别供应商和具体模型的关键,前缀代表协议,后面是模型标识;
  • 本地私有化模型也可以通过设置api_base指进来,网关会统一封装。

3.2 本地启动网关

配置文件准备好以后,服务启动就是一条命令的事:

docker run \ -v $(pwd)/config.yaml:/app/config.yaml \ -e LITELLM_MASTER_KEY=sk-master-local \ -e LITELLM_SALT_KEY=random-salt-value \ -p 4000:4000 \ ghcr.io/berriai/litellm:main-latest

启动后,打开http://localhost:4000能看到健康检查页面,GET/health/liveliness会返回服务状态。此时网关已经在运行,只是还没有具体调用。

注意几个环境变量的作用:

  • LITELLM_MASTER_KEY:管理密钥,签发虚拟 Key、管理配置都要用到,务必设强;
  • LITELLM_SALT_KEY:用于加密虚拟 Key 的盐值,生产环境必须设为随机数,且不能随意更改,否则已有虚拟 Key 全部失效。

3.3 业务侧接入:只改 base_url,不动业务逻辑

网关起来以后,业务接入是成本最低的一步。以 Python 为例,你原来用某个 OpenAI 风格 SDK 的代码,只需要改两个地方:

from openai import OpenAI client = OpenAI( api_key="sk-虚拟Key", base_url="http://localhost:4000" ) resp = client.chat.completions.create( model="provider-a/gpt-style-model", messages=[{"role": "user", "content": "你好"}] ) print(resp.choices[0].message.content)

看到没有,模型名换成了你在配置文件里定义的别名,其余代码照旧。换供应商、换模型、加路由,都不需要改这段业务代码。

如果不想引入 OpenAI SDK,直接 HTTP 调用也一样。凡是支持自定义base_url的工具和框架,几乎都能无缝接上。

3.4 上线前先配好成本与限流规则

很多人在本地验证通过后就直接丢到生产,这是我在实际项目中踩过坑才学到的。网关默认情况下不会限制任何一个虚拟 Key 的花费,如果不提前配置,某次异常调用或某个不熟悉价格的同事,很可能一天烧掉平时一周的钱。

我现在的习惯是:任何新模型上线之前,先在配置里写明model_info,包括上下文窗口、输入输出单价,然后给每个业务方签发带预算上限的虚拟 Key:

model_list: - model_name: provider-a/gpt-style-model litellm_params: model: provider-a/gpt-style-model api_key: os.environ/PROVIDER_A_KEY model_info: max_tokens: 8000 max_input_tokens: 128000 input_cost_per_token: 0.000003 output_cost_per_token: 0.000015

有了成本单价,网关才能在做预算控制时算得准。这个环节虽然不产生功能价值,但它是生产环境稳定性的隐形保障。

4. 生产环境容易踩的坑与排查清单

4.1 认证与密钥类问题的快速定位

用得越久,踩的坑越集中。我整理了几个高频问题:

现象可能原因解决办法
请求返回 401虚拟 Key 或 Master Key 不正确重新在后台签发 Key,检查Authorization头格式
返回 403 且提示模型未授权虚拟 Key 没有绑定该模型更新 Key 的models白名单
所有 Key 突然失效LITELLM_SALT_KEY被改动恢复原盐值,Key 才能继续用
管理接口进不去没有带 Master Key 请求用 Master Key 重新请求/key/generate等接口

其中最容易忽略的是盐值问题。部署配置升级时,LITELLM_SALT_KEY往往被一些自动化脚本顺手重新生成,结果就是存量虚拟 Key 全废。这个变量在生产环境里应该和数据库密码一样纳入变更管理。

4.2 请求失败与路由不生效的排查思路

路由配置了 fallback,但实际请求时兜底没生效,这个问题我排查了很久。原因通常是供应商返回的错误在 litellm 看来不属于“可重试错误”。比如某些业务侧参数错误导致的 400,它不会走兜底逻辑,因为那是你代码的问题,不是上游服务问题。

理解这个逻辑之后,问题就好办多了。排查请求失败时,我建议按下面几步来:

  1. 看网关日志,确认实际请求转发到了哪个上游;
  2. 看上游返回的具体状态码和错误体;
  3. 判断错误属于“可重试”(限流、5xx、超时)还是“不可重试”(参数错误、鉴权失败);
  4. 对应调整fallbacks配置或修改业务参数。

还有一个容易踩的细节:模型名的大小写。配置文件里写的是什么,请求里就要用一模一样的字符串。某个同事自定义了一个大写别名,请求时用了小写,网关直接报模型不存在,排查半天才发现是大小写问题。

4.3 数据库连接与日志异常

打算长期使用的话,建议接上外部数据库,否则日志只能存在内存里,服务一重启就什么都没了。连接 Postgres 或 MySQL 的方式很直接,设置DATABASE_URL环境变量即可。

但注意,首次连接后 litellm 会做建表迁移。如果基础表已经存在,迁移失败或版本不匹配会直接导致管理后台打不开。遇到这类问题:

# 检查数据库连接是否正常 psql "$DATABASE_URL" -c "select 1;" # 查看迁移版本表 SELECT * FROM schema_migrations;

如果迁移状态很乱,最省力的做法是备份现有数据后清空相关表,重新初始化。注意日志表里如果有长期统计需求,先导出再处理。

生产环境另一个容易被忽略的问题是时区。litellm 的默认日志时间和成本统计通常按 UTC 存储,如果你团队都在国内,看面板时容易对不上账。我的经验是直接在查询或者报表层做时区转换,不要试图修改服务内部的存储时区。

4.4 性能与规模瓶颈

网关本身是纯 Python 实现,单实例在中小流量下完全没有问题。但如果你每天有百万级请求,单实例的并发能力会遇到瓶颈。此时有几个优化方向:

  • 网关实例横向扩容,前端加负载均衡;
  • 把路由、日志等状态依赖(比如数据库)和网关解耦;
  • 对高吞吐的向量化接口单独部署网关实例,避免被对话请求挤占。

在我们实际流量里,单实例扛住每秒几十个请求很稳,响应延迟增加不到 10ms。再往上就需要上负载均衡了,这块不要一开始就往复杂了设计。

5. 再往深走:团队协作与扩展思路

5.1 多团队共用网关的权限隔离

当网关从个人工具变成团队基础设施,第一件事就是做权限隔离。litellm 的虚拟 Key 天然支持按模型和预算隔离,这已经能满足大多数场景。

我的建议是,每个子团队或每条业务线一个虚拟 Key,而不是一人一个。好处是:

  1. 出问题能快速定位到业务线;
  2. Key 个数可控,管理不至于太散;
  3. 预算上限直接跟业务线挂钩,责任清晰。

管理界面上还能给每个 Key 打标签备注用途,建议把这个当规范执行。之前有一次同事共享了同一个 Key,结果业务出问题互相扯皮,最后靠日志分成才查清楚。用独立 Key 就没这种事。

5.2 自定义回调与内部观测体系打通

litellm 支持在请求生命周期里挂回调函数,把每次调用的元数据推送到你内部已有的监控体系或者日志平台。

这个点非常实用。公司内部往往已有统一监控大盘,你不需要让运维去熟悉又一个新面板,直接把网关日志推送到已有通道即可。我们当时通过回调把模型调用量、耗时、成本作为指标上报,出事直接在原有监控里查告警,不用切来切去。

对应的配置格式很简单,在config.yaml里声明callback_settings,指定回调类型和目标地址。不需要写太多胶水代码。

5.3 后续扩展:本地模型与远程模型混合调度

我最后想提的扩展方向,是混合调度。现在很多团队会在本地部署一些小参数模型做低成本场景,同时依赖远程大模型做高难度任务。litellm 把本地模型地址加进配置里就能统一纳管,和远程模型并列。

这意味着你的业务代码完全不需要关心某个模型的物理位置,网关根据模型别名自行路由。本地模型和远程模型的切换、权重分配,都是配置层面的改动。这种灵活性对成本优化和数据合规场景都很有价值。

最后说点个人心得

用 litellm 这一年多,我最大的体会是:工具本身不难,难的是在设计阶段想清楚“哪些事应该由基础设施层承担”。模型 API 适配、密钥治理、成本控制、限流这些横切关注点,放在业务代码里,每一条业务线都做一遍,是巨大的浪费;但抽出来放到网关层,就变成了一次性建设、全员受益。

如果你团队里已经有人开始分散接入各家模型,我建议尽早把网关搭起来。不用等系统很复杂,一两个模型跑通就值得引入。越早做,后面重构越痛。

最后分享一个小技巧:新模型接入后,先用低流量虚拟 Key 跑几天,观察真实成本数据,再放宽配额。我见过太多人一上来就放开预算,结果一个 Bug 就把预算烧穿。网关再强大,也不如一开始设置好边界来得安心。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询