如果你搞过几个大模型应用的对接,大概会记得那种到处找 SDK 的日子。A 平台有 A 的调用方式,B 平台有 B 的鉴权逻辑,想给公司内部做个小工具,光是模型接入这块就能占掉一半工作量。litellm 是我目前见过的能把这堆事情收拢得最干净的项目。它做的事情很朴素:对外提供一个统一的 API 网关,帮你把不同模型服务商的接口差异消化掉;对内负责模型路由、密钥管理、余额统计和请求转发。
换句话讲,你不需要再为每一家模型服务商写一套独立的调用代码,也不需要把上游密钥散落到各个业务服务里。只要把 litellm 往中间一放,业务代码只认一个本地地址、一套请求格式、一个虚拟 Key,剩下的事全交给网关。这篇文章我会从实际落地的角度,把 litellm 的核心机制、部署方式、配置细节和排坑经验一次性讲清楚。适合正在做多模型接入、想统一管理模型调用成本,或者准备搭建内部 AI 基础平台的开发者参考。
1. 项目概述:litellm到底解决了什么问题
1.1 多模型时代,最让人头疼的不是模型能力,而是厂商差异
我接手过一些内部 AI 应用项目,最后发现大部分时间不是在研究模型效果,而是在处理接口差异。同一个聊天补全功能,服务商 X 的 SDK 是这么调,服务商 Y 的 SDK 又是另一套风格;有的要用 Access Key 签名,有的直接传 Token 就行;模型名字更是各叫各的。业务方想从 A 模型切到 B 模型,常常要改好几个文件,重新发版,稍不留神就把线上服务搞挂了。
litellm 最核心的价值,就是把“模型调用”这个动作从业务代码里剥离出来,变成基础设施的一部分。业务侧只需要知道:我要一个聊天补全结果,传什么内容,用哪个业务别名。至于这个别名背后指向的是哪家服务商、用什么模型版本、用什么密钥,都不需要关心。这样做的收益很直接:模型切换、多模型备份、成本分摊,都变成了网关层的配置问题,而不是代码问题。
1.2 litellm 的核心设计:统一入口 + 可配置路由
litellm 的定位是一个轻量级网关服务。它对外提供 HTTP API,接口风格尽量兼容市面上主流模型客户端的调用习惯,客户端基本改一下 base_url 和 api_key 就能接入。对内的核心是一个可配置的路由层,你通过一份 YAML 配置文件,定义“业务模型别名”到“真实模型服务”的映射关系。
一份最小的配置文件大概是这样的:
model_list: - model_name: my-chat-model litellm_params: model: service-a/chat-v1 api_key: sk-xxxx这里 model_name 是给业务方看的别名,litellm_params 是实际要调用的模型标识和相关参数。业务方向网关传 model: my-chat-model,litellm 会查一下路由表,把这个请求转发给真正的 service-a/chat-v1。如果同一个别名下面配置了多个真实模型,litellm 还能做负载均衡和故障转移。
这套设计并不仅仅是省了一次封装。它把模型服务商当成了一种可插拔资源,公司内部如果要做一个统一的 AI 能力平台,litellm 天然就是那个中间层。
1.3 谁适合接入 litellm,改造前先想清楚这三件事
不是所有项目都需要一上来就接 litellm,但它非常适合以下三类场景:
- 团队里有多个业务在同时接入模型,缺少统一入口,各写各的调用代码。
- 需要频繁做模型切换、A/B 对比,或者想找一个“失败自动换模型”的兜底方案。
- 需要精细管控 API 调用,比如按团队、按用户设置预算,审计到底谁在调用模型、花了多少钱。
接入前,我建议你先想清楚三件事:第一,业务侧习惯用同步调用还是流式输出,这会影响网关的配置和客户端写法;第二,公司现有的密钥管理方式是什么,litellm 需要能拿到上游密钥,但又不希望明文写进代码仓库;第三,这个网关是只给自己用,还是准备给多个团队共用,后者需要从一开始就规划好虚拟 Key 和预算体系。
2. 核心机制拆解:网关为什么能解决这些问题
2.1 协议层面的“翻译层”:对外一套格式,对内各自适配
litellm 的核心机制,是协议转换。它对外提供一套固定的请求格式,比如聊天补全请求就是POST /v1/chat/completions,参数包含 model、messages、temperature 这些通用字段。当请求进来后,litellm 会根据配置把请求转成目标服务商真正能识别的结构,再拿着对应的上游密钥去发起调用。
这个翻译层解决了一个很实际的痛点:模型服务商之间,接口风格其实并不完全一样。有些厂商的鉴权方式在 Header 里,有些在 URL 参数里;有些流式返回的格式也不同。如果每个业务组都要自己处理这些差异,很容易出错。litellm 把这些差异收拢到一处,由它去适配。业务代码从此只需要关心“传什么内容”,不需要关心“怎么传才能被服务商接受”。
这里我多说一句,接入 litellm 的过程中,最省力的方式是保持它默认的接口风格。很多人会想着“我有自己的封装,能不能让 litellm 兼容我的格式”,这种想法会把简单问题复杂化。litellm 的兼容性已经覆盖了绝大多数常见客户端,顺着它的格式走,后续升级成本最低。
2.2 模型路由和故障转移:不把鸡蛋放在一个篮子里
litellm 的路由能力,是它和普通 HTTP 转发服务最大的区别。同一个业务模型名,可以对应多个真实模型服务,或者对应同一个服务商的多个密钥。litellm 会根据策略选择实际要调用的那一个。
常见的路由策略包括轮询、随机、按权重分配,还有基于响应延迟的智能路由。比如你配置了两个模型都叫 my-chat-model,一个效果更好但价格贵,另一个稍微差一点但便宜,你可以设置权重,让大部分流量走便宜的,小部分走贵的,用来验证效果差异。
更有价值的是故障转移。模型服务商偶尔会限流或者直接返回 5xx 错误,litellm 支持在这种情况把请求自动切到另一个健康节点。这个能力在生产环境非常实用。我见过不少团队,因为某一家服务商抖动,结果整个模型功能全部不可用。用 litellm 配置一个 fallback,至少能保证服务不中断,用户感知到的只是响应慢了一点。
需要说明的是,路由策略并不是越复杂越好。刚开始建议先配置轮询或者简单权重,把可观测性做好后再逐步尝试动态策略,否则出了问题都很难定位是策略原因还是模型原因。
2.3 配额、预算与观测:让每个 key 都花得明白
litellm 的另外一个亮点,是内置了预算和观测能力。你可以为每个虚拟 Key 设置最大消费额度,一旦达到上限,这个 Key 的请求就会被拒绝。在企业内部,这意味着可以把成本精确分摊到团队、项目甚至个人。
我实际用过之后,觉得最舒服的一点是它可以区分“用户看到的 Key”和“真正调上游的 Key”。业务开发手里拿的是一个虚拟 Key,即使泄露了,也不至于把上游模型服务商的根密钥暴露出去。管理员在 litellm 上创建虚拟 Key、绑定预算、查看调用日志,全部都可以在一个管理界面完成。
观测方面,litellm 默认会记录每次请求的模型、耗时、输入输出 token 数量、估算费用。你可以通过管理端 API 拉取这些数据,也可以接 webhook 推到自己的监控平台。对中小团队来说,光是省掉自己写调用审计系统的功夫,就已经值回部署成本了。
3. 实操:从零部署 litellm 网关
3.1 安装与启动:拿最小配置先跑起来
litellm 是一个 Python 包,安装起来很简单。建议在虚拟环境里安装,避免和系统 Python 环境冲突。
pip install 'litellm[proxy]'这里带上了 proxy 扩展,主要是为了让网关所需的依赖一并装好。安装完成后,先写一个最简配置,随便配一个模型服务进去。比如:
model_list: - model_name: demo-chat litellm_params: model: service-a/chat-v1 api_key: sk-demo然后启动:
litellm --config ./config.yaml默认情况下,litellm 会在http://localhost:4000起服务。启动成功后,你可以先访问/health接口确认服务状态,也可以访问/看内置的可交互 API 文档。这一步不要跳过,先把网关跑起来,再逐步加配置,排查问题时能少很多干扰。
3.2 模型列表配置:YAML 里写清“门牌号”
配置文件是 litellm 的灵魂,第一次接入的人最容易在 model_list 上栽跟头。我强烈建议把 model_name 和真实的模型标识分开理解:model_name 是你自己给业务方看的门牌号,litellm_params 下面的 model 才是真正的地址。
model_list: - model_name: internal-chat litellm_params: model: provider-a/chat-v2 api_key: os.environ/PROVIDER_A_KEY上面的写法里,api_key 通过环境变量引用,这是比直接写明文更稳妥的方式。litellm 支持os.environ/变量名这种写法,部署的时候只要在系统环境变量里设置好对应值就行。
如果你想让同一个别名支持多个真实模型,那就多写几条记录,model_name 保持一致:
model_list: - model_name: internal-chat litellm_params: model: provider-a/chat-v2 api_key: os.environ/PROVIDER_A_KEY - model_name: internal-chat litellm_params: model: provider-b/chat-v1 api_key: os.environ/PROVIDER_B_KEY这样配置之后,业务方仍然只传model: internal-chat,网关会自己决定走哪条上游。多条记录的场景下,litellm 默认会做负载均衡,你也可以通过 router_settings 调整策略。
3.3 客户端接入:业务代码只认一套 API
网关跑起来后,客户端接入就非常顺滑了。以 Python 为例,大部分常见模型客户端都支持自定义 base_url,你只要把它指向 litellm 服务的地址,再把 api_key 换成在 litellm 上生成的虚拟 Key 就行。
from llm_client import Client client = Client( base_url="http://localhost:4000", api_key="sk-litellm-virtual-key" ) resp = client.chat.completions.create( model="internal-chat", messages=[{"role": "user", "content": "你好"}] ) print(resp.choices[0].message.content)这段代码里没有出现任何真实模型服务商的信息,业务团队拿到之后不需要关心上游是谁。也可以用纯 HTTP 请求验证:
curl http://localhost:4000/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-litellm-virtual-key" \ -d '{ "model": "internal-chat", "messages": [{"role": "user", "content": "你好"}] }'如果你本来就是用主流模型客户端开发的,改成 litellm 通常只需要改两个配置:地址和 Key。这也是 litellm 在接入阶段体验最好的地方,几乎不需要动业务逻辑。
3.4 进阶配置:重试、超时、流式和缓存
基础配置跑通之后,我建议再补几个生产环境必须考虑的配置项。
首先是超时。模型调用通常比较慢,尤其是生成式模型,动辄几十秒,网关默认超时可能不够。可以在 router_settings 里设置一个合理的超时时间:
router_settings: retries: 2 timeout: 60retries 表示失败后重试次数,timeout 是每次请求的上游超时时间。注意这两个参数要配合流式输出一起考虑,流式请求一般会持续很久,超时设置太短会导致长文本生成中途断开。
其次是缓存。litellm 支持 semantic caching,可以缓存重复请求的结果。对内部工具类应用来说,很多问题可能是反复问的,开启缓存能明显降低调用成本和响应时间:
litellm_settings: cache: true不过缓存要慎重,不适合强实时性场景。如果业务数据经常变化,建议只在匹配度要求比较严格的情况下开启,或者设置较短的缓存过期时间。
最后是流式输出。如果你要在对话应用里实现“打字机”效果,客户端记得传stream: true,litellm 会透传上游的流式事件。对于使用常见 SDK 的客户端,流式解析是自动完成的,主要确保网关和客户端的超时配置都不至于切断长连接。
4. 常见问题与排查实录
4.1 鉴权失败:为什么一直 401
litellm 的鉴权链路有两层:第一层是客户端和 litellm 之间,使用你在 litellm 管理端创建的虚拟 Key;第二层是 litellm 和上游模型服务商之间,使用你配置在 YAML 里的真实 Key。排查 401,首先分清楚是哪一层出了问题。
如果客户端请求直接返回 401,说明虚拟 Key 不存在或者已被禁用。可以去管理端重新生成一个 Key,确认请求头里 Bearer 后面跟的是最新的值。如果虚拟 Key 没问题,但还是失败,那就需要打开 litellm 的详细日志,看它转发到上游时是不是返回了 401。这个场景十有八九是 YAML 里的 api_key 没配对,或者环境变量没有被正确加载。可以先在启动终端里 echo 一下环境变量,确认进程确实能看到这个值。
我踩过的一个坑是:在本地终端设置了环境变量,但用 systemd 或者容器启动 litellm 时没有同步过去,结果网关起来了,key 一直为空,所有请求都报鉴权失败。排查的时候一定要确认运行 litellm 的那个进程环境,而不是你当前 shell 的环境。
4.2 模型映射错误:报“模型不存在”怎么办
这个问题的典型表现是:业务传 model: internal-chat,litellm 返回 model not found。原因通常是 model_name 写错了,或者配置文件改了之后没有重启网关。
litellm 启动时会加载模型列表并登记路由表,如果修改了 YAML,必须重启才能生效。排查时可以直接调用 litellm 的管理接口,查看当前 model_list 里有哪些可用的 model_name,和配置文件对照一下。有时候配置里写了多个同名 model_name,中间某一条语法有问题,整组都加载不出来,这种情况在启动日志里能看到报错,建议逐条检查缩进和字段名。
还要注意,litellm_params 里的 model 标识要和模型服务商实际提供的版本一致。有些服务商模型名里带版本号、带日期,写错一个字母就会失败。拿不准的时候,先绕过 litellm,用上游原始客户端测一下真实模型名能不能调用,成功了再写进配置。
4.3 流式输出和超时问题
流式输出的问题,大部分出现在代理层和后端之间的缓冲上。如果你发现客户端等很久才收到第一个 token,但上游直接用流式调用时很快,说明网关所在网络环境到模型服务商的链路质量一般。litellm 本身对流式的处理开销很低,瓶颈通常在于跨地域的网络延迟。生产环境尽量把 litellm 部署在离上游服务更近的机房,能明显改善首包时间。
超时方面,我建议不要把 timeout 设成固定值。生成式模型的耗时和输入长度、输出长度强相关,短请求可能几秒就结束,长请求可能跑几分钟。更稳妥的做法是:客户端自己设置合理的超时,网关的 timeout 设置得稍微宽松一些,让请求能完整体验完,不要因为网关过早超时导致用户看到断掉的内容。
4.4 成本统计不准怎么办
litellm 自带的成本计算依赖内置的模型价格表。大多数主流模型在刚发布时价格还算准确,但价格调整或者新模型出现后,内置数据不一定能同步跟上。如果你发现 litellm 统计的费用和你从模型服务商后台看到的不一致,可以在配置里手动覆盖价格。litellm 支持 custom pricing 相关的配置,按实际账单校准即可。
这里有个小技巧:尽早把成本统计接入到自己的监控系统。litellm 本身虽然提供日志和统计,但数据保留策略、可视化能力都不如专业监控平台。通过 webhook 把调用日志实时推送出去,再用看板展示消费趋势,这样一旦费用暴涨,团队能第一时间发现是哪个 Key、哪个模型出了问题。
5. 落地经验与扩展方向
5.1 多环境多团队的部署建议
如果你不是给自己一个人的小工具用,而是准备给团队共用,我建议从一开始就做好隔离。开发、测试、生产环境使用不同的 litellm 实例和不同的虚拟 Key,避免有人拿着生产 Key 去调测试模型。
虚拟 Key 的命名要规范。可以用“团队名-项目名-用途”的结构,方便在日志里追踪。预算也要分开设,比如给某个数据组设置 500 元/月的上限,给另一个运营组设置 200 元/月。这样即便某个业务方写了个死循环疯狂调模型,损失也是可控的。
配置文件要纳入版本管理。模型切换、参数调整都应该走代码评审流程。我在实际项目里看到过最头疼的情况就是有人直接登录服务器改了 YAML,不通知任何人,结果其他人排查问题排查了半天,最后发现是配置被临时改过。把配置当成代码看待,是稳定运行的前提。
5.2 从单点网关到高可用的演进
litellm 默认使用本地 SQLite 保存 Key 和日志,单机部署足够。但如果整个公司的 AI 能力都依赖这个网关,就必须考虑高可用。
高可用方案一般分两步:第一步,让 litellm 使用外部数据库,比如 PostgreSQL,保证多实例之间虚拟 Key、预算数据是共享的;第二步,部署多个 litellm 实例,前面挂负载均衡,由负载均衡负责分发请求。litellm 实例本身基本无状态,真正的共享数据在数据库里,所以横向扩展难度不大。
另外,litellm 本身也支持将数据存到 Redis 等外部缓存,多实例场景下可以提升性能和一致性。这个演进不要一开始就做,流量到了瓶颈再升级,否则运维复杂度会提前压到你头上。
5.3 让 litellm 真正融入你的技术栈
litellm 作为一个中间层,最大的优势是可以和现有技术栈衔接。比如公司内部已经有模型服务目录,可以通过脚本自动生成 litellm 配置;已经有一套指标采集系统,可以通过 webhook 把调用数据汇总上去;CI/CD 流程里也可以加一个“模型回归测试”的环节,每次切换模型后自动跑一遍既有测试用例,对比响应质量。
我在实际落地时的一个习惯是,先把所有上游模型的关键参数写到一个文档里,然后照着文档配置 litellm,而不是边配边试。几次踩坑之后,我发现配置文件的版本化和管理比部署本身更重要。如果你们团队正在搭建模型统一入口,litellm 是一个值得认真对待的选项,先从小流量开始,跑顺了再逐步接管所有模型调用,这个过程比想象中要平滑。