☰
litellm统一大模型API网关:一次接入,全模型兼容
2026/10/14 9:01:56 网站建设 项目流程

撸了这么久的各种大模型接口,我最深的体会是:各家模型厂商的 API 风格差异太大,哪怕只是从这家换到那家,代码里的 base_url、鉴权方式、请求格式都要跟着改一遍,烦得很。后来项目里接的模型越来越多,从对话到 Embedding 到图片理解,维护成本彻底失控。直到用了 litellm,这个状态才终结。

litellm 说白了就是一个LLM API 网关,一个统一的代理层。你只需要按照它规定的格式发请求,它帮你转发到后面任意一家模型服务商(OpenAI 系、Anthropic 系、Google 系,以及各种开源模型的托管服务),而且响应格式会统一转换成 OpenAI 的风格。对于已经用 OpenAI SDK 写好的业务代码来说,换模型几乎零成本——只改一个 base_url 和 key 就行。这篇文章我就把它核心的东西、部署方式、踩过的坑一次说清楚。

1. 为什么需要一个统一的 LLM 网关

1.1 多模型接入的碎片化阵痛

我先讲一个真实的场景。某跨平台系统的开发初期只接了 OpenAI 的接口,代码里全是openai库直连,业务跑得挺顺。后来为了降本,想把部分简单任务切到更便宜的模型上,问题立刻冒出来了:

  • 鉴权方式不同:有的服务用 Bearer Token,有的要自定义 header 传 API Key,有的还分主 Key 和子 Key。
  • 请求体结构不同:同样是对话补全,OpenAI 用messages,有的平台用prompt,有的还要求额外的top_p、temperature之外的私有参数。
  • 响应格式不同:有的返回choices[0].message.content,有的直接给一个字符串字段;usage的信息结构也千奇百怪。
  • API 地址和版本差异:同一个模型在不同托管平台上的请求路径可能完全不一样。

如果在业务代码里逐家适配,那代码里就全是if model == "xxx"之类的分支。每加一个新模型,就要动一次核心逻辑,测试回归的工作量很大。这个痛点是所有接过多家模型的人都有的。

而 litellm 把这些差异全部吸收到了网关层。你的业务代码只需要认 OpenAI 的格式,上游想接什么模型、想切换什么模型,都由网关配置统一搞定。这种"后端解耦、前端统一"的思路,和我们在数据库前面加一层 ORM 本质上是一样的道理。

1.2 网关层能给你的额外红利

在网关层做统一转发,表面上只是"格式转换 + 代理转发",但当流量真正经过这一层时,会得到几个额外的能力:

  • 集中式密钥管理:模型厂商的 API Key 不用散落在各个服务里,全部收口到 litellm 配置或它的数据库中,下游服务只认 litellm 颁发的虚拟 Key。一旦有人泄露了 Key,可以在网关侧直接吊销,不用跑去模型厂商后台操作。
  • 成本与用量追踪:litellm 内置了每个 Key、每个模型、每个项目的 Token 消耗统计和预估费用(按模型单价计算),这对做预算管控和多租户计费非常关键。
  • 统一的限流与配额策略:可以在网关层给不同团队或不同业务设置不同的 RPM(每分钟请求数)和 TPM(每分钟 Token 数),避免某个业务把配额打满拖累其他人。
  • 缓存与重试:网关层可以缓存部分响应(比如通过s-maxage控制),也可以配置失败自动重试到备用模型,这些策略对上层业务完全透明。

这些红利虽然通过自研中间件也能实现,但 litellm 的好处在于它把这些能力做成了开箱即用的配置,而且持续维护,省去了自己踩坑和造轮子的时间。

2. litellm 核心能力拆解

2.1 统一 API 格式:OpenAI 协议作为中间层

litellm 对外暴露的 API 格式和 OpenAI 的ChatCompletion保持一致。也就是说,你以前怎么调 OpenAI,现在就怎么调 litellm,只需要把base_url指向 litellm 的地址,把 API Key 换成 litellm 生成的虚拟 Key。

POST http://your-litellm-host:4000/v1/chat/completions

请求体就是一个标准的 OpenAI 格式:

{ "model": "gpt-4o-mini", "messages": [ {"role": "user", "content": "你好,介绍一下自己"} ] }

litellm 收到之后,会依据model参数去匹配配置文件中对应的上游模型映射,然后以合适的格式转发给真实模型服务,再把响应转回 OpenAI 结构返回给调用方。这里有一个关键设计:model字段并不是真实模型的名字,而是一个"逻辑路由名",完全由你在配置里定义。比如你可以把model: "my-app-assistant"映射到某个模型,也可以映射到一个模型组(一组模型)。

这个设计最大的好处是:业务代码根本不需要知道真实模型是谁,只需要知道自己要用的"逻辑模型"是什么。哪天你想把底层模型从 A 换成 B,改动全部在 litellm 配置里,业务侧一行代码不用动。

2.2 模型路由与自动回退

litellm 支持把多个真实模型组合成一个model_list,并定义负载均衡策略和回退顺序。比如下面这个配置,把 "new-model" 路由到主模型,并设置备选模型:

model_list: - model_name: new-model litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY - model_name: new-model litellm_params: model: anthropic/claude-3-5-sonnet-20241022 api_key: os.environ/ANTHROPIC_API_KEY

当主模型(gpt-4o)返回错误或限流时,litellm 会自动尝试下一个同名的模型(claude-sonnet)。这个能力在实际生产环境里非常救命,因为模型厂商的限流、网络抖动、服务降级是完全不可控的,而业务方希望请求尽量能成功返回。所以,litellm 事实上把"高可用"从应用层下沉到了网关层。

配置回退还有一些细节值得注意:

  • 默认同一个 model_name 下的多个litellm_params是顺序列表,litellm 先打第一个,失败再打第二个。
  • 可以通过routing_strategy设置为simple-shuffle(随机打乱顺序)或least-busy(选择当前排队请求最少的),实现负载均衡。
  • 可以通过model_group_alias设置模型组别名,让一个组名指向另一个组名。

2.3 多租户与虚拟 Key 体系

litellm 的"虚拟 Key"是我特别喜欢的功能。它本质上是一套用户和密钥管理系统:你可以在 litellm 上为每个业务线创建一个 Key,然后绑定这个 Key 可以访问的模型、速率限制、预算上限,以及 TPM/RPM 限制。

虚拟 Key 的用途非常大。比如有 A、B、C 三个团队都用你的网关,你想限制 A 团队只能使用便宜的模型,B 团队可以访问大模型但每天预算不能超过 X 美元,C 团队请求频率不能太高。这些都可以通过虚拟 Key 的配置实现,而不需要到模型厂商后台单独创建用户或限额。

在代码里,调用方只需要把 API Key 设置为 litellm 生成的虚拟 Key:

from openai import OpenAI client = OpenAI( base_url="http://your-litellm-host:4000/v1", api_key="sk-litellm-virtual-key-xxxx" )

litellm 会根据这个 Key 自动判定权限和限额。如果超额、超频或尝试访问未被授权的模型,请求会被网关直接拒绝。这为构建内部 LLM 平台提供了天然的多租户底座。

2.4 成本追踪与异常监控

litellm 内部用了一套独立的数据库(默认是 SQLite,生产环境建议用 PostgreSQL)来记录每次调用的元数据:请求的时间、模型名、虚拟 Key 的来源、Token 消耗、延迟、费用预估、报错信息。它提供了一组管理接口用来查询:

  • /spend/logs:查询某个 Key 的调用明细
  • /spend/keys:查询每个虚拟 Key 的累计消费
  • /global/spend:全局消费概况

这个对财务透明很有价值。以前多个业务共用同一个模型厂商账号,月底账单来了根本分不清是哪个团队用的。现在有了 litellm,每一分钱都能追踪到具体的虚拟 Key 和请求记录。如果对接了企业内部的审计系统,基于这些日志做操作审计、行为追溯都很方便。

遇到异常时,litellm 的日志里会保留完整的失败原因和数据轨迹,方便排查。我们之前排查过一次"某个特定时间段请求成功率下降"的问题,直接从 litellm 的日志里看到是某上游服务商的限流策略调整,然后根据时间戳反查到了具体是哪个虚拟 Key、哪个业务线的流量,解决问题很快。

3. 部署与初始配置

3.1 Docker 一键起服务

litellm 官方提供了镜像,最常见的方式是 Docker 部署。这里给一个可以直接复制的最小启动方式:

docker run -d \ --name litellm \ -p 4000:4000 \ -v $(pwd)/litellm_config.yaml:/app/config.yaml \ -e LITELLM_MASTER_KEY=sk-your-master-key \ -e DATABASE_URL=postgresql://user:pass@host:5432/litellm \ ghcr.io/berriai/litellm:main-latest \ --config /app/config.yaml

有几个参数必须解释清楚:

  • LITELLM_MASTER_KEY:主密钥,用来访问管理接口和生成虚拟 Key 的。务必用一个强随机字符串,不能是弱密码。
  • DATABASE_URL:生产环境请使用 PostgreSQL,不要长期用默认的 SQLite。SQLite 在并发量上来之后会有写入锁竞争,而且数据文件迁移和备份都比较费劲。PostgreSQL 可以从一开始就避免这些麻烦。
  • --config /app/config.yaml:配置文件路径,所有模型映射、策略配置都在里面。

启动后,litellm 会在 4000 端口提供服务。你可以先调用一下健康检查:

curl http://localhost:4000/health

正常情况下会返回类似{"status": "OK"}的内容。这一步能快速确认服务是否起了。

3.2 配置文件的结构与要点

litellm 的配置文件是一个 YAML 文件,核心是model_list。下面是一个相对完整的示例:

model_list: - model_name: gpt-4o-mini litellm_params: model: openai/gpt-4o-mini api_key: os.environ/OPENAI_API_KEY rpm: 1000 tpm: 120000 - model_name: claude-3-5-sonnet litellm_params: model: anthropic/claude-3-5-sonnet-20241022 api_key: os.environ/ANTHROPIC_API_KEY max_tokens: 4096 - model_name: embedding-large litellm_params: model: openai/text-embedding-3-large api_key: os.environ/OPENAI_API_KEY general_settings: master_key: sk-your-master-key database_url: postgresql://user:pass@host:5432/litellm

注意os.environ/XXX这种写法:litellm 不会读取 YAML 里的真实密钥明文,而是从进程环境变量中获取,这是一种更安全的实践。密钥不应提交到代码仓库。

rpm和tpm是速率限制选项,在网关侧控制上游 API 的请求频率和 Token 消耗,防止突发流量触发服务商限流。max_tokens设定了模型输出的上限,也可以在这里统一控制。

3.3 测试转发与虚拟 Key

服务起来以后,第一件事是验证转发链路是否正常。我建议先创建虚拟 Key 再测试:

curl -X POST http://localhost:4000/key/generate \ -H "Authorization: Bearer sk-your-master-key" \ -H "Content-Type: application/json" \ -d '{"models": ["gpt-4o-mini"], "max_budget": 50}'

返回结果里会包含一个key字段,就是虚拟 Key。接下来用这个 Key 发起一个真实请求:

curl http://localhost:4000/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-virtual-key-xxx" \ -d '{ "model": "gpt-4o-mini", "messages": [{"role": "user", "content": "你好"}] }'

如果返回了标准的 OpenAI 格式响应,说明链路已经通了。后面的复杂能力(路由、回退、缓存)都在这个基础上叠加。

4. 生产环境的关键进阶配置

4.1 模型回退与负载均衡

很多人在生产环境有这样一个诉求:优先用便宜的模型,便宜模型挂了或限流了,自动切到贵的模型兜底。litellm 的配置方式是这样的:

model_list: - model_name: cost-effective litellm_params: model: openai/gpt-4o-mini api_key: os.environ/OPENAI_API_KEY - model_name: cost-effective litellm_params: model: anthropic/claude-3-5-sonnet api_key: os.environ/ANTHROPIC_API_KEY

请求时指定model: "cost-effective",litellm 会在同一组里按序尝试。要注意,这个回退是"同步"的:它会先等主模型返回错误才能处理下一个,如果上游长时间挂起,请求可能会等较久。所以建议配上超时参数。

litellm 还支持异步路由,通过routing_strategy: "usage-based-routing"或"latency-based-routing"这类策略,网关会选择当前表现最好的上游。这些策略在模型服务商较多、流量分布不均的场景下非常有用,能有效降低整体延迟。

回退策略要结合业务特性来设置。如果是一个实时对话产品,主备切换很关键;如果是离线批量任务,回退的紧急性就没那么高。不要不加区分地在所有模型组都配置一堆备选,因为备选模型的成本可能完全不同,过度配置会让费用不可控。

4.2 缓存策略:降低成本和延迟的利器

litellm 支持基于s-maxage参数的响应缓存。也就是说,客户端可以在请求中带上s-maxage,决定这个响应可以缓存多久。例如:

curl http://localhost:4000/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-virtual-key" \ -d '{ "model": "gpt-4o-mini", "messages": [{"role": "user", "content": "今天天气怎么样"}], "s-maxage": 300 }'

litellm 会对完全相同的messages内容进行哈希作为缓存的 Key,在s-maxage秒内,相同请求直接返回缓存结果,不会重复调用上游模型。这样既省了钱,也降低了响应时间。对于高频的、结果确定性较强的请求(比如知识库问答中的常见问题),这个策略非常实用。

但要注意:缓存一定要配合业务场景。对话类的多轮请求通常不适合长缓存,因为上下文不同会导致结果差异。另外,涉及用户隐私的数据也不宜缓存。所以s-maxage应该由调用方精确设置,而不是全局统一开。

4.3 请求日志、审计与可观测性

litellm 提供了多种日志集成方案,包括输出到控制台、写入数据库、以及接入 Prometheus 指标(用于 Grafana 监控)。在部署时,我建议至少做到以下几点:

  • 结构化日志:开启 JSON 格式日志,方便日志系统解析和检索。
  • 数据库持久化:确保调用记录完整落库,特别是费用记录。
  • 监控告警:通过/metrics端点暴露指标,监控请求成功率、延迟、Token 消耗的异常波动。

如果公司内部已有统一可观测性平台(如 Prometheus + Grafana 或者类似系统),litellm 的指标接入非常容易。我见过不少团队甚至直接在 Grafana 上给不同虚拟 Key 建了独立的费用看板,每个业务负责人可以自助查看自己团队的消耗情况,这极大减少了"这个月的账单是不是算错了"这种沟通成本。

4.4 多租户限额与配额管理

litellm 的虚拟 Key 可以在创建时就设定:

  • models:允许访问的模型列表
  • max_budget:总消费上限(美元)
  • budget_duration:预算周期,比如"30d"或"1d"
  • rpm_limit:每分钟请求数
  • tpm_limit:每分钟 Token 数

当虚拟 Key 的消费或频率达到限额时,litellm 会返回 HTTP 429 或相关错误码。这让"计费控制"变成一个网关侧的硬约束,而不是靠业务方自律。在对接外部客户或临时合作方时,我一般还会额外设一个较低的总预算,防止对方误操作或恶意刷量造成大额扣费。

这里有一个细节值得注意:在创建虚拟 Key 时,如果不显式指定models,有些版本默认会允许所有模型,这存在安全隐患。我在配置新环境时都会在 Key 上显式绑定允许的模型列表,从最小权限开始,按需放开。

5. 从开发测试到上线的实施步骤

5.1 本地快速验证链路

先不用把整套生产架构都搭起来。本地起一个 Docker 容器,配一个最简单的config.yaml,通过 curl 或 Python 脚本调用一下,确认能通。这一步的目的是排除网络、上游服务、密钥这些基础问题。

docker run -d --name litellm-test -p 4000:4000 \ -v $(pwd)/config.yaml:/app/config.yaml \ -e LITELLM_MASTER_KEY=sk-test-master \ ghcr.io/berriai/litellm:main-latest \ --config /app/config.yaml

本地验证通过后,再用虚拟 Key 测试不同模型的路由是否准确。比如在配置里把model_name: test-route指向真实的模型 A 和 B,然后用model: test-route发出请求,观察 litellm 在 A 不可用时是否切到 B。这一步确认了回退逻辑。

5.2 业务侧改造:只改 base_url 和 key

对于已经使用 OpenAI SDK 的 Python 项目,改造量其实很小:

from openai import OpenAI client = OpenAI( base_url="http://your-litellm-host:4000/v1", api_key="sk-litellm-virtual-key-xxx" ) resp = client.chat.completions.create( model="cost-effective", messages=[{"role": "user", "content": "你好"}] ) print(resp.choices[0].message.content)

对于 Node.js 项目,也是类似的做法,把baseURL和apiKey改成 litellm 的地址和虚拟 Key。对于用 HTTP 直接调用的场景,把请求地址改为 litellm 的/v1/chat/completions即可。

要注意的是:如果之前代码里硬编码了某些模型特有参数(比如 Anthropic 的max_tokens必填,OpenAI 则不需要),迁移到 litellm 后最好统一去掉这些特例,让网关侧去配。否则业务代码还是携带着对特定模型的假设,换模型时又会出幺蛾子。

5.3 灰度切换与回滚预案

在所有服务都切到 litellm 网关之前,一定要有一个灰度计划。我常用的方式有两种:

  • 按服务灰度:先挑一个低风险、低流量的内部服务切到 litellm,观察延迟和错误率,再逐步扩大到核心服务。
  • 按模型灰度:先让模型组里同时存在旧模型和新模型,通过 litellm 的回退配置,让一小部分流量走新链路,验证稳定后再放量。

回滚预案也很重要。litellm 本身作为代理层,如果它出了问题,所有下游业务都会被影响。所以我会保留一条直连上游模型厂商的通道作为 emergency 方案。一旦 litellm 异常,可以通过环境变量或发布系统快速切回原来的直连逻辑,保证业务连续性。网关层虽然好用,但它也确实是额外的故障点,这一点要有清醒认识。

5.4 统一封装:团队内的最佳实践

在落地过程中,我强烈建议开发团队在 litellm 之上再做一层轻量的内部 SDK 封装,而不是让每个业务方直接裸调 litellm 接口。这层封装的职责是:

  • 统一设置 base_url、key 和超时时间
  • 统一做错误重试(比如遇到 429 或 5xx 时退避重试)
  • 统一埋点(把 model、latency、token 等信息打到内部监控系统)
  • 提供类型定义,让调用方有类型提示,避免写错字段

这层封装不需要很重,可能一个模块就够了,但它能让业务代码更简洁,也能在 litellm 本身升级或调整时,把对业务的影响降到最小。

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

6.1 连不上上游模型服务

现象:请求时返回带有 "connection error" 或 "timeout" 的报错,litellm 日志里能看到上游地址连接失败。

常见原因:

  • 上游模型服务的密钥不合法、过期或没有对应模型的权限。
  • 目标模型服务的 API 域名不可达(可能被防火墙拦截,或者域名解析失败)。
  • 上游服务当前限流或宕机。

排查方法:

  • 先绕过 litellm,直接用上游的 SDK 或 curl 请求,确认上游本身是通的。
  • 到 litellm 的日志里查看完整的错误信息。litellm 设计上会在报错时把原始异常信息带上。
  • 检查环境变量是否真正传给了容器。很多人配置了os.environ/XXX,但忘了在 Docker run 时传递-e XXX,导致 litellm 找不到密钥。

6.2 模型路由不生效,请求总是打到同一个模型

现象:配置了多个相同model_name的模型组,但观察上游流量发现只用了第一个模型,回退或负载均衡没有发生。

可能原因:

  • 请求本身并未返回错误,所以 litellm 只命中了第一个模型。回退只在有异常时才触发,正常插队不会发生。
  • 使用的model_name写错了。比如配置里是cost-effective,请求体里写了cost_effective,litellm 可能把这个当成不认识的模型,转而走了默认策略。
  • 负载均衡策略需要显式设置为simple-shuffle或least-busy,默认的顺序可能就是你看到的"总用第一个"。

建议:先在配置中把不同模型的上游 key 换成打印日志的特殊 key,或观察 litellm 管理后台的请求日志,看实际走了哪个litellm_params。确认逻辑之后,再调整策略。

6.3 虚拟 Key 权限报错

现象:使用虚拟 Key 请求时报 401 或 403,但主 Key 直接请求是通的。

排查:

  • 检查虚拟 Key 的models范围是否包含了你要访问的model_name。如果虚拟 Key 是在创建模型之前生成的,可能没有刷新权限。
  • 检查虚拟 Key 是否被设置了max_budget且已经用超了。
  • 检查请求的model参数和虚拟 Key 绑定的模型名是否完全一致(大小写、连字符差异都要注意)。

这种问题最容易出现在"模型名改了,但 Key 没更新"的场景。建议所有的模型命名都规范化,避免出现别名混乱。

6.4 数据库连接问题导致启动失败

现象:启动时日志报错,提示无法连接数据库。

原因:DATABASE_URL配置错误,或者数据库还没有初始化。litellm 在启动时会对数据表做 migration,如果连不上库,服务会拒绝启动。

解决:

  • 确认 PostgreSQL 已经运行,并且该账号有建表权限。
  • 在 Docker 命令里检查环境变量DATABASE_URL是否被正确传入。
  • 如果用的是远程数据库,确认网络能通,防火墙放行了对应端口。

如果你只是试玩,可以先用默认的 SQLite 起一个;但要上线,务必尽早切到 PostgreSQL,不然后续数据迁移的成本会很高。

6.5 TPM/RPM 限流失效

现象:明明给虚拟 Key 设置了 TPM/RPM,但高并发下还是限制不住。

原因:litellm 的限流机制需要数据库做分布式锁记录。如果用 SQLite,在多个实例或多进程场景下,限流计数可能不准。另一个原因是新旧配置没生效,需要重启服务或热加载。

建议:

  • 生产环境使用 PostgreSQL,确保多个实例共享同一个计数器。
  • 通过/config接口热更新配置后,确认配置已经生效。
  • 限流是"尽力而为"的,不要完全依赖它做业务层的流量兜底。重要的业务侧还是应该有自己的保护机制。

7. 常见问题速查表

场景典型报错/现象根因方向推荐动作
上游连接失败Connection error上游不可达/密钥错误先用上游 SDK 直连测试,检查环境变量
模型路由不生效总是打到一个上游默认顺序策略,或模型名写错定期限流切换策略,核对 model_name
虚拟 Key 无权限401/403Key 的 models 范围不匹配检查 Key 绑定的模型列表和 model 参数
费用统计不准当月账单和后台不一致数据库未正确记录/模型单价配置缺失核对模型单价,确保日志落库
全链路超时请求长时间无响应上游慢或回退等待超时配置自定义超时(如timeout)和重试策略
缓存未生效相同请求未命中缓存未传s-maxage,或消息中带随机字段确认请求结构稳定,添加缓存参数

最后分享两个实操经验

第一点是回退模型的选择要克制。很多人会把最贵的模型作为一切问题的保底,这样确实提升了成功率,但费用会飙升。我更推荐的做法是:同一个模型组内,备选模型的数量最多两个,并且优先选择价格相近、能力相近的模型。这样既保证可用性,又不会让异常流量带来巨额账单。

第二点是定期审视虚拟 Key 和模型映射。litellm 配置的灵活性也意味着,如果长期不清理,会产生一大批废弃 Key、多余模型映射,既难以审计,也浪费内存。我会每隔一段时间清理掉 30 天内无请求的 Key,并把线上实际使用的模型名梳理一遍,删掉不用的映射。这样维护成本和风险都会小很多。

litellm 解决了多模型接入的痛点,但它不是银弹。引入任何中间件都会增加运维复杂度,这是必须接受的代价。我的建议是:先从小流量场景开始,跑通链路、积累运营数据,再逐步扩大覆盖范围。把 litellm 定位成"LLM 基础设施"的一部分来长期运营,而不是当成一个临时的小工具,你才能真正享受到它带来的长期收益。

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

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

立即咨询