资讯动态

litellm:用统一API网关告别多模型接入混乱

发布时间:2026/10/13 11:52:55 来源:尧图企业网站定制
litellm 这个名字第一次听到的人容易一脸懵它既不是模型也不是框架而是一个专门解决“模型接入混乱”问题的开源工具。简单说litellm 是让你用一套统一协议调用上百家模型服务的中间层它把各家五花八门的 API 请求全部转成一种标准格式同时把模型切换、成本统计、密钥管理、限流重试这些脏活累活都包了。我最早是在做多模型聚合平台时接触到它的一开始只是当成一个“转换工具”用后来发现它真正解决的是整个团队协作和接入治理的问题。这篇文章我打算从设计思路、核心配置、实操落地到常见坑位把我踩过的路完整讲一遍适合正在做 AI 应用接入、或者想统一管理多模型调用的开发者和团队参考。1. 为什么需要 litellm统一网关的设计思路1.1 多模型时代的接口泥潭现在做 AI 应用几乎没人只用一家模型服务。场景稍微复杂一点项目里就会出现“主模型用大厂闭源、摘要模型用云端开源、私有数据走本地部署”这种组合。问题在于每一家模型的请求格式都不一样有的用 prompt 字段传字符串有的用 messages 数组传结构化内容有的返回 choices[0].message.content有的返回 output_text鉴权方式也各搞一套有的是 Bearer Token有的是签名头有的还要配置 region 和 project id。我在项目初期就吃过这个亏。团队里每个人各自封装了一层客户端A 写的模块调用主模型的 SDKB 写的服务直接 requests 打某家的 HTTP 接口。结果一共接了五家模型代码里就出现了五套请求逻辑、五套错误处理。后来加了一个新模型改了三天代码才把各处的调用兼容完而且还不敢动老接口因为一动就可能导致线上回归。这个问题的本质是业务代码不应该感知底层模型 API 的差异。好的做法是引入一层网关业务只关心“模型叫什么名字、参数怎么传”至于这个模型实际跑在哪家服务、用什么协议、key 从哪里来统统由网关层搞定。litellm 扮演的就是这个角色。1.2 统一网关解决了什么核心痛点相比自己在代码里封装 SDK直接引入现成网关有几个非常实际的好处。第一是接入成本几乎为零。litellm 的核心函数是completion()用法和主流模型服务的客户端极其相近熟悉其中任何一家的开发者都能立刻上手。从零开始接一个新模型只需要在配置里加一行映射不用改业务代码。第二是天然具备“模型路由”能力。可以把一个逻辑模型名映射到多个上游实例比如把main-model同时映射到大厂 A 的旗舰模型和大厂 B 的同级别模型litellm 会自动做负载均衡还可以设置 fallback 链主模型挂了自动切到备用模型业务侧无感知。第三是治理能力。密钥集中管理、按用户或按团队分配虚拟 key、设置预算上限、记录每次调用的 token 用量和费用这些能力靠自研往往要做很久而 litellm 都内置了。对于小团队来说与其造轮子不如先把这套用起来节省的时间拿去打磨业务价值更划算。1.3 两种形态SDK 嵌入与 Proxy 代理litellm 的使用方式分两种理解清楚才能选对。一种是 Python SDK 方式。你可以在自己的服务里直接from litellm import completion把它当普通库调用。适合单个 Python 服务内部需要多模型调用的场景引入简单不需要额外部署进程也不改变现有架构。另一种是 Proxy 方式。litellm 提供一个基于 HTTP 的代理服务你启动一个 litellm 服务进程团队所有服务都通过 HTTP 访问它。这个模式最大的优势是语言无关不管业务用的是 Python、Java、Go 还是 Node.js只要按照 OpenAI 兼容格式发请求就能接入。而且模型配置集中在一个 yaml 文件里改配置不用重新发布业务服务。我个人在生产环境强烈推荐 Proxy 模式。原因很朴素隔离和可控。业务方只需要拿到一个虚拟 key 和网关地址模型切换、限流策略、成本预算都在网关层调整不会因为某个业务线的代码写得不规范把真实的 API key 泄露出去。后面我讲的实操也主要基于 Proxy 模式。2. 核心细节解析与实操要点2.1 安装与最小可用配置litellm 的安装很直接用 pip 就能搞定。普通 SDK 模式一条命令就够了pip install litellm如果你要跑 Proxy 服务建议用完整模式把底层的服务器组件和依赖一并装好pip install litellm[proxy]装完之后命令行里就可以直接启动一个代理服务。例如litellm --model gpt-3.5-turbo --port 8100这条命令会启动一个本地 HTTP 服务暴露一个/chat/completions接口。你可以用任何 OpenAI 兼容的客户端访问它只需要把 base_url 指到http://localhost:8100。不过实际项目中很少用命令行参数来指定模型因为模型一多就管理不过来。更正规的做法是通过 config.yaml 管理模型列表。一个最小的配置长这样model_list: - model_name: main-model litellm_params: model: gpt-3.5-turbo api_key: os.environ/OPENAI_API_KEY这里model_name是暴露给调用方的逻辑名字litellm_params.model是真实的模型标识api_key可以从环境变量读取避免把密钥硬编码进配置文件。只要理解了这个结构后面所有复杂配置都是它的扩展。2.2 新手必看模型映射的两个关键参数我见过很多人在模型映射上翻车主要是不理解model_name和litellm_params.model的区别以及 provider 前缀的作用。model_name是你自己定制的名字业务代码只认这个名字。比如你可以把某个开源模型命名为light-model把大厂旗舰命名为pro-model业务方根本不需要知道背后到底是什么模型。litellm_params.model才是真正告诉 litellm 去调哪家服务的字符串格式通常是provider/模型名。例如openai/gpt-3.5-turbo表示走某大厂的 chat 接口anthropic/claude-3-5-sonnet表示走另一家的 claude 系列接口ollama/llama3.1表示连接本地 Ollama 托管的模型huggingface/meta-llama/Llama-3-8B-Instruct表示走托管平台接口有一个容易忽略的点如果不带 provider 前缀默认会当成某家头部厂商的模型来处理。很多人写了一个简单的模型名结果发现请求发错了地方原因就在这里。每次新增模型都应该确认前缀和模型名的组合是否准确。另外一个实用参数是api_base。如果你的服务使用的是自建推理平台或者公司内部有统一的模型服务出口可以在litellm_params里手动指定api_baselitellm 会用这个地址而不是默认地址。这在私有化部署场景里非常重要。2.3 生态支持范围与选型建议litellm 的兼容列表很长我实际用下来覆盖了主流的闭源大厂服务、主流云端开源托管服务、本地推理框架。具体到日常选型我通常按下面几类来使用闭源大模型适合作为主力模型通用理解能力强走默认接口即可。云端开源模型适合批量任务和低成本场景模型标识按托管平台格式填写。本地部署模型通过 Ollama、vLLM 这类框架把模型跑在自己机器上litellm 通过本地接口接入适合数据敏感场景。选择哪一类取决于业务对成本、延迟和隐私的要求。litellm 的价值在于它把这些差异全部抹平了你随时可以把某个逻辑模型从云端切换到本地业务代码一行都不用动只要改配置和 key 就行。2.4 密钥管理与虚拟 key这一点我想单独强调因为太重要了。如果不设置 master key你的 litellm 代理就会完全裸奔任何能访问到这个端口的人都可以用你的模型额度而且看不到是谁在用。生产环境必须设置general_settings.master_key然后通过这个主密钥去生成虚拟 key 分发给业务方。general_settings: master_key: sk-your-master-key生成虚拟 key 用 HTTP 接口curl -X POST http://localhost:8100/key/generate \ -H Authorization: Bearer sk-your-master-key \ -H Content-Type: application/json \ -d {models: [main-model], max_budget: 20}返回结果里有一个token字段这个就是业务方用来调用网关的 key。虚拟 key 可以限制可访问的模型范围、设置预算上限。万一某个 key 泄露直接在网关侧吊销即可不会影响到真实密钥。我的建议是给每个业务线或每个环境单独配一把虚拟 key并打上标签。这样月底看成本时按 key 一查就能知道钱花在了哪个项目上不需要靠猜。3. 实操过程与核心环节实现3.1 搭一个团队共享网关从零开始的完整步骤下面以一个真实的接入场景为例团队里同时使用闭源大模型、云端开源模型和本地部署的模型需要给业务统一出口。整个搭建过程大约三十分钟。第一步创建配置文件。假设文件叫litellm-config.yamlmodel_list: - model_name: pro-model litellm_params: model: gpt-4o api_key: os.environ/PROVIDER_A_KEY - model_name: fast-model litellm_params: model: gpt-3.5-turbo api_key: os.environ/PROVIDER_A_KEY - model_name: cheap-model litellm_params: model: anthropic/claude-3-5-haiku api_key: os.environ/PROVIDER_B_KEY - model_name: local-model litellm_params: model: ollama/llama3.1 api_base: http://localhost:11434 litellm_settings: drop_params: true set_verbose: true general_settings: master_key: sk-master-key-2024注意drop_params: true这个参数的作用是如果请求里带了某个上游不支持的参数litellm 会自动把多余参数丢掉而不是直接报错。实测中这个配置非常省心因为业务方经常会按某家模型的参数习惯传入字段换到另一家兼容性就出问题有了这个开关可以明显减少报错。第二步启动服务litellm --config litellm-config.yaml --port 8100看到日志输出Uvicorn running on http://0.0.0.0:8100后服务就起来了。第三步验证连通性。用 curl 简单测一下curl http://localhost:8100/chat/completions \ -H Authorization: Bearer sk-master-key-2024 \ -H Content-Type: application/json \ -d { model: pro-model, messages: [{role: user, content: 用一句话介绍你自己}] }如果配置正确会返回类似 OpenAI 格式的 JSON。到这一步网关已经能用了。3.2 不同客户端接入网关的方法网关立起来后接入方式就非常统一了。因为我故意把接口设计成 OpenAI 兼容格式所以几乎所有主流客户端都能直接指过来。Python 的 OpenAI 兼容客户端接入from openai import OpenAI client OpenAI( base_urlhttp://localhost:8100, api_keysk-virtual-key-xxx, ) resp client.chat.completions.create( modelpro-model, messages[{role: user, content: 你好}], ) print(resp.choices[0].message.content)Node.js 也类似import OpenAI from openai; const client new OpenAI({ baseURL: http://localhost:8100, apiKey: sk-virtual-key-xxx, }); const resp await client.chat.completions.create({ model: pro-model, messages: [{ role: user, content: 你好 }], }); console.log(resp.choices[0].message.content);这里关键点在于客户端只知道网关地址和一个虚拟 key完全不需要知道上游真实服务是什么、实际密钥是什么。这也意味着替换模型对调用方是透明的他们感知不到任何变化。如果你想在 Python 项目里不做 HTTP 调用直接用库函数方式可以这样import litellm resp litellm.completion( modellocal-model, messages[{role: user, content: 你好}], api_basehttp://localhost:11434, )但这种用法更适合单机脚本或测试环境。团队协作场景下还是走代理更规范因为所有调用都有日志和审计。3.3 路由策略负载均衡与故障转移业务规模上去之后单一上游实例未必扛得住。litellm 允许你把一个逻辑模型映射到多个上游实例由网关自动调度。配置稍微复杂一点但收益很明显model_list: - model_name: pro-model litellm_params: model: gpt-4o api_key: os.environ/PROVIDER_A_KEY model_info: supports_function_calling: true - model_name: pro-model litellm_params: model: gpt-4o api_key: os.environ/PROVIDER_A_BACKUP_KEY同一个model_name出现两次网关就会把它当成同一个逻辑模型的多个上游副本默认采用轮询策略分配流量。更精细的负载均衡可以在配置里启用预调用检查router_settings: routing_strategy: simple-shuffle enable_pre_call_checks: truesimple-shuffle策略会在每次请求前检查健康状态优先路由到延迟低、可用性高的实例。这里插一句所谓“健康”不只是服务能连通还包括限流余额、超时表现等综合因素。如果某个上游频繁报错litellm 会自动把它标记为冷却状态过一段时间再试探恢复。故障转移方面除了在模型列表里配多个实例还可以显式指定 fallbacks。某些版本的调用接口支持如下写法当主模型失败时自动切换到备用模型response router.completion( modelpro-model, messagesmessages, fallbacks[{model: cheap-model}, {model: local-model}], )这种链路设计能显著提升可用性。我曾经遇到过上游服务大规模限流的情况fallback 让业务几乎无感日志里能看到路由切换记录但用户那边没有报错投诉。3.4 成本追踪与预算控制成本控制是很多团队选择 litellm 的核心理由。它内置了一份主流模型的价格表每次调用之后会自动估算 token 费用并记录到持久化存储里。在 Proxy 模式下查看每个虚拟 key 的花费非常方便curl http://localhost:8100/spend/logs \ -H Authorization: Bearer sk-master-key-2024响应里会包含每次调用的模型、token 数、估算费用和时间戳。如果不想记 API也可以在启动参数里litellm --config config.yaml --port 8100 --log_success开启成功日志之后控制台会实时打印每次调用的明细我一般先用这个观察流量确认稳定后再切到数据库存储。限流和预算同样可以配置在虚拟 key 上。比如某个外部客户接入你的网关时你希望控制他的消费上限可以在生成 key 时加上curl -X POST http://localhost:8100/key/generate \ -H Authorization: Bearer sk-master-key-2024 \ -H Content-Type: application/json \ -d {models: [pro-model], max_budget: 50, max_parallel_requests: 10}这样这个 key 最多消费 50 块钱并发最多 10 个请求超了直接拒绝。对对外提供 AI 能力的小团队来说这个功能几乎是刚需。4. 常见问题与排查技巧实录4.1 环境变量里的 key 没生效很多人明明在.env里写了PROVIDER_A_KEYsk-xxx但启动后 litellm 报 401。最常见的原因是你启动了 litellm 之后才修改.env或者终端会话没有加载最新的环境变量。排查方法很直接先确认环境变量在当前 shell 里能看到echo $PROVIDER_A_KEY如果为空用source .env或者重新登录终端。如果环境变量没问题再看配置里的引用方式是否正确os.environ/变量名这个前缀不要写错。还有一个小坑是 Python 的.env加载并不是自动的。你需要在启动命令前用工具加载它或者在启动脚本里读取。比如set -a source .env set a litellm --config config.yaml --port 8100我的习惯是关键密钥统一放到环境变量层配置文件里只写环境变量引用避免配置文件和密钥一起被提交到仓库。4.2 模型名映射错误导致请求失败有段时间我把一个自建服务的模型名写成了gpt-3.5-turbo没有带前缀。litellm 默认把它识别成某头部大厂的模型于是请求直接发到了官方接口返回 401 或者模型不存在的错误。排查这类问题先看报错。如果是认证失败大概率是 provider 路由错了。如果返回的是“model not found”说明模型标识本身和上游实际名字对不上。我的建议是新增模型时先直接用 litellm 命令行测试不要马上进配置。比如litellm --model ollama/llama3.1 --api_base http://localhost:11434 --test通了再写进 config.yaml。这个--test参数直接发一条测试请求能快速验证模型标识、key 和 api_base 是否正确比反复重启服务调试高效得多。4.3 重试导致重复请求和费用翻倍litellm 默认在遇到超时或 5xx 时会自动重试这是好事也是坏事。好事是系统更稳坏事是如果你上游在“请求已处理但响应丢失”的情况下返回超时重试可能造成重复调用和重复计费。这个问题不好彻底消除因为上游 API 本身不保证幂等。我能给出的实际建议是合理设置超时和重试次数不要默认值拉满。对真实输出结果做缓存相同请求参数在短时间内直接命中缓存减少重复调用。对成本特别敏感的调用在业务侧做好去重和幂等标记。litellm 的重试策略是可配置的。在代理启动时设置合理的重试次数避免因为临时的网络抖动把费用翻倍。比如litellm --config config.yaml --port 8100 --num_retries 2 --request_timeout 30这个值可以根据服务的延迟情况调整。如果上游平均响应时间较长超时设置太短会导致大量重试反而拖垮链路。4.4 高并发场景的连接数瓶颈网关虽然用起来简单但它也是一个真实网络服务。并发上来了连接池和文件描述符会成为瓶颈。我线上运行的时候遇到过一个情况单机网关被多个业务共享压测跑到三百并发响应开始变慢日志里出现连接上下游超时。解决思路有几个方向对虚拟 key 设置并发限制防止单个调用方占满所有连接。在网关前面再加一层负载均衡多个 litellm 实例共享同一份配置和存储。注意如果用了本地 sqlite 存日志多实例部署时建议换成共享数据库避免写入冲突。调整操作系统文件描述符上限和对上游 HTTP 连接池的大小。我在实际部署里最省心的方案是把 litellm 网关部署为两个实例前面用负载均衡转发虚拟 key 和用量记录存在共享数据库里。这样即使一个实例挂了另一个也能继续服务业务方基本无感知。4.5 安全问题排查速查表最后整理一份我反复用过的问题速查表供大家参考现象可能原因快速处理调用返回 401虚拟 key 错误或 master key 未设置检查请求头里的 Authorization请求返回 404模型名不在 model_list 中确认 model_name 与配置一致请求很慢上游服务本身延迟高查看/health接口延迟统计费用异常飙升重试次数过多或未设置预算调低重试次数给 key 加 max_budget部分模型报错provider 前缀或 api_base 不对用命令行--test单独验证虚拟 key 泄露无吊销机制或 key 权限过宽立即吊销并重新生成最小权限 key如果你刚把 litellm 接入生产我建议先小流量跑一周重点观察成本统计是否准确、模型切换时业务是否报错、失败自动转移是否生效。确认这些都没问题再把流量逐渐放大。我个人在实际运行中的体会是litellm 这个项目最大的价值不是省掉了几个 HTTP 请求的适配而是把“模型接入”这件事从业务代码里彻底剥离出去了。以前加一个模型要协调各个业务线改代码、发版本现在只要网关管理员更新一下配置业务方第二天再调用就会自动落到新模型上。这种对团队效率的改善远比省下的开发时间更有意义。最后分享一个小技巧如果你要在多个项目里复用同一套 litellm 配置可以把 config.yaml 纳入版本管理并配合 CI 配置检查。每次改动配置后跑一遍模型连通性测试再发布能避免很多线上的低级错误。照这个方式用了一段时间之后我们的模型接入流程基本实现了“配置即服务”这个思路对小团队尤其适用。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑