☰
开源网关Litellm:统一大模型API,搞定路由、缓存与成本控制
2026/10/21 10:11:44 网站建设 项目流程

做了小半年AI应用开发,我发现真正让人挠头的往往不是模型效果本身,而是"接各家模型服务商API"这件事。这个礼拜还在用某家的对话模型,下个礼拜客户说想换成另一个开源的本地模型;这边刚做完流式输出,那边又要支持按用户维度统计成本。如果每次切换都去改业务代码,改到第三轮基本就想骂人了。litellm就是在这个背景下冒出来的开源项目——它把自己定位成一个中间层代理,用一套统一的接口格式去封装各种模型服务,前端业务只需要对接一个地址,后面到底调的是哪家的模型、要不要负载均衡、会不会自动重试,全部由litellm来处理。

这篇内容面向后端工程师、AI应用开发者,也适合正在做内部AI能力平台、想要收敛多模型调用的团队。我会从litellm的设计思路讲起,然后拆解核心功能,接着给出可以直接照抄的部署和调用步骤,最后聊几个我实际踩过的坑。全程基于常见实践来补充细节,争取让没接触过的人也能照着落地。

1. 项目概述与技术定位

1.1 模型调用管理为什么成了工程问题

早几年做大模型应用,大家的做法很直接:代码里直接写某个模型服务的SDK,调完了事。但现在的情况变了,至少有三个变化让一个"简单调用"变成了需要专门治理的工程问题。

第一是模型供给碎片化。市面上既有闭源服务,也有开源社区跑起来的自托管模型,还有各家云厂商的托管版本。每个渠道的鉴权方式、接口路径、请求字段、限流逻辑都不一样。业务代码如果直接依赖某一个渠道,就相当于把所有鸡蛋放进了一个篮子里,换供应商的成本会高到让人放弃重构。

第二是成本与容灾的诉求。模型调用不像普通HTTP请求,它的响应时间波动很大,价格差异也大。很多时候业务上希望多个模型互为备份,某个模型超时或报错能自动切走,或者一部分流量打到便宜的模型上、一部分打到效果更好的模型上。这个调度逻辑如果散落在业务代码里,几乎没法维护。

第三是多团队、多项目的治理需求。公司大了之后,不同项目组都在调模型,谁用了多少额度、哪个API key对应的预算是多少、有没有人在跑死循环把token烧穿了,这些都需要一个统一的流量入口来做计量和控制。

把这些需求放在一起,你会得到一个非常自然的结论:需要一个独立的中间层,负责统一接入所有模型、下发路由策略、执行限流与计量。litellm就是干这件事的。

1.2 litellm在整个技术栈里的位置

用一张通俗的图来理解:你的业务后端只和litellm这一个服务通信,litellm再向上游的各个模型服务商发起真实请求。对业务方来说,所有模型调用看起来都像在调OpenAI格式的接口;对上游来说,litellm就是它的一个普通客户。

我在一个模拟项目X里验证过这个架构。业务团队用FastAPI写后端,中间挂一个litellm代理,上游接了三类渠道:一个闭源对话模型、一个开源模型的托管API、一个跑在GPU服务器上的本地模型。业务代码里从头到尾只需要一种请求格式,完全感知不到后面有几个渠道。改动渠道,只需要在litellm的配置文件里调整路由,业务服务一行都不用改。

这种架构的额外好处是接入成本低。litellm本身就是一个轻量服务,不需要对现有业务做侵入式改造,它的定位是"网关"而不是"框架"。至于部署形态,既可以跟业务一起放一台机器上跑进程,也可以单独当成一个内部服务统一部署,后面我会讲具体配置。

2. 核心功能拆解:litellm到底能做什么

2.1 统一接口:用OpenAI协议当"普通话"

litellm最核心的设计是把OpenAI的接口协议作为统一中间格式。也就是说,你用它代理任何模型,对外暴露的请求和响应结构都长得跟OpenAI的Chat Completions接口一样。

这样做的原因很实际:OpenAI的协议格式在实际使用中被验证得最充分,生态工具多,很多开源框架也都内置了兼容层。litellm相当于把这套格式当成"普通话",各家模型服务商的语言都被它实时翻译成普通话。对于请求方来说,只用学一个标准,不用为了换一个模型重新写一套调用逻辑。

还别说,这个设计让我省了不少事。我们有个功能要同时比对三个模型在同样prompt下的表现,如果不走litellm,我得维护三套不同格式的请求,还要各自处理错误码、重试逻辑。走了litellm之后,拿一个循环换model字段就能把三个渠道的结果都拉回来。

这里额外说一点:如果你在做AI Agent或RAG应用,把litellm放在中间,之后换模型、加模型、做A/B测试都是配置项级别的改动,不用动应用层。这是它最吸引人的特性。

2.2 多模型路由与负载均衡

litellm的另一个核心能力是路由。真实业务里不太可能只用一个模型,比如日常聊天用性价比高的模型,复杂推理用能力强的模型。litellm允许你为同一个逻辑名称挂多个真实模型,然后配置路由策略,比如weighted(按权重分配)或者priority(优先使用某个、失败再切换)。

我在实践中用的一个场景是:主模型配了一个付费的强模型,备用模型配了一个自托管的开源模型,权重分别设成7和3。其中70%的流量走强模型保证质量,30%走自托管模型缓解成本压力。当强模型那边限流或者返回错误时,litellm自动把流量切到备用模型,整个切换对业务方是无感的。

这个功能背后还带了一个容易被忽视的点:litellm会从上游的错误响应里识别"限流""过载""鉴权失败"等状态,根据失败原因决定要不要切换。也就是说,不是光看HTTP状态码就来回切,而是有一定智能判断的。相比自己写轮询重试的代码,这种封装明显更稳。

2.3 缓存机制:省钱和降延迟的法宝

大量真实场景中,用户会反复问相似的问题。比如企业内部的知识库问答,几个人查同一份文档的同一段内容,prompt几乎一模一样。如果每一次都真实调用模型并发起计费,成本上非常不划算。

litellm自带缓存层,可以本地内存缓存,也可以接Redis做分布式缓存。关键的是它支持语义缓存,也就是说不是要求prompt完全一字不差才命中,而是根据语义相似度去匹配相似请求,直接将历史响应返回。这意味着即便用户换了一种问法,只要意图一致,仍然能拿到缓存结果。

这个功能实测下来非常香。我在某公司内部的一个客服问答Demo上打开语义缓存之后,相同知识点的重复问题命中率明显上升,模型调用量直接降了一截。如果你本来只是想让litellm当个调用入口,建议认真研究一下这块,缓存策略调好了,成本会有肉眼可见的改善。

2.4 限流、额度与预算控制

如果说路由是"往哪走",那限流和额度管理就是"谁能走、能走多少"。litellm在这块做得相当细,它支持按API key维度做限流,也支持给每个key设置预算上限,超过预算自动拒绝请求。

它的一个典型用法是给不同团队发不同的API key,限制每分钟请求数、每天token用量、每月花费预算。比如给测试环境配1000次/天的额度,给生产环境配更高的额度。如果某个团队的应用出了bug在疯狂循环调用,预算耗尽后请求直接404,不会让你月底收到一份天价账单。

这个能力放在企业内部做模型能力平台时几乎是标配。你不需要给每个项目组开放模型服务商的后台,只需要发一张litellm的虚拟key,所有计量、限额都在litellm这一侧完成,管理成本极低。

2.5 密钥管理与安全隔离

还有一个日常容易忽略但很重要的点:真实各渠道的API key,不应该撒得到处都是。如果每个前端项目都保存一份服务商密钥,一旦某个项目的代码泄露,密钥就跟着泄露了。

litellm允许你把上游渠道的真实密钥放在服务端配置里,业务方通过litellm的虚拟key访问。业务方拿到的只是一个litellm生成的key,根本接触不到上游渠道的密钥。就算这个虚拟key泄露了,运维侧也可以随时在litellm里吊销重建,不需要去渠道后台折腾。

从安全角度说,这是一个很聪明的收敛方案:密钥集中在网关层,权限可控,审计方便。尤其对于有几个项目组同时用模型的公司,这个能力值得优先部署。

3. 实操部署:从安装到发出第一个请求

3.1 环境准备与安装

litellm是Python写的,所以最基本的依赖就是Python环境。实测在3.9到3.11版本上都稳定,官方推荐3.11以上。安装直接用pip:

pip install litellm[proxy]

装完之后,命令行会多出一个litellm命令。这个包分成两部分内核:一部分是SDK,可以在代码里直接调用模型;另一部分是代理服务(proxy),就是我们要部署的HTTP服务。写业务层对接用代理服务比较多,因为可以独立部署、统一治理。

部署形态我建议优先考虑独立进程,别跟业务代码挤在一个进程里。因为代理服务要承担流量转发、缓存、限流这些逻辑,单独放一份更清晰,也方便后续加机器扩展。如果团队里有现成的容器编排环境,直接打个镜像更省心。

3.2 配置文件的核心结构

litellm的代理服务靠一个YAML配置来定义渠道、路由、缓存、限流等。下面是一个我实际用过的结构骨架,稍微简化了一下:

model_list: - model_name: gpt-like litellm_params: model: openai/gpt-4o-mini api_key: sk-123456 - model_name: gpt-like litellm_params: model: deepseek/deepseek-chat api_key: sk-abcdef - model_name: local-model litellm_params: model: ollama/qwen2.5:7b api_base: http://127.0.0.1:11434 api_key: fake-key litellm_settings: cache: true cache_params: type: redis host: localhost port: 6379 general_settings: master_key: sk-my-master-key

这个配置里有一个关键概念需要解释一下:model_name是暴露给业务方的逻辑名称,litellm_params.model才是真实渠道的模型标识。litellm的模型标识通常用provider/model-name这种格式,比如openai/gpt-4o-mini、anthropic/claude-3-5-sonnet。前面配置了两个逻辑名为gpt-like的真实模型,它们会一起参与负载均衡。

master_key是代理服务的管理密钥,所有请求都要带上这个key来认证。建议用一个足够长的随机字符串,别学我用这种示例值。我见过有人把master_key配成123456的,服务一放到内网就被别人白嫖了。

3.3 启动代理服务

配置文件写好之后,启动非常简单:

litellm --config config.yaml --port 4000

如果你配了Redis缓存,确保Redis服务已经在运行。启动日志里会打印出本地监听地址和当前加载的模型列表。看到类似"Uvicorn running on http://0.0.0.0:4000"的信息,说明服务已经起来了。

在实际业务环境里,建议代理服务监听在内网地址,通过反向代理对外提供访问,并加上一层HTTPS。这样既能做传输加密,又能跟公司的统一认证体系对接。如果是小团队内部试用,直接暴露4000端口给内网成员也可以,但master_key一定要保管好。

3.4 用curl验证接口

代理起来后,验证方式跟调OpenAI原版接口几乎一样。下面是一个包含master_key认证的Chat Completions请求:

curl http://localhost:4000/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-my-master-key" \ -d '{ "model": "gpt-like", "messages": [{"role": "user", "content": "你好,介绍一下你自己"}] }'

这里注意请求体里的model字段必须填配置里的逻辑名,也就是gpt-like,而不是真实渠道的模型名。litellm收到请求后,根据配置找到对应的真实模型进行转发。如果你填了真实模型名,反而会报模型找不到的错误,这一点很多第一次用的人容易搞混。

如果配置了多个模型指向同一个逻辑名,litellm默认按顺序做负载均衡。想要验证转发到了哪个渠道,可以看代理服务的日志,里面会记录每次请求实际命中的上游模型,也会打印耗时和token数量。

3.5 在Python SDK中调用

除了HTTP接口,litellm也提供了原生Python调用方式,适合不想起代理、直接在后端代码里管理模型的情况。但默认还是推荐走代理,因为前面说的治理能力都集中在代理层。

如果用Python调用代理,可以直接用openai的SDK,只要把base_url和api_key换掉:

from openai import OpenAI client = OpenAI( base_url="http://localhost:4000/v1", api_key="sk-my-master-key", ) resp = client.chat.completions.create( model="gpt-like", messages=[{"role": "user", "content": "讲个冷笑话"}], ) print(resp.choices[0].message.content)

这段代码跑起来,你会发现除了地址换了,其他都跟在官方文档里写的一样。这个"无感兼容"就是litellm最有价值的地方:既有生态里的那些Agent框架、评测工具、调试工具,只要支持OpenAI协议,都能无缝接到litellm上,不用改业务代码。

4. 落到业务场景的高级玩法

4.1 像配流量一样配模型路由

做后端的人都知道Nginx可以做灰度发布,设计思路是上游好几台机器、按权重分流。litellm的模型路由其实也是同一套思想,只是把"机器"换成了"模型渠道"。

配置方式我刚才已经提到了,用model_list里相同逻辑名加不同真实模型实现。这里补充一个更细的玩法:你可以给一个逻辑名配置多个渠道,并给每个渠道加routing_strategy。比如强制优先用某个渠道,失败再走备用的策略,对稳定性要求高的场景非常合适。

举个例子:逻辑名chat先配置了渠道A,再配置了渠道B。正常情况下所有请求都走A,一旦A返回5xx或触发限流,litellm自动把请求转发给B,业务方看到的只是响应时间变长了一点,完全没有感知到这个故障转移过程。

这种冗余设计我强烈建议用在生产环境,成本不高,但是能避免很多半夜被叫起来改配置的情况。

4.2 多租户流量建模

内部模型平台做到一定规模,一定会遇到多租户问题:好几个项目组共用一个代理,各组之间要隔离,指标要分开看。litellm的做法是用虚拟key来划分租户。

你可以用管理接口生成多个虚拟key,每个key用metadata字段标记归属。比如给A项目组生成一个key,打上team: project-A标签;给B项目组生成另一个key,打上team: project-B。然后给每个key分别配预算和限流。这样一来,同一个代理服务、同一个模型池,却被不同项目组使用,互不干扰。

生成虚拟key的接口大概是POST /key/generate,body里带上预算、速率限制和metadata。我建议在内部平台上线时做一个简单的管理页面,把这些创建操作包装成按钮,方便非技术同事自助申请key。

4.3 预算超限的兜底策略

预算控制这件事,配置不好容易出两种极端:一种是设得太松,超支了才发现;另一种是设得太紧,正常业务被误伤。litellm提供了max_budget这种整体预算配置,也有per-key的预算限额。实际落地的时候,我建议先设成告警而不是直接拦截,跑几天看看用量分布,再逐步收紧。

另外要留意一个细节:litellm的预算统计是异步刷新的,意味着它不一定能做到"超过一分钱就立刻拦截",可能略有延迟。如果对成本极其敏感,可以把限额设得比实际可接受值低一点,留出缓冲。

4.4 保障流式输出体验

现在很多应用都用流式输出,模型一个字一个字往外蹦。这种体验对网关提出了额外要求:转发请求时要能正确转发stream=true参数,中间层还要把多个上游的流式数据块原样透传给客户端,不能缓存整个响应等结束再返回。

litellm对流式支持做得比较到位。你在业务侧用OpenAI SDK传stream=True,实际请求就会往上透传。如果配置了多模型负载均衡,注意流式场景下的故障切换还是要依赖上游尽早报错,因为一旦开始吐字,中途再切换模型会导致输出内容拼接混乱。这个限制我理解是行业通行做法,litellm也没法完全避免。

4.5 可观测性:请求日志与成本追踪

最后说可观测性。litellm会自动记录每次请求的完整信息,包括模型、token数量、消耗金额、延迟等。这些数据既写在本地日志里,也可以推送到外部监控平台。

如果你要做成本分摊,litellm的日志字段里有spend和total_tokens,按虚拟key聚合就能得出每个项目组的月度费用,做内部结算时就省事多了。延迟数据可以帮你发现某个渠道是不是响应越来越慢,从而及时调整路由权重。

可以把这个数据接进Prometheus做常规图表,也可以直接用litellm自带的UI看板。我们实际用下来,成本数据比想象中还要有用,因为模型的价格是动态调整的,手动算一笔账很容易算错。

5. 常见问题与排查技巧实录

5.1 请求返回401:master key没对上

最典型的报错就是认证失败。很多人的第一反应是检查业务代码里的api_key,但漏了master_key这个配置项。litellm要求所有通过代理的请求都带master key,如果你的key写错或者根本没写,它会在认证阶段直接拒绝。

排查方法很简单:先用curl手动带master key发一个测试请求,如果能通,说明问题在业务侧传参;如果curl都能被拒,检查启动配置里的general_settings.master_key是否生效。改完配置记得重启服务。

注意:master_key是代理服务的管理凭证,而虚拟key是给不同业务方使用的子凭证。两者不能混淆,也别图省事都用一个key。

5.2 模型返回model not found

这个问题出现频率极高,但绝大多数情况是对逻辑名和真实模型名的理解错位。业务请求里填的model字段必须是配置文件中model_list里的model_name,也就是逻辑名。如果填了litellm_params.model里的上游标识,比如openai/gpt-4o-mini,反而会找不到。

我的排查习惯是先看一眼配置里的model_name叫什么,再用curl请求那个名字。如果请求成功,再去查业务侧是不是把模型名写死成了上游ID。

5.3 响应超时与重试策略

模型服务的响应时间波动极大,一个复杂推理任务等几十秒都是正常的,但HTTP网关通常有自己的超时时间。如果litellm的默认超时太短,就有可能导致长任务被提前掐断。

处理办法有两个方向:一是调大litellm的timeout参数,二是把推理类的慢请求从常规聊天链路里拆开,走单独的代理地址和超时配置。我实践中发现,把超时设成300秒对大部分场景都够用,但要注意跟业务侧的前端请求超时对齐,否则前端先超时了,网关后面再返回也没意义。

5.4 缓存命中率太低

打开缓存后发现效果不理想,先别急着下结论。语义缓存的命中率跟两个因素关系很大:一是prompt的相似度阈值设置,二是缓存键的提取逻辑。阈值设得太高,只有完全相同的请求才会命中,语义缓存的价值就发挥不出来;设得太低,又会把不同语义的请求误判成同一结果,导致回答错乱。

我的建议是从0.9的相似度起步,观察一段时间,根据答案准确率逐步往下调。另外,需要保证Redis能存储大量的embedding向量和响应结果,如果内存太紧张,缓存淘汰频繁,命中率也会一直上不去。

5.5 自定义渠道接入失败

litellm虽然内置了很多主流渠道的适配,但企业内部总有一些私有化部署的模型服务,用的是自定义接口,官方适配不一定涵盖。遇到这种情况,优先检查api_base地址是否正确、鉴权方式是不是简单的Bearer token。

对于不兼容的私有接口,litellm支持自定义provider开发,但需要写代码扩展。对于普通团队,我建议先用兼容OpenAI格式的框架(比如vLLM这类)把私有模型包装成一个标准服务,再接进litellm。这样中间少一层适配工作,稳定性和后续可维护性都更高。

6. 团队落地时的几条实战经验

6.1 把配置当成代码来管理

litellm的YAML配置文件是纯文本,完全可以放进Git仓库里管理。这样渠道变更有记录、可回溯、能review。我见过有人直接在服务器上手改配置然后重启,时间一长就没人知道线上到底跑的是什么配置了,出了事故只能干瞪眼。

建议在配置仓库里分环境管理,比如dev.yaml和prod.yaml,两边的渠道和限额都不同。改配置走merge request流程,出问题也好回滚。

6.2 先跑通最小链路再逐步加功能

初次接触litellm,别一上来就搞负载均衡、语义缓存、预算控制全套。我的路线是先只配一个渠道、一把master_key,跑通最简单的curl请求,然后再逐步加第二个渠道、开缓存、建虚拟key。每加一个功能就验证一遍,这样出问题的时候定位面很小。

有一次我图省事一次性把配置全部写好,结果Redis缓存参数写错了一个字符,启动时一直报连接异常,排查了半天才发现是端口写成了6378。如果当时先用内存缓存跑通流程,这个问题就会晚点出现,也不至于卡在最开始。

6.3 安全红线不要碰

有几个安全底线我会反复跟团队强调:不要在上游渠道配置里硬编码明文密钥并提交到公开仓库;不要给虚拟key配过高的权限;不要在生产环境关闭认证拿master key开白名单。这些看起来是基础常识,但在实际项目里总有各种借口破例。

另外,litellm的master key和生成的虚拟key都建议定期轮换。轮换时留意正在运行的业务会不会因为key失效而中断,最好在低峰期操作,或者先发新的key、给业务切换窗口,再吊销旧的key。

6.4 把成本报表做成例行任务

litellm给出的日志数据很全,但数据拿到了不用等于白拿。我们在内部是每个月固定跑一次成本聚合,按项目组、按模型维度出报表,发给各团队负责人。这样每个团队都知道自己用了多少、花了多少,有了成本意识之后,乱调模型的次数肉眼可见变少。

如果你一时没有精力搭报表系统,也可以直接从litellm导出的CSV日志里用Excel做透视表,几秒钟就能拉出各key的费用排名。别小看这个动作,它能让模型网关从一个技术工具变成一个成本治理抓手。

最后再分享一个我自己的体会:litellm这个项目看着不起眼,但它是那种装完后很多人会后悔"为什么没早点装"的工具。大模型应用里模型本身是耗电大头,但调用层如果还是原始的直连方式,换模型、做灰度、控成本都会变得异常痛苦。我建议每个依赖大模型API的团队,都认真评估一下要不要在业务前面加一层这样的网关,尤其是团队人数超过三个、开始有协作分工的时候,这个中间层的价值会非常明显。

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

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

立即咨询