litellm 实战:统一多模型 API 调用的网关方案
发布时间:2026/10/14 10:16:13 锦皓数字建站

最近一两年做大模型应用的人应该都有一种很强烈的体会模型选型越来越难了。不是模型不够用而是选择太多、接口太杂。今天接一个开源模型明天换个商用 API每次切换都要改一大堆代码、适配不同的参数格式和鉴权方式工程量不小。我自己在多个项目里都踩过这个坑有一阵子甚至在同一个项目里同时接了三家模型服务维护成本直接起飞。后来朋友安利了一个叫 litellm 的开源项目用了一段时间之后我基本把它当成了团队里所有模型调用的统一入口。这篇就把我对 litellm 的理解、实际部署和使用经验整理一下给同样被多模型整合折磨的朋友一个参考。1. 先搞懂 litellm 在解决什么问题1.1 多模型时代的第一痛点接口碎片化过去做 AI 应用大部分人的起点是调用某个固定的模型接口。代码里写死一个端点、一套鉴权、一种消息格式业务跑通就算完事。但现在的情况完全不同了同一个应用可能需要在不同场景下选择不同模型比如日常对话用通用模型、复杂推理用更强的大参数模型、需要低延迟就切到本地量化模型。每个模型厂商的 API 风格虽然有相似之处但细节差异能让人崩溃。举个最常见的例子OpenAI 兼容接口的消息格式是messages列表里面每个元素有role和content。但另一个厂商可能在同样的位置用prompt字符串又或者对temperature、max_tokens这类参数的命名和取值范围有自己的一套。更麻烦的是流式输出的格式有的走 SSE有的返回 JSON 数组有的压根不支持流式。这些差异意味着你每接入一个新模型都要重新写一段适配代码。如果业务逻辑里多条代码路径都直接依赖这些细节后面想切换模型或者加个新模型几乎是要伤筋动骨。litellm 干的事情非常简单直接它把所有这些模型的 API 差异吃掉对外暴露一套统一的接口风格。你只用学一次 litellm 的调用方式就能在背后切换到任意一个已被它支持的模型。这个抽象层的价值在模型数量变多之后会体现得淋漓尽致。1.2 litellm 在技术栈中的位置一个“模型网关”你可以把 litellm 理解成数据库连接池那类中间件只不过它代理的是大模型 API。它在你的业务代码和真实模型服务之间插入一个转发层。业务代码只和 litellm 交互litellm 负责把请求翻译成目标模型厂商的格式发出去再把结果转成统一格式返回。这个“网关”定位带来了很多额外好处。常见的鉴权信息、API Key 管理可以集中放在 litellm 这一层不用散落到业务代码里也不用担心前端把 Key 暴露出去。重试逻辑、超时控制、请求排队也都能在网关层统一处理。如果某个上游模型服务不稳定你还可以在 litellm 里配置自动把流量转移到备用模型上这对生产环境的稳定性帮助非常大。另外litellm 不是只能转发那些标准的云服务商 API它也支持接入本地跑的模型服务。比如你内网部署了一套基于开源模型的服务只要它暴露的是 OpenAI 兼容接口litellm 就可以把它当成一个普通上游接入。这样一来你在代码里的调用方式完全不用变只是通过配置切换上游实际提供服务的来源。1.3 什么时候值得上 litellm什么时候没必要虽然 litellm 很香但它也不是银弹并不是每个项目都必须上它。如果你只是在自己的脚本里调一两个模型也不需要频繁切换那直接写原生 SDK 反而更轻快。引入任何中间件都是有代价的litellm 的代价是额外一层配置和维护成本。但如果你遇到下面几种情况我觉得就该认真考虑它了项目里有多个业务模块各自都在直连模型 API鉴权信息和配置散落得到处都是。你希望给非技术同学比如产品、运营一个简单的入口去测试不同模型的效果。你需要把模型服务抽象出来方便未来切换供应商避免被某一家云服务商绑定太死。你对稳定性和成本有要求想统一做限流、配额管理、调用统计。我个人的经验是只要项目会持续迭代模型数量超过两个或者团队里同时有多条业务线需要调模型litellm 的收益就非常明显。它让你在做技术选型的时候更从容因为你不用在代码层面为一个模型做太多定制。2. 核心功能拆解litellm 到底提供了什么2.1 统一调用格式SDK 层的打开方式litellm 首先以一个 Python SDK 的形式存在。安装之后你的代码可以长这样from litellm import completion response completion( modelclaude-3.5-sonnet, messages[{role: user, content: 你好简单介绍一下你自己}], ) print(response.choices[0].message.content)注意看这里的model参数直接指定的是目标模型名称这里是框架内置的映射名而不是一个base_url。真正负责转发到哪个地址、使用哪个 Key全部由 litellm 在底层根据配置自动完成。你要是想换成另一个模型比如 GPT 系列或者某个开源模型只需要改model参数其他代码一行都不用动。这种用法对开发者来说很友好因为它的调用习惯跟 OpenAI 的 Python SDK 几乎一致。你甚至可以把 litellm 当成一个“能连所有模型的开源 SDK”来理解。如果你之前写过 OpenAI 接口那上手 litellm 基本没有学习成本把openai.ChatCompletion换成litellm.completion再补上模型映射配置就行。除了completionlitellm 还支持 embedding 接口也就是说文本向量化这一步也可以统一走 litellm 网关。这在一个项目里同时用到多种向量模型时非常方便。你可以在一个配置文件里声明可用的 embedding 模型然后在业务代码里随意切换不需要关心各家厂商的鉴权和参数细节。2.2 Proxy 模式直接帮你起一个 OpenAI 兼容服务比起单纯在 Python 代码里调用 SDKlitellm 更实用的形态是 Proxy 模式。简单说就是你在服务器上起一个网关进程它会暴露一个完整的 HTTP 端点这个端点兼容 OpenAI 的接口规范。你现有的项目哪怕是用很旧的 OpenAI SDK 版本只要把base_url改成 litellm proxy 的地址再把 API Key 换成 proxy 配置的 master key就能直接开始用。所有下游模型的路由和鉴权都在 proxy 侧完成。这个能力太关键了。意味着你不需要修改业务代码里已有的调用逻辑就能把流量切到 litellm 上。从代码层面看业务方感知不到背后的模型到底是什么他们只是以为自己在调一个“无限能力的 OpenAI 服务”。实际上背后可能是某个开源模型也可能是另一家厂商的商业 API。启动 proxy 也很简单先写一个配置文件然后一条命令就能跑起来litellm --config /path/to/config.yaml --port 8000启动之后http://你的服务器:8000就是一个标准 OpenAI 兼容端点。拿 curl 试一下curl http://你的服务器:8000/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer 你的masterkey \ -d { model: gpt-4o, messages: [{role: user, content: 你好}] }你会发现在输出结构、字段命名、错误格式上它跟 OpenAI 原版接口几乎一样。但实际处理请求的可能是你在配置里声明的一个本地模型服务。这让那些基于 OpenAI SDK 写的旧项目几乎零成本接入多模型切换能力非常实用。2.3 生产级网关的硬实力重试、降级、限流、预算一个只做转发的东西叫代理能扛生产压力的才配叫网关。litellm 在这一点上做得比较全面尤其是它的重试和降级机制我在实际项目中体会很深。先说重试。模型接口经常会出现瞬时错误比如限流、网络抖动、上游过载。litellm 允许你配置最大重试次数、重试间隔、退避策略。我经常会配一个 3 次重试失败后先停 1 秒再依次翻倍这样能比较平滑地应对短时间的高负载。再说降级。这是我最喜欢的功能。你可以给一个模型配置一个 fallback 列表。比如主模型是 A 厂商的服务如果连续请求都失败litellm 可以自动把请求转发到备选模型 B 上。而且它在返回结果里会带上实际使用的模型信息方便你追踪。这个机制对线上服务来说几乎是救命稻草尤其在主模型服务不稳定的时候能极大降低业务受影响的时间。限流和配额管理方面litellm 支持按 key、按用户、按 IP 分别设置请求速率和并发限制。它还支持设置预算上限比如某个业务线的月度 token 用量不能超过多少。一旦超限就可以自动拒绝后续请求或者路由到更便宜的模型。这些能力对一个多团队共享模型网关的场景特别重要能让成本可控不至于月底看到账单时心梗。另外litellm 还提供了请求日志和调用统计。谁在什么时间调了哪个模型、用了多少 token、花了多少钱这些数据都可以查询。对于想给业务部门做成本分摊的公司团队来说这个能力省去了自己开发计量计费模块的麻烦。2.4 模型管理与密钥托管的多团队协作价值多团队场景下模型密钥的集中管理往往比想象中重要。很多公司的模型 Key 分散在多个项目里有的甚至被提交到代码仓库里安全隐患很大。litellm proxy 可以把所有上游模型的密钥统一配置在服务端业务方拿到的只是访问 litellm 的 key。这些 key 分别对应不同的权限和预算即使某个业务方的 key 泄露了影响面也只是他自己那块不会波及主账号。同时litellm 支持定义模型别名。比如配置里把gpt-4o这个名称指向实际的上游模型当上游模型升级或者价格调整时你只需要在配置里改一次映射业务方完全无感知。这相当于给团队内部提供了一个稳定的模型命名规范避免了业务代码里写满各种供应商专有名称引起的混乱。统一管理和降级、限流、监控搭配起来litellm 就不只是一个“转发器”了它更像是一个团队级别的模型基础设施。你自己用的时候可能觉得它就是个工具但当团队扩大到多人、多项目的时候它能省下非常多协调和排障的时间。3. 实操落地从安装到完成一次跨模型调用3.1 安装部署的几种方式和环境准备litellm 的安装比较简单因为它本质上是一个 Python 包。官方推荐的做法是用 pip 直接安装pip install litellm另外你也可以把它作为 Docker 容器跑这个方式在隔离性和环境一致性上更有优势。我自己实际部署的时候更倾向于用 Docker因为我的服务器上还跑着其他服务用容器能避免 Python 依赖互相干扰也能方便地控资源。如果你用 Docker大概的思路是拉取 litellm 的官方镜像然后把宿主机上的config.yaml挂载进去。命令大概长这样docker run -d \ -p 8000:8000 \ -v $(pwd)/litellm_config.yaml:/app/config.yaml \ --name litellm \ ghcr.io/berriai/litellm:main-latest \ --config /app/config.yaml在准备环境的时候有几个小细节值得留意。一是确保服务器的 outbound 网络能访问你计划调用的模型 API 端点有些私有化部署环境的网络策略很严格这一步容易卡壳。二是如果你的模型 API 有额外的环境变量或证书配置需要在启动 litellm 时一并传入。比如某些模型厂商支持通过环境变量设置区域节点这些都要提前确认清楚。3.2 最小配置文件的写法与字段解析先看一个最简单的config.yamlmodel_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: sk-xxxxx - model_name: claude-3.5-sonnet litellm_params: model: anthropic/claude-3-5-sonnet-20241022 api_key: sk-ant-xxxxx - model_name: llama3.1 litellm_params: model: openai/llama3.1-70b api_base: http://你的内网模型服务:8000/v1 api_key: dummy-key这里的model_list是核心。model_name是你在业务代码里真正使用的模型名称可以任意指定比如你给团队定一个统一的llm-chat别名让所有应用都用它然后在配置里把llm-chat映射到某个具体模型。这样做的好处是未来换模型的时候团队代码完全不用动。litellm_params下面的model字段是 litellm 认识的上游模型标识。openai/gpt-4o的意思是走 OpenAI 的 SDK 格式去调 gpt-4oanthropic/claude-...是走 Anthropic 的格式。如果接的是 OpenAI 兼容服务比如本地部署的 vLLM、Ollama 等就在model里写openai/模型名再用api_base指到服务地址。在上面的例子里llama3.1实际上是接的一个本地服务但因为它是 OpenAI 兼容接口所以统一用openai/前缀去连接。这一点非常实用意味着你本地跑的开源模型和云端商业 API 在 litellm 的视角里没什么区别。3.3 Proxy 模式完整配置与验证流程配置写好后启动 proxy然后我习惯先做几轮验证确保路由正确。第一步确认服务状态和版本信息直接请求/health健康检查端点curl http://localhost:8000/health/liveliness第二步发起一个真实请求验证默认路由是否生效curl http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-master-key \ -d {model: gpt-4o, messages: [{role: user, content: ping}]}第三步在配置里临时把gpt-4o的api_base指向一个不存在的地址再发一次请求确认报错信息里能体现连接异常这能证明请求确实走了 litellm 的逻辑分支而不是直接透传。验证完再恢复配置。我还习惯看一下 litellm 的日志输出默认在控制台会打印每次请求的详细信息包括上游模型名、耗时、token 使用量。这些日志对排查问题非常有用比如某个请求慢你会看到是不是卡在重试上还是上游响应本身就慢。3.4 给团队引入时的路由分流与透明加密如果团队规模稍大或者你希望某些特定请求走特定模型litellm 支持基于请求内容的路由规则。比如判断消息里是否包含某个关键词然后自动路由到成本更低的模型或者根据用户 ID 把某类流量固定到一个模型上。这些规则在配置里声明式的写清楚就行改起来也很方便。还有一个我认为很重要的建议如果 litellm 和业务后端不在同一台机器上或者需要跨网络访问建议在 litellm 前面再加一层 HTTPS 反向代理比如用 Nginx给对外暴露的请求做一次 TLS 终止。这样可以避免 API Key 在网关上以明文方式传输。litellm 本身也可以配置持久的加密密钥来保护存储在数据库里的密钥数据这个功能在存储层非常关键。尤其是团队里有多个管理员协同维护配置时加密存储能减少密钥被意外泄露和查看的风险。4. 常见问题与排查技巧实录4.1 高频报错速查与处理思路我自己在实践里踩过不少坑这里把最典型的情况整理出来方便大家直接对号入座。模型返回 401 鉴权失败这种情况往往是上游模型的 API key 错误或者 key 没有开通对应模型的权限。重点检查litellm_params里的api_key是否对上以及上游账号的权限范围。一直提示 model not found常见原因是model_list里model_name和请求里的model字段不一致。注意 litellm 严格按配置匹配字符串多一个空格都不行。还有可能是你直接把业务给上游模型的名字写了进来但这个名称没有在model_name里声明litellm 自然无法识别。请求超时或重试次数过多先从日志看是请求卡在哪个环节。很多时候是上游模型本身负载高或者是 litellm 到上游的网络链路有延迟。可以在 litellm 的环境变量里调整超时时间比如设置LITELLM_REQUEST_TIMEOUT为 300 秒。如果上游接口经常超时我建议在配置里加入 fallback 模型让系统自动切换别硬等一个不透气的模型。流式响应中断导致客户端解析异常这个问题容易出现在一些旧的客户端 SDK 上。litellm proxy 输出的是标准 SSE 流但有些客户端对 SSE 格式的容忍度低遇到某些包含换行内容的消息就会解析断掉。如果你用的是官方最新 SDK基本不会碰到但如果你是自研客户端就得注意对 SSE 流的异常处理要足够健壮。升级上游模型后输出格式变化这个不怪 litellm是上游厂商的问题。但 litellm 的日志和统计功能能帮你快速定位是哪一次升级导致的它会记录模型版本信息。如果你开启了模型映射甚至可以在不经业务方同意的情况下把新版本先切到内部测试专用模型别名验证通过后再全局切换。4.2 性能调优的几条实用建议先说重试策略。不要配太激进的无限重试尤其是遇到上游 4xx 错误时重试没有意义反而会耗尽资源。我的做法是对 429限流和 5xx服务端错误做有限重试对 4xx 直接放弃。这个可以在 litellm 的配置里针对不同错误码精细控制。再说并发控制。litellm 允许你通过环境变量限制全局并发请求数。比如设置最大同时处理 50 个请求超过的请求就排队。这个机制能防止你的网关在上游模型限流时被打穿。如果你有多个业务方共用网关强烈建议开这个功能不然某个业务方突发流量可能会拖垮所有人。最后提一下连接池。如果你的业务是高并发场景可以调整 litellm 内部连接池的大小。litellm 基于 HTTP 客户端维护连接池默认值在特定场景下不够用。我实践下来适当调大连接数可以有效降低平均延迟但这需要结合你服务器自身的内存和文件描述符上限来综合考虑别调太大反而拖垮服务器。4.3 权限分配与多环境隔离的实战心得用 litellm 做团队网关时我强烈建议不要把 master key 直接发给每个开发者。正确的做法是为每个人或每个业务线分配独立的 API Key并对应设置不同的模型访问范围和预算。我的做法是这样的给开发环境一个独立的 litellm 实例配置里允许使用所有模型key 权限很宽松给生产环境单独起一个 litellm 实例只允许使用稳定可靠的那一两个模型并且设置比较紧的预算上限。这样开发环境和生产环境做到隔离不会出现有人误操作把生产模型入口暴露进去的情况。隔离的好处还体现在模型灰度上。你想试一个新模型时先在开发环境的配置里加进去内部测试没问题后再同步到生产。如果生产环境的某个新模型出了故障可以迅速把生产配置回滚到上一个版本不影响整体业务。4.4 什么时候不要硬上 litellm也有朋友问过我是不是所有项目都应该引入 litellm。我的回答是不一定。如果你的项目就是一个非常简单的 Python 脚本或者只是临时的数据分析任务直接调用原生 SDK 完全可以没必要为一个脚本维护一个网关服务。尤其是模型调用量极低、逻辑也极简单的情况下litellm 带来的配置复杂度可能超过它节省的适配成本。另外如果你的上游模型之间接口差异小到可以忽略并且你不太可能在未来切换供应商那 litellm 的优势就不明显了。但现实是这种情况很少因为模型市场变化太快今天的最优选择过几个月就可能被另一家超越。所以从技术债的角度考虑做一个轻量抽象始终是值得的。litellm 还有一个适用边界如果你对请求的某些特殊参数非常敏感比如某些模型有独家的 sampling 参数litellm 的标准化抽象可能会限制你直接透传这些参数。虽然在 litellm 里也能通过extra_body传额外参数但毕竟多了一层封装总不如直连来得直接。这种情况下你可以考虑 litellm 只作为常规场景的网关对于特殊需求保留直连通道。5. 最后分享一个自己常用的小技巧在配置 litellm 时我特别喜欢用环境变量来管理密钥和配置而不是把密钥硬编码在 YAML 文件里。具体做法是通过环境变量插值的方式引用密钥这样配置文件本身就只是一个结构模板即使被不小心提交到仓库里也不会直接泄露敏感信息。举个小例子在 config 里这样写model_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY然后我在启动 litellm 之前在 shell 里设置好对应的环境变量。配置文件的版本管理、多人协同比直接塞明文密钥要安全很多。尤其是在团队协作场景下这个习惯能避免很多事故。另一个小技巧是如果某个上游模型经常不稳定我通常会在配置里把 fallback 模型设成一个本地开源模型这样即使云端的模型挂了请求也能落到内网服务至少保证业务不至于完全不可用。这种灰度容错方案在关键时刻真的能救命。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。