
1. 为什么需要一层“模型网关”我看到的几种真实痛在接触 litellm 之前我一度觉得多模型接入就是写几层胶水代码的事。后来陆续给几套内部应用做模型集成甚至帮朋友排查过线上故障才发现问题远不是“环境变量里多放几个 key”那么简单。你会有十几个服务各自调不同家的大模型有人用 OpenAI 格式有人用国内厂商的 SDK还有人直接怼着 Claude 原生接口写。等到要上线发现 prompt 版本对不上、计费口径对不上、连 model 名称都对不上运维的人想快速把一个模型切到另一个简直无从下手。这个痛点直接催生了 litellm 这种“模型网关”的流行它把所有供应商的差异收敛到一层业务侧只认 OpenAI 风格的接口其余都交给代理处理。1.1 接口格式不统一不是小问题很多开发者的第一反应是“格式不就多写一层 adapter 吗”。确实一个 adapter 解决不了多个团队并行接入的问题。假设你有 A、B、C 三个业务线A 用了 LangChainB 直接裸调 SDKC 走 Azure OpenAI。每个业务线都自己封装一次就意味着三套参数校验、三套错误码转换、三套 token 计数。而 litellm 的做法是把整个能力都收敛到代理服务里业务侧请求 /chat/completions携带一个 alias 模型名比如“gpt-4o-team-a”后面真正连的是什么都由配置中心掌控。这也是我会在内部反复强调的一句话与其在代码里做兼容不如在网络边界做兼容。1.2 模型名与计费信息割裂我最早接触 litellm 是因为一次成本账单核对。某团队每月在多个模型之间切换OpenAI 的账单按模型和 token 计费Anthropic 的计价单位又略有差异几个 provider 的报表格式都不一样财务想看清哪个业务线烧了多少钱只能靠手工拼 CSV。litellm 内置了一套“模型名到供应商”的映射表也维护了常见的 token 单价代理层就能把每次调用的 token 数和估算成本记下来。虽然它不是财务系统但胜在能统一记录接上你的日志系统后成本归属一下就清楚多了。1.3 网关层与代码内层 SDK架构选择你可能已经在代码库里直接依赖某个厂商的 SDK会觉得“再套一层网关”多一跳延迟偏高。我的看法是如果只是写个人脚本直接 SDK 完全没问题但一旦是多个后端服务共享一套模型资源必须把流量收敛到网关。网关带来的负载均衡、自动重试、预算控制都是业务代码里很难自己写稳妥的。而且它把模型替换变成了配置变更不用重新发版。延迟方面正常本地区域网内部转发损耗远小于一次模型调用的网络往返影响基本可以忽略。2. LiteLLM 拆开到底做了什么LiteLLM 本身提供的不是“一套 UI 或者一个魔改 SDK”我更愿意把它理解成一个自带模型目录的透明代理。它同时维护两种使用姿势一种是在 Python 代码里直接 import另一种是把它跑成一个独立服务。线上我更推荐后者因为独立服务可以做统一鉴权、配额和日志业务侧无感知。2.1 一个包还是两种使用姿势用起来最简单的方式是在 Python 脚本里这样写import litellm response litellm.completion( modelgpt-4o, messages[{role: user, content: 你好}], api_keysk-xxxx, )如果只到这个程度它还只是一个“帮你转发到不同供应商的 client”。真正有价值的是把它作为网关跑成服务所有请求都打到同一个端口然后由 litellm 路由到不同的后端。两种姿势底层逻辑一致区别是服务化之后配置可以热更新也可以接密钥和预算体系。2.2 核心对象Router 与配置服务化的核心概念是 Router。Router 持有全部模型供应商的凭据和策略每次进来一个请求它会根据 model 参数找到对应的一组上游再按路由策略挑一个发出去。一个最简配置文件看起来是这样model_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: ${OPENAI_API_KEY} - model_name: claude-3-5-sonnet litellm_params: model: anthropic/claude-3-5-sonnet api_key: ${ANTHROPIC_API_KEY}这里的 model_name 是业务侧看到的别名litellm_params 里真正指定供应商和原始模型名。配置足够干净团队里不懂供应商差异的后端也能轻松对接。另一个常被忽略的是它天然支持很多 provider 前缀比如 azure/、bedrock/、vertex_ai/、ollama/、huggingface/几乎不用改业务代码。2.3 调用链路过一遍一次完整请求的路径大致是业务服务发起 HTTP 请求到 litellm 网关网关先做身份校验和预算扣减再通过 Router 选择一个目标模型随后补全供应商 SDK 需要的参数把消息体转换成对应格式上游响应返回后litellm 统一转成 OpenAI 风格的响应体并顺带记录消耗的 token 和成本。对于业务侧而言它连的是“一个 OpenAI 服务”只是这个服务恰好什么模型都认。3. 从零跑通一个本地代理很多人看文档一上来就 Docker确实主流部署方式也是容器。但本地开发阶段最简单的反而是直接用 pip 装一个包启动内置服务。我习惯先在本机跑配置好再加运维层。3.1 安装与环境准备前提是 Python 3.9 以上的环境。执行pip install litellm装完后直接在终端启动litellm --port 4000 --config config.yaml首次启动它会读取配置、校验模型列表、检查环境变量里有没有对应的 key。如果 key 没配全启动并不会失败而是请求到对应模型时才报错这一点新手要注意。我会习惯在启动前用env | grep -i openai这类命令确认环境变量已经加载避免后面查半天。3.2 最小配置跑起来假设你有 OpenAI 的 key下面这份配置足够用model_list: - model_name: my-gpt litellm_params: model: openai/gpt-4o api_key: sk-xxxx启动后验证curl http://localhost:4000/v1/models看到返回的模型列表里有 my-gpt 就说明服务正常。接着发一个聊天请求curl http://localhost:4000/v1/chat/completions \ -H Authorization: Bearer sk-本地测试key \ -H Content-Type: application/json \ -d {model: my-gpt, messages: [{role: user, content: 讲个冷笑话}]}注意这里的 Authorization 头是 litellm 自身的访问控制和上游 OpenAI key 是两码事。如果还没有配置虚拟密钥服务会接受任意 Bearer 串上线前必须补上密钥管理。3.3 把本地开源模型也接进来litellm 一个很讨喜的点是能把本地模型统一管理起来。比如机器上跑着 Ollama 的 qwen2.5配置里加一条- model_name: local-qwen litellm_params: model: ollama/qwen2.5 api_base: http://localhost:11434加上这条之后业务代码里调用 local-qwen 和调用云端模型没有任何区别这在上线前做模型对比测试特别省事。我自己经常在同一套测试用例里切模型的别名A/B 效果对比就是改一个字符串的事。4. 生产环境真正要用的能力跑通代理只是开始真正让 litellm 值回票价的是生产环境那几件事负载均衡、失败回退、预算管理和可观测性。这几个能力也是我向别人推荐它的主要原因尤其是预算治理很多团队之前是完全没有手段的。4.1 多模型负载均衡与路由策略同一个模型名背后可以挂多个上游比如两家不同供应商都能提供同一个开源模型或者你有多个 OpenAI 账号共用额度。此时配置可以按权重拆分流量model_list: - model_name: shared-gpt litellm_params: model: openai/gpt-4o api_key: ${KEY_1} weight: 3 - model_name: shared-gpt litellm_params: model: openai/gpt-4o api_key: ${KEY_2} weight: 1Router 支持多种路由策略我不建议一上来就追求“最智能”稳定优先策略大致行为适用场景simple-shuffle按权重随机挑选多个同质 key 摊分流量least-busy挑当前未完成请求数最少的并发高的在线服务latency-based-routing记录历史延迟倾向最快上游对响应速度敏感usage-based-routing按 tpm / rpm 剩余配额路由有一些供应商限流严格实测下来头两个策略最容易上手后两个需要一定数据积累才能发挥效果。用量少的时候策略间差异不大但并发一上来least-busy 明显比 shuffle 能压住 P99。4.2 自动重试与失败回退模型接口总会抖动业务代码里最常见的做法是 try except 重试但重试逻辑在 litellm 里配置化以后统一性好很多而且可以指定不同供应商互为备用。一个常见的配置思路是router_settings: retries: 2 retry_after: 2 fallbacks: [ {model: shared-gpt, fallbacks: [claude-fallback]} ]意思是 shared-gpt 连续失败时自动切换到 claude-fallback业务方只感知延迟稍微变高不会直接看到 503。这个设计对线上鲁棒性提升很大。需要注意的是 fallback 的模型最好已经定义在 model_list 里别名要提前规划否则配置加载时会很混乱。4.3 预算、配额和应用维度治理我见过太多团队月底被账单吓一跳。litellm 的预算能力可以从两个层面控制一是对整个代理服务设总预算超过后直接拒绝请求二是按 key 或团队设单独限额。更常用的是给业务线一把虚拟 key预设max_budget这样即使某个测试脚本死循环它也只能烧到设定上限自动停止不会把整个月的额度搭进去。4.4 可观测性与成本报表litellm 把每次请求的延迟、token 数、成本都记录在案可以接 Prometheus 做指标监控也可以把结构化日志推到自建日志平台。我个人的习惯是先把成本字段单独拉一张表每天定时看。如果不做这一步配置里调路由策略就像闭眼开车根本不知道每次切换带来了多少成本变化。5. 周边生态和运维视角的补充litellm 不是孤立的一个服务它周边值得研究的东西不少。如果你已经在用 Redis、Prometheus或者需要多团队共享一个代理下面这几个点会直接影响部署方案。5.1 Redis 缓存与语义缓存差异模型调用是典型的外部 IO重复请求能缓则缓。litellm 支持把完整响应缓存到 Redis命中缓存就直接返回显著降低成本和延迟。不过要小心缓存只对完全相同的请求体生效prompt 里稍微加一个数字就失效。更高级的语义缓存需要外部向量库配合不要指望开箱即用。实际部署里我建议先开最基础的 Redis 缓存观察命中率再决定是否上复杂方案。5.2 虚拟密钥与团队权限隔离生产环境绝不能所有人共享一个主 key。litellm 的虚拟 key 机制相当于代理层的访问令牌每个 key 可以关联某个模型集合、预算上限和过期时间。给前端团队一把 key、给数据分析团队一把 key互不越权某一把泄露也能单独吊销。这一点在多人协作项目里特别重要否则一个 key 泄露就要全局换凭据牵一发动全身。5.3 与自建网关的取舍也有团队会选择自己写 Flask 转发层觉得“成本不高”。从我观察到的结果看自建版的维护成本往往在三个月后开始失控模型厂商新增一个参数自建层要跟上某供应商错误码变化自建层要跟上想加缓存、加配额全部自己造轮子。litellm 胜在把“模型供应商接入”这种脏活大量沉淀下来代码里少写几千行胶水逻辑更不用说它持续的版本迭代。当然如果你的需求极其定制自建也不是不行只是得接受这些长期成本。6. 我实测中反复踩到的坑和习惯最后这部分是我最想说的。文档写得再好实际用起来还是会碰到一些隐蔽的问题而且这些问题大多不会立刻报错而是慢慢磨掉你排查故障的效率。6.1 配置里前缀和 model_name 最容易搞混model_list 里model_name是“对外暴露的名字”而litellm_params.model才是真正调用供应商的模型名。不少人会直接把openai/gpt-4o写到 model_name 里表面上请求能通实际上就把“别名”和“真实供应商模型”混淆了。一旦后面想切换供应商这种写法会让你非常痛苦。我的规范是model_name 永远不带供应商前缀只用业务友好的名字。6.2 上游限流和重试的叠加效应litellm 默认开启重试但如果上游已经明确返回 429盲目按原请求重试只会加重限流。我建议针对不同错误码做分级策略网络错误和 5xx 可以重试429 要看 Retry-After 头再决定。否则线上可能出现雪崩式请求堆积尤其在多个服务共用同一个代理时时特别明显。这个问题在配置里没有一键开关要靠 router_settings 和请求头的配合来控制。6.3 长上下文与流式响应必须测一遍模型供应商对长文本、流式输出的处理差异比想象中大。litellm 在转发 SSE 时如果上游中途断开它可能表现为“正常开始但突然结束”业务侧如果没做超时判断页面会卡住。我始终建议在集成阶段就用一个长 prompt 测一次非流式和流式两条路径把超时时间写进下游代码别把希望完全寄托在代理层。6.4 一个值得坚持的部署习惯我实际使用中形成了一套比较固定的部署流程配置文件的密钥一律从环境变量读取不用明文每次改动配置先在本机同步模型列表验证上线前先放少量流量观察成本指标给每个团队单独建虚拟 key。这套流程不复杂但能挡住绝大多数线上事故。LiteLLM 这种工具最大的价值就是让这些流程不再依赖某个“懂行的同学”而是变成团队里可以照做的固定做法。最后再分享一个小技巧调试阶段可以在配置文件里临时加一个mock_response模型比如model: openai/gpt-4o配合本地 mock让 litellm 返回固定内容。这样即使上游服务不可用联调也不会被外部依赖卡住。等 mock 用完了再切回真实模型整个过程对业务代码完全透明非常省心。