☰
用litellm统一管理多家大模型API,打造生产级模型网关
2026/10/13 13:56:08 网站建设 项目流程

这两年做大模型应用,最让我头疼的往往不是模型效果本身,而是“一堆模型接口怎么统一管理”。应用要接两三个不同厂商的模型,每个厂商的 SDK 不一样,密钥体系不一样,计费口径不一样,出问题时的报错风格也不一样。后来我把 litellm 架在了应用和模型服务之间,这个状态才算彻底清爽下来。

litellm 是一个开源的模型网关与代理服务,核心能力是把主流大模型的 API 统一成一套标准接口,同时提供负载均衡、自动降级、预算控制、成本统计、日志审计这些生产环境刚需功能。不管你是个人开发者在做 AI 工具,还是团队里负责模型接入的工程师,只要需要同时对接多个模型,这个项目都值得花半小时试一遍。下面我会把它的设计思路、核心功能、落地配置以及我实际踩过的坑一次性讲清楚。

1. 项目定位与核心设计逻辑

1.1 它站在哪儿

先理解 litellm 的位置。它本质上是一个独立服务,站在你的业务应用和各家模型服务商之间,所有请求都先打到 litellm,再由它转发到真正的模型供应商,并把响应原路返回。

如果你用过支付聚合,理解起来就特别顺。以前接支付是每个渠道一套 SDK、一套密钥、一套对账逻辑;现在接大模型也变成了这幅模样——每个厂商有自己的接口格式、鉴权方式和计费模型。litellm 做的就是把这一层杂乱收拢掉,业务代码只认识一个标准接口,由代理服务去消化各家差异。

因为所有请求都从这一层经过,很多能力可以集中实现:限流、鉴权、记录、兜底、配额控制。这些能力如果散落到每个应用里,就是大量重复代码,每个项目都要重新实现一遍。litellm 把它做成了独立网关能力,业务系统只需要知道“请求发给它就行”。

1.2 为什么选择代理而不是 SDK

litellm 官方其实提供了两种用法。第一种是作为 Python 包直接集成到代码里,调用litellm.completion()这种函数,适合快速脚本和个人实验。第二种是代理模式,跑一个独立服务,业务方通过 HTTP 接入。如果你只是在本地跑几个脚本,用 SDK 模式没问题,但凡是团队协作或生产环境,我更推荐代理模式。

原因是代理模式不绑定语言。你的后端用 Java、Go、Node 都能通过标准 HTTP 接口接入,前端如果直接调用也能走同一套网关。另外,代理模式切换模型不需要重新发布代码。我在实际项目里换过一次底座模型,业务代码一行没动,只在 litellm 配置里改了目标地址,前后几分钟完成切换。SDK 模式下要改依赖、改初始化参数、重新验证,对比太明显了。

而且 litellm 代理模式的对外接口风格和主流开放接口保持兼容,大多数现有代码只需要改一下 base_url 就能接入,这个改动量非常小。

1.3 轻量是相对什么说的

很多人一听到“网关”就想到企业级 API 网关那一套东西,觉得重、觉得复杂。litellm 的“轻”在于它只做模型相关的事情。它不会去管通用的服务发现、流量染色、插件市场这些能力,而是专注于模型语义层面的问题:模型怎么路由、按什么权重分配、出错了怎么降级、token 消耗怎么计费、模型健康状态怎么判断。

这种聚焦换来的是部署简单。一个 Python 异步服务,单实例内存占用通常几百兆级别,配置就是一份 YAML 文件,不需要依赖消息队列、注册中心那些重型组件。对一个几十人的团队来说,把模型流量统一走它,成本和运维压力都完全可控。

我还见过一种用法:只用 litellm 的虚拟密钥和成本统计功能,把多个业务线的模型调用汇聚到一个管理面,这样老板问“这个月模型费花哪了”,可以直接从看板拉数据。这种价值很容易被低估。

1.4 统一格式背后的工程收益

litellm 把所有模型响应统一成主流的 Chat Completions 格式,包含choices、usage、model这些标准字段。别小看这一步,各厂商返回格式差异其实很大,不只是字段不同,错误码语义、限流表现、重试建议都不一样。

统一之后,上层的错误处理、日志解析、监控报警全都可以用同一套逻辑。比如业务代码里只需要判断标准错误码,不用针对每家厂商写适配。再比如 token 统计,所有模型都在一个字段结构里拿到prompt_tokens和completion_tokens,成本计算只需要查价格表相乘就行。

2. 核心能力逐个拆解

2.1 模型目录:一个名字对应多个物理模型

litellm 配置里最核心的概念是model_list。每个条目有一个model_name,这是业务侧的“逻辑模型名”,还有一个litellm_params,里面写的是“物理模型地址”。两者之间是一对多的关系。

最典型的用法是这样的:你在应用代码里永远只写gpt-class-model这个名字,但在配置里你可以把gpt-class-model同时映射到两个不同厂商的模型。本地开发时走便宜的开源权重模型,生产环境自动切到效果更好的付费模型;也可以配置多家服务商做冗余,一家挂了自动走另一家。

model_list: - model_name: gpt-class-model litellm_params: model: provider-a/gpt-class-model api_key: os.environ/PROVIDER_A_API_KEY - model_name: gpt-class-model litellm_params: model: provider-b/gpt-class-model api_key: os.environ/PROVIDER_B_API_KEY api_base: https://your-endpoint.example.com/ api_version: 2024-02-01

这里有个细节,litellm_params里的model前面带了个前缀,provider-a/、provider-b/这种。它的作用是告诉 litellm 走哪家厂商的接入层,不同厂家的前缀不同,实际配置时换成自己账号对应的前缀即可。如果写错了前缀,litellm 可能无法正确加载对应的 SDK 适配层。

2.2 路由与自动容错:不止是“换个供应商”

litellm 的路由能力分为几个层次,从最基础到最复杂可以这样理解。

首先是负载均衡。默认策略会把请求均匀分发到model_list里的多个物理模型上。你可以配置权重,让某个模型承担更多的流量。其次是失败重试,单次请求遇到网络错误或者 5xx 时会自动重试,不用业务方自己在外面套循环。再次是故障冷却,某个模型连续失败到达阈值后,litellm 会把它临时标记为不健康,在一段时间内不再分配流量,这个时间在cooldown_time里配置。

最后是兜底降级,也是最实用的能力。在配置里声明一个 fallback 列表,当主模型失败了,自动把请求转到备选模型。

router_settings: routing_strategy: simple-shuffle cooldown_time: 30 fallbacks: - gpt-class-model: - claude-class-model - local-llama-model

我遇到过一整天里某家厂商持续 5xx 的情况。如果没有 fallback,业务直接停摆;配了 fallback 后流量自动切到备用模型,用户几乎无感。这种容错能力在生产环境里非常值钱。

2.3 虚拟 Key:给每个业务线发一把独立钥匙

litellm 有一套完整的密钥体系。最顶层是master_key,相当于管理员账号,所有管理接口都靠它鉴权。master key 可以动态生成无数个“虚拟 key”,每个虚拟 key 可以绑定允许使用的模型列表、设置预算上限、设置有效期。

这个设计特别适合多团队共用一个网关的场景。给 A 业务线发一把 key,预算 100 美元;给测试环境发一把 key,预算 20 美元;给外部客户发一把 key,做了模型白名单,只能调用指定模型。某把 key 泄漏了,在管理界面删掉它就行,完全不影响其他 key。

生成虚拟 key 直接用管理接口:

curl -X POST http://localhost:4000/key/generate \ -H "Authorization: Bearer sk-master-key" \ -H "Content-Type: application/json" \ -d '{"models": ["gpt-class-model"], "max_budget": 50, "budget_duration": "30d"}'

返回结果里会带一个sk-xxx的 key,后面让业务方把它当成普通 API key 使用。所有请求都会记录到这把 key 下面,月底一查就知道每个业务线花了多少钱。

2.4 日志、成本与可观测

litellm 自带请求日志和成本统计能力。每一条请求都会记录模型名、token 数量、延迟、状态码、估算成本。默认情况下日志放在内存里,生产环境一定要接 Postgres,否则网关一重启所有历史日志和虚拟 key 配置都会丢。

接上数据库之后,litellm 的管理面板会展示每个 key 的累计消耗、每个模型的平均延迟和成功率,还可以对接常见的可观测系统做指标采集和告警。

成本统计有个前提:它需要知道每个模型每百万 token 的单价。内置模型库已经包含很多常见模型的公开价格,但是模型价格调整了、或者你用的是自部署模型,就需要自己在model_info里维护价格。这个字段一旦漏配,成本这一栏就会显示为 0,等于白接。

3. 实操部署与关键配置

3.1 本地快速跑起来

先说实话,litellm 的启动门槛很低。如果你是第一次上手,用 Python 方式最快:

pip install "litellm[proxy]" litellm --config config.yaml --port 4000

跑起来之后先验证一下服务状态:

curl http://localhost:4000/health/liveliness

看到存活响应说明代理已经就绪。生产环境我更推荐用 Docker,镜像内部已经做了依赖封装,宿主机只需要装容器运行时:

docker run -d --name litellm \ -p 4000:4000 \ -v $(pwd)/config.yaml:/app/config.yaml \ ghcr.io/berriai/litellm:main-latest \ --config /app/config.yaml

镜像标签建议锁定具体版本号,不要用 latest 直接上生产。litellm 迭代速度很快,配置格式偶尔会有小调整,锁定版本可以避免升级带来的意外变更。

3.2 配置文件的正确写法

起步配置直接照下面这个精简版改就行。这个配置已经覆盖了日常最需要的功能:多模型映射、重试、超时、缓存、兜底降级和主密钥。

model_list: - model_name: gpt-class-model litellm_params: model: provider-a/gpt-class-model api_key: os.environ/PROVIDER_A_API_KEY model_info: cost_per_1k_input_tokens: 0.002 cost_per_1k_output_tokens: 0.004 - model_name: gpt-class-model litellm_params: model: provider-b/gpt-class-model api_key: os.environ/PROVIDER_B_API_KEY api_base: https://your-endpoint.example.com/ api_version: 2024-02-01 model_info: cost_per_1k_input_tokens: 0.0015 cost_per_1k_output_tokens: 0.003 litellm_settings: num_retries: 3 request_timeout: 30 drop_params: true cache: true cache_ttl: 300 router_settings: routing_strategy: simple-shuffle cooldown_time: 30 fallbacks: - gpt-class-model: - claude-class-model - local-llama-model general_settings: master_key: sk-your-master-key database_url: postgresql://user:password@localhost:5432/litellm

逐个说下关键字段。litellm_params.api_key里可以写os.environ/变量名,从环境变量读取密钥,避免把明文密钥写进配置文件。model_info里的价格字段是成本统计的基础,建议从一开始就配好,不然后面想查历史成本会发现数据缺一块。

litellm_settings.drop_params: true的意思是,当上游厂商不支持某个参数时,litellm 直接把它丢弃而不是报错。这个选项非常实用,后面我会在踩坑部分详细展开。

router_settings.fallbacks配置的是降级顺序,主模型失败后,会依次尝试claude-class-model和local-llama-model。注意 fallback 里的模型名必须是model_list里已经定义过的model_name或模型库内置名字,否则会配置校验失败。

3.3 把密钥体系和预算做起来

先启动一个带master_key的 litellm,然后就可以通过管理接口生成虚拟 key 了。我习惯按用途分类创建:每个业务线、每个环境各一把,命名上尽量能对上。

curl -X POST http://localhost:4000/key/generate \ -H "Authorization: Bearer sk-your-master-key" \ -H "Content-Type: application/json" \ -d '{"models": ["gpt-class-model"], "max_budget": 20, "budget_duration": "30d"}'

这里声明的意思是:这把 key 只允许调用gpt-class-model,30 天内最多花费 20 美元。预算耗尽后,这把 key 的请求会被拒绝,不会出现“月底账单爆掉才反应过来”的情况。

应用侧接入其实特别简单。因为 litellm 的代理接口和主流 SDK 兼容,大多数项目只需要改两行代码:

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

业务代码完全不知道自己背后是哪个厂商的哪个模型,它只认得gpt-class-model这个逻辑名。

3.4 生产环境要补的几个细节

第一,必须接持久化数据库。如果general_settings里没有配置database_url,litellm 会把所有虚拟 key、日志、预算数据放在内存里。进程一重启,所有 key 全部失效,维护成本立刻上来。用 Postgres 是最省心的方案。

第二,不要直接暴露 4000 端口到公网。比较合理的做法是前面加一层 HTTP 处理来做 TLS 终止和域名转发,同时限制来源 IP。litellm 本身有鉴权,但网关上还有一层传输加密和访问控制总是更稳。

第三,容器日志。容器时间默认是 UTC,排障时先想清楚这一点。日志建议挂载到宿主机目录,方便集中收集,否则容器一删日志全没了。

4. 真实使用场景中的踩坑与解决

4.1 一张表解决 80% 的启动问题

现象可能原因处理方法
返回 401 Unauthorizedmaster key 错误或虚拟 key 被删除检查 Authorization 头的 Bearer 格式,确认 key 存在且未过期
返回 404 model not found请求里的 model_name 不在 model_list 中检查配置里的 model_name 是否与请求一致
返回 429 Too Many Requests上游厂商限流或虚拟 key 预算耗尽加大 num_retries,配置 fallback,或调整预算上限
请求持续超时上游响应慢或 request_timeout 设置过短调大 request_timeout,同时排查上游状态
成本统计始终为 0model_info 没有配单价在 model_list 里补齐 cost_per_1k_tokens 字段
网关重启后所有 key 失效没接 Postgres配置 database_url,重启后再生成一次 key 即可验证

4.2 几个我印象很深的坑

先说说参数透传的问题。有些模型服务商对参数支持不完整,比如某个上游接口根本不接受temperature参数,你传了 0.7,对方直接返回 500。这种问题在直连时非常隐蔽,因为本地测可能单独传参数能通过,换到统一网关后就报错。

解决方案是开启drop_params: true。开启后,litellm 会根据目标厂商的能力定义,自动丢弃不支持的参数。缺点是无法做到百分之百完美,因为厂商更新参数支持速度很快。我的建议是:先默认开启 drop_params,然后针对个别模型单独关闭,把注意力放在更关键的模型效果上。

再一个是流式响应半路断开的问题。SSE 流式输出时,如果上游连接中途断开,客户端可能会卡住,表现为一直转圈但没有数据返回。litellm 对这种情况有专门的流式重试机制,但配置项比较隐蔽。实践上最稳妥的做法是客户端自己做一层超时控制和重连逻辑,不要把流式请求的稳定性完全交给代理。

还有一个容易忽略的是预算币种问题。litellm 默认按美元计算费用,如果你的账单是人民币,直接看面板数字会误导人。曲线救国的方法是用 model_info 里的自定义价格,把单价直接换算成你要的货币单位,虽然账面数字看着大一点,但至少口径是对的。

4.3 调优建议

不要一上来就配十几个模型的复杂路由。先用单模型跑通,验证业务侧接入没问题,再逐步增加模型、fallback、缓存这些高级能力。我见过很多团队第一步就搞复杂配置,结果排障时连“请求打到哪台模型”都分不清。

故障冷却时间cooldown_time建议设置在 30 到 60 秒。太短会导致上游抖动时频繁探测,反而放大故障;太长则会让某个模型在恢复后很长时间仍然接不到流量。我实测下来 30 秒是个不错的平衡点,能兼顾快速恢复和稳定性。

缓存功能要谨慎。litellm 内置了响应缓存,适合 prompt 完全固定的场景,比如系统提示词不变、用户高频重复查询。但如果你做的是对话机器人,用户输入几乎不可能重复,开缓存命中率很低,反而增加一层判断开销。动态场景建议把 TTL 设短,比如 60 秒,或者直接用类似自定义缓存 key 的方式按会话维度控制。

还有一个日常维护动作:定期检查模型价格表。模型厂商调价后,litellm 内置价格库可能不会第一时间更新,成本统计就会失真。好在每个模型项都能单独覆盖价格,发现偏差直接改 model_info 里的 cost 字段即可。

最后说点个人体会。litellm 最容易被低估的是它后台那套日志和统计能力。以前我切换模型,要改代码、改依赖、重新测试,耗费半天;现在改一行配置,灰度切流,再在面板上看一眼延迟和成本有没有异常,收工。如果你正被多模型接入、费用失控、切换模型痛苦这些问题困扰,先把最简单的代理跑起来,再逐步加上预算、缓存、fallback 这些能力。我就是从一条命令开始的,后来把团队全部模型流量都收口到它下面才真正理解:网关这一层,迟早要有,早搭早省心。

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

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

立即咨询