从零打通统一大模型网关:我用 litellm 托管了项目里所有 LLM 调用
先抛一个场景:你负责一个需要同时对接多个大模型 API 的项目,早先用的是 OpenAI 格式,后来加上 Claude 兼容接口,又接了开源模型的内网服务,还想让新同事统一用同一套 key 来访问,别隔三差五来问“这个模型的环境变量在哪配”。如果你也经历过这种到处找代码、改 base_url、补鉴权头的日子,那 litellm 就是专门解决这个问题的工具。
litellm 是一个开源的 LLM API 代理 / 网关,核心作用是把各种主流大模型接口统一成一个和 OpenAI SDK 兼容的入口。简单的说,你原来的client = OpenAI(...)代码几乎不用改,只要把 base_url 指到 litellm 服务,把 key 换成 litellm 分配的 key,就能直接调度几百个模型后端。我自己用下来的感受是:它不只是一个接口转发器,更像是一个带路由、限流、预算统计、模型管理后台的“API 聚合层”。适合那些需要给团队统一模型入口、做成本治理、或者想在不同模型之间灵活切换的开发者,不管你是三五人的小项目,还是已经有多个服务在跑的中型团队,litellm 都能快速落地。
这篇文章我会从设计思路、核心功能、实际部署、配置拆解到踩坑记录,完整讲一遍我是怎么用它的,顺便把那些官方文档里没写清楚、但实操中一定会遇到的细节一并交代清楚。
1. 为什么需要一层“LLM 网关”:litellm 的设计思路
先想一个问题:直接在自己的服务里挨个封装不同模型的 SDK 不就行了?为什么还要多跑一个代理进程?
1.1 多模型集成最大的痛点是“格式锁”
如果你只用一家模型,问题不大。现实是,我们会因为效果、成本、供应稳定性等原因,在同一个应用里同时用多家模型的 API。每家 API 的请求结构、参数命名、鉴权方式都不同,而且模型更新很快,接口也会变。如果直接把各家 SDK 散落在业务代码里,每次换模型都要改业务逻辑,测试量翻倍,新人理解成本也高。
litellm 的解法很直白:它不管你上游是哪个厂商,统一用 OpenAI 的/v1/chat/completions协议向下游暴露。你只需准备一份配置文件,声明每个模型对应的真实 provider 地址、密钥和模型名;litellm 收到请求后,按配置把 OpenAI 格式转成对应厂商的格式,再把响应标准化回传。这样业务代码只认一套协议——OpenAI SDK,这已经是事实上的标准接口了。
1.2 网关带来的额外红利:密钥收敛与控制
把 key 集中在 litellm 配置文件里,对团队来说是个大好事。以前每个服务都要配一套自己的 key,密钥散落在环境变量、配置中心甚至代码仓库里。现在统一通过 litellm 暴露一个虚拟 key(比如sk-abc123),业务侧永远只有 litellm 的地址和 key,上游密钥完全隔离。就算虚拟 key 泄漏,你也只在 litellm 里回收这一个 key,不影响真实上游账号。
另外在网关层可以做全局的限流、重试、模型禁用、预算上限,这些如果散落在每个业务服务里,根本没法统一管理。这也是我最终选择引入 litellm 的核心原因:不是因为它转发性能多快,而是因为“管理能力”集中了。
1.3 兼容性策略:为什么只兼容 OpenAI 格式
业界现在很多工具(比如各类框架的 LangChain/LlamaIndex)默认支持 OpenAI 格式的接入,很多开源模型自己做服务化时也会提供一个 OpenAI 兼容接口。litellm 选择只暴露 OpenAI 格式,很大胆但非常聪明:对上层应用来说,接入成本极低;对下层 provider 来说,litellm 负责翻译,双方互不干扰。实测下来,普通文本对话、流式输出、函数调用(tools)、JSON 输出等常用场景都能透传,比较省心。
2. 核心功能拆解:litellm 到底能管哪些事
光说“网关”太抽象,我把功能分几个维度拆开,你看完就明白它能覆盖多少场景了。
2.1 统一模型路由与模型名映射
在 litellm 的配置里,你可以自己定义对外模型名,比如对外统一叫gpt-4o-mini,但内部实际路由到 Azure 上的某个部署或者 Ollama 本地服务。这样换模型时业务代码零改动,只要调配置。命名上我还喜欢用带版本的方式,比如claude-3.5-sonnet-prod,方便标注生产环境用的模型版本。
路由规则也可以做条件判断:比如根据请求参数或上下文长度,决定打到哪个后端;也可以按模型组做 fallback,主模型挂了自动切到备选模型。这个对稳定性提升很明显,我是在主模型偶尔限流的场景下用上的。
2.2 虚拟密钥与多租户隔离
litellm 支持创建一堆虚拟 key,每个 key 可以绑定某些模型、设置预算上限(按美元计)、设置速率限制(RPM/TPM),还能绑定到某个团队或用户。你可以在管理后台生成一个只允许访问claude-3.5-sonnet、月度预算 50 美元的 key 交给某个下游服务。
多租户隔离就靠这个:A 团队用 key1,只能访问 A 的模型池;B 团队用 key2,访问 B 的模型池。两个团队互相看不到对方的 key 和配额。如果你接的是面向内部多部门的大模型平台,这个能力几乎是刚需。
2.3 流式与非流式的一体化处理
现在很多应用都是打字机式输出,litellm 对 SSE 流式响应是做了一层缓冲转发的,实测体验比较稳定。它不会把整个响应缓存完再发给下游,而是边接收上游的 chunk 边透传给客户端,因此首字延迟和直连模型差距很小。对于非流式请求,litellm 也支持自动转换成流式,方便你统一做前端的流式渲染。
2.4 成本追踪与用量统计
这个功能是亮点。litellm 内置了用量记录,每次请求都会记录模型名、token 数、延迟、成本估算、key、用户 ID,还可以把这些数据打到 Prometheus、Grafana 做可视化。用它做成本看板非常方便,哪条业务线烧了多少钱,一看便知。我甚至可以直接拿它的数据库表写 SQL 去做月度账单拆分。
2.5 对 provider 的兼容范围
litellm 官方支持一百多种 provider,包括 OpenAI、Anthropic、Google Gemini、Azure OpenAI、各类国产模型、开源模型(通过 Ollama/vLLM 等),还支持 Bedrock、VertexAI。大多数我们日常接触的模型都能直接写配置,不需要自己写适配代码。如果你想接入自定义的 HTTP 接口,也可以用custom_llm_provider自定义 provider,灵活性够高。
2.6 缓存与重试
litellm 支持语义缓存和请求缓存:当你的请求使用相同 prompt(或近似语义命中)时,可以直接返回缓存结果,减少重复调用,降低成本。它的重试机制也做得比较细,可以针对特定错误码(比如限流、5xx、超时)自动重试,并有指数退避策略,配合多模型 fallback 使用效果很好。
3. 从零部署:最小可用的 litellm 实例
下面直接进入实操。我的环境是一台普通 Linux 服务器,Python 3.10+,用 Docker 或 pip 都可以。我更推荐 pip 直接装,因为后续改配置和升级方便。
3.1 安装与启动基础服务
pip install 'litellm[proxy]'安装完成后,启动一个最简单的服务:
litellm --config config.yaml --port 4000如果没有任何配置,它默认会在 4000 端口起一个代理,但没有模型可用。我们需要写一份配置文件。先来一份最简单的:
model_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY这里解释一下字段:model_name是暴露给下游的“别名”;litellm_params里model是真实的 provider 模型标识,格式是provider/模型名,比如openai/gpt-4o、anthropic/claude-3-5-sonnet-latest、ollama/llama3。api_key可以直接写明文,也可以写os.environ/环境变量名让它自动读环境变量,推荐后者。
启动后,你可以直接用一个 GET 请求测活:
curl http://localhost:4000/health返回OK就是好了。
3.2 用 OpenAI SDK 连接 litellm
这是我最喜欢的一点,业务侧代码几乎不动。以 Python OpenAI SDK 为例:
from openai import OpenAI client = OpenAI( base_url="http://localhost:4000/v1", api_key="sk-1234", # 这个 key 是 litellm 的虚拟 key,后面讲怎么创建 ) resp = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": "你好"}], ) print(resp.choices[0].message.content)你看,model参数填的是我们在配置里定义的model_name,而不是真实上游模型名。这样当我把gpt-4o的配置改成指向anthropic/claude-3-5-sonnet-latest时,代码完全不用动,只要重启 litellm 让配置生效即可。链路瞬间切换,这是真省事。
3.3 配置多个 provider 与模型
实际项目中模型不会只有一个。我们看一份多模型的配置:
model_list: - model_name: my-gpt4 litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY - model_name: my-claude litellm_params: model: anthropic/claude-3-5-sonnet-latest api_key: os.environ/ANTHROPIC_API_KEY max_tokens: 8192 - model_name: my-gemini litellm_params: model: gemini/gemini-1.5-pro api_key: os.environ/GEMINI_API_KEY - model_name: local-llama litellm_params: model: ollama/llama3.1:8b api_base: http://localhost:11434注意几个细节:对于 ollama 这类本地模型,你不需要 api_key,但必须指定api_base,否则 litellm 不知道去哪儿找你的 Ollama 服务。对于某些 provider,可能需要额外的参数,比如 Azure OpenAI 需要api_base、api_version,版本参数经常忘,好在 litellm 的错误信息会提示。
配置完以后,重启 litellm,你就能用上面代码里的my-gpt4、my-claude等发请求了。
注意:
model字段里的前缀,比如openai、anthropic、gemini、ollama,是 litellm 内部识别 provider 的标识,不能乱写。具体支持哪些,可以运行litellm --help或查官方文档。如果你不确定自己用的 provider 对应前缀,直接在搜索引擎搜“litellm + 提供商名”基本都有结果。
4. 进阶配置:模型组、负载均衡、预算与权限
跑通最小实例之后,面临的才是真正的工程化问题:高并发、故障转移、成本限制、团队权限。litellm 在这些方面提供了比较完整的配置项,我把常用的几个讲透。
4.1 模型组做故障转移
一个很常见的需求:OpenAI 某个模型偶尔限流,想在限流时自动切到备用模型(比如 Anthropic)。litellm 用model_group配合 fallback 来实现。修改配置:
model_list: - model_name: primary-assistant litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY - model_name: primary-assistant litellm_params: model: anthropic/claude-3-5-sonnet-latest api_key: os.environ/ANTHROPIC_API_KEY注意,这里两个模型的model_name都叫primary-assistant,litellm 会把它们视为同一个模型组。默认情况下它会做负载均衡——按 round-robin 轮流分发请求。如果其中一个模型报错,litellm 自动尝试组内下一个模型。你还可以引入routing_strategy: "usage-based"让 litellm 根据实时延迟和成功率动态路由,实测比较聪明,能自动避开已经故障的端点。
4.2 全局与局部预算管理
预算管控是我愿意强烈推荐大家用的功能。很多人觉得“就几个 key,不需要预算”,但模型失控调用一个月扣掉大几千不是夸张。litellm 的预算可以做到很细:
- 本身支持在配置里写一个全局最大预算
max_budget; - 每个虚拟 key 也可以设置单独
budget、budget_duration(比如每天 10 美元); - 还支持按用户维度的预算,配合用户 ID 一起用。
general_settings: master_key: sk-master-12345 database_url: postgresql://user:pass@localhost:5432/litellm max_budget: 100 # 全局每月预算注意database_url很重要。如果不用数据库,litellm 只能把 key、用量这些信息存在内存里,一重启全没了,预算和虚拟 key 也不持久。所以生产环境必须挂一个 Postgres 数据库。我第一次用的时候没配数据库,重启后创建的 key 全失效,白白排查了半天。
虚拟 key 的创建一般通过管理接口或者 UI。启动时加上--port 4000,浏览器访问http://localhost:4000/ui就能打开一个简易管理后台,在里面可以创建 key、绑定模型、设置预算。也可以直接用 API:
curl -X POST http://localhost:4000/key/generate \ -H "Authorization: Bearer sk-master-12345" \ -H "Content-Type: application/json" \ -d '{ "models": ["my-gpt4"], "budget": 20, "budget_duration": "30d" }'返回里key字段就是给下游用的虚拟 key。把真实的sk-master-12345好好保管,它相当于主管理员 key,能管理所有虚拟 key。
4.3 多租户与用户管理
如果你的平台要服务多个业务线,建议为每个业务线建一个team,然后给 team 分配 key。litellm 的team概念挺清晰:team 里可以有多个用户,key 可以绑到用户或团队。你可以这么操作:先通过 UI 或 API 创建一个 team,比如 “搜索产品线”,然后生成一个只允许访问该产品线所需模型的 key,预算设成该产品线的月度成本上限。这样业务线之间完全隔离,某条线爆预算也只是它的 key 被停,不影响别人。
4.4 限流与并发控制
有时候上游模型并发有限,litellm 支持在模型组配置里设置rpm(每分钟请求数)和tpm(每分钟 token 数)限制,超出后会自动排队或重试。例如:
litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY rpm: 200 tpm: 100000设置后,litellm 会像一个漏斗一样,限制每秒发往该模型的请求数量,避免一不小心打爆上游的配额。
4.5 语义缓存:降低成本的好帮手
litellm 支持基于向量相似度的缓存,也就是“语义缓存”。假设你的客服机器人经常收到相似的提问,第一次调用模型后,后续相似问题可以直接返回缓存答案。配置如下:
litellm_settings: set_verbose: true cache: true cache_params: type: redis host: localhost port: 6379这里我用的 Redis 作为缓存存储,生产环境很推荐。缓存粒度也可以控制,比如对某些请求跳过缓存。注意,语义缓存需要 embedding 模型来算向量,litellm 默认会调用一个 embedding 模型,你需要在模型列表里配置一个 embedding 模型;如果不配置,可以用简单的请求缓存(完全相同的 prompt)。我的经验是:对公共知识类问题效果好,对个性化或随机生成类问题收益有限。
5. 实用运维指南:日志、监控与排错
litellm 本身只是一个代理进程,你可以把它当做一个常规服务来运维。但它有一些特定于 LLM 业务的监控指标,值得专门讲。
5.1 日志查看与问题定位
默认运行时 litellm 会在终端打印日志,包含请求用的模型、provider、耗时、token 数、返回状态等。我习惯加一个log_requests: true将请求日志记录到数据库中,之后可以查表:
litellm_settings: log_requests: true然后在数据库里查看LiteLLM_RequestLog表,每一行是一次请求的记录,包括model、user、prompt_tokens、completion_tokens、total_cost、response_time。有一次业务方说某条线调用模型太慢,我直接查这个表,发现是某个时间点某个模型在高并发下排队,立刻定位到了瓶颈。
5.2 Prometheus 监控
生产环境建议打开 Prometheus 指标接口。在配置里加:
general_settings: prometheus_metrics: truelitellm 会在/metrics端点输出标准指标,包括请求总数、token 总数、成本总额、缓存命中率、模型错误次数等。我用 Grafana 接这个端点做过一个内部看板,主要盯三块:首要的就是成本曲线,每天/每周花了多少钱;其次是模型错误率,5xx 数量飙升的时候能及时发现;最后是响应延迟,出现飙升可以结合上游状态判断。
5.3 常见问题和排查思路实录
我在实际用的时候踩过不少坑,这里挑几个典型的一并记录:
第一个:认证失败但 key 看起来没问题
如果你用虚拟 key 调用时返回 401,先确认是否用 master key 还是虚拟 key。master key 是默认生成的(如果没配,默认是sk-master-key,强烈建议改成自己的),虚拟 key 则需要先通过/key/generate生成。还有,检查你启动 litellm 时是否加了--master_key参数?如果加了,默认配置里的 master key 就是它,之前生成的 key 可能对应的是另一个 key,所以要保证你用的 master key 一致。
第二个:模型返回 404 not found
多半是配置中的model字段写错了。尤其是 Azure OpenAI,需要在litellm_params里额外写api_base和api_version,模型名要填你自己部署的模型名称(deployment name),不是模型类型名。这个顺序经常搞反,我一开始就吃过亏。
第三个:调用 Anthropic 模型时参数兼容
Anthropic 的max_tokens是必填项,但 OpenAI 格式里没这个字段。litellm 会自动为它补一个默认值(好像是 4096?),但如果你需要更大,最好显式在配置里写max_tokens: 8192。另一个问题:Anthropic 目前不支持某些 OpenAI 参数,比如logit_bias可能被忽略。如果你传了不支持的参数,litellm 通常会忽略或者报 warning,不会整个请求失败,但输出可能不符合预期。建议在测试阶段多打日志观察。
第四个:本地模型(vLLM/Ollama)和 openai 兼容模式
如果你用 Ollama 或者 vLLM 起的 OpenAI 兼容服务,注意 litellm 的模型前缀写法是ollama/模型名或者openai/模型名?这里有个细节:如果 vLLM 服务本身已经兼容 OpenAI 格式,你可以直接用openai/模型名加上你的api_base指过去,它就会按 OpenAI 方式转发,不需要额外适配。Ollama 则有自己的前缀,因为 Ollama 的原生接口格式与 OpenAI 不完全一致,litellm 转换起来更顺手。
第五个:配置修改后没生效
litellm 不会热加载配置,改完config.yaml必须重启进程。如果你用 systemd 或 docker,记得重启。如果是容器,用docker restart 容器名即可。另外,如果你忘了加--port,默认端口是 4000;如果你同时跑多个实例,端口冲突也会导致启动失败,日志会马上告诉你。
第六个:长时间的流式请求中断
有些长对话模型可能输出几十秒,中途网络闪断可能导致流断开。litellm 有超时设置,可以在litellm_settings里写:
litellm_settings: request_timeout: 600s默认可能只有 300 秒?反正我调成了 600 秒以确保大输出不中断。同时客户端那边也要设置对应超时,否则 litellm 没断,客户端先断,两边不一致,服务体验就会很奇怪。
部署层面,我建议给 litellm 单独开一个服务账号运行,不要拿 root 跑。资源占用方面,它本身很轻,主要是 Python 进程和数据库连接。如果请求量很大,可以用多个 litellm 实例配合负载均衡,由于有数据库持久化,多实例共享状态没有问题。也可以把 litellm 放进 Docker,镜像本身就带好了环境,用 docker-compose 管理最简单。
6. 实战复盘:一个内部多租户接入案例
前面讲了这么多功能,我拿一个实际遇到的场景做一次完整复盘。假设我们现在有一个内部智能助手平台,三个业务线(客服、营销、研发)要接入大模型,各自有不同的模型偏好和预算。原来的情况是,每个业务线自己写代码接各家 API,密钥管理混乱,月底要对账很难。我们决定用 litellm 统一收敛入口。
我的落地方案分四步走:
第一步,梳理模型需求。客服线需要性价比高的中文模型,营销线需要输出质量高、支持长文本的模型,研发线主要用代码模型。据此建立模型清单,每个模型配置好 provider、key、别名。比如客服线用claude-haiku,营销线用gpt-4o,研发线用deepseek-coder和claude-3-5-sonnet。所有 key 通过环境变量注入 litellm 配置文件。
第二步,建团队和虚拟 key。在 litellm 管理后台创建三个团队,每个团队创建两个 key(一个给开发环境、一个给生产环境),开发环境 key 预算设 20 美元/月,生产环境 key 预算按业务线预估设置,比如客服线 200 美元/月。同时设置 RMP、TPM 限制防止异常流量。
第三步,业务方接入。我们给每个业务线发了一份简单的接入文档,示例代码就是上面 OpenAI SDK 的样子。因为几乎不用改代码,只用改了 base_url 和 api_key,整个接入过程大约半天就完成了。
第四步,监控与优化。上线后我们在 Grafana 上做了一个简单看板:总成本、各团队成本、各模型调用量、错误率。第一个月就发现营销线的成本增长异常,点开明细发现是产品经理测试时把上下文加太长,单次 token 消耗巨大。后来给团队 key 设了单次请求最大 token 限制,成本立刻稳定下来。
这个案例里,litellm 最大的价值不是“省代码”,而是“省管理成本”。如果没有一个统一网关,母数检查、配额调整、账号回收……任何一个操作都可能要碰业务代码。
我个人在实际操作中的体会是,litellm 作为工具已经相当成熟,但它需要你认真对待配置和运维,不能抱着“装完就跑”的心态。我这里再分享几个用了大半年之后觉得特别加分的“私藏”技巧。
第一,善用环境变量加--config的加载顺序。如果你有多个环境(dev/staging/prod),可以在每个环境的服务器上配置不同的.env,然后在同一个 config.yaml 里用os.environ/XXX_API_KEY去读,这样配置文件几乎可以完全复用,环境差异通过环境变量隔离,很干净。
第二,给关键模型设置一个“影子”模型组。比如my-model-shadow,指向你想试用但不想全量切换的另一个模型。代码先调my-model不变,你可以在 litellm 层把my-model的路由做调整,或者用 UI 手动一键切换组内模型权重。这个在灰度切换模型时非常管用,不用改业务代码。
第三,如果你用 UI,记得把UI_USERNAME和UI_PASSWORD设置好,默认没有开认证是很危险的。有一次我临时起了一个实例忘了设,同网段其他机器都能打开管理后台,好在只是内网测试,但这种事一次都不能有。
litellm 这套东西真正用起来后,你会发现它的上限其实很高:除了代理,它是你所有大模型资产的“控制面”。不管是成本、权限、稳定性还是可观测性,都能收口到一个地方。如果你现在已经被“多模型、多 key、多账单”搞得焦头烂额,不需要犹豫,直接把 litellm 搭起来试试,大概率能省下你未来几个月反复接 API 的体力活。