☰
用litellm搭建统一LLM网关:接口聚合、负载均衡与预算治理实战
2026/10/14 8:39:22 网站建设 项目流程

做LLM应用开发最头疼的事,往往不是模型效果不够好,而是接口五花八门。不同的大模型平台,鉴权方式不一样,请求结构不一样,模型名更是各写各的。业务代码里塞满了各种适配逻辑,今天换一个供应商,明天调一个版本,到处都在小修小补。尤其当团队里同时要测好几家模型,或者需要把模型能力开放给不同业务线时,“怎么把模型调用管起来”就成了比“选哪个模型”更棘手的问题。我在这篇文章里要聊的litellm,就是一个专门解决这类痛点的开源项目:它把几乎市面上主流的大模型服务商统一成一套接口,让应用只需要认一个地址,就可以自由切换底层模型,同时还能帮你做负载均衡、自动重试、故障转移、用量统计和预算控制。

这篇文章会从它到底解决什么问题讲起,拆开它的核心模块,再一步步带你把一个可用的网关搭起来。无论你是在做多模型效果对比的算法同学,还是负责把模型能力落地到生产环境的开发,甚至只是被多个平台Key搞到焦头烂额的技术负责人,应该都能从里面找到能直接用的东西。

1. litellm是什么:一个LLM网关到底解决了什么问题

1.1 接口碎片化带来的真实成本

先说一个我见过无数次的场景。某团队的项目里,核心功能依赖A平台的模型,后来因为成本原因想对比B平台的开源模型,于是代码里出现了两套鉴权逻辑、两套参数构造方式、两套错误处理。如果再加一个云厂商托管的模型,代码就会变成三套。

这种“碎片化”的代价,在开发阶段只是多写几段代码,在生产阶段就变成灾难。每个平台的限流策略不一样,超时行为不一样,报价机制也不一样。你的业务逻辑很难对上游做统一假设,一旦某家平台抖动,排查链路就得重走一遍。更麻烦的是,Key的管理在多人协作时几乎失控:谁在用、花多少钱、被哪个团队调爆了限流,全凭运维靠感觉判断。

1.2 litellm的定位:一个独立部署的模型网关

litellm本身有两层东西。第一层是一个Python库,提供统一的调用函数,让你在代码里直接用同一个接口去请求不同平台;但真正在生产环境里发挥大作用的是第二层,也就是它自带的Proxy Server,一个可以独立部署的网关服务。

可以把整个结构理解成这个样子:

你的应用 -> litellm网关 -> 平台A / 平台B / 某云厂商托管模型

应用只跟litellm打交道,拿到的是一个固定的请求地址和一个固定的Key。至于背后到底路由到哪家模型、哪家挂了要不要换一家、这次调用花了多少钱,这些事全部收口到网关层处理。这比你自己在每个应用里塞一段封装函数要干净得多,因为所有跟模型供应商有关的策略,都变成了网关配置文件里的几行描述,而不再是散落在代码各个角落的补丁。

我见过不少团队把“统一模型调用”做成一个内部工具包,一开始确实很爽,但随着接入方变多,工具包开始承载大量业务无关的逻辑,比如权限、计费、限流。litellm这类网关的价值就在于此:它把这些横切关注点从业务代码里摘了出去,让应用专注做自己的事情。

2. 为什么要上模型网关:成本、稳定和治理的三笔账

2.1 实验阶段:一天测完三家模型

很多人觉得,一个网关是给生产环境用的,前期做验证没必要。实际上我从经验看,恰恰是在实验阶段,litellm能帮你省下大把时间。

假设你要评测某个提示词在不同模型上的表现。没有网关时,你得分别跑一套脚本,每家平台的参数格式还略有差异。有了网关之后,同一份测试样例、同一套调用代码,只需要通过配置把同一个逻辑模型名映射到不同平台,一轮跑完,换一行配置,再来一轮。这种对照效率是物理级别提升的。

另外一个隐藏好处是:网关可以帮你做压力测试。绝大多数平台的免费额度都有速率限制,直接把应用怼上去,很容易刚跑两个请求就被限流。litellm对每个上游平台都可以单独配置每分钟请求数上限,相当于给你加了一层缓冲,让你的测试脚本不会因为触发限流而中断。

2.2 生产阶段:稳定性与切换自由

生产环境里我最看重的,其实是“切换自由”。今天效果最好的模型,半年后未必还在,价格也可能调整。只要供应商不是完全锁死在你的代码里,你永远有选择权。而litellm把“换模型”这件事从一次发版,变成了一次配置修改。

更重要的是稳定性。真实生产里,没有任何一家平台能保证100%可用。litellm支持故障转移,也就是某个模型返回异常或者限流时,自动把请求转移到备用模型。它还支持重试、超时控制、并发限制。这些机制如果不放在网关层,就要在每一个应用里重复实现,而且每个应用实现的细节大概率还会不一样,最终变成一个无人敢动的雷区。

2.3 自研网关?先想清楚这三件事

我也被问过很多次:litellm做的事情,自己写个几十行的封装函数不也能做吗?能,但前提是你的需求足够简单。当你想清楚这三个问题之后,很多团队就会改变主意:

第一,预算分摊怎么做?多个团队共用模型资源,每个团队花了多少,你需要一张表去记录。自研方案就要自己设计存储、对账和展示。第二,限流和权限怎么收敛?是不是要给每个接入方发独立的Key,能不能控制单个Key的调用频率。第三,审计与告警怎么办?谁在什么时候调用了什么模型,出了问题能不能追溯。

litellm把这些基本框架都搭好了,虽然不是开箱即用,但你需要做的只是配置和运维,而不是从零造轮子。对一个三五个人的团队来说,自研封装函数还算可控;一旦接入方规模变大,自研方案的长期维护成本会迅速超过引入成熟网关的成本。

3. 核心功能逐个拆:路由、重试、预算和缓存都是怎么工作的

3.1 逻辑模型名与真实模型名的解耦

litellm最核心的设计,是引入了“逻辑模型名”和“真实模型标识”的映射关系。调用方只认逻辑名,网关再把逻辑名翻译成某个平台上的具体模型。

拿最简单的配置来说:

model_list: - model_name: chat-small litellm_params: model: platform-a/chat-small api_key: os.environ/PLATFORM_A_API_KEY

这里model_name是暴露给应用的逻辑名,应用请求时只需要传chat-small。litellm_params.model字段才是请求真正发往的模型标识。这样做的好处是,当你想把主模型从A平台换到B平台时,只需要调整这处映射,应用代码一行都不用动。

更妙的是,同一个逻辑名可以对应多个真实模型,litellm会在它们之间做负载均衡:

model_list: - model_name: chat-small litellm_params: model: platform-a/chat-small api_key: os.environ/PLATFORM_A_API_KEY weight: 3 - model_name: chat-small litellm_params: model: platform-b/chat-small api_key: os.environ/PLATFORM_B_API_KEY weight: 1

这个配置的意思是,所有发给chat-small的请求,平均每四次里有三次会落到A平台,一次落到B平台。这种按权重分配的能力,非常适合做灰度切换:先放10%的流量到新模型,观察效果稳定后再逐步加大权重。

3.2 重试、fallback与超时控制的配合

模型服务偶尔抖动是很正常的。litellm对上游请求有重试机制,默认会重试失败请求,也允许你通过环境变量或配置调整重试次数。

但重试只是兜底,真正的生产利器是fallback。你可以为某个模型指定备用模型:

model_list: - model_name: chat-small litellm_params: model: platform-a/chat-small api_key: os.environ/PLATFORM_A_API_KEY fallbacks: [chat-small-open]

当A平台的服务返回错误、超时或触发限流时,网关会自动把请求转给chat-small-open,也就是你配置的另一个逻辑模型。应用方完全无感知,只知道自己发出的请求得到了响应。

这里要特别注意一个点:fallback通常意味着响应模型变了,回答的语言风格、能力边界可能都和主模型不一样。所以在设置fallback时,最好选能力相近的模型,同时业务侧要能容忍一定的差异。别把所有希望都寄托在“反正能返回”上,质量波动也是稳定性的一部分。

超时控制也建议做两层:连接超时和读取超时。只设一个总超时,遇到上游半死不活的连接时,你的线程会被白白占住,积少成多就会拖垮整个网关。

3.3 预算、虚拟Key与用量统计

litellm自带的虚拟Key体系,是团队接入时最实用的功能之一。你可以为每个人、每个业务线生成独立的Key,并在生成时指定预算和速率限制。所有调用都会记录到数据库里,后台可以直观看到哪个Key在请求什么模型、消耗了多少Token、预估费用是多少。

这个能力在多人共用模型资源时特别重要。以前我遇到过一种尴尬局面:几个人共用一个平台Key,月底看账单完全对不上是谁花的。换成litellm之后,每个团队一条Key,费用口径清清楚楚。再加上预算控制,你甚至可以在某个团队超额时自动拒绝新的请求。

不过预算控值得谨慎使用。直接设一个硬上限,万一业务正在高峰期,超过预算就全部拒绝,很可能会引发线上事故。我的建议是先开告警,观察一段时间的使用曲线,再逐步切换成硬限制。

3.4 缓存和流式响应:降本和体验的平衡

litellm还支持请求缓存。相同或相似的请求在有效期内会直接返回缓存结果,不再真正请求模型。对一些高频且回答可以复用的场景,比如常见问题回复、内容分类、意图识别,缓存能把成本降下来一大截。

但缓存有个前提:你的业务能够容忍结果相对固定。如果模型回答会依赖当前时间、用户状态这类动态信息,千万别开缓存,否则用户会拿到牛头不对马嘴的回复。

流式响应同样要留意。流式本身很顺畅,打字机效果体验很好,但流式模式下fallback的逻辑会变复杂:服务端已经开始往外吐token之后,你就没法把这段流切回备用模型了。如果主模型在流式过程中段报错,你能做的只有中断这次的流,并让客户端重新发起请求。所以流式功能一般建议搭配快速的超时探测,争取在输出流开始之前就完成健康检查。

4. 从零搭一个可用网关:安装配置到发出第一个请求

4.1 安装与环境变量

先用pip安装litellm的代理模式组件:

pip install 'litellm[proxy]'

注意安装的是带proxy扩展的版本,这样才能用到网关服务,而不仅仅是Python库。

然后把模型平台的Key配置到环境变量里:

export PLATFORM_A_API_KEY=你的平台A密钥 export PLATFORM_B_API_KEY=你的平台B密钥

我不建议把Key直接写进配置文件。哪怕配置文件是本地私有仓库,都有泄露风险,用环境变量注入是更稳妥的方式。

4.2 最小配置文件与启动

创建一个config.yaml,内容类似这样:

model_list: - model_name: chat-small litellm_params: model: platform-a/chat-small api_key: os.environ/PLATFORM_A_API_KEY

然后启动服务:

litellm --config config.yaml --port 4000

启动成功后,终端会打印出服务地址、主Key等信息。一个最简单的网关就这样跑起来了。默认情况下它还带一套Swagger文档页面,直接在浏览器打开http://localhost:4000就能看到接口文档,方便你测试各种请求。

4.3 通过代码发出第一个请求

网关本身提供的是和主流Chat风格SDK兼容的HTTP接口。如果你项目里之前用的是某平台的官方SDK,通常只需要把服务地址改成litellm的地址,再把鉴权Key换成网关下发的Key。

如果你更喜欢直接用Python包验证,那用litellm自身也很方便:

import litellm resp = litellm.completion( model="chat-small", messages=[{"role": "user", "content": "你好,做一个简单的自我介绍"}], api_base="http://localhost:4000", api_key="sk-你的虚拟Key", ) print(resp.choices[0].message.content)

这里的核心在于传入的model填的是配置文件里的逻辑名chat-small,而不是某个平台的真实标识。这个设计一开始会让不少人不太习惯,但用熟了之后你就会发现,它就是整个灵活性的源头。

4.4 用curl快速做连通性验证

改代码之前,我习惯先用curl验证网关本身是否正常:

curl http://localhost:4000/chat/completions \ -H "Authorization: Bearer sk-你的虚拟Key" \ -H "Content-Type: application/json" \ -d '{ "model": "chat-small", "messages": [{"role": "user", "content": "ping"}] }'

如果返回了正常的补全内容,说明网关到上游的链路是通的。之后不管是排查网络问题,还是验证配置变更,我都优先用curl做最小复现,效率比直接改业务代码高很多。

5. 生产环境落地的关键配置:数据库、虚拟Key和Docker部署

5.1 接上持久化存储

litellm默认使用轻量级的嵌入式文件数据库来保存调用记录和Key信息,单机试用没问题,但生产环境建议换成外部的成熟开源关系型数据库。这样历史记录不丢,也能让多个网关实例共享同一份数据。

配置里指定数据库连接地址后,重启服务就会自动完成建表和迁移。第一次接入时建议先看一眼表结构,理解哪些字段是记录请求量的,哪些是保存Key信息的,后续排查问题会顺手很多。

5.2 给每个接入方发独立的Key

生产环境的第一个动作,就是别再用启动时打印的主Key给所有业务方用。主Key的权限太大,一旦泄露,全部模型资源都可能被刷爆。

litellm提供了生成虚拟Key的接口,你可以为每个团队单独生成一个Key,同时指定这个Key的使用限制。比如某个工具链团队,你可以给它设每分钟200次请求、每日最多50万Token。这样就算某个调用方写了个死循环,也不会影响其他团队的正常使用。

实际运营中,我还会建议在Key的Metadata里写上团队名和负责人信息,这样统计面板上一眼就能看出每个Key的归属,对账的时候不用再去问一圈。

5.3 预算告警和超限行为

预算配置是litellm比较有特色的能力。你可以按虚拟Key设置总预算,比如100元。当实际消费达到这个额度,网关可以选择发出告警,或者直接拒绝后续请求。

第一次设置预算,我强烈建议先设置成“仅告警”模式。因为模型费用估算和实际账单之间会有误差,你掌握的模型单价也很可能不是最新价,直接设置硬上限可能会误伤正常业务。等跑了一段时间、确认了大概的费用节奏之后,再切到硬限制模式。

告警通道也建议尽量多地接出去,IM通知、邮件都好。模型费用不像服务器费用用户量那么线性,一个异常的批量任务可能在一个小时内烧掉整月预算,没有一个自动告警盯着,比较难及时发现。

5.4 Docker化部署与配置管理

生产环境部署litellm,最常见的方式是容器化。一个典型架构会包含网关服务、开源内存缓存、关系型数据库三件套,用编排工具把它们串起来。

容器化部署时有一个细节容易被忽略:配置文件里的Key不要写成明文,优先用环境变量注入。同时建议为网关服务配置健康检查,让编排平台能自动重启异常实例。日志也要统一收集,litellm的请求日志里有很多排查线索,散落在宿主机上基本等于没用。

6. 常见故障排查:认证、路由、超时和成本统计的坑

6.1 401/403认证错误

遇到认证错误,先确认到底是谁在拒绝你。如果是网关返回401,说明你传给网关的虚拟Key不对,或者Key已经被删掉、停用。如果是网关本身返回正常,但业务报错信息来自上游平台,那就是网关配置里的上游Key出了问题,比如环境变量没加载对。

排查认证问题,我的方法是从两头往中间查。先用curl直接请求网关,绕过业务代码,看能不能通;然后再看网关日志,确认它实际用哪个Key去请求了哪个平台。绝大多数认证问题,在日志里都能找到明确线索。

6.2 模型路由错误

模型路由报错的表现通常是你传了chat-small,网关却说这个模型不存在。这种情况八成是配置文件里的model_name写错或者大小写不匹配。还有一种情况是,逻辑模型名存在,但对应的litellm_params.model真实标识已经过期,平台那边已经下线或者改名。

这里要特别提醒:如果某个逻辑名被多个平台共用,比如作为负载均衡或fallback的一组模型,只要其中一个真实标识失效,整个逻辑名都会被影响。改配置的时候要全局检查一遍,别只盯着单独的一条。

6.3 超时与重试风暴

当上游平台出现大面积抖动时,如果你的应用自己还有一层重试,litellm也配置了重试,两层重试叠加就成了重试风暴,反而会把上游平台打得更惨。

解决思路是收敛重试入口。应用层尽量不重试,把重试策略统一放到网关层;网关层的重试次数也不要贪多,一两轮就够。真正生产环境更要做好并发上限控制,避免网关到上游的请求数量无限制增长。fallback虽然能提升可用性,但每个失败的请求都会多消耗一次备用模型的算力,成本也要观察。

6.4 成本统计为什么对不上

成本对不上是常见的疑难问题。可能的原因有很多:某一批请求走了fallback,记录里实际用的模型和业务以为的模型不一致;缓存命中直接返回了,没产生上游费用但日志里可能仍有记录;各平台的计价规则更新了,网关内置价格表没有同步更新。

要解决这个,先把视角收窄到单条Key、单次请求级别。用时间范围过滤出那一批请求,逐条看模型、输入输出Token数和实际返回状态,再去跟平台控制台比对。大多数情况下你能很快锁定是计费单价不准还是统计口径不一致。litellm允许自定义模型单价和计费单位,如果平台价格有变,维护自己的价格表比依赖内置数据更稳妥。

7. 选型与实操心得:什么项目适合引入litellm

7.1 什么规模值得上网关

我个人判断标准有两个,满足任意一条就值得考虑litellm:第一,你的环境里同时要面对两家以上的模型服务商,且切换比较频繁;第二,有多个团队或多人需要共享模型资源,你想把Key和预算管起来。

反过来,如果项目只有一个模型、一个平台、一个开发者在做,直接调用平台官方接口反而更省事。引入网关意味着多一个服务要维护,多一层链路要监控,这些成本是实打实的。别为了“架构先进性”给自己添负担。

7.2 建议的启用顺序

第一次接触litellm,别试图一次性把所有功能全部打开。我建议按这个顺序来:

第一步,只做统一路由和虚拟Key,让应用通过网关访问模型,Key按团队分发。第二步,把fallback和重试打开,稳定性和自动容灾能力先建立起来。第三步,再把预算告警、缓存、详细审计这些治理能力逐步加进去。

每增加一个能力,都要观察一段时间,确认它没有副作用之后再继续。一次全开的问题在于,一旦出了问题,你根本不知道是哪个环节引起的,排查成本反而更高。

7.3 几个容易忽略的经验细节

配置文件和数据库虽然承担的能力不同,但都是网关的“状态来源”。配置文件变化后建议完整重启再确认,不要想当然认为它一定自动生效了。

还有,litellm终究是一层代理,它帮你屏蔽了上游差异,但没有消除上游本身的不确定性。价格调整、接口下线、模型退役,这些仍然会传导到网关层。我始终保留在各平台控制台核验账单的习惯,即使litellm做了记录,最后的费用事实还是以上游账单为准。

我前前后后在不同项目里用过好几版自研接入层,后来换成litellm,最明显的感受不是“少写了两百行代码”,而是把“请求往哪里路由、能不能花、花了多少”这些问题从代码里彻底摘出去了。团队同学不再需要关心供应商差异,只需要知道自己手里的Key对应什么模型、有多少预算。不过它终究不是银弹,如果一个项目只有一个模型、一个应用、一个开发,直接调平台接口反而清爽得多。选择工具的核心标准永远是:当你不确定自己未来会在多少家平台之间切换时,一个统一网关给你的是切换的自由,而不是绑定的义务。

最后分享一个小技巧:新项目第一次接入litellm时,一定要在测试环境里人为把主模型调挂一次,验证fallback路径真的能顶上。很多人觉得自己配置没问题,但等生产环境出故障再验证,代价就完全不一样了。用网关不是图一时方便,是给未来的自己留一条后路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询