ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

litellm:打造统一多模型接入的开源LLM网关

litellm:打造统一多模型接入的开源LLM网关

现在很多做 AI 应用的同学,尤其是那些需要同时对接多家模型服务的团队,正在被一个非常琐碎的问题反复折磨:每个平台都有自己的 API 格式、认证方式、限流策略和计费规则,今天要在代码里兼容这个,明天要适配那个。更别提团队里不同成员可能各自申请了不同的密钥,月底对账的时候只能对着账单发懵。我第一次遇到这个场景,是在一个需要同时跑国内和国外多个模型做效果对比的项目里,当时我就在想,要是能有一个统一的管道,把所有模型接口都收敛到一个入口,让上层应用只管发 HTTP 请求,底层细节全被屏蔽掉就好了。后来我发现,一套成熟的开源方案其实已经把这条路走通了,那就是名为 litellm 的模型网关服务。

这里先直接给结论:litellm 是一个用 Python 编写的开源 LLM 代理网关,它把 OpenAI、Anthropic、Google Gemini、Azure OpenAI、以及国内常见的各类兼容接口全部统一成 OpenAI 的请求/响应格式。这意味着你不需要为每家模型单独写 SDK,只需要往配置里写清楚上游地址和密钥,然后所有应用都请求 litellm 服务本身即可。它还额外提供了密钥管理、负载均衡、成本追踪、限流以及简单的前端面板,基本上一个团队自用或者小规模生产环境所需的网关能力,它都覆盖了。

这篇文章我会从实际落地的角度出发,先把这套网关的核心设计逻辑讲清楚,再带着你把配置、部署、调用、排错走一遍。无论你是刚接触 AI 开发的初学者,还是已经在生产环境维护服务的资深工程师,应该都能从里面找到可以直接拿回去用的内容。文章里不会塞一堆晦涩的概念,我尽量用大白话加实际踩坑经验来讲,保证你看完能上手。

1. 核心思路拆解:一个入口接管所有模型服务

1.1 为什么需要一层“中间代理”

很多人最开始不理解,为什么不在代码里直接换个库、改几行请求参数,非要引入一个额外的服务层。我举一个非常典型的场景:你的项目里先用 OpenAI 的 GPT 做文本总结,后来发现另一个平台的模型在中文长文本上效果更好、价格更便宜,你决定切换过来。如果没有网关,你需要把工程里所有调用 OpenAI 的代码全部扒出来,把请求地址改成新平台的地址,把请求体里的字段名按新平台规范改一遍,认证方式换掉,然后测试所有链路。这一套下来,一个中大型项目少说也要折腾一到两天。

引入 litellm 之后,这个过程变成什么样子呢?你在后端部署好 litellm 服务,配置里写好“模型 A”指向 GPT 的 upstream,“模型 B”指向另一家平台的 upstream。上层应用实际看到的是一个 OpenAI 格式的接口,需要的只是一个虚拟的模型名(比如gpt-4o-custom)。后续要切换模型,你只需要修改网关配置文件或者直接通过 API 动态调整路由规则,应用代码一行都不用动。这种方式相当于给你的应用层和模型供应商之间加了一个适配层,供应商的协议差异、密钥体系、限流策略全部被隔离在这个适配层内部。

还有一个隐藏得很深的价值:统一网关实际上帮你做了一层审计和管控。在直接接各家 API 的时候,每次调用要花多少钱、被谁调的、成功率和延迟怎么样,这些数据分散在供应商后台,看不全也难统计。而 litellm 作为所有请求的汇聚点,天然记录了每次调用的模型、项目、用户、token 消耗、耗时和费用估算,你可以在一个面板上掌握全部情况。

1.2 技术架构的三层逻辑

从技术上看,litellm 的架构可以拆成三层来理解。第一层是北向 API 层,也就是对上层应用暴露的接口。这一层的设计非常聪明,它直接复用了 OpenAI 的v1/chat/completions接口格式,所以你在 OpenAI Python SDK 里随便改一下base_url指向 litellm,再把 API key 换成 litellm 生成的虚拟 key,就能正常使用。这种设计让迁移成本降到几乎为零,因为 OpenAI 的 SDK 生态是市面上最成熟的,几乎所有语言都有现成封装。

第二层是路由层,这也是 litellm 的灵魂。它负责拿到请求之后,从配置和策略里确定应该把请求转发到哪个模型供应商。路由层要处理的事情包括:如果配了多个相同名称的 upstream,怎么根据权重、健康状态和最大并发数动态分流;如果发现某个 upstream 持续报错或者超时了,怎么自动摘除并切换到备用节点;以及如果模型名称对不上实际服务,如何做纠错和映射。这一层把复杂的容错逻辑沉淀在了定时任务和健康检查机制里,上层不需要关心任何细节。

第三层是南向供应商适配层。litellm 对各家供应商的 API 差异做了大量兼容工作。它走的是动态解析 JSON Schema 的路线,请求进来时先把 OpenAI 规范的请求体翻译成各供应商能识别的格式,再把返回的响应翻译回 OpenAI 规范。这个翻译过程不是简单字段改名,还包括处理不同平台的消息格式差异(比如某些平台的 system 消息、工具调用格式不太一样)、不同平台对参数默认值的理解差异等。可以说,这一层才是 litellm 的核心技术壁垒。

2. 核心功能解析:密钥、预算、路由和可观测

2.1 多密钥管理与预算控制

在 litellm 里,密钥管理并不是简单的“存起来给你用”,它是一套完整的虚拟密钥体系。你可以理解成:真实的供应商 API key 被加密存在 litellm 的配置库中,称为“后端密钥”;而你分发给团队成员的,是 litellm 自己生成的“虚拟密钥”,与后端密钥一一对应或共享某个配额池。

管理员通过管理接口或面板创建一个虚拟密钥时,可以指定这个 key 能调用哪些模型、每分钟/每天/每个月的最大请求数或最大花费金额、绑定到哪个团队或用户,以及在什么时间段内生效。举个实际例子:你公司有实习生在做测试,你不想让他用你的主 key 去生产环境模型上疯狂跑,给他开一个虚拟 key,限制只能调用最便宜的模型,月预算上限 50 块钱,到期自动失效。这个流程在管理面板上两分钟就能完成,意义在于让密钥使用变得可管控,不会出现一个 key 泄露导致整个账户被刷爆的惨剧。

实战中我强烈建议:真实供应商 key 的权限越少越好,如果供应商支持子账号体系,就为 litellm 单独创建一个专用子账号,不要用主要账号的 key 去配。因为网关存储的密钥虽然本身是加密的,但任何系统都扛不住密钥泄露,如果泄露的是子账号且只授权了有限模型,你的损失是可控的。

2.2 路由策略与负载均衡配置逻辑

路由策略是一个网关最值得强调的地方。litellm 的路由不是简单的“写死一个地址转发”,它支持在同一模型名下配置多个 upstream,形成一组专用后端。请求到来时,网关会结合你配置的权重、最近 100 次调用的平均耗时、失败率、以及每个上游当前的并发请求数来做综合决策。

最常见的配置方式是:同一个模型服务部署在多套供应商或区域节点,比如你同时拥有标准版和低延迟版两个渠道,正常情况下所有流量走标准版,但标准版超时率达到预设阈值时,自动切换到低延迟版。另一种常见的用法是主备模式:主供应商偶尔抽风,备供应商集成在你的配置里,一旦主供应商 API 返回 500/429 超过设定比例,litellm 会把流量切到备供应商。这个能力对生产环境至关重要,因为没有任何一家模型服务商能保证 100% 的 SLA,但通过网关层的自动切换,你的应用可以做到对外几乎无感。

我在本地测试时给两个不同的上游渠道分别设了routing_strategy="usage-based-routing"和routing_strategy="latency-based-routing",实测发现延迟策略在我们流量不均匀的场景下不太稳定,因为单次调用的延迟波动受网络影响很大。后来改成simple-weight加失败自动摘除,效果反而更稳。这里想说明的是,路由策略不是越智能越好,要看你的实际流量特征,小团队用简单策略加健康检查就非常香。

2.3 成本追踪和 Token 级别的数据洞察

成本追踪这一块,litellm 做得比较深入。每次请求结束之后,网关会根据上游返回的 usage 信息(prompt tokens、completion tokens)、以及你在配置里为模型设定的单价,计算出这次调用的估算成本,写入独立的数据库表。你可以在面板上按天、按模型、按团队、按用户查看消耗趋势。对于做预算控制的人来说,这个功能基本是刚需。

不过要注意的是,“估算成本”不一定等于“真实账单”。因为部分模型供应商对大额充值用户的折扣价、月末返点等优惠不会体现在公开单价里,litellm 的计算是基于你配置的价格表。建议你在季度末用供应商后台的账单去校准一下 model 的单价配置,偏差大的话手动调价,这样日常成本趋势才更准确。

另外,litellm 会把每次请求的完整调用链信息(包括请求的原始输入截断、模型输出截断、耗时、状态码、错误信息)持久化存储。这意味着你可以在面板里回看某一次调用到底发了什么、模型回了什么。排查问题的时候,再也不需要去翻应用日志和供应商后台空对照,直接在网关里看请求日志就清楚多了。

3. 实操部署全流程:从配置到生产可用

3.1 环境准备与基础安装

litellm 对 Python 版本的要求不算苛刻,3.8 以上都没问题,官方接口推荐 Python 3.11。安装方式最省事的是直接通过pip安装主包,它会把依赖的客户端库一并带上。这里我要提醒一句:安装时不要图省事用pip install litellm然后什么都不管,建议新建一个独立的虚拟环境来跑网关服务,避免污染你现有的 Python 环境。我们实际部署踩过版本冲突的坑,就是在原有项目的虚拟环境里直接安装,结果把某个依赖库版本挤掉导致项目起不来。

# 创建一个专用虚拟环境 python3.11 -m venv litellm-env source litellm-env/bin/activate # 安装 litellm(生产环境建议指定版本) pip install "litellm[proxy]" # 查看版本,确认安装成功 litellm --version

装好之后,最快的启动方式是使用 SQLite 作为默认存储,服务会初始化一张简单的 KV 表来保存密钥和配置;如果你配置了数据库连接串,它也能自动建表并迁移。生产环境我建议直接接一个 PostgreSQL,SQLite 在并发稍高的时候会有锁冲突,影响网关性能。数据库的连接方式和标准 ORM 类似,设置好 URI 环境变量即可。

3.2 第一步配置:接入第一个模型服务

我们用最常见的 OpenAI 兼容接口来演示配置。假设你手头有一个平台,它的 API 地址是https://xxx.example.com/v1,模型名是my-model,供应商 key 是sk-abc123。

首先,创建一个配置文件config.yaml:

model_list: - model_name: my-model-proxy litellm_params: model: openai/my-model api_base: https://xxx.example.com/v1 api_key: sk-abc123 rpm: 500 model_info: mode: completion

然后启动服务:

litellm --config config.yaml --port 4000

启动之后,litellm 会监听 4000 端口。你本地用 curl 做一次快速连通性验证:

curl --location 'http://localhost:4000/v1/chat/completions' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer sk-1234' \ --data '{ "model": "my-model-proxy", "messages": [ {"role": "user", "content": "你好,请回复一句话"} ] }'

这里有个细节要说明:model字段在litellm_params里写成openai/my-model,这个前缀openai/是告诉 litellm 走 OpenAI 兼容协议去解析,后面跟的才是真正的模型名。如果你的上游是别的平台,前缀可能变成anthropic/、gemini/、azure/等,litellm 就是靠这个前缀来识别该走哪个协议适配器。这是最容易出错但又最值得理解的地方,把model前缀和api_base地址分别理解成“协议类型”和“目标地址”,配置文件读起来就轻松很多。

3.3 打开密钥管理并生成虚拟密钥

初次启动后,管理接口默认没有开启。你需要在配置文件里加上master_key并指定一个管理员用户名密码,这样面板和管理 API 才会被激活。这个master_key相当于整个网关的超级管理员,请务必用强随机字符串并妥善保管,它可以在不配置数据库的情况下管理所有虚拟密钥。

加入如下配置:

general_settings: master_key: sk-master-strong-random-key database_url: postgresql://user:password@localhost:5432/litellm

管理员用户名密码在环境变量里指定:

export LITELLM_PROXY_ADMIN_PASSWORD="admin_secure_password" litellm --config config.yaml --port 4000

重启之后,访问http://localhost:4000/ui进入管理面板。你可以用 master key 登录(部分版本直接用 master key 作为管理员密码),然后进入密钥管理页面,点击生成新的虚拟 key,给它绑定目标模型(也就是my-model-proxy),设置好预算和过期时间。生成出来的 key 形如sk-XXXXXXXXXXXXXXXX,把它配到你的应用环境变量里。

很多人刚开始会忽略这一步,直接在应用里使用真实供应商 key 去请求 litellm。这样做不是不行,但等于完全放弃了密钥管控。我建议把“应用 → litellm 虚拟 key → 真实 key”这套链路作为标配,后面查问题看日志的时候,你能根据虚拟 key 区分是哪个应用在调用,而不是所有流量混在一起。

3.4 高可用部署的关键动作

当 litellm 从本地实验走向生产,有几点是必须提前规划的。第一是数据库必须外置且高可用,不要依赖进程内嵌的 SQLite。第二是网关本身建议跑多个副本,前面挂一层负载均衡,这些副本共享同一个数据库和配置文件,运行时状态是粘在 PostgreSQL 里的,所以多实例部署很自然。

第三点很容易忽略:litellm 默认的模型路由数据是存在内存里的,多副本部署时,每个副本只有自己内存中的健康状态。这意味着如果一个副本已经把一个上游标记为不健康,另一个副本可能还在往这个上游发请求。要解决这个问题,需要把健康检查状态和部分路由状态持久化到 Redis 里。官方文档提供了redis_host等配置,在general_settings下加上:

general_settings: redis_host: 127.0.0.1 redis_port: 6379 redis_password: ""

这样之后,多副本之间的健康状态、缓存数据就可以共享了。实践下来,即使只有单副本,接一个 Redis 也能让并发处理能力明显提升,因为很多请求参数校验的结果会被缓存,不用每次重新解析。

4. 高频问题与排查经验实录

4.1 模型名称映射错误,请求一直 404

最常见的问题集中在model前缀上。很多人把 OpenAI 的 SDK 包直接改 base_url 指向 litellm,然后请求时还传model: gpt-3.5-turbo,但没有在 litellm 的model_list里配置gpt-3.5-turbo这个名字,于是 litellm 根本找不到匹配的路由规则,直接返回 404 或者报错 “model not found”。

解决办法是:无论 SDK 里传什么模型名,必须保证这个字符串存在于 litellm 的model_list里。如果你希望上层业务代码保持原样(还是传gpt-3.5-turbo),那就把配置里的model_name也命名为gpt-3.5-turbo并映射到你的真实上游。让网关的模型名和业务侧模型名保持一致,是最省心的方案。

4.2 请求超时和上游限流的连锁反应

上游模型服务偶尔响应变慢,如果 litellm 默认超时时间设得过短,网关会很快放弃并返回错误给客户端。但调大超时时间又有风险:并发一高,网关这边堆积大量等待中的请求,内存飙升,最后整台机器卡死。我们遇到过最严重的一次,是某个上游集体限流,所有请求都在排队,结果 litellm 的 worker 全部被堵住,健康检查端口都无法响应。

后来我们做了三个动作:第一,根据上游的响应特点分别设置request_timeout,比如普通生成模型 60 秒,重计算类模型 300 秒;第二,在 litellm 前方加了超时更快的网关层,快速失败返回给客户端,不让请求在 litellm 里无限堆积;第三,给 litellm 进程单独配置内存上限,并设置容器级别的自动重启策略。这样即使上游彻底抽风,我们的服务也只是损失部分请求,不会拖垮整个应用。

4.3 成本统计和实际账单有偏差

成本这块前面提了一嘴,这里详细说。litellm 计算成本时,需要model_info块里的input_cost_per_token和output_cost_per_token,不同模型肯定不一样。如果你图省事不配置这两项,网关就用默认值论“百万 token 美元”来算,准确率很低。而且部分模型的实际价格是累进计费(超出一定 token 量单价变化),litellm 内置的固定单价模型算不了这种场景,偏差就更大。

处理办法是:在配置里尽量精确填写单价,尤其是 token 密集的对话场景,差一两位小数月末汇总起来误差都不小。另外,litellm 的统计更适合看趋势,不建议完全替代财务对账。

4.4 虚拟密钥泄露后的紧急处置

一旦发现虚拟 key 被人刷了,第一反应应该是到管理面板立刻把该 key 删除,阻断后续请求。然后查日志确认被调用的是哪些模型、量级多少、损失约多少钱。由于真实供应商 key 始终在 litellm 内部,外泄的虚拟 key 即使被他人拿到,能调用的也只限于你绑定给它的模型和预算额度,这是虚拟密钥体系最大的好处。

5. 最后再分享两个实用小技巧

第一个技巧:litellm 支持把多个不同的供应商 key 配成同一个model_name,系统会自动把密钥分散使用,起到轮询的效果。比如同样的模型你有两个账号,免费额度大家都懂的原因,不想一下子消耗完,就可以在配置里写两个litellm_params,网关会轮流切换账号调用,变相提高可用容量。但这个技巧请谨慎使用,务必确认服务商允许这种用法,别触碰服务条款。

第二个技巧:如果你在做一个面向大量用户的产品,可以在请求体的 metadata 里塞上用户 ID 和会话 ID,litellm 会把它们透传到日志系统。之后你想统计“哪个用户消耗了多少 token、花了多少钱”,在面板日志里就能直接筛选,不用自己另外打点。这个习惯建议从第一天就养成,不然后期补数据会异常痛苦。

最后,根据我的实际经验,litellm 早期配置阶段看着繁琐,但一旦路由、密钥、数据库这几条主线捋顺了,日常维护非常轻松。它的价值不在于帮你写业务代码,而是让你把“模型接入”这件事沉淀为基础设施能力。我强烈建议但凡有多个模型渠道的团队,都花半天时间把它部署起来,后面真的要切模型、做灰度、控成本的时候,你会庆幸自己当初做了这个决定。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进