☰
用litellm构建统一LLM API网关:接口管理与模型调用实践
2026/10/14 9:01:54 网站建设 项目流程

LLM 接口管理这件事,我一开始是拒绝自己折腾的。项目里的模型调用散落在好几个服务里,OpenAI 的、Claude 的、本地私有化部署的,各写各的客户端、各配各的 Key,哪怕只是统一加个日志都得改一圈代码。后来实在忍不了,把接口层抽出来做了统一网关,整个迁移过程比想象中顺利,这中间最让我省心的工具就是litellm。这篇就把我实际落地的经验完整写出来,从核心设计到代码实现、从配置到底层原理、再到踩过的坑,一次性说清楚。

1. 先搞清楚 litellm 到底解决什么问题

1.1 接口碎片化是真实存在的痛点

很多团队的项目里,模型调用并不少,但接口管理几乎为零。业务代码里到处散落着openai.ChatCompletion.create(...)、anthropic.Anthropic(...)、requests.post(本地模型地址),每个调用点都耦合了 SDK、模型名、Key、超时设置、重试逻辑。测试环境换一个模型供应商,就得全项目搜索替换。更麻烦的是,各家模型的输入输出格式不完全一致,有的返回content,有的返回text,有的带choices数组,有的直接返回字符串,对接层写起来又脏又乱。

我接手过一个模块化项目,里面同时用了三个不同厂商的模型做不同任务,代码里大量if model_provider == 'xxx'的分支,日志格式也是各写各的。当时要加一个统一的 token 用量统计,结果发现每个调用点都得单独改一遍,改到怀疑人生。那时候就想,要是有一个统一的转发层,所有模型请求都走它,上游接口统一,日志统一,成本统计统一,那该多好。

1.2 litellm 的核心定位与设计

litellm 本质是一个模型调用网关(Model Gateway),它把所有主流大语言模型供应商的 API 规范统一成一个格式。你可以把它理解成支付领域的聚合支付:你不需要分别对接微信、支付宝、银联,只需要对接一个聚合 SDK,它帮你做协议转换和路由。

具体来说,litellm 做了三件事:

  • 统一请求格式:无论底层是 OpenAI、Anthropic、Cohere、HuggingFace 还是本地 Ollama,上游都按 OpenAI 的 ChatCompletion 格式(messages、model、temperature等)来发请求。
  • 统一响应格式:无论底层返回什么结构,litellm 都转成 OpenAI 风格的响应结构,业务端解析起来完全一致。
  • 统一路由与管理:支持根据模型名自动路由到不同供应商,支持负载均衡、重试、限流、预算控制等企业级能力。

它有两种使用形态:一种是直接在 Python 里调用它的 SDK 接口;另一种是启动一个代理服务(Proxy Server),对外暴露一个/chat/completions接口,任何语言任何框架都能通过 HTTP 调用。第二种形态特别适合多语言团队,或者想把协议转换能力独立出来的场景。

我当时选择直接用代理服务形态,原因很简单:我们是 Python、Go、Node 三种技术栈混着用的,共享同一个 HTTP 网关比每个语言都引入一套 SDK 要省事得多,后续加鉴权、限流也统一在网关层做。

1.3 明确适用场景和边界

litellm 适合的场景非常清晰:

  • 项目用了不止一家模型供应商,想统一接口;
  • 需要精细化管理模型调用,比如按团队分配额度、记录调用日志、统计成本;
  • 从 OpenAI 切换到其他兼容模型时,不想大改业务代码;
  • 需要自建一个模型 API 网关,供多个内部服务复用。

如果只是在一个单语言小项目里用一家固定厂商的模型,那直接装官方 SDK 就行,没必要引入网关层。多一层转发总是多一份延迟,虽然 litellm 的代理转发开销非常小,但没必要为简单场景增加复杂度。另外,如果团队已经有成熟的 Kubernetes Ingress 或服务网格,也可以结合使用,litellm 更偏应用层的协议转换,两者不冲突。

2. 环境准备与核心配置解析

2.1 安装方式选择

litellm 通过 pip 安装,当前主流版本要求 Python 3.9 以上。直接安装:

pip install 'litellm[proxy]'

如果你只需要 Python SDK,不跑代理服务,可以只装依赖更少的版本:

pip install litellm

这里我强烈建议装[proxy]版本,因为代理功能几乎是必须的,而且依赖装全了后续省心。如果你用 Docker,官方提供了镜像,直接拉下来就能跑:

docker pull ghcr.io/berriai/litellm:main-latest

我自己本地开发用 pip 装,生产环境用 Docker 部署,两者配置思路完全一样。

2.2 模型供应商配置(config.yaml)

litellm 的代理服务通过一个 YAML 文件来声明所有模型路由,这是整个工具最核心的配置。先看一个基础示例:

model_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY - model_name: claude-3-5-sonnet litellm_params: model: anthropic/claude-3-5-sonnet api_key: os.environ/ANTHROPIC_API_KEY - model_name: llama3-local litellm_params: model: ollama/llama3 api_base: http://localhost:11434

这里有三个关键点需要理解:

model_name是暴露给你的调用方的逻辑模型名,业务代码里就用这个名字发起请求。litellm_params.model是实际发给底层供应商的真实模型标识,格式是供应商前缀/模型名,例如openai/gpt-4o表示走 OpenAI 接口请求gpt-4o,anthropic/claude-3-5-sonnet表示走 Anthropic 接口。api_key支持从环境变量读取,避免把密钥写死在配置里,os.environ/OPENAI_API_KEY这种写法代表运行时从环境变量OPENAI_API_KEY取。

对于本地模型,api_base指向 Ollama、vLLM 等本地推理服务的地址,litellm 会自动按对应的原生协议转发。

2.3 启动方式与验证

配置好了之后,启动代理服务:

litellm --config config.yaml --port 4000

默认端口是 4000,你可以改成任意可用端口。启动日志会打印出模型列表和对应路由,确认无误后,用 curl 快速验证:

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

如果配置正确,会返回 OpenAI 格式的响应结构,包含choices、usage等字段。我第一次尝试时,在 config 里漏了api_base,本地 Ollama 一直返回 404,加上之后就正常了。验证响应正常后,就可以开始接入业务了。

2.4 环境变量与密钥管理

密钥管理是生产环境必须注意的事。不要把 API Key 直接写进 YAML,而是用环境变量方式注入:

export OPENAI_API_KEY="sk-..." export ANTHROPIC_API_KEY="sk-ant-..." litellm --config config.yaml

如果你的团队使用集中配置中心,也可以在启动前把环境变量拉取到进程环境里。litellm 在读取os.environ/变量名时,会自动去进程环境里找,不存在则报错,这种显式失败比静默降级好得多,避免上线后发现 Key 没注入导致请求失败。

3. 实操过程:部署代理服务并接入业务

3.1 完整配置示例:多供应商 + 成本跟踪

在实际工作里,我用的配置会比官方示例复杂一些。这里给出一份可以直接参考的完整配置,里面包含多供应商、模型别名、成本计算和健康检查:

model_list: - model_name: production-gpt4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY model_info: price_per_token: 0.0000025 - model_name: production-claude litellm_params: model: anthropic/claude-3-5-sonnet api_key: os.environ/ANTHROPIC_API_KEY model_info: price_per_token: 0.000003 - model_name: local-llama litellm_params: model: ollama/llama3 api_base: http://localhost:11434 litellm_settings: drop_params: true set_sentry: false general_settings: master_key: os.environ/LITELLM_MASTER_KEY database_url: os.environ/DATABASE_URL

这份配置里,model_info.price_per_token用于成本估算,litellm 会把 token 用量乘以单价,记录到数据库中。master_key是网关自身的访问密钥,外部调用时必须带这个 Key,防止网关被裸奔暴露。database_url用于持久化日志和用量数据,不配的话数据只存在内存里,重启就丢。

3.2 从 Python 端接入 Gateway 的代码示例

业务代码接入时,理论上你只需要改 base_url 和 api_key,其他代码结构不用动。以 Python 的 openai SDK 为例:

from openai import OpenAI client = OpenAI( base_url="http://localhost:4000", api_key="your-litellm-master-key", ) resp = client.chat.completions.create( model="production-gpt4o", messages=[ {"role": "system", "content": "你是一个技术助手"}, {"role": "user", "content": "用三句话解释什么是 API 网关"} ], temperature=0.7 ) print(resp.choices[0].message.content) print(resp.usage)

注意这里model参数写的是production-gpt4o,也就是你在 litellm 配置里定义的逻辑名。实际调用哪个底层模型,完全由网关层路由决定。这意味着你换模型时不需要改业务代码,只需要改网关配置。

3.3 非 Python 技术栈接入示例

用 Go 或者 Node 接入,本质就是发 HTTP 请求,没有任何 SDK 依赖。以 Node 的 axios 为例:

const axios = require('axios') const resp = await axios.post('http://localhost:4000/chat/completions', { model: 'production-gpt4o', messages: [ { role: 'system', content: 'You are a helpful assistant.' }, { role: 'user', content: 'Hello!' } ] }, { headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer your-litellm-master-key' } }) console.log(resp.data.choices[0].message.content)

你甚至不需要知道 litellm 的存在,只要目标接口是 OpenAI 兼容的,就能直接接。这正是网关模式的优势:接口规范只定一套,语言随意,SDK 随意。

3.4 关键参数调优

代理转发过程中有些参数需要注意。timeout方面,litellm 默认超时是 600 秒,这个值对长输出场景比较友好,但如果你的业务对延迟敏感,可以适当调低,避免请求挂住。我一般把它设置为 300 秒,既能覆盖绝大多数模型输出,又能及时失败。

max_retries方面,默认重试次数为 2。对于偶发的 5xx 错误和限流 429,重试机制很有效。但要注意,重试会放大请求压力,如果模型服务本身已经过载,重试可能加剧问题。建议只对幂等请求开重试,并且配合退避策略。

drop_params作用很实用:当你的请求里包含某个供应商不支持的特殊参数时,例如response_format在有些本地模型上不支持,开启这个配置后 litellm 会自动丢弃不支持参数,而不是直接报错。这个开关我建议在生产环境开启,避免模型供应商差异导致调用失败。

关于请求参数,OpenAI 的 ChatCompletion 格式里有一组通用参数,比如temperature、top_p、max_tokens,litellm 会把这些参数透传给底层模型,但底层模型如果不支持,就会忽略或报错。这种差异化的行为需要在联调阶段提前测一遍。

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

4.1 模型路由 404 / Model Not Found

这是最常见的错误。出现这个报错,先检查 config.yaml 里model_name是否与实际请求的 model 名完全一致,注意大小写和空格。然后再确认启动时是否正确加载了这个配置文件。调试方式是用litellm --config config.yaml启动时观察日志,它会打印 model_list 清单。

我踩过一个坑:配置文件里有两个model_name重复了,后一个覆盖了前一个,结果请求全部被路由到错误的模型上。检查配置时一定要看完整日志,不要只看部分信息。

4.2 认证与权限错误

如果你启用了master_key,而请求时没有带上正确的Authorization头,会收到 401 错误。litellm 的认证方式与 OpenAI 类似,直接在 Header 里写Authorization: Bearer your-master-key。

还有一种情况是底层供应商的 Key 失效,错误信息会显示比如 “Incorrect API key provided”。这时去检查环境变量是否注入正确,尤其在使用 Docker 部署时,环境变量传递很容易漏。

4.3 token 统计与成本数据不准

litellm 的 token 用量统计依赖于响应中的usage字段。有些本地模型返回的 usage 字段缺失或格式不规范,成本计算就会不准确。解决办法是在配置里手动指定model_info.max_tokens、input_cost_per_token、output_cost_per_token,尽量准确填写供应商的计费规则。对于本地模型,成本可以设为 0。

如果发现写数据库的记录比实际请求少,检查是否配置了database_url,并且数据表是否已初始化。litellm 首次启动时如果数据库表不存在,会自动建表,但如果你的数据库用户没有建表权限,就会静默失败,容易让人困惑。

4.4 高并发下的连接与超时问题

生产环境高并发时,注意 HTTP 连接池的大小。litellm 基于 Python 的 httpx,它默认的最大连接数可能不够大。如果出现大量 timeout 或者线程阻塞,可以在启动命令里调整:

litellm --config config.yaml --port 4000 --num_workers 4

num_workers参数控制代理服务内部的处理进程数,类似预 fork 模型。我实践下来,单机 4 个 worker 足够应对普通业务,如果并发再高,建议横向扩展服务实例,前面加负载均衡器。

4.5 请求延迟变高,如何定位瓶颈

当响应延迟显著升高,先用 litellm 自带的健康检查接口确认整体状态,再分别测每个底层模型供应商的直达延迟。litellm 转发本身的额外开销在毫秒级,但如果开启复杂规则(如多级重试、动态预算检查),会增加一些延迟。还有一个容易忽略的点:master_key认证、日志写入、成本计算都是同步操作,如果日志数据库响应慢,会拖垮整个请求。建议生产环境接入高性能时序数据库或者使用批量异步写入。

我个人排查延迟的顺序是:先看底层模型调用是否变慢,再看网关所在主机 CPU/内存是否占满,最后看日志写入是否有瓶颈。顺序反了容易浪费时间。

5. 进阶能力:预算控制、负载均衡与权限隔离

5.1 按用户 / 团队设置预算

litellm 支持很细粒度的预算控制。通过/user/new接口创建用户,给用户分配预算限额,然后在请求头带上user信息,litellm 就会按用户维度统计用量,当达到限额时自动拒绝请求。这一套在多部门共享一个网关的场景下特别实用,能防止某个同学一次性把月度预算全刷完。

配置预算的方式也很灵活,可以放在 config 里:

general_settings: max_budget: 1000 budget_duration: 30d

这样配置,表示网关总体每 30 天最多消费 1000 美元,超出后所有请求都会被拒绝。如果再配合数据库使用,历史用量会持续累积计算,精确度更高。

5.2 负载均衡与故障转移

如果你配置了多个供应商提供同一个模型名,litellm 支持自动负载均衡和故障转移。例如同时配了 OpenAI 和 Azure 的 GPT-4 模型,逻辑模型名相同,litellm 会根据权重分配请求,当其中一个供应商不可用时自动切换。

这个功能在金融类客户场景特别有意义。他们对可用性要求很高,单一供应商一旦出状况,整个业务停摆不可接受。litellm 的故障转移可以做到单供应商故障时客户端无感知切换,前提是提前配好冗余供应商。

5.3 虚拟 API Key 实现部门隔离

litellm 允许你创建虚拟 API Key(virtual key),每个 Key 可以绑定不同的模型访问权限、预算、速率限制。例如产品和算法两个团队共用同一个网关,产品团队的 Key 只能访问 GPT-4o,算法团队的 Key 可以访问全部模型,两者互不干扰。创建虚拟 Key 的请求很简单:

curl -X POST http://localhost:4000/key/generate \ -H "Authorization: Bearer master-key" \ -H "Content-Type: application/json" \ -d '{"models": ["production-gpt4o"], "max_budget": 100}'

返回的key字段就是生成的虚拟 Key。把这个 Key 分发给对应团队,后续在 Header 中携带即可。审计时,每个请求都会记录虚拟 Key 的 ID,出了问题能精准追查到具体配置方。

6. 底层原理深入解析:litellm 是如何做协议转换的

6.1 供应商前缀路由机制

litellm 的核心机制是provider/模型名前缀匹配。当你请求anthropic/claude-3-5-sonnet时,litellm 根据前缀anthropic选择对应的适配器,把 OpenAI 格式的输入转换为 Anthropic 格式,再按 Anthropic 的 API 规范调用底层服务。响应返回后,适配器又把 Anthropic 的响应转换为 OpenAI 格式。

如果配置中指定了api_base,litellm 会优先向该地址发起请求,并把前缀作为协议选择依据。这意味着你可以把任意一个实现了 OpenAI 兼容接口的服务器接入 litellm,只要协议对上,litellm 不加限制。

6.2 请求格式转换细节

OpenAI 的 ChatCompletion 请求体里messages是一个对象数组,每个对象有role和content。Anthropic 的请求格式不同,它是system单独字段,messages里不允许有systemrole。litellm 在转换时会自动把system消息提取出来单独处理,再拼装成 Anthropic 格式。

还有一个容易忽略的细节是max_tokens参数的映射。OpenAI 的行为与 Anthropic 对max_tokens的要求不同,Anthropic 强制要求这个字段,OpenAI 是可选的。litellm 适配器会自动填充合理的默认值,避免因为字段缺失直接报错。

6.3 流式输出的转换

大语言模型应用几乎都离不开流式输出。litellm 对流式的处理也比较成熟:它把底层 SSE 流中的data片段统一转换为 OpenAI 的chunk格式,逐块转发给客户端。当你使用stream=True请求时,litellm 会建立上游流式连接,然后边收边发。

实测下来,流式场景的额外延迟非常低,基本只在 5~15 毫秒左右,用户几乎无感知。但要注意,如果底层供应商不支持流式,litellm 会回退为非流式,然后模拟分批输出吗?不是的,它会直接把完整响应一次性返回,对客户端来说就变成非流式。如果你对交互体验有严格要求,选型时要确认供应商支持 SSE。

7. 生产环境部署建议与经验总结

7.1 部署拓扑参考

生产环境我推荐将 litellm 作为一个独立服务部署,不要塞进应用进程里,理由很直接:独立服务才能独立扩缩容、独立观测、独立升级。应用通过内部域名访问 litellm 网关,网关再出外网访问各家模型供应商。网络拓扑上,注意把网关部署在能访问到各家模型 API 的网络里,不要因为安全组把外网出方向关了,导致底层请求全部失败。

数据库方面,建议用 PostgreSQL 或 MySQL,不要用 SQLite 在生产环境。SQLite 并发性能有限,日志写入量大时会成为瓶颈。我已经遇到过 SQLite 在持续写入下导致请求耗时飙升的问题,换成 PostgreSQL 后整个世界安静了。

7.2 日志与监控配置

litellm 支持自定义回调把日志推送到外部监控系统,比如 Prometheus、Sentry 等常见系统。litellm_settings.success_callback和failure_callback分别控制成功与失败日志的回调目标,直接指向日志服务或监控平台。

我更建议在网关前面再架一层 API 网关或负载均衡,用于统一收集访问日志。litellm 自己负责模型层日志,API 网关负责流量层日志,两层互补,出问题时更好排查。

7.3 升级与兼容性注意

litellm 迭代速度很快,版本升级时经常会有破坏性变更,比如配置字段改名、默认行为变化。升级前一定要先阅读官方 Changelog,并在测试环境用完整回归用例验证关键模型调用。我见过一次升级后model_list的litellm_params.model字段要求强制带 provider 前缀,旧配置全部失效,启动直接报错。升级锁版本很重要,不要随手pip install -U litellm,生产环境用固定版本号。

7.4 成本与收益的最终判断

接入 litellm 是否值得?我的判断标准很简单:项目里同时存在两条及以上不同厂商的模型调用,或者同一个模型要接给多个团队用,就值得。如果只是单供应商单应用,直接 SDK 更轻量。

接入成本主要在前期配置与适配,大约半天到一天时间可以跑通。收益是一旦配好,后续新增模型、切换供应商、调整权限几乎零代码,整个团队的接口规范也能统一。用上之后你再也不会想回到到处散落 SDK 调用的状态。

最后分享一个小技巧:升级模型或供应商切换时,先在 litellm 配置里加一个新模型名,比如gpt-4o-new,业务侧灰度切换一部分流量到新模型名,验证没问题后再把旧模型名下掉。这种双跑策略借助网关的模型名隔离特性,比直接改底层模型配置要安全得多,我给好几个团队都是这么建议的。

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

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

立即咨询