资讯动态

从零落地大模型API网关:litellm配置、负载均衡与踩坑实战

发布时间:2026/10/21 10:05:15 来源:尧图企业网站定制
前阵子接手了一个内部 AI 中台项目第一件事就是把散落在各业务线的大模型调用全部迁到 litellm 网关下面。做出这个决定并不轻松毕竟之前大家各调各的有人直接用某模型供应商的官方 SDK有人自己拼 JSON 调接口密钥放在各自的配置中心预算也是各付各的。等到真要排查线上问题的时候光是确认这个请求到底打到哪家、用了谁的 key就要折腾半天。litellm 作为一个统一的大模型 API 网关确实把这一摊子事情理顺了。这篇文章不是泛泛介绍 litellm 是什么而是我从零开始把它落地到生产环境后的完整复盘。包括部署方式怎么选、配置文件的坑、负载均衡和限流的细节、客户端如何零成本接入以及几个我实际踩过的性能问题。如果你正在被多供应商、多 key、多团队的模型调用管理搞得焦头烂额这篇应该能帮你省下不少时间。1. 统一大模型网关到底解决什么问题从一次事故说起1.1 一个典型的混乱现场我接手的中台项目最头疼的其实不是模型效果而是调用方式太乱。业务 A 的代码里直接用着某家的 Python SDK业务 B 用的是另一家的 SDK业务 C 干脆自己用 requests 手写请求逻辑。三个团队的 API key 各自放在各自的配置中心预算也是各付各的。一次灰度上线业务 B 的模型频繁报限流业务 A 想帮忙分流却发现根本没法统计 B 的实时调用量。更麻烦的是不同供应商的返回结构不一样有的带 usage 字段有的要自己解析 content有的错误码是 429有的却是 500 加一个限流提示。业务代码里塞满了各种兼容逻辑谁都不敢动。坦白说这种混乱并不是某一个人的责任而是直连所有供应商这种模式天然会暴露的问题。只要团队一多、模型一多SDK 版本、请求格式、错误处理、成本统计这些细节就会被无限放大。1.2 集中式网关解决的五类问题痛点直连多供应商时的表现接入 litellm 网关后接口协议不统一每家 SDK 风格不同返回结构不同统一为 OpenAI 风格的 chat completions 格式密钥分散难以治理key 散落在代码、配置中心、同事电脑里密钥集中在网关配置下游使用虚拟 key限流与预算不可控只能依赖各家供应商控制台网关侧配置 rpm/tpm 与预算超限即停故障定位成本高需要去多个控制台翻日志网关日志统一记录模型、key、token、费用模型切换风险大切换供应商要改业务代码只改网关配置下游无感知其中我感受最深的是最后一条。统一网关本质上是把模型供应商和业务调用方解耦了。业务方只需要知道我有一个叫 chat 的模型可用至于这个 chat 背后是 gpt-4o 还是别的模型业务方完全不需要关心。这在直连模式下是不可能的因为 SDK 和请求格式已经写死在代码里了。1.3 litellm 的准确角色定位很多人第一次接触 litellm 会误以为它是一个模型聚合平台或者模型市场。实际上不是它做的事情更纯粹一个 API 代理 / 网关。你在配置文件里声明每个模型由哪个供应商提供、用哪个密钥、限流多少网关启动后下游拿到的就是一个标准的/chat/completions接口。它和自己在业务代码里写一个统一封装层是有本质区别的。封装库需要每个服务都引进来版本升级要靠所有团队同步更新出了问题还得逐个服务排查。而网关把所有适配集中在一处升级只在网关侧操作。对我来说这个边界感非常重要litellm 只管转发和翻译业务逻辑还是留在各自的服务里。2. 两种部署方式怎么选先跑起来再谈优化2.1 本地 pip 验证 vs Docker 固定版本litellm 的部署方式非常灵活最常见的两种是pip install和 Docker 镜像。对于刚接触的人我建议先在本地用 pip 跑通最小配置再考虑上生产。pip install litellm[proxy]这个命令安装的是带有代理功能的全量版本。本地跑起来后改配置重启都很快适合验证思路。生产环境我推荐用官方 Docker 镜像固定版本号放到自己的镜像仓库里然后做滚动发布。好处是版本可控不会出现今天这台机器是 v1.2、明天那台是 v1.5 的尴尬局面。用 Docker 时关键目录和端口要单独挂出来docker run -d \ --name litellm-proxy \ -p 4000:4000 \ -e DATABASE_URLpostgresql://user:passhost:5432/litellm \ -e MASTER_KEYsk-master-xxx \ -v $(pwd)/config.yaml:/app/config.yaml \ ghcr.io/berriai/litellm:main-latestDATABASE_URL是用来持久化存储虚拟 key、模型调用记录和成本数据的生产环境一定要配。MASTER_KEY是管理接口的访问凭证相当于整个网关的超级管理员密码千万不能省略否则任何拿到网关地址的人都能调用管理 API。2.2 最小可用的 config.yaml不管用哪种方式启动核心都是配置文件。下面这个配置是任何项目都能起步的最小例子model_list: - model_name: chat litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY general_settings: master_key: sk-master-xxxmodel_name是对外暴露的名字下游请求时用的就是这个litellm_params里才是真正发给上游的模型标识和密钥。这种外部名 内部参数的双层设计是整个配置文件的灵魂后面我会专门展开讲。然后启动litellm --config config.yaml --port 4000看到服务监听在 4000 端口网关就算跑起来了。2.3 用一次 curl 验证链路是否打通配置好后我习惯先发一个最简单的请求确认链路通没通curl http://localhost:4000/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-master-xxx \ -d { model: chat, messages: [{role: user, content: hello}] }返回结构应该是标准的 OpenAI 风格包括id、object、choices、usage等字段同时还会附加类似model、cost的额外信息。第一次看到这个返回的时候我特意确认了一下请求确实是打到了上游模型上而不是网关伪造的响应——因为返回值太像真实的 OpenAI 响应了几乎无缝。这里有一个小建议先测一个不带流式的请求确认链路稳定之后再测试stream: true的情况。流式输出走的是 SSE很多问题往往只会在流式场景下暴露后面我会专门说。2.4 生产环境必须补充的启动参数本地验证通过之后真正上生产之前有几个启动参数需要重点关注--num_workers默认单进程可能扛不住并发一般按 CPU 核数设置比如 4 核机器就开 4 个 worker。--database_url不配数据库的话虚拟 key 和调用记录都只存在内存里重启就丢生产必须配。--detailed_logging开启详细日志能看到每次请求的响应耗时、token 消耗、费用估算。--port默认 4000如果团队有端口规范就按规范来。生产环境部署多台实例时litellm 本身是无状态的状态都存在数据库里所以直接在前面挂一层负载均衡就行横向扩容非常方便。我自己的做法是先在一台机器上把配置跑稳再复制到另外两台组成一个小集群。3. config.yaml 的核心结构逐项解读3.1 双层命名外部名与真实模型标识litellm 的配置核心是model_list里面的每一项都有model_name和litellm_params两层信息。第一遍看配置的时候会觉得有点绕但理解了之后你会觉得这个设计非常合理。model_name是暴露给下游的名字下游代码里永远只认这个名字litellm_params里的model字段才是真正发给上游的模型标识。比如我希望内部统一提供一个名为chat的模型接口实际后端可以是openai/gpt-4o也可以是某个开源模型的托管服务model_list: - model_name: chat litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY这个双层命名最大的好处是切换供应商时下游代码一行都不用改。今天chat后面挂的是 gpt-4o明天想换成另一家的模型只需要把配置里的litellm_params.model换掉重启网关即可。对于业务团队来说他们感知不到任何变化。3.2 同一外部名挂多个后端路由、轮询与自动降级litellm 还支持把一个model_name对应多个后端这是实现负载均衡和故障转移的基础model_list: - model_name: chat litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY_1 - model_name: chat litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY_2同一个model_name配置了多个litellm_params请求会自动在多个 key 之间轮询。如果某个 key 触发了上游限流litellm 会尝试下一个 key。这在供应商有每分钟请求数限制时特别有用相当于用多个账号把限流额度拼出来。不过有一个使用上的注意点不要把一个高成本模型和一个低成本模型挂在同一个外部名下。虽然技术上完全支持但下游业务方无法预期每次调用的延迟和计费出了问题很难解释。我一般只把同一型号、同一档位、价格差异很小的模型做聚合。3.3 密钥管理机制环境变量注入、多 key 轮询与权限隔离密钥管理是很多团队接入 litellm 时的第一道坎其实处理起来非常套路化。首先是密钥不能写死在配置文件里litellm 支持从环境变量引用litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY这样 config.yaml 可以纳入代码仓库版本管理真正的密钥只在部署环境的环境变量里。谁都能拉配置但拿不到真实密钥。其次是多 key 轮询上游供应商一般会限制单个 key 的每分钟请求数如果你有多个 key直接多配几条litellm 会自动做轮询分摊。我实测下来两个 key 的限流上限基本是单 key 的两倍左右效果非常直接。最后是权限隔离。litellm 支持用 master key 管理整个网关也支持为每个下游团队生成独立的虚拟 key。虚拟 key 的调用范围、模型白名单、预算上限都可以单独配置这样就算某一个团队的 key 泄露了影响也是可控的不会牵连整个网关。4. 生产级流量治理负载均衡、限流、重试与预算控制4.1 多 key 负载均衡是怎么工作的上一节提到的多 key 配置本质就是负载均衡。litellm 默认会按轮询方式调度多个相同model_name的条目。遇到 429 或上游 5xx 错误时它会自动把故障的 key 临时摘除把请求切换到其他健康的 key 上。这里我踩过一个小坑最开始我把两个 key 配置到了同一个上游以为 litellm 会自动做健康探测实际上它默认没有太复杂的健康检查机制。某个 key 如果被上游封禁它只有在真实请求失败时才会感知并切换。所以我的建议是除了依赖 litellm 的自愈能力最好定期关注上游控制台里各 key 的状态提前发现异常的 key。4.2 限流参数配置从上游限制到网关侧限制接入 litellm 之后限流可以分成两层理解。第一层是上游供应商的限制第二层是网关本身对下游调用方的限制。第二层其实是很多团队迫切需要的因为不可能让每个业务方都直接跟供应商控制台打交道。在 config.yaml 里可以这样配model_list: - model_name: chat litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY rpm: 100 tpm: 50000rpm是每分钟允许的请求数tpm是每分钟允许的 token 数。超过限制的请求会直接被网关拒绝并返回限流错误不会继续打到上游这对成本保护非常重要。我通常会把 rmp 设置为上游实际限制的 80% 左右留出缓冲避免触发供应商的惩罚性限流。4.3 失败重试与供应商降级的策略设置litellm 默认对部分错误码有重试机制比如 429、503 这些临时性错误。重试的间隔和次数可以通过环境变量调整。这里要特别提醒一点重试机制对成本敏感场景要谨慎。如果业务方主要做的是实时问答重试次数太多会显著增加响应等待时间如果上游故障持续时间较长重试反而会堆积更多请求。我自己的做法是普通请求保留默认重试最多重试 1-2 次流式长任务不重试因为用户已经看到一半输出从头再来体验很差。同时结合降级策略——在 config 里配置多个后端时litellm 可以对同一个model_name指定优先顺序首选模型不可用时自动切换到备用模型。不过降级的前提是备用模型的响应质量可接受这个需要业务方提前确认。4.4 虚拟 key 与成本归属账单不再是一笔糊涂账多团队共用网关之后成本归属是最容易引发矛盾的。litellm 的虚拟 key 机制很适合解决这类问题。通过管理 API 可以生成一个虚拟 keycurl -X POST http://localhost:4000/key/generate \ -H Authorization: Bearer sk-master-xxx \ -H Content-Type: application/json \ -d { models: [chat], max_budget: 100, budget_duration: 30d }返回的key字段就是给下游团队用的虚拟 key。它能指定可以调用哪些模型、预算是多少、有效期多长。每次请求的 token 数和估算费用都会记录到数据库里。下游团队用了多少、还剩多少预算一目了然。需要说明的是litellm 的费用是基于模型单价和 token 数估算的不同供应商的计费规则有差异所以这个费用适合做内部核算不适合直接当对外账单的最终依据。但对内部成本分摊来说已经足够精确了。5. 客户端接入只改一个 base_url 的适配技巧5.1 Python 客户端一行改动完成切换litellm 最让我满意的就是客户端接入成本极低。如果你已经在用 OpenAI 官方 Python SDK只需要改base_url和api_key其他代码不用动from openai import OpenAI client OpenAI( base_urlhttp://localhost:4000/v1, api_keysk-master-xxx ) response client.chat.completions.create( modelchat, messages[{role: user, content: Hello}] ) print(response.choices[0].message.content)注意model参数填的已经不再是上游的真实模型名而是 config.yaml 里的外部名chat。这个改动的意义是业务代码与具体的模型供应商彻底解耦了。之后哪怕后端模型换掉业务服务只需要重新部署一次环境变量或配置中心的值代码完全不用动。5.2 Node.js 和其他语言的接入方式Node.js 生态用 OpenAI 官方包也是一样的逻辑import OpenAI from openai; const client new OpenAI({ baseURL: http://localhost:4000/v1, apiKey: sk-master-xxx, }); const completion await client.chat.completions.create({ model: chat, messages: [{ role: user, content: Hello }], }); console.log(completion.choices[0].message.content);其他语言只要实现了 OpenAI 兼容接口的 SDK都可以用同样的方式接入。这其实是 litellm 的一个隐藏优势它让OpenAI 接口规范成为你公司内部的模型调用标准不管上游是什么下游永远只面对一种接口风格。5.3 非 OpenAI 供应商的响应统一网关在背后做了什么很多人在第一次使用时会好奇上游根本不是 OpenAI 系的模型为什么返回结构这么标准原因在于 litellm 在网关内部做了两层翻译下游发过来的 OpenAI 风格请求会被转换成上游供应商的请求格式上游返回的结果又会被转换回 OpenAI 风格的响应。业务侧完全看不到中间的差异。不过有一点还是要提醒虽然 litellm 做了大量兼容工作但个别供应商特有的参数比如某些多模态输入格式、工具调用的细节不一定在所有版本中都支持透传。切换模型时必须测试完整用例不能只看一个简单的文本问答就认为没问题了。我一般会在测试环境跑一遍包含多轮对话、流式输出、工具调用等场景的回归脚本。6. 实际生产环境里踩过的坑与调优建议6.1 连接池与并发上限默认配置扛不住峰值流量我第一次对 litellm 做压测时并发一上去就发现大量请求排队单请求延迟飙升。当时第一反应是模型本身的性能问题查了半天才发现是网关进程的连接池和 worker 数不够。litellm 默认配置适合低流量验证不适合直接承受生产峰值。解决办法分两层一是启动时配置足够的--num_workers二是调大上游连接池相关的环境变量。我的经验是先按预估峰值 qps 的 2 倍预留并发能力再根据压测结果逐步收敛。压测时不要只看平均延迟要看 p99 和队列积压情况这两个指标才能反映网关的真实瓶颈。6.2 流式输出与超时设置不同场景要分开处理流式输出踩坑是我记忆最深的。短问答场景用默认超时没问题但换成流式长文本生成后客户端经常报读超时。原因是很多 HTTP 客户端的默认读取超时对 SSE 流式响应并不适用需要把客户端的 read timeout 调大。反过来普通短请求如果超时设置得太长会导致故障响应变慢用户等半天才发现失败。我的建议是给网关和客户端两侧都设置分级超时普通请求 30 秒以内流式请求按模型最大输出时长设置比如 5 分钟。同时把超时错误和上游限流错误分开监控两者反映的问题完全不一样。6.3 日志与监控看哪些指标判断网关健康度litellm 的日志信息量非常大每次请求会记录模型名、使用的 key、token 数、响应延迟、估算费用。这些日志对排查问题很有帮助。生产环境我建议把 metrics 接入 Prometheus 体系重点看四个指标p99 延迟反映整个链路的真实体验。429 错误比例判断是否接近上游限流阈值。token 吞吐量观察模型使用量的长期趋势。虚拟 key 的预算消耗提前发现预算超限风险。日志和监控本质上是在回答同一个问题这个网关到底是在正常干活还是在替上游扛锅有数据支撑后跟供应商沟通限流问题、跟业务方对齐成本问题都会更有底气。6.4 什么时候其实不需要 litellm最后说一个反直觉的观点不是所有项目都适合上 litellm。如果你只有一个小应用、只用一个模型、只有一个 API key也没有其他团队接入那直接调 SDK 就足够了完全没必要多加一层网关。引入网关意味着多一个需要维护的组件、多一层故障可能性这是客观成本。litellm 真正的价值在于复杂度到了一定程度之后的集中治理。至少 3 个以上模型、多个团队共用 key、预算成本归属混乱、或者正在准备切换供应商这些诉求中出现两三个的时候它才值得引入。如果只是尝鲜建议先在自己的笔记本上跑通最小配置感受一下统一网关带来的变化再决定生产环境是否要上。最后分享一个我自己的操作习惯config.yaml 一定纳入版本管理但所有密钥一律用os.environ/XXX引用Docker 镜像固定具体版本不追 latest每次升级 litellm 之前先看一遍变更记录因为个别版本调整过数据库字段和路由策略。这个项目目前迭代力度很大版本之间如果跨得太多迁移成本可能会超出预期。掌握好这个小节奏litellm 会是你长期管理多模型调用的得力帮手。

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

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

免费获取报价 →
↑