先从一个真实场景说起。我做过一个小团队的技术负责人,那阵子团队同时在接 OpenAI、某云厂商的自研大模型,还有两家开源模型的托管服务。每个服务商的 SDK 风格都不一样,OpenAI 用client.chat.completions.create,另外一家用client.generate,还有一家干脆只给了 HTTP 接口。每次切换模型,代码要改一遍、Key 要换一个、账单还得去三个后台分别拉。这种状态维持了大概三周,直到我把 LiteLLM 摆到它们面前:所有模型统一成一套 OpenAI 格式的接口,Key 集中管理,预算统一控制,路由由一个本地服务完成。这就是 LiteLLM 最核心的价值——它不是某个模型,也不是某个平台的客户端,而是把你手里所有 AI 服务的调用入口收拢成一个网关。
如果你手头也攒了不少模型服务的 API,或者你想让团队从一套代码切到另一套模型时不再手忙脚乱,又或者你只想给项目加一层成本控制和鉴权能力,那这篇内容就是写给你的。下面我会从它解决什么问题开始,一路讲到本地部署、生产级配置、常见坑,最后放一些我实际踩过后的经验。
1. LiteLLM 解决的核心问题:当 AI 服务商多到记不住的时候
1.1 为什么需要统一网关:SDK 碎片化的现实
做 AI 应用的人都有体会:模型本身不是瓶颈,接口生态的碎片化才是。每家的请求格式不同,有的传messages,有的传prompt;鉴权方式也不同,有的是Bearer,有的是x-api-key;参数命名更是各说各话,temperature和top_p还算通用,到了别的平台可能叫temperature但取值范围不一样,甚至支持top_k的地方另一家压根不认。如果你在代码里硬编码了某一家 SDK,那换模型的成本就等同于重写一次调用层。
LiteLLM 的思路很直接:它就是那个调用层。它把各家原生 SDK 的差异吸收到网关内部,对外只暴露一个你早就熟透的 OpenAI 风格接口。也就是说,你的业务代码永远只认一套格式,真正跟不同服务商打交道的事,全部由 LiteLLM 完成。
注意:这个“OpenAI 兼容接口”不是认死理。OpenAI SDK 本身已经是事实上的行业标准,市面上几乎所有模型托管平台都提供了兼容端点。LiteLLM 等于把这一套标准反向用到了所有平台身上。
1.2 核心价值拆解:接入、鉴权、计量三位一体
LiteLLM 能做的远不止“格式转换”,它更像一个流量调度与控制面板,我总结下来是三件事:
- 统一接入层:所有上游模型,不管来自哪个厂商或自建推理服务,都在
config.yaml里登记为一个数据条目。业务侧调用时用的是你自己起的别名,例如gpt-4o-team-a,背后它指向谁、真实型号叫什么、走哪个 API 地址,业务侧完全不用关心。 - 集中鉴权层:网关对外可以颁发自己的虚拟 Key(Virtual Keys),团队里每个人、每个服务拿到的是一把专用钥匙。你可以随时吊销其中某一把,而不必回到上游平台去滚动 API Key。这把虚拟钥匙还可以绑定额度上限,比裸用原始 Key 安全得多。
- 计量与预算层:每一条请求的 token 消耗、模型费率、预估成本都会被网关记录下来。你可以按 Key、按用户、按团队统计消耗,超过预算的请求会被直接拒绝。这一点对 to B 项目和多团队协作的价值非常大,后面我单独展开。
1.3 LiteLLM 不是什么:把预期放对位置
为了避免读完文章后产生误解,我先把边界讲清楚。LiteLLM 不是一个模型训练框架,也不是一个向量数据库,更不是某种 AI 应用开发平台。它不负责生成 token,只负责把你请求转发到真正生成 token 的服务并返回结果。它本身也不存业务数据,虽然可以配置数据库来保存计费和 Key 信息,但那只是元数据。把它理解为“API 路由器 + 计费面板 + 密钥管理”三合一,这个预期就非常准确。
2. 上手实操:本地把第一个代理跑起来
2.1 安装与启动:五分钟跑通默认代理
LiteLLM 的安装几乎没有门槛,只要你的环境里有 Python 3.8 以上版本:
pip install 'litellm[proxy]'装完后你可以在命令行直接启动一个最基本的代理:
litellm --model openai/gpt-4o --api_key sk-你的key启动后,LiteLLM 会在本地8000端口监听,这时候你直接把原来指向https://api.openai.com的地址改成http://localhost:8000,原来的api_key填什么都行(如果你还没开启虚拟密钥校验),代码一行都不用改,就能发起来第一轮请求。
这就是 LiteLLM 设计的精妙之处:它不是要你重写业务,而是在你现有架构前面加一层。我的建议是第一次做验证时就拿一个现有脚本改base_url试试,5 分钟内你会看到原来调用 OpenAI 的代码原封不动跑通了。
提示:
openai/gpt-4o这种provider/model格式是 LiteLLM 的通用写法。它约定了一套“厂商前缀 + 模型名”的命名方式,例如anthropic/claude-3-5-sonnet、azure/gpt-4o、bedrock/llama3-70b。这样在配置里一眼就能看出模型属于谁。
2.2 用配置文件管理多模型:静态路由的精髓
命令行启动适合验证,一旦模型数量超过两个,就必须用配置文件来管理了。下面是最常见的一个最小配置示例:
model_list: - model_name: gpt-4o-mini litellm_params: model: openai/gpt-4o-mini api_key: os.environ/OPENAI_API_KEY - model_name: claude-sonnet litellm_params: model: anthropic/claude-3-5-sonnet api_key: os.environ/ANTHROPIC_API_KEY - model_name: local-llama litellm_params: model: host_vllm/llama3-70b api_base: http://localhost:8001/v1启动方式变成:
litellm --config config.yaml这份配置要说清楚几个点:
model_name是你对外暴露的别名,业务代码里只用这个名字,它跟上游实际型号完全解耦。litellm_params.model是真正的上游模型标识,格式是厂商/模型名,LiteLLM 会依据前缀加载对应的适配器。api_key可以指向环境变量,也可以明文写在配置里(不推荐),甚至某些本地模型不需要 Key。- 如果你自己用 vLLM 或 Ollama 起了推理服务,可以通过
api_base指向它,让 LiteLLM 也管理本地自建的模型。
配置写好后,调用方脚本只需把客户端指向http://localhost:8000,然后设置model="claude-sonnet",拿到的就是 Anthropic 模型的返回结果。业务代码彻底和上游厂商解耦,这就是配置路由带来的最大好处。
2.3 第一个关键参数:可见别名如何影响你到底层
我在项目里经常被问到“别名会不会影响模型能力?”答案是:不会。别名只是网关维护的映射关系,你传入gpt-4o-mini时,网关会把它翻译成真正的openai/gpt-4o-mini去请求。但要注意的是,如果你在同一个model_name下面挂了好几个上游模型,LiteLLM 会默认用负载均衡策略轮询它们。这既是优点也是隐患:你嘴上说的“claude-sonnet”实际上可能一会儿打到 Anthropic,一会儿打到别的服务商,响应质量和成本都会不一样。所以在起别名时我建议直接保持真实的模型名语义,不要乱起,否则后面统计账单的时候你会一头雾水。
3. 深入核心机制:虚拟密钥、预算与负载均衡
3.1 虚拟密钥:给团队发钥匙,而不是交出主密钥
如果你只是自己调试,直接在请求头里带上上游 Key 也说得过去。但一旦团队超过三个人,或者你要把能力开放给外部系统,就必须启用虚拟密钥体系。
启用方式是设置主密钥并挂上数据库:
export LITELLM_MASTER_KEY=sk-your-master-key export DATABASE_URL=postgresql://user:pass@localhost:5432/litellm litellm --config config.yaml --database_url $DATABASE_URL之后访问http://localhost:8000/ui可以看到一个管理面板,在面板里你可以为每个成员或每条业务线生成一个新的虚拟 Key。这个 Key 的格式像sk-1234...,它并不是上游平台的 Key,而是 LiteLLM 自己签发的令牌。
我用一个例子来说明虚拟 Key 的价值。假设你给 A 业务发了一把 Key,给它设定的预算是每月 50 美元。某天这个 Key 被盗了,或者业务方使劲循环调用把预算打爆,你只需在面板上把该 Key 吊销,或者让预算上限自动拦截后续请求。你完全不需要跑到上游平台去重置 API Key,也不影响 B 业务继续使用。这比把同一个 OpenAI Key 发给所有人再后悔要安全得多。
3.2 预算控制:从“事后对账”到“事前拦截”
成本控制是我认为 LiteLLM 被低估的功能之一。很多团队在月底拉账单时才知道某条业务线超支了,但 LiteLLM 可以在请求发出前就做检查。
在配置文件中给某个 Key 设定限额的方式如下:
virtual_keys: - key: sk-业务A专用 max_budget: 50 budget_duration: 30d models: - gpt-4o-mini - claude-sonnet这样设置后,这个 Key 在 30 天内的累计花费一旦达到 50 美元,后续请求会直接返回 429 或预算耗尽错误,而不会硬着头皮继续调用上游接口。预算粒度还可以细化到单次请求限流、每分钟令牌数等。
这里我加一个思考供你参考:预算控制是“网关思维”与“SDK 思维”的分水岭。只用 SDK 的人看不了全局账单,而网关把每次请求的成本都归一化记录,让钱的问题变得可视化。
3.3 负载均衡与多 Key 轮转:消除单点限流
同一个厂商的同一个模型,往往有速率限制(RPM、TPM)。如果你只有一个 API Key,一旦跑批任务把额度打满,请求就会被限流。LiteLLM 支持把同一个上游模型对应到多个 Key 上,并自动轮转:
- model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY_1 litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY_2严格来说上面的写法不够直观,更清晰的写法是两条路由条目都叫gpt-4o,LiteLLM 会按顺序轮询或按负载情况分发。当某个 Key 触发限流时,网关会自动把请求切到下一个可用 Key。这个机制在跑评测脚本、批量数据处理时非常实用,能明显提高吞吐上限。
3.4 与 LangChain、OpenAI SDK 的无缝集成
用 LiteLLM 最大的爽点之一,就是它跟生态工具的兼容成本几乎为零。如果你在用 LangChain,它的OpenAI类本身接受base_url参数,把它指向 LiteLLM 即可。如果你在用 OpenAI 官方的 Python SDK 或 Node SDK,同样只需要改base_url。我的团队在迁移时,大约只花了一个下午就完成了所有服务的指向变更,后续新增模型时业务代码根本不动。
4. 部署到生产:从本地进程到高可用网关
4.1 容器化部署:推荐你直接上 Docker
本地开发用litellm --config就够了,但生产环境还是建议容器化。LiteLLM 官方提供了镜像,我用的是ghcr.io/berriai/litellm:main-latest。一个典型的docker-compose.yml结构是这样:
services: litellm: image: ghcr.io/berriai/litellm:main-latest ports: - "8000:8000" volumes: - ./config.yaml:/app/config.yaml environment: - LITELLM_MASTER_KEY=sk-master-key - DATABASE_URL=postgresql://litellm:litellm@postgres:5432/litellm - OPENAI_API_KEY=${OPENAI_API_KEY} depends_on: - postgres postgres: image: postgres:16 environment: - POSTGRES_USER=litellm - POSTGRES_PASSWORD=litellm - POSTGRES_DB=litellm用容器跑的好处是配置与环境变量一起走,部署到测试环境、预发环境时不需要重新安装依赖。而且把数据库独立出来之后,虚拟密钥和预算数据不会因容器重建而丢失。
注意:我首次部署时只配了 SQLite,并发一高就会出现数据库锁冲突。换成 PostgreSQL 后稳定性瞬间提升。生产环境务必用 PostgreSQL 这类独立数据库,不要用默认的本地库。
4.2 配置优先级:环境变量、配置文件、管理后台
LiteLLM 的配置来源有三个:启动参数、config.yaml、管理后台的运行时修改。理解它们的优先级很重要:
- 静态配置(模型路由)写在
config.yaml,重载服务后生效。 - 密钥和预算这类敏感信息走环境变量或管理面板。
- 后台 UI 里可以对虚拟密钥做动态调整,不需要重启服务。
三条通道相互补充,你不需要把所有信息都塞进 YAML。我的经验是:路由用文件管,密钥用环境变量管,团队配额用后台管,职责分明才不容易乱。
4.3 安全加固:网关前面的那一道防线
LiteLLM 本身只是一个代理,如果你直接暴露公网,至少要加三道防护:
- 启用主密钥校验:所有转发的请求必须携带
Authorization: Bearer <LITELLM_MASTER_KEY>或有效虚拟 Key,否则一律 401。 - 禁用默认文档:生产环境不要把管理后台 UI 暴露给公网,可以让它只监听内网端口,或者用你自己的网关加一层访问控制。
- 限制上游 Key 权限:即使 LiteLLM 被突破了,上游 Key 的权限也尽可能做成最小可用集,比如只允许使用特定模型。
4.4 可观测性:日志、用量与健康的结合
生产运维光能用不够,还得能观察。LiteLLM 自带/health端点可以查看后端模型健康情况,也提供了/spend/logs用来按请求维度查询消耗明细。在我自己的项目里,我会把它的日志接到现有的 ELK 或 ClickHouse 里,重点看三类数据:
- 失败率:哪个上游模型频繁报错,出错时是超时、限流还是鉴权问题。
- 延迟分布:P95 延迟是什么水平,多个模型之间的响应速度差异。
- 成本走势:按天聚合的美元消耗,用来跟预算阈值做对照。
这套可观测体系搭好之后,你会比原来更早发现某个模型质量下降或某个 Key 出现异常调用。
5. 踩坑实录与问题排查清单
5.1 最常见的五个坑,我替你先踩过了
坑一:模型前缀拼错,导致请求走错适配器
LiteLLM 是按厂商/模型名来分发请求的。如果你把anthropic/claude-3-5-sonnet写成了openai/claude-3-5-sonnet,网关会拿这个字符串去请求 OpenAI,然后返回 404 或模型不存在。排查时注意看报错信息里的模型地址,别被“model_not_found”误导。
坑二:虚拟 Key 没绑定模型,结果请求全被拒
在管理后台创建虚拟 Key 后,很多新手忘记给 Key 绑定可访问的模型列表,结果业务方拿着 Key 请求任何模型都被拒。虚拟 Key 默认的权限模型是显式授权,你得明确指定它可以用哪些模型。
坑三:预算时长单位理解错误
budget_duration支持30d、1h等单位。我遇到过有人写成30直接被当成秒处理,导致 Key 刚建好就过期。请务必带单位。
坑四:请求体里的model跟配置里不一致
当业务方直接传了model: openai/gpt-4o,而配置里别名是gpt-4o,LiteLLM 也能处理,但你可能绕过了别名的负载均衡配置。所以生产环境中最好在网关侧强制开启模型白名单,让请求只能使用你配置的别名。
坑五:忘了处理流式响应
LiteLLM 默认是支持流式输出的,但代理层如果配置了某些自定义超时或缓冲区,流式请求可能会被截断。遇到流式响应不完整时,优先检查反向代理层是否关闭了缓冲。
5.2 排查思路:先看日志,再看指标
当请求失败时,我通常按这个顺序排查:
- 看 LiteLLM 启动日志是否报上游连接错误。
- 用命令行直接
curl网关,排除业务代码的问题。 - 查
/health看模型健康状态。 - 查数据库里的
spend记录,确定请求是否到达了网关。
这套流程能快速把问题定位在“业务侧”“网关侧”还是“上游侧”。
5.3 性能调优:网关要不要加高并发参数
LiteLLM 基于 Python 的异步框架实现,默认性能对中小团队完全够用。如果你单机要支撑很高的并发,可以关注几个调整点:
- 数据库连接池:确保 PostgreSQL 的连接池上限够用,避免高并发时拿不到连接。
- 上游超时设置:通过
request_timeout合理配置超时,避免某个慢模型拖垮整体响应。 - 横向扩容:多个 LiteLLM 实例共享同一个 PostgreSQL,上方再挂一层负载均衡器,就能实现网关层的水平扩展。
6. 结尾:如果你准备引入 LiteLLM,我有几条私房建议
在实际项目里用 LiteLLM 一年多,我的整体感受是:它不是一个“看起来很酷但不实用”的玩具项目,而是真正把 AI 接入基础设施化的工具。刚开始你可能会觉得多了一层反而麻烦,但一旦模型数量上去、团队规模扩大,你会感谢这层“麻烦”帮你省下的协作成本。
最后分享三个摸索出来的技巧:
第一,先把配置写得极其简单,能跑通再慢慢加虚拟 Key、预算、鉴权。一上来就堆完整配置,出了问题你根本不知道是哪一部分引起的。第二,团队内发布一份调用规范,把base_url、模型别名、可用 Key 的获取方式写清楚,这款工具的价值有一半要靠规范才能兑现。第三,别忽略/health端点,把它接入你的监控系统,上游模型挂了你是第一个知道的人,而不是从业务那里听说的。如果你后续要做多模型灾备或成本优化,这些习惯都会派上大用场。