写代码这几年,最让我上头的不是模型效果不够好,而是每个模型服务商的接口格式都不一样。今天要聊的 litellm,就是专门治这个毛病的工具。它用一个统一的标准格式去调各家大模型的服务,相当于给模型API装了一个通用转接头。如果你干的是应用开发、AI产品落地、测试或者运维,只要你的项目里要接大模型,这篇内容基本就是冲着你来的。
我自己第一次接触 litellm 也是抱着试试看的心态,毕竟这类“统一封装层”的项目太多了,要么文档画饼、要么代码烂尾。但用下来一段时间之后,我觉得它的设计思路确实踩在了真实痛点上:开发时一套代码到处跑,上线后又能集中管理密钥、控制预算、观察日志。这篇就基于我实际部署与调用的经验,把 litellm 从是什么、怎么部署、怎么配、到怎么排坑,完整过一遍。
1. 先把话说清楚:litellm 到底解决了什么
1.1 大家 API 不统一这件事,有多恶心
你可以把各家模型服务商想象成不同品牌的充电桩:有的接口是圆头,有的是方头,有的需要你先扫码再插枪,有的插上就充。你想在自己的应用里同时用三四家模型服务,就得给每一家单独写一套适配代码,维护三四种请求格式、鉴权方式、错误码体系。今天这家升级了字段,明天那家改了限流策略,你的代码就得跟着改一轮。这还只是“能用”的阶段,等你想做负载均衡、自动重试、用量统计的时候,工作量直接翻倍。
litellm 的思路特别朴素:既然大家的协议不统一,那我在上面加一层,把请求统一成 OpenAI 的格式,再转给各家。你的业务代码只需要认识 OpenAI 那一种格式,剩下的转换、路由、重试、鉴权,全交给 litellm。我之前搞过一个模拟项目X,里面要同时测三家模型的中文效果,没有 litellm 之前,光是写适配层就花了两天,换用 litellm 之后,配置文件一改,新增一家服务商基本就是加一个 key 的事。
1.2 litellm 它在架构里站哪个位置
你可以在 litellm 官方文档里看到它自称“LLM API Gateway”,但我更愿意把它理解成一个位于你的应用和所有大模型服务之间的中间代理。从部署形态上看,litellm 可以作为一个本地服务跑起来,暴露一个类似 OpenAI 的 HTTP 接口,你的后端服务把请求发给它,再由它把请求分发到对应的真实模型服务。
这个位置非常关键,因为它意味着 litellm 对你业务代码是透明的。你以前写openai.ChatCompletion.create(...),现在改成请求 litellm 的地址,代码整体不用动。你以前在一个服务里写死了某一家服务商的 key,现在 key 统一收敛到 litellm 的配置文件里,由它统一管。你以前需要在代码里做超时重试,现在 litellm 自己就能处理。
所以从架构视角看,litellm 是个典型的“门面模式”:对外暴露统一接口,对内隐藏复杂差异。这个设计带来的好处是,模型服务和业务应用之间的耦合被切断了,后续想换服务商、加新模型、调整路由策略,都不需要重新发版业务代码。
2. 核心能力盘点:它不只是“翻译官”
2.1 统一接口:一套代码接所有模型
这是 litellm 给开发者最直观的价值。它支持的范围非常广,主流服务商基本都覆盖了,包括市面上常见的几家头部模型服务商,以及大量开源模型托管平台。你只需要写符合 OpenAI 接口规范的请求体(model、messages、temperature这些字段),litellm 会负责翻译成目标服务商能理解的格式。
一个真实的调用场景是:你在 litellm 配置里把模型名映射好了,比如把gpt-4o、claude-3-5-sonnet、gemini-1.5-pro分别映射到三个后端服务,然后你的代码里只需要改model字段的名字就能切换实际调用哪家。这种切换发生在运行期,不需要改动请求结构,也不需要改动你的业务逻辑。我实测下来,从发请求到拿到返回,延迟损失基本可以忽略,因为 litellm 转发请求的时间开销是微秒到毫秒级别,大头还是花在模型服务本身的推理上。
2.2 路由、重试与限流:把容错逻辑从业务里抽出来
最先让我觉得 litellm 有点东西的,是它内置的路由策略。你可以设置多个不同服务商的 key,littelhm 会按负载均衡策略分发请求,也可以按优先级路由,某个服务挂了自动把流量切换到备用服务。
它配合重试机制的效果很实用。以前我在代码里手动处理 429 限流和 5xx 服务错误,要么写循环重试,要么直接失败让用户再试一次。litellm 把这个逻辑内置了,你可以在配置里设置最大重试次数和重试退避策略。当请求被限流时,它会先等一段退避时间再重试,超时时间也可以单独配置。这个对生产环境尤其重要,因为大模型服务的限流策略普遍比较频繁,特别是并发上来之后,429 几乎天天见。
如果你有预算控制的诉求,litellm 也提供了请求速率限制和 token 数量限制。可以按 key、按用户、按 IP 设置每分钟请求数和 token 上限,超过就拒绝服务。这等于把之前的流量控制能力下放到了网关层,业务代码里就不用自己维护计数器了。
2.3 密钥管理与观测:给甲方评审时最好用的两张牌
以前做项目,模型服务的密钥就写在代码配置里,凡是能拉到代码仓库的人都能看到。团队一大,密钥就满天飞,出了问题根本不知道是哪个同事、哪个项目在用。
litellm 给出的方案是把密钥统一管起来:你可以在配置里维护虚拟密钥(Virtual Key),业务方拿的是 litellm 生成的虚拟 key,而不是真实服务商的 key。虚拟 key 可以绑定独立的速率限制、预算上限和过期时间。就算某个虚拟 key 泄露了,直接吊销它就行,不会影响真实密钥。
观测方面,litellm 提供了详细的使用日志,包括每次请求的模型、token 消耗、延迟、成功失败状态、费用估算。这些数据汇总起来,就能做模型服务商的成本对比。我之前在两个模型服务商之间犹豫选型,就是靠 litellm 的日志跑了一周的流量,最后按总 token 数和费用做了决策,不用自己去手工统计了。
3. 上手实操:从零部署一套 litellm 网关
3.1 环境准备和安装方式选择
litellm 是一个 Python 项目,所以最简单的安装方式就是通过 pip。不过在安装之前,我建议你先确认一下 Python 版本,建议用 3.9 以上,版本太低的话某些依赖会装不上或者运行时报错。
装起来就一行:
pip install "litellm[proxy]"注意这个[proxy]很重要,它会把跑代理服务所需的额外依赖一起装进来,比如 FastAPI、uvicorn 这些。如果你只装 litellm 而漏了 proxy 部分,那命令行里可能没有litellm启动代理的命令。装完之后可以验证一下:
litellm --version如果你不想污染本机 Python 环境,也可以用 Docker 方式部署。官方镜像拉下来就能跑,这种方式对后面上生产环境会更友好一些:
docker pull ghcr.io/berriai/litellm:main-latest docker run -d --name litellm-proxy -p 4000:4000 -v $(pwd)/config.yaml:/app/config.yaml ghcr.io/berriai/litellm:main-latest3.2 一个最简配置示例:接两家服务商
安装之后需要一份配置文件,litellm 启动时会读取它。下面这个是我整理过的最简配置,包含了两家服务商的接入:
model_list: - model_name: gpt-4o litellm_params: model: gpt-4o api_key: os.environ/OPENAI_API_KEY - model_name: claude-3-5-sonnet litellm_params: model: claude-3-5-sonnet api_key: os.environ/ANTHROPIC_API_KEY general_settings: master_key: sk-my-master-key这里有两个关键点。一个是model_name是给外部调用时用的模型名,而litellm_params.model是写实际服务商认识的那个模型名,两者可以不一致。另一个是master_key,这是访问 litellm 管理接口和请求转发的总密钥,建议用一个足够复杂的长字符串。
启动代理服务:
litellm --config config.yaml --port 4000跑起来之后,litellm 会监听 4000 端口,你本地就有一个 OpenAI 格式的接口了。
3.3 用一份代码同时调两个模型
网关跑起来之后,用 OpenAI 的官方 SDK 就能调,地址指向本地,key 用 master_key:
import openai client = openai.OpenAI( api_key="sk-my-master-key", base_url="http://localhost:4000" ) resp = client.chat.completions.create( model="gpt-4o", messages=[ {"role": "user", "content": "你好,介绍一下你自己"} ] ) print(resp.choices[0].message.content)想切到另一家模型,只需要把model改成claude-3-5-sonnet即可。你的代码、鉴权方式、请求参数都不用变,这就是 litellm 给你省下的工作量。
如果不用 Python,直接 http 请求也行:
curl http://localhost:4000/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-my-master-key" \ -d '{ "model": "gpt-4o", "messages": [{"role": "user", "content": "你好"}] }'3.4 配置文件里的进阶参数:路由与重试
当你的场景需要更高级的容错时,可以给模型列表补充路由和重试配置。比如下面这个配置把gpt-4o映射到了两个不同服务商的 key 上,当一个服务不可用时自动切换:
model_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY - model_name: gpt-4o litellm_params: model: azure/gpt-4o api_key: os.environ/AZURE_API_KEY api_base: os.environ/AZURE_API_BASE router_settings: routing_strategy: "simple-shuffle" num_retries: 3 retry_after: 0.2这里routing_strategy可以选择多种策略,simple-shuffle就是轮流分配,实现负载均衡;还有基于失败次数的兜底策略等。真实生产环境里,我比较推荐至少配置三到四家服务商作为池子,配合重试参数,整体的服务稳定性会有明显提升。
4. 部署之后我做的几件关键事
4.1 虚拟密钥和预算管控的实际配置
部署完 litellm 之后,第一件事不是着急接业务,而是把密钥体系和预算体系搭好。litellm 提供了一套管理接口,你可以用 master_key 去创建虚拟密钥:
curl http://localhost:4000/key/generate \ -H "Authorization: Bearer sk-my-master-key" \ -H "Content-Type: application/json" \ -d '{ "max_parallel_requests": 10, "tpm_limit": 60000, "budget_limit": 100.0 }'出来的响应里会包含一个key字段,这个就是虚拟密钥,发给业务方用即可。请求量被限制在每分钟 6 万 token,总预算 100 美元,花超了会被自动拒绝。
我实际测试过,这个预算限制是按美元实时估算扣减的,精度虽然做不到分毫不差,但用来卡住成本上限足够了。对团队或创业项目来说,这个功能相当于给你的模型账单上了一道保险丝,至少不会因为一个死循环把预算烧穿。
4.2 通过日志看每次请求到底花了多少钱
litellm 自带日志记录,默认在 SQLite 或者你可以用--database_url参数连接到 PostgreSQL。日志里的核心字段包括请求模型、请求时间、prompt tokens、completion tokens、总 token 数、响应延迟、费用估算和成功状态。
我一般会在接入的第一个工作日晚上看一遍日志,重点关注两类数据:一是模型响应延迟的分布,特别是有没有 P99 明显偏高的情况;二是 token 消耗费用最高的前几条请求,看看是不是有冗余内容输出。这个“先看日志再调配置”的习惯,几乎每次都能发现一些可以优化的点。
有一个小功能很有用,就是 litellm 支持按 API Key 分组统计费用。配合虚拟密钥的精细化管理,你可以很清楚地看到业务线A和业务线B分别用了多少费用、调了多少次模型。这对多部门共用一套网关的场景是非常有用的。
4.3 用 Docker 跑生产环境时的配置补充
生产环境不推荐直接裸跑 Python 进程,建议用 Docker Compose 编排。我这个模拟项目X 的 compose 文件里,大概长这样:
services: litellm: image: ghcr.io/berriai/litellm:main-latest ports: - "4000:4000" volumes: - ./config.yaml:/app/config.yaml - ./litellm.db:/app/litellm.db environment: - OPENAI_API_KEY=${OPENAI_API_KEY} - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} - DATABASE_URL=postgresql://user:pass@postgres:5432/litellm depends_on: - postgres restart: always postgres: image: postgres:16 environment: POSTGRES_USER: user POSTGRES_PASSWORD: pass POSTGRES_DB: litellm volumes: - pgdata:/var/lib/postgresql/data volumes: pgdata:这里需要注意,配置文件里如果用了os.environ/OPENAI_API_KEY这种写法,真实密钥是通过环境变量注入的,不会明文写在配置文件里。这也是生产环境的基本要求:密钥不进仓库,从环境变量去读。顺便一提,我发现restart: always这个参数很有必要,因为 litellm 进程如果因为内存占用或者其他原因挂了,Docker 会自动拉起来,省得出门在外收到告警才发现服务已经躺了很久。
5. 常见问题与排查技巧实录
5.1 模型名报错:404 还是 400 要分清
我们在接入某个新服务商时,最容易碰到的问题就是模型名映射不对。litellm 转发请求时,如果找不到对应的模型名,会返回 404,提示模型不存在;如果模型名写对了但请求参数不兼容,会返回 400。
排查这两个错误的方法不一样。404 优先去看配置文件里的model_name与实际请求时的model是否完全一致,注意大小写和空格都要精确匹配。400 则要打开 litellm 的 debug 日志,看它转发给上游服务商的 body 里哪个字段不合法,通常是不支持某个参数,把它从请求里删掉或禁用就行。
提示:在本地调试时可以用
litellm --config config.yaml --port 4000 --debug启动,debug 模式会在控制台打印详细的请求与响应日志,排查问题效率会高很多。
5.2 限流和超时:业务侧要不要兜底
虽然 litellm 内置了重试机制,但我在实际使用中还是建议业务侧自己保留一个简单的超时控制。原因是:litellm 的重试只是解决“上游限流之后自动换个时间再试”的问题,如果你的业务对响应时间要求很高,重试反而会增加整体等待时长。
我在配置里通常会同时设置request_timeout为 60 秒,但业务侧用 30 秒超时来控制自己的等待上限。两者配合起来的效果是:litellm 在内部尽量兜底重试,但如果 30 秒内没结果,业务侧先返回降级内容,避免用户白等。这是一个在生产环境验证过比较稳妥的做法,单靠网关或单靠业务侧都不是最优解。
5.3 Docker 部署后容器重启丢配置的问题
很多人刚开始用 Docker 跑 litellm 时会遇到一个问题:启动时用的配置和 token、日志数据都在容器里,容器一删就全没了。解决方法是挂载卷,把配置文件和 SQLite 数据库文件都挂到宿主机上。这也是我前面 compose 里写./litellm.db:/app/litellm.db的原因。
如果你更换了 litellm 镜像版本,启动后日志数据显示为空,十有八九就是数据库文件没有挂载到同一个位置。这个坑我踩过一次之后,已经把“先挂卷再启动”当成了默认动作。
5.4 请求延迟突然变高
如果你发现 litellm 转发请求的延迟整体上涨,先不要怀疑 litellm 的性能,它本质上只是一个 HTTP 代理,延迟增量非常有限。大概率的问题出在上游服务商侧。这时候打开 litellm 的日志,看每次请求的上游响应时间,如果上游响应时间已经很大,那是模型服务本身的问题,可能是服务商限流或者在高峰时段推理负载高。
另一种情况是配置了多 key 负载均衡,但由于某个 key 已经被限流,litellm 反复重试反而拖慢了整体响应。解决办法是把该 key 的权重调低或者直接停用,网络池里留健康节点即可。
6. 回顾一下我的真实使用感受
litellm 用了一段时间下来,我最大的体会是:它把“接大模型”这件事从“写适配代码”变成了“写配置文件”。你不需要为每一家模型服务商写维护一份 SDK 调用逻辑,也不用在业务代码里塞一堆重试和限流判断。团队协作时,新同学只需要看一个配置文件,就能知道当前接了哪些模型、密钥是谁在管、费用上限是多少。
如果后续要扩展,litellm 做的功能还有不少可以挖掘的空间。它支持多模型间的自动回退策略、支持流式输出、支持在同一请求里并行调用多个模型做结果对比,这些对做复杂 AI 应用的人来说都很实用。
最后分享一个工作习惯:每次改完配置,先用一条最简单的请求验证连通性,再跑通核心链路,慢慢扩大验证面。这个习惯看着老套,但配合 litellm 这种配置驱动的工具,确实能省下大量排查问题的时间。直接一把梭把全部模型写进配置,出问题时根本分不清是哪一层的锅,这种教训我经历过太多次了。