大模型多供应商接入不再难:用litellm构建统一API网关

发布时间:2026/10/13 18:49:11
大模型多供应商接入不再难:用litellm构建统一API网关 多家大模型服务商的接口风格不统一每次新增一家供应商就要改一批业务代码这种日子我过了大半年。后来被逼着做统一接入层才真正把litellm这个项目用起来。它不是某个大厂的商业方案而是一个开源的轻量级工具库既能当 SDK 嵌入业务系统也能当作独立代理服务统一分发模型请求。对靠 API 做产品的团队来说这个项目最值钱的地方在于把几十家模型服务商的差异全部收敛到一个标准接口后面业务侧只需要维护一个客户端配置模型商怎么换、参数怎么变都由它去消化。如果你也在做 LLM 相关应用被多供应商接入、费用统计、负载均衡这些问题烦过这篇文章值得花十分钟看完。里面没有任何广告全部是我自己实际试过的接入流程、配置参数和排坑记录也包含一些网上文档没写清楚的取舍逻辑。1. 为什么同一套业务代码要对接八家模型服务商1.1 多供应商调用需求是怎么来的早期我参与的项目只接了一家模型服务商SDK 固定、接口固定上线跑得很顺。到了下半年产品要支持更多场景同一个功能在有些场景下需要更快的响应在另一些场景下追求更低成本于是名单从一家扩展到多家。问题随之而来每家供应商的请求格式不一样鉴权方式不一样错误码定义也不一样连模型名称都各叫各的。当时业务服务里开始出现大量if (provider equals xxx)的分支每个分支里塞一套独立的 HTTP 调用逻辑。模型供应商增加一个分支就多一套代码量指数上升。更要命的是上游供应商修改了响应字段我需要逐个接口排查测试成本非常高。产品迭代节奏因此被拖慢连带着线上问题的定位也变困难。这种情况下最合理的做法不是继续往下堆分支而是在业务层和模型服务商之间增加一个统一的接入层。业务层只需要面对一种接口协议剩下的鉴权、格式化、转发、重试全部交给接入层处理。litellm能替代自己写的这套接入层并且比我预想的考虑得全面很多。1.2 统一接入层要解决的四类问题归纳下来业务侧真正需要统一层解决的是四类问题接口协议统一不管后端请求的是哪种风格的服务商接口统一层对外只暴露一种调用方式参数命名、返回结构保持一致。鉴权信息收敛不同服务商的 API 密钥不再散落在各个业务服务里而是集中配置在接入层权限回收、密钥轮换都在一处完成。成本与用量可观测每个请求用了哪个模型、消耗了多少 Token、花了多少钱都要有统一口径的记录否则月底对账完全靠猜。故障转移与负载均衡某一家服务商超时或限流时接入层能把请求自动切换到备用的服务商而不是让业务端自己处理异常。这四个问题litellm都有对应的能力。它最擅长的就是把不同模型服务商的请求格式转换成统一的内部表示再转成目标服务商的格式发出。业务端拿到的是一个标准响应对象不管背后实际请求的是哪家解析逻辑都一样。1.3 为什么不是自己写一个 Request 中转模块很多人第一反应是自己写一个中转模块把几家服务商的请求转发逻辑包一层。我也这么写过写完之后才感受到维护成本比想象中高太多每家服务商的 SDK 版本在更新、接口字段在变动、新模型不断出现同一模型在不同供应商那里的名字还不一样自己维护一个适配层相当于给自己请了一份全职工作。开源项目的优势是社区已经把大量适配工作做完了支持的供应商列表越来越长模型映射表也在持续更新。你只需要升级依赖就能获得新的适配能力。自己写的模块做不到这种同步速度尤其在模型服务商快速迭代的现阶段跟进成本极高。2. litellm 到底帮你管了哪些事2.1 它既不是 SDK 也不是纯网关我最开始对litellm的认知有些偏差以为它只是一个类似统一 SDK 的 Python 库后来发现它还自带一个高性能代理服务可以独立运行。换句话说它同时提供两种使用方式嵌入式模式和代理模式。嵌入式模式适合业务服务直接调用Python 代码里引入包后使用统一接口发请求适合单体应用或 Python 技术栈的团队。代理模式则是把它启动为一个独立服务业务端通过 HTTP 接口访问适合多语言团队、多个服务共用一个接入层的场景。这两种模式不是互斥的甚至可以配合使用。比如让代理承担统一的鉴权和费用记录业务服务则通过标准 OpenAI SDK 风格接口去调用代理。能让现有代码几乎零改动迁移这种兼容性设计是它比较讨喜的地方。2.2 请求转换和模型映射的价值真正花功夫的部分是请求转换层。不同服务商的系统提示词格式、模型名称、温度参数上限、Token 计算方式各不相同litellm内部维护了一套模型映射表可以把统一的请求参数翻译成每个服务商能理解的格式。以模型名称为例同一类能力在不同供应商那里可能叫 A、B、C 三个名字你在业务代码里只需要写一个内部的通用名由litellm映射到实际供应商的模型。如果有一天你决定把所有请求切换到一个新的供应商业务代码不需要改动只需要修改接入层的映射配置。2.3 返回結果结构化处理不同服务商的返回结构差异很大有的直接返回文本有的返回带思考链的结构有的把拒绝原因放在一个独立字段里。litellm会把它们统一成大家都熟悉的风格比如补全内容字段、Token 使用量字段、结束原因字段。我实际感受是这种结构化处理在日志分析和成本核算时特别省事。之前自己做转发层每个供应商的 Token 统计字段都不一样统计费用还得写一堆兼容代码。用统一结构之后一行代码就能把每次请求的 Token 消耗和费用归档到数据库。3. 先跑通嵌入式调用再考虑部署网关3.1 安装和最小可用实例建议从嵌入式模式开始先把litellm跑通理解它的请求模型之后再上代理模式。安装很简单使用 Python 的依赖管理工具即可推荐创建独立的虚拟环境避免污染全局 Python 环境。python -m venv llm_env source llm_env/bin/activate pip install litellm最小调用代码如下把服务商密钥配置到环境变量后直接指定模型名称发起请求import os import litellm os.environ[PROVIDER_A_API_KEY] 你的密钥 response litellm.completion( modelprovider-a/model-name, messages[{role: user, content: 你好请介绍一下你自己}] ) print(response[choices][0][message][content])这里比较关键的是model参数的写法格式是服务商名称/模型名称。litellm会解析出服务商前缀然后按对应的鉴权方式、接口协议去调用。如果你不写服务商前缀它还会尝试从已配置的密钥环境变量中自动推断但建议在代码里写清楚避免歧义。3.2 消息格式转换带来的参数兼容问题很多从某一家服务商直接迁移过来的项目总以为消息格式是通用的实际并非如此。有的服务商把系统消息单独放一个字段有的要求所有消息走同一个列表有的不支持某些角色类型。litellm会做转换但是转换过程中可能丢一些非标准字段。如果你用到了某家服务商特有的参数比如某个特定的采样开关需要确认它在统一参数中是否有映射。litellm的 实现中提供了extra_body或自定义参数的透传能力必要时应使用这个能力把这些特殊字段传给后端。该透传时就透传不要硬套统一模型否则特殊参数会被静默丢弃。3.3 异步调用和流式输出实际业务中同步调用撑不住高并发场景需要在上线前改用异步和流式。import asyncio import litellm async def stream_chat(): response await litellm.acompletion( modelprovider-a/model-name, messages[{role: user, content: 用流式方式输出一段文字}], streamTrue ) async for chunk in response: delta chunk[choices][0][delta].get(content) if delta: print(delta, end) asyncio.run(stream_chat())注意流式响应的结构可能因服务商而异但在统一层内它会尽量收敛成一致的增量块格式。实际项目里如果出现首字延迟过高问题往往不在统一层而在后端服务商的流式响应速度排查时要分清楚责任边界。4. 把代理网关部署到生产环境的细节4.1 为什么最终选择了代理模式嵌入式模式验证完能力之后我最后把生产环境的接入层改成了独立代理服务。原因有三点业务服务由多个团队维护技术栈不完全一致统一用 HTTP 调用比强迫所有团队引入同一个 SDK 更现实。密钥和预算策略需要集中管控放在业务代码里容易被无意间泄露到日志。上游服务商如果发生变化只需要维护代理的配置不需要要求各业务团队重新发版。代理服务的部署形态很简单它是基于 Python Web 框架实现的可直接用进程管理器或者容器方式托管。我这边是使用容器方式部署的一个实例承载了所有模型请求的中转。4.2 基本启动配置启动代理前需要准备一份配置文件用于声明要从哪些服务商请求、模型如何对应、费用如何记录。配置格式是 YAML看起来直观。model_list: - model_name: text-sm litellm_params: model: provider-a/model-a-mini api_key: os.environ/PROVIDER_A_API_KEY model_info: max_tokens: 4096 - model_name: text-large litellm_params: model: provider-b/model-b-pro model_info: max_tokens: 8192启动命令litellm --config config.yaml --port 4000启动后业务侧可以通过兼容接口访问代理。只要请求中的model字段填的是配置里的text-sm或text-large代理就会按配置转发到对应的真实模型服务商响应格式和原版一致。这个设计大大降低了业务方的迁移成本之前用标准接口的项目只需要修改 base_url 就能切换过来。4.3 环境变量注入密钥的安全做法千万不要把密钥直接写进 YAML 文件提交到代码仓库。实践中的安全做法是配置中引用环境变量密钥由发布系统注入仓库里只保留占位符。具体写法是在api_key字段填os.environ/变量名代理启动时会从环境变量读取。在配置管理方面至少要把以下信息分开管理模型列表属于代码配置密钥属于敏感配置费用预算属于运行时配置。三者混在一起是事故发生的高发原因。4.4 网关层面的权限校验代理如果不做任何校验相当于把你的模型资源开放给外网风险极大。我见过有人把代理端口暴露到公网被刷了几百块钱费用才发现。最少要在代理前面加一层带密钥的鉴权比如要求所有请求携带一个统一的访问令牌代理校验通过后才允许转发。更细的做法是按业务线划分不同令牌每个令牌绑定不同的模型访问范围和预算上限。这样某个业务线泄露了令牌损失可以被限制在最小范围内。5. 预算控制、负载均衡与失败重试的配置思路5.1 预算策略从前端限制做起模型调用费用不像普通服务器账单那么直观它跟请求量、输入长度、输出长度强相关同一个模型不同时段价格还可能不同。如果不做限制线上一个 bug 可能导致无数个循环请求费用快速上升。litellm支持设置预算上限可以按团队、按密钥、按照用户维度限制。我常用的配置是给每个业务线分配一个最大消费额度接近上限时开始告警达到上限时直接拒绝新请求并返回一个自定义错误信息。router_settings: budget_budget_duration: 30d max_budget: 1000配置说明这里的max_budget是按美元计价的硬上限budget_budget_duration是滚动周期。建议初始阶段先设置一个偏保守的额度运行一段时间之后根据实际用量再放宽。5.2 负载均衡路由算法当同一个模型逻辑被映射到多个供应商时代理可以把请求分配到不同供应商上。比如保证高可用主供应商故障时切换备用或者追求成本均衡按预设比例把流量分散到不同服务商。配置示例router_settings: routing_strategy: simple-shuffle更高级的路由可以通过权重配置实现把routing_strategy换成带权重的策略。需要强调的是路由策略要配合健康检查机制使用否则会把请求持续转发给一个已经不健康的供应商导致大量超时。我在生产环境把主用和备用供应商设置了不同的优先级并开启了自动重试。某个供应商连续返回限流错误时代理自动将请求转发到备用供应商。这一配置上线后某次主供应商大面积故障期间业务几乎无感知。5.3 重试次数和退避策略怎么调重试机制是统一接入层最有价值的能力之一但也是最容易配错的地方。核心问题不是要不要重试而是重试策略是否符合被调用服务商的实际限流逻辑。我踩过的坑是重试次数设得太大退避间隔又太短高负载时段把限流推得更严重。后来把重试次数降到三次并采用指数退避加抖动等待时间从 1 秒开始递增效果明显改善。配置里的相关参数通常包括max_retries、timeout和退避系数。线上建议至少留 30 秒的总等待时间既不影响用户体感又给后端留出恢复窗口。5.4 费用记录与对账代理模式的另一个好处是统一记录了所有请求的 Token 消耗和费用信息。这些数据默认存储在本地数据库中也可以配置为导出到外部监控系统。我每周会对一次账把代理记录的总费用和各供应商后台的费用明细做比对。刚开始总有小差异原因是各家统计工具的统计口径不同对输入输出 Token 的定义有细微差别。后来统一以代理记录为准供应商后台数据只做参考差异在合理范围内即可不需要追求完全一致。6. 集成过程中容易踩的坑与排查方法6.1 模型名称写错导致连带失败最普遍的错误是模型名称不规范。一种是忘了写服务商前缀另一种是模型名称中的版本号不对。这两类错误通常在调用时才会暴露表现为 404 或模型不存在错误。排查方法很简单看代理的日志里面会记录最终发给目标服务商的模型名和接口地址。先用最小调用脚本逐家验证确认每家都能独立连通再接入统一层不要一上来就调代理。6.2 超时时间设置不当引发雪崩模型生成本身耗时较长尤其在输出很长时单次请求可能几十秒才返回。如果给代理配了太短的超时时间它会把正常的慢请求当作失败触发重试逻辑导致服务商并发翻倍然后又反过来加剧耗时。处理方式不要把全局超时设成统一的固定值而要根据模型复杂度单独配置。比如轻量模型 30 秒大模型 120 秒。配置允许为不同模型设置不同超时时间灵活度很高。6.3 本地存储爆满和日志轮转问题代理有一段运行时间之后会出现本地数据库文件快速增长的情况。原因是每个请求的详细数据都会被落盘在流量大的时候数据量相当可观。我没有特意去关闭日志而是做了两件事一是把历史请求的保留周期缩短二是在系统层面配置日志轮转。如果模型调用量特别大建议把请求记录接入外部数据存储避免本地磁盘成为瓶颈。6.4 某家供应商密钥失效后的可视化供应商密钥有有效期密钥失效时如果代理仍继续尝试调用会返回鉴权错误而且可能多次重试浪费延迟。这个问题不是一次性配置就能解决的需要在监控里把鉴权错误单独分类设置明确的告警规则。我在实际过程中专门建立了一个错误码映射表把各家服务商返回的鉴权错误统一映射为同一个错误码。这样无论是哪家供应商密钥失效业务团队都能从日志里一眼识别不会因为各家报错词汇不同而误判。7. 和技术团队自研封装相比怎么决策7.1 开发成本和长期维护对比自研封装的初始成本看起来不高就是一个 HTTP 转发函数加几张映射表。但长期维护成本会逐渐超过使用开源方案的成本。原因在于模型服务商更新频繁每次接口调整都要跟上。个人维护时这块工作的持续性很难保证。用litellm之后这部分升级工作由开源社区承担你只需要在合适时机升级版本。升级可能出现不兼容情况但概率总体可控风险远低于完全自己维护。7.2 可扩展性是不是短板开源项目也存在定制空间不足的问题这是所有开源方案的通病。如果你有一些非常特殊的内部需求比如需要和内部权限系统深度打通或者需要对响应做精细的后处理可能需要在代理外面再包一层服务或者基于它的回调机制做二次开发。实际项目里我们做了两件事一是通过预调用来实现内部权限校验二是在代理外部增加一个薄薄的定制层专门处理那些需要结合内部业务逻辑的场景。这样既保留了开源方案的能力又满足了定制要求。7.3 决策建议落地经验我的建议是如果团队只有一个模型服务商后续也暂时没有增加的计划直接用官方 SDK 即可完全不需要引入统一接入层。一旦规划中的服务商数量大于两个或者已经在两个以上间切换过立即引入统一接入层越早成本越低。不过有一点要清醒litellm并不能解决模型能力本身的问题。它只是把调用过程变得标准化让业务代码不必跟着服务商一起变。模型选型、成本评估、效果调优这些工作仍然需要业务团队自己做判断。8. 写在最后的扩展用法与个人体会8.1 从统一调用层开始逐步搭建内部 LLM 平台几个月的实际使用让我体会到litellm适合作为内部大模型平台的底座。业务团队把它当作一个标准的模型入口所有模型请求从这一个口子进出。后续接新的供应商时业务侧完全无感模型团队只需要更新映射配置和验证效果。往这个方向上扩展还能接上更丰富的模型管理能力。比如为不同的业务场景提供不同的模型别名为不同类型的调用设置不同的优先级再配合监控系统做 SLA 分析整个内部 LLM 平台就能从能调用进化成能治理。这个思路适合任何规模在增长、模型调用开始变得复杂的团队不管是从零起步还是已经有一个自研转发层想迁移都可以参考。8.2 我的几点经验总结如果不是一开始就理解了嵌入式模式和代理模式的区别我大概会在部署架构上走不少弯路。建议先小范围用嵌入式模式做概念验证确认统一接口能满足业务需求后再上代理模式这个过程会比较平稳。配置代理的服务名、超时、预算时不要追求一步到位。先保守再逐步调整。线上环境永远按最小的可运行集开始加上完整的监控告警再逐步完善策略这是我多次踩坑之后得到的经验。最后无论选用哪种方式密钥管理都必须放在第一位。我对接过的项目里面因为密钥泄露导致费用异常的比模型调用异常多出好几倍。接入任何统一层之前先把安全边界画清楚。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询