资讯动态

LiteLLM实战:构建统一LLM网关,轻松实现多模型切换与成本管控

发布时间:2026/10/13 4:48:00 来源:尧图企业网站定制
1. 为什么你的项目也需要一个LLM中间层第一次知道 litellm 这个项目是在处理一个多模型接入的调度需求时。当时手头要同时对接五六个不同厂商的大模型接口每个厂商的 SDK 风格都不一样有的走纯 REST有的封装了 Python 客户端有的对话消息格式五花八门。业务代码里塞了一堆 if-else每接一个新模型就要额外写几百行适配代码测试排期一次比一次长。后来一个朋友把 litellm 丢给我说你先把这玩意儿试跑一下我才算真正入了门。这个项目本质上做的事情特别简单把市面上主流的模型厂商接口全部包一层统一成同一种调用格式。你只需要会一套 API就能在几十个模型之间来回切换而且切换成本低到令人怀疑人生——改一个字符串的事。它既能作为 Python SDK 直接内嵌到你的项目里也能单独起一个代理服务给整个团队当网关用。对于正在做 LLM 应用开发、想避免被单一模型厂商绑死、又被多供应商接入折腾得头疼的开发者来说litellm 基本就是你想要的中间层。我见过很多团队一开始只用一个模型代码写得很爽等产品跑起来想换更便宜的模型或者加个备用模型时才发现当初的爽全变成了债。老实说这类问题的根源不在模型本身而在你的业务代码和模型 API 之间缺一个统一的抽象层。litellm 能帮你把这个抽象层补上而且补得相当稳。1.1 各家 SDK 差异到底有多痛很多人没同时接过两个以上模型体会不到这种痛。拿最简单的对话补全接口来说厂商 A 的请求体长这样厂商 B 的长那样厂商 C 的可能连响应结构都和你以为的不一样。有的用system字段有的叫instructions有的干脆让你拼在第一条消息里。参数名也是千奇百怪temperature、top_p这些都是小事真正麻烦的是max_tokens、stop_sequences、tools这类字段各家定义不完全一样你写业务代码时就得疯狂做兼容。如果只是几个字段的差异还好说最怕的是流式响应的数据格式完全不同。一家给你发data: {...}的 Server-Sent Events另一家发的是 JSON 数组还有一家是 websocket。你在流式场景下要想做一套通用代码得额外写一层适配器把各家流式输出统一成自己的事件结构。我见过有团队这套适配器写了上千行最后模型一更新某些字段废弃了又要改一轮。litellm 解决这个问题的方式很直接它把这些差异全部吞掉对外暴露一个 OpenAI 兼容的请求响应结构。你传messages数组它负责转换成各家模型需要的格式返回的时候再转换成统一结构。这样一来你的业务代码只需要面对一种形态的 API厂商的差异被隔离在中间层内部。1.2 模型切换是刚需不是炫技你可能觉得一个模型用得好好的为什么非要切换真实场景里切换模型的原因太多了。成本是最大的驱动力。同一个任务用头部大模型和用开源精调小模型价格能差一个数量级。很多应用的压力测试跑下来发现 80% 的请求根本不需要最强模型用便宜模型就够了于是团队决定做模型路由简单问题走便宜模型复杂问题才走强模型。这种路由策略本质上就是代码里经常要切换模型。稳定性和容灾也是。模型供应商的服务不是永远可用特别是某些时段请求量大容易触发限流。如果核心链路只依赖一家一旦对方出问题你的产品就挂了。很多团队都开始配主模型 备用模型主模型失败时自动切换到备用。这种能力靠自己在业务代码里写工作量不小因为要处理异常类型识别、重试间隔、熔断标记等等。litellm 把这些能力做成了内置功能一个fallbacks参数就能指定失败时切换的模型列表代理模式里还能做负载均衡把请求分散到同一个模型的多个部署上。这些能力让模型切换从需要排期开发的功能变成了改个配置就能上线的事。1.3 花在管理上的时间往往比写功能还多接入大模型之后团队很快会发现另一个头疼的问题账号和权限管不过来。每个人的 API Key 直接写在项目配置里代码一提交就泄露了有的成员拿 Key 去跑自己的实验月底账单出来分不清哪些是业务花的哪些是乱花掉的。你说要限制预算但模型接口层根本没有预算这个概念得自己在外面包一层统计。litellm 代理模式里的虚拟 Key 和预算体系就是专门解决这个的。你在网关后面创建一堆虚拟 Key每个 Key 可以绑定模型白名单、设置额度上限、按天/按月限流。开发、测试、不同的业务方各拿各的 Key网关帮忙记账。后端还有一套完整的用量日志谁在什么时候调了哪个模型、花了多少 token、折合多少钱全都拉得出来。这种管理能力对于一个超过五个人的团队来说基本是刚需。2. LiteLLM 的核心机制拆解统一协议层到底做了什么前面讲了它解决什么问题现在聊它是怎么做到的。litellm 不是那种黑盒网关它的设计其实很朴素理解了核心机制你排错的时候会轻松非常多。2.1 一个函数包住一百多家模型litellm 的 SDK 核心就一个函数litellm.completion()。你只要把model参数传成厂商名/模型名的格式比如openai/gpt-4o-mini、anthropic/claude-3-haiku、bedrock/claude-v2剩下的消息体、参数全部按 OpenAI 的规范写。litellm 内部根据前缀判断走哪个厂商的适配器然后完成请求格式转换、鉴权、发送、响应解析。这个厂商前缀的设计是它的命根子。它把一百多家模型的服务商抽象成了字符串前缀你在代码里切换模型就是换字符串的事。为了做到这一点litellm 为每个厂商维护了一套独立的转译规则入参怎么映射、请求体怎么构造、响应怎么解析成统一结构。这就是它最核心的工作量所在。有一个很关键的设计细节是litellm 对外的统一格式不仅仅是长得像 OpenAI而是连错误信息、限流状态、流式事件这样的边角料也做了统一。比如所有厂商的限流错误最终都会归成带RateLimitError类型的异常你的业务代码只需要统一捕获这一类异常就能处理所有厂商的限流场景。这个细节在排错时价值极高不用再为每个厂商写一种异常分支。2.2 SDK 模式和 Proxy 模式两种用法各有分工litellm 的第二种玩法是起一个代理服务在服务器上跑起来对外暴露一个标准 OpenAI 接口。你的服务只需要配置 base_url 指向这个代理连 SDK 都不用换就能让整个团队共享同一份模型接入配置。SDK 模式和 Proxy 模式的区别一句话总结SDK 模式适合单人或者轻量项目模型配置写在代码里Proxy 模式适合团队协作和生产环境配置集中在网关层权限、预算、监控都在这一层解决。Proxy 模式还有一个很大的优势上游模型的 Key 不再需要分发到每个业务服务里。业务服务只需要知道代理的地址和它自己的虚拟 Key上游厂商的密钥全部锁在网关环境变量里。这样即使某个业务服务被攻破泄露的也不过是一把权限受限的虚拟 Key风险面小很多。2.3 一次转发背后litellm 帮你做了多少事很多人以为 litellm 就是个请求转发器实际上它在你发一个请求时背后默默做了很多事。首先是 token 计数。litellm 会估算请求和响应各消耗了多少 token。估算不是简单数一下字数它会针对不同的模型加载不同的 tokenizer 规则尽可能贴近真实消耗。这些计数最终汇入成本统计这就是它能自动告诉你这个 Key 这个月花了多少钱的原因。其次是重试和超时控制。litellm 内部对某些类型的错误连接错误、限流错误会做自动重试默认带指数退避策略。你不需要在业务层写重试逻辑它会尽量保证请求完成。再次是内容安全层面的支持。新版 litellm 支持在网关侧挂入内容审核、敏感信息检测之类的钩子可以根据需求在请求前或者响应后触发。这块我个人觉得适合把一些通用的审计逻辑沉淀在网关里而不是在每个业务项目里重复实现。搞清楚这些机制之后你会明白 litellm 的定位已经不是简单的API 聚合器而是一个偏完整的 LLM 网关中间件。它把接入层、管理层、观测层的能力都打包了这也是为什么它在开源社区里热度一直在涨。3. SDK 模式快速跑通五分钟切换多家模型如果只是想先体验一下SDK 模式是最快的路径。我建议所有初次接触 litellm 的人都先从 SDK 模式跑一遍把核心调用逻辑搞清楚再决定要不要上 Proxy。3.1 安装与环境准备安装非常简单一条命令的事pip install litellm[proxy]方括号里的proxy是额外依赖包含代理服务需要的组件。如果你只打算用 SDK 模式直接pip install litellm就够了。装完之后要把你要用的厂商 Key 配到环境变量里。litellm 在请求时如果检测不到对应的 Key会直接抛异常提醒你。这里有个容易踩的坑不同厂商的 Key 环境变量名不一样比如 OpenAI 的是OPENAI_API_KEYAzure 的是AZURE_API_KEY加一堆AZURE_*参数千万别只配一个API_KEY就指望所有厂商都能用。export OPENAI_API_KEYsk-xxxx export ANTHROPIC_API_KEYsk-ant-xxxx3.2 第一个统一调用配好环境变量就可以开始调了import litellm messages [{role: user, content: 用一句话解释什么是 API 网关}] # 调用 OpenAI 系 resp litellm.completion( modelopenai/gpt-4o-mini, messagesmessages, temperature0.7, ) print(resp.choices[0].message.content) # 换成 Anthropic 系只改 model 参数 resp litellm.completion( modelanthropic/claude-3-haiku, messagesmessages, temperature0.7, ) print(resp.choices[0].message.content)注意两段代码除了model字符串不同其他一模一样。这就是统一接口的意义——你的业务层只需要关心模型名字不需要关心厂商差异。实际项目里你完全可以把模型名写到配置中心里通过配置动态切换模型代码一行都不用改。流式调用也差不多把streamTrue加上就行resp litellm.completion( modelopenai/gpt-4o-mini, messagesmessages, streamTrue, ) for chunk in resp: print(chunk.choices[0].delta.content or , end)litellm 会把各家流式输出统一成 OpenAI 的 chunk 结构逻辑处理起来非常顺手。3.3 顺手把用量和成本统计也接上SDK 模式下litellm 会在响应对象里附带 token 用量信息。你可以直接读usage resp.usage print(输入 tokens:, usage.prompt_tokens) print(输出 tokens:, usage.completion_tokens) print(总 tokens:, usage.total_tokens)如果开了成功日志回调它还会把 model、messages、响应、用量、延迟等信息全部打到回调函数里非常适合做流量记录def log_usage(model, messages, kwargs, response_obj, start_time, end_time): print(f模型: {model}, 耗时: {(end_time - start_time).total_seconds():.2f}s) print(f用量: {response_obj.usage}) litellm.success_callback [log_usage]这种细粒度的日志在做成本分析和链路排查时非常有用。我建议从一开始就把用量记录接好等量大了再回头补历史数据基本补不上。4. 把 LiteLLM 架成公司网关Proxy 模式才是重头戏SDK 模式解决的是我自己的代码怎么省事但团队的模型接入管理最终还是得靠 Proxy 模式。这一节重点讲怎么把 litellm 跑成一个真正的网关服务以及生产环境里哪些配置是必须的。4.1 用一份配置文件启动网关Proxy 模式的入口是一个 YAML 配置文件里面定义了两类核心内容模型列表和通用设置。模型列表告诉网关有哪些上游模型可用通用设置决定网关本身的运行策略。下面是一份最简配置model_list: - model_name: gpt-4o-mini litellm_params: model: openai/gpt-4o-mini api_key: os.environ/OPENAI_API_KEY - model_name: claude-3-haiku litellm_params: model: anthropic/claude-3-haiku api_key: os.environ/ANTHROPIC_API_KEY general_settings: master_key: sk-master-key-123 database_url: postgresql://user:passlocalhost:5432/litellm注意几个细节。model_name是暴露给调用方的名字你可以起一个跟上游完全无关的别名比如把上游某个模型叫text-fast业务方只认这个别名以后你在后面偷偷换上游模型业务方毫无感知。litellm_params.model才是真正的上游模型路径。master_key是管理网关用的管理员密钥所有虚拟 Key 管理操作都要用它鉴权这个必须单独设一个足够复杂的值。启动命令也很简单litellm --config config.yaml --port 4000启动之后你的服务就对外提供了一个标准的 OpenAI 兼容接口地址是http://localhost:4000。任何支持自定义 base_url 的 OpenAI SDK 客户端都可以直接连上来。4.2 虚拟 Key 和预算管控团队接入的核心网关起来了接下来最重要的一步是给团队成员分配虚拟 Key而不是把上游 Key 直接给他们。通过管理员密钥调用/key/generate接口就能生成curl http://localhost:4000/key/generate \ -H Authorization: Bearer sk-master-key-123 \ -H Content-Type: application/json \ -d { models: [gpt-4o-mini], budget: 10, max_parallel_requests: 100 }这个 Key 的预算上限是 10 美元只能调用gpt-4o-mini这一个模型并发上限 100。也就是说这个 Key 就算被人偷了别人最多只能在这个额度内用指定的模型风险完全可控。虚拟 Key 的典型使用场景我列一下给每个开发者一把 Key额度设成个人月度预算超了自己去申请。给每个业务方一把 Key绑定他们实际需要的那几个模型防止误调到最贵的模型。给 CI/CD 环境一把专用 Key额度低一点防止测试脚本失控。如果配了数据库litellm 还会记录每个虚拟 Key 的完整调用历史。管理员可以在控制台按 Key、按模型、按时间段查询 token 消耗和费用。出了账单问题直接按 Key 对账几分钟就能定位到是哪个业务方在猛调。4.3 负载均衡和自动回退生产环境的保命配置在配置文件里同一个model_name可以挂多个上游实现。litellm 默认会用加权轮询的方式把请求分发到这些实现上实现负载均衡。比如你的主供应商和备用供应商各部署了一个同型号模型可以这样配model_list: - model_name: main-model litellm_params: model: openai/gpt-4o-mini api_key: os.environ/OPENAI_API_KEY model_info: priority: 1 - model_name: main-model litellm_params: model: anthropic/claude-3-haiku api_key: os.environ/ANTHROPIC_API_KEY model_info: priority: 2priority决定优先顺序1是主2是备。默认情况下网关优先打主供应商主供应商连续出错达到阈值后后续请求自动切到备用供应商。回退配置更简单直接在litellm_settings里声明litellm_settings: fallbacks: [{main-model: [claude-3-haiku]}]意思是main-model失败时自动用claude-3-haiku顶上。注意回退逻辑主要解决的是这个请求有没有成功返回的问题它会在请求发出前先按优先级列表逐个尝试直到有一个模型成功。我强烈建议任何生产环境都把回退配上。模型供应商的稳定性说实话没有想象中那么高有回退和没有回退故障处置时间能差一个数量级。4.4 缓存机制省钱和降延迟的利器litellm 代理内置了响应缓存支持内存缓存和 Redis 缓存。对于重复性较高的请求比如固定 prompt 的摘要、分类、信息提取任务缓存命中后可以直接省掉一次模型调用既省钱又降延迟。配置 Redis 缓存litellm_settings: cache: true cache_params: type: redis host: localhost port: 6379 ttl: 3600这里有个经验之谈不要对个性化、实时性要求高的请求开缓存比如对话聊天场景缓存会让用户体验变得很奇怪。缓存最适合的是那些输入输出高度确定的任务比如从文本里提取结构化字段、给工单打标签这类。5. 我踩过的 LiteLLM 坑位与调优经验任何工具跑生产环境都会遇到文档里没写的坑。litellm 我用下来整体很顺手但下面这几个问题每一件都让我实打实花过时间排查写出来帮你省点弯路。5.1 流式请求的超时配置不能照抄默认值litellm 默认的请求超时时间对普通短请求够用但流式生成场景下模型首字延迟和整体生成时间完全是两回事。如果你用默认超时去请求一个要生成几千 tokens 的长文本很可能会出现超时被杀但上游其实还在正常生成的情况。后果就是用户那边看到一半断了。我的做法是单独给流式请求配更宽松的超时并且把超时设置放进模型参数里litellm_params: model: openai/gpt-4o-mini api_key: os.environ/OPENAI_API_KEY timeout: 300另外首字延迟类的排查要看日志里的ttft指标如果首字延迟就很高多半是上游模型当时负载大或者网络链路有问题这时候调超时没用得换模型区域或者加自动回退。5.2 fallback 触发时小心业务侧重复写入fallback 配置本身没问题但有些业务代码会把请求失败和开始重试这件事记到自己的数据库里。比如请求main-model失败网关自动切到claude-3-haiku并且成功了业务侧如果按每次异常都记录一条失败日志去写就会产生误导性的错误数据。我的调整方案是在业务侧只关注最终响应。只要最终成功返回了就不算失败只有最终全部都失败才记录一个完整失败。网关内部的多次尝试过程让它写进网关自己的日志里就行避免两边数据对不上。5.3 上游 Key 的管理不能省配置里如果直接写明文 Key一旦配置仓库权限管控不严Key 就泄露了。litellm 支持os.environ/环境变量名这样的语法在配置文件里引用环境变量。我见过有人图省事直接明文写上去后来仓库被扫描工具扫出了 Key被迫全部轮换。这个教训成本挺高。还有一点Key 权限也要尽量最小化。给网关用的上游 Key能不开联网搜索功能就不开能不开文件访问就不开。毕竟网关是团队共享的入口它的权限边界越窄出事时的损失越小。5.4 高并发下记得把缓存和数据库一起规划好litellm 代理的用量记录和虚拟 Key 管理依赖数据库。早期团队可能觉得先用本地 SQLite 跑跑就行但并发一上来SQLite 的写锁会成为明显的瓶颈网关会整体变慢。我建议从部署第一天就接 PostgreSQL省得后面迁移。同理多实例部署的时候内存缓存是各实例各存一份的会导致缓存命中率下降。这时候必须上 Redis 做统一缓存层。我的经验是litellm 一旦跑多实例Redis 不是可选项是必选项。6. 在项目中落地 LiteLLM 的几点建议工具再好用不对地方反而增加复杂度。最后聊几个我在实际落地过程中得出的判断供你参考。6.1 什么样的场景其实不需要它如果你只有一个模型、一个人开发、项目也是短期实验性质那直接用模型厂商自己的 SDK 是最快的没必要引入 litellm。它的价值在多模型和多人协作这两个条件下才会充分体现。硬上一个中间层反而要多维护一份配置多一个故障点早期没必要。还有一种情况是强依赖某个厂商独特功能、完全不考虑切换的项目。比如某模型的视觉理解能力独一档你的产品就是奔着它去的那中间层的价值也不大。litellm 擅长的是通用对话、文本生成这类标准化能力过于独特的模型特性在统一层里往往会被向下对齐。6.2 团队协作里的配置管理纪律一旦把 litellm 作为团队网关配置文件的变更管理就要严肃起来。我建议把config.yaml纳入代码仓库走 MR 评审流程模型上线前由负责人确认配好的 Key、模型名、预算是否正确。litellm 也支持在数据库里存在 config hash配置变化会留痕方便回溯。虚拟 Key 的命名规范也值得提前定。比如统一用项目-环境-用途的格式rec-api-prod、rec-api-test、analyst-personal这样一眼能看出是谁在用什么。否则随着 Key 数量增加管理后台会变成一团乱麻。6.3 后续扩展的想象空间litellm 的扩展能力可以帮你做很多更进阶的事情。比如配合它的落库日志你能在数据仓库里做模型质量监控对比不同模型的输出延迟、token 消耗、失败率辅助模型选型和替换决策。再比如把网关的指标接入监控大盘设置预算告警费用冲到一定水位自动提醒防止月底爆单。我自己现在所有涉及大模型的项目基本都默认先接 litellm就算一开始只接一个模型也这么干。原因很简单以后加模型的时候不用再改代码跑数据复盘的时候不用临时补埋点。这个习惯帮我省下的时间远比当初引入它花掉的时间多。如果你正被模型接入的多样化问题困扰建议你也拿一个小项目先跑通感受一下只写一种调用代码的舒畅感。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑