资讯动态

litellm:大模型调用网关,统一多模型接入与成本治理

发布时间:2026/10/21 18:30:28 来源:尧图企业网站定制
最近好几个做AI应用开发的朋友都在聊同一个词litellm。我们团队在半年前把内部的模型调用层整体切到了这个方案上从最早只是图它“统一接口”到后来把密钥托管、预算控制、模型回退全交给它可以说解决了很多原本要手写代码才能搞定的问题。如果你现在正在做多模型接入或者已经因为各家API格式不统一而维护着一堆适配代码这篇文章值得你从头到尾看一遍。litellm本质上是一个大模型调用网关它把自己放在你的业务代码和真实模型服务商之间把不同厂商的鉴权方式、请求格式、返回结构全部翻译成统一的OpenAI兼容协议。同时它还能做负载均衡、自动重试、模型降级、预算限制、虚拟密钥和成本统计。我用下来最直观的感受是以前团队里每接一个新模型都要改重点代码现在只需要在litellm的配置文件里加一段映射业务代码一行不用动。1. 先搞清楚litellm到底解决什么问题1.1 多模型接入的“接口混乱”现状先回想一下最原始的多模型接入方式。假设你的产品要同时用三家不同模型服务商的能力第一家走的是OpenAI兼容格式请求体里写model、messages第二家走的是另一套风格可能要求prompt字段可能用max_tokens_to_sample这种不太常见的参数名第三家干脆连鉴权方式都不一样不是简单的Bearer Token而是带签名、带时间戳的复杂流程。这种情况下的业务代码会变成什么样子最常见的是在封装层里写一个巨大的if-else读配置判断当前用的是哪家然后组装不同的请求体、解析不同的返回结构。刚开始只有两三家还撑得住一旦模型数量涨起来每一个新接入都意味着新一轮体量巨大的改造和回归测试。我见过最夸张的情况是一个底层函数里塞了五六种厂商的分支逻辑参数名互相冲突连调个temperature都要小心翼翼地绕过保留字段。还有一个非常容易被忽略的问题密钥安全。过去的做法是把各个厂商的API Key直接写进后端服务的环境变量甚至有团队直接硬编码在代码仓库里。这样做的问题也很明显一是所有能接触到代码的人都能看到全部密钥二是一旦需要给不同项目分权或者限制额度根本没有一个统一的地方做控制。再加上成本审计基本靠猜月底对账的时候才知道哪些模型烧了多少钱出了问题连是哪个业务线调的都不知道。1.2 litellm的定位与整体设计思路litellm做的事情用一个类比来说就是你不需要分别跟每个供应商谈对接方式、记账方式、售后方式而是找了一个中间服务商它把所有供应商的“合同模板”统一了你只需要按同一个格式下单剩下的翻译、协商、账单都由它处理。从实现上看litellm有两条使用路径。第一条是SDK内嵌模式你在Python代码里直接import litellm用它的completion方法去调用所有模型第二条是独立代理服务模式你启动一个litellm server让团队各个业务服务通过HTTP接口访问它再由它转发到真实模型服务商。实际在团队协作场景中我强烈推荐第二种因为网关独立部署之后业务侧、算法侧、运维侧的职责就清晰了算法同学在litellm配置层调整模型路由不用打扰业务开发业务开发只需要知道一个固定的endpoint和一个虚拟key模型怎么切换完全不用关心。这种“中间层”的设计思路本质上是在解耦。它把模型供应商的差异隔离在网关内部让上游业务代码只依赖一种协议。而且litellm不是简单的转发代理它还能在中间层做限流、预算、审计、密钥托管这些能力如果都塞进业务代码里会让项目变得非常复杂。我把它放到生产环境之后才发现网关模式最大的红利不是“少写代码”而是“让治理和观测变得可管理”。2. 快速跑通litellm两种接入方式实战2.1 安装与环境准备我建议直接用一个干净的Python虚拟环境来安装避免跟你的项目依赖混淆。litellm本体安装很简单如果你的目标是用代理服务模式需要安装带proxy扩展的版本。pip install litellm[proxy]装完之后先确认一下命令行工具是否正常litellm --help如果能看到参数说明说明基础安装成功了。接下来要准备各模型服务商的密钥。litellm通过环境变量来读取真实厂商的密钥最常规的做法是在当前终端或者进程环境里设置。这里有一个细节官方文档里通常会把各个厂商的密钥环境变量名写得很明确比如某家厂商的密钥对应哪个环境变量名你照着配即可关键是不要把Key写在代码里更不要提交到Git仓库。为什么要强调环境变量因为在实际部署中环境变量可以挂在进程管理器、容器编排平台或者密钥管理系统上权限可控、可轮换而且不会因为代码仓库泄露导致密钥暴露。我自己踩过一次坑早期为了省事把Key写在配置文件里结果同事不小心把这个配置文件提交到了内部仓库还好及时发现并轮换了密钥。从那以后所有密钥一律从环境变量或密钥管理服务注入。2.2 SDK模式代码里一行切换模型先看SDK内嵌模式这个模式适合你的项目本身就是Python写的而且调用量不大、不需要团队共享网关的场景。核心用法非常简单import litellm response litellm.completion( modelgpt-4o-mini, messages[{role: user, content: 你好请介绍一下自己}] ) print(response[choices][0][message][content])这段代码跟直接调某个具体厂商的SDK相比最大的区别是model这个参数。你把model换成另一家主流厂商的模型标识比如换成某个开源模型的部署名只要环境变量里配好了对应的密钥其他代码完全不用改。这就是SDK模式最大的价值模型切换收敛为一个参数变更。实际使用中还有一个技巧litellm允许你把一个自定义的模型名注册到某个特定的api_base和部署名上。比如你的公司内部搭建了一个模型服务平台协议沿用OpenAI兼容格式但是base_url是内网地址你可以这样映射litellm.register_model( modelinternal-chat-model, litellm_params{ model: your-deployment-name, api_base: http://internal-model-platform.example.com/v1, api_key: your-internal-key } )之后你在代码里只需要写modelinternal-chat-modellitellm会自动路由到内网平台的对应模型。这个技巧非常实用特别是当你有自建模型服务或者私有化部署需求时它让业务代码完全不需要感知底层地址变化。2.3 代理服务模式团队接入的标配如果你们团队有多个后端服务我建议直接用代理服务模式。这种模式下litellm会启动一个独立的HTTP服务你用一份YAML配置文件来描述模型列表和路由规则。先看一份最基础的config.yamlmodel_list: - model_name: gpt-4o-mini litellm_params: model: gpt-4o-mini api_key: os.environ/OPENAI_API_KEY - model_name: claude-sonnet litellm_params: model: anthropic/claude-3-5-sonnet-latest api_key: os.environ/ANTHROPIC_API_KEY启动服务litellm --config config.yaml --port 4000启动之后业务侧只需要把OpenAI SDK的base_url指向你的litellm服务地址from openai import OpenAI client OpenAI( api_keysk-litellm-master-key, base_urlhttp://localhost:4000 ) resp client.chat.completions.create( modelgpt-4o-mini, messages[{role: user, content: hello}] )注意看这里的model参数业务侧填的其实不是真实模型名而是你在litellm配置里定义的model_name。这就意味着只要在litellm配置里调整model_name指向的真实模型业务侧什么都不用改。比如你想把gpt-4o-mini从技术效果一般的基础模型升级为更强的模型只需要修改config.yaml里那一个字段重启litellm发布结束。用curl验证一下更直观curl http://localhost:4000/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-litellm-master-key \ -d { model: gpt-4o-mini, messages: [{role: user, content: hello}] }只要返回正常的chat.completion结构就说明代理服务已经跑通了。从这一步开始你的业务团队可以完全抛弃对真实模型厂商的依赖眼中只剩下一个统一的万能服务。3. 核心能力拆解litellm不只是“翻译官”3.1 负载均衡与自动重试如果你只是把litellm当成一个API翻译器那就太浪费了。我在生产环境里用得最频繁的功能之一是负载均衡。场景非常常见同一个模型你申请了多个密钥想把请求分散到这些密钥上避免单个密钥因为并发太高被限流或者同一个模型服务在不同区域有多个入口你想让请求自动挑一个快的。配置方式是在model_list中为同一个model_name配置多个litellm_params实例model_list: - model_name: gpt-4o litellm_params: model: gpt-4o api_key: os.environ/OPENAI_API_KEY_1 model_info: rpm: 1000 - model_name: gpt-4o litellm_params: model: gpt-4o api_key: os.environ/OPENAI_API_KEY_2 model_info: rpm: 1000litellm会在这两个配置之间做路由默认策略是简单的轮询打散也支持基于延迟和基于用量的策略。我实际测下来simple-shuffle模式在请求量比较均衡的时候效果不错配置简单如果请求的模型多而且每个模型负载差异大可以切到usage-based策略让litellm根据当前每个上游实例的在飞请求数来动态分流更不容易打爆某个密钥。自动重试也是这个模块里的一个重要能力。litellm在收到上游的429限流、5xx错误、超时异常时会自动对请求进行重试。默认重试次数不一定适合所有场景我给你一个建议值general_settings: max_retries: 3 retry_after: 5 cooldown_time: 30max_retries控制单个请求最多重试几次retry_after是收到限流后等待的秒数cooldown_time是某个上游实例连续出错后进入冷却状态的时长。注意重试要跟你的业务超时时间配合如果上游已经卡了很久重试三次会让用户等待更长所以建议给litellm的请求整体设置一个合理的超时上限。3.2 模型回退与灰度切换模型回退是我非常喜欢的一个功能它解决的是“主模型不可用或质量不达标时自动降级到备用模型”的问题。典型场景有两个一个是主模型服务商故障秒级切换到备用服务商保证业务不断另一个是新模型灰度上线先用小流量验证万一效果不好就自动退回老模型。配置方式是在litellm_params里加fallbacks字段model_list: - model_name: primary-model litellm_params: model: gpt-4o api_key: os.environ/OPENAI_API_KEY fallbacks: - backup-model - model_name: backup-model litellm_params: model: anthropic/claude-3-5-sonnet-latest api_key: os.environ/ANTHROPIC_API_KEY当primary-model因为限流、超时、5xx等异常失败时litellm会把同一个请求自动转发给backup-model。这里有一个非常重要的点不同厂商的模型能力差异很大比如有的模型系统提示词支持弱一些有的对长文本的处理方式不同。你在做回退设计时必须保证业务侧的提示词和参数在主备模型上都能得到接近的效果否则降级虽然保住了可用性但回答质量可能会出现肉眼可见的下降。我还有一个建议谨慎使用自动回退处理业务语义错误比如内容安全过滤类的返回码。这类错误说明模型或者请求本身有问题并不是服务不可用盲目回退到另一个模型可能造成成本翻倍还拿不到预期结果。正确的做法是对这类错误走业务侧的逻辑分支而不是在网关层无脑重试或回退。3.3 密钥安全、预算和限流这一块是我觉得litellm在生产环境里最值钱的能力。通过虚拟密钥机制你可以在litellm上签发多个子密钥每个子密钥可以绑定特定的模型组、预算上限和过期时间。业务团队拿到的只是虚拟密钥真实厂商密钥永远只在litellm服务端。这么做的价值很明显你不用再担心某个开发者的Key泄露会导致整个厂商账户被盗用也不需要在人员离职时轮换主密钥。只要在litellm管理端删除对应的虚拟密钥即可。如果你用的是代理服务模式可以通过管理接口或者UI来创建虚拟密钥。在配置层面你可能需要给虚拟密钥设置一些约束。常用的参数包括参数作用我常用的配置rpm每分钟请求数限制按业务峰值估算tpm每分钟token数限制按业务峰值估算max_budget密钥总预算美元按项目月度预估budget_duration预算重置周期30dexpires_at密钥过期时间按项目周期设定举个例子如果你创建一个给数据分析小程序用的虚拟密钥希望它只能调用某个轻量模型、每月最多花50美元、三个月后失效那就在创建密钥时把model_id限定为该模型组设置max_budget50、budget_duration30d、expires_at为三个月后的日期。限流和预算还有一个隐藏的价值防止线上故障导致成本失控。一个典型的场景是算法模型在循环里疯狂调用本来一次调用只要几分钱因为死循环或者数据量暴涨一下午跑出几千美元的费用。如果配了预算上限litellm会在达到阈值时直接拒绝新的请求及时止损。基于这个原因我建议所有接入的模型组都至少配一个保守的预算上限。3.4 成本追踪与用量审计litellm自带成本计算和日志能力。每一条请求都会记录模型、token数、耗时、虚拟密钥、模型组等信息并按配置的单价计算成本。这个功能对于多团队、多项目共用同一套网关的架构来说特别重要它能让你把成本归因到业务线、项目、甚至单个功能模块。成本计算的配置一般放在模型组信息里。litellm对很多公开模型内置了单价表开箱即用但对于私有化部署或者自建模型单价按token计算的方式不一定适用就需要手动在配置里给模型添加价格信息。比如一个自建模型你可以配置输入输出token的价格model_info: input_cost_per_token: 0.000002 output_cost_per_token: 0.000006价格单位是美元。这样设好之后litellm的日志和统计报表里就会自动为你计算每一次请求的成本。我习惯每天拉一次前一天的按模型组汇总报表重点关注成本突增的模型和调用量异常偏大的虚拟密钥这能帮我及时发现线上异常。这里有一个我在实际中总结的排查方式如果某一天总成本突然翻了倍先去查是哪个model_group贡献的增量再查是哪个key、哪个业务接口带来的调用变多。如果某个key平时每天只有几百次请求突然涨到几万次大概率不是用户量涨了而是某个自动化任务出了bug。这时候可以直接在litellm侧临时调整该key的限流配置先稳住成本再定位代码问题。4. 生产环境落地实录参数调优与问题排查4.1 部署方式选择与性能基线litellm在生产环境的部署形态我建议用Docker容器。官方提供了镜像构建和启动都很简单。一个典型的docker-compose服务定义大概长这样version: 3.8 services: litellm: image: ghcr.io/berriai/litellm:main-latest ports: - 4000:4000 volumes: - ./config.yaml:/app/config.yaml environment: - DATABASE_URLpostgresql://user:passwordpostgres:5432/litellm - REDIS_URLredis://redis:6379 - LITELLM_MASTER_KEYsk-master-key-here command: [--config, /app/config.yaml, --port, 4000] postgres: image: postgres:16-alpine environment: - POSTGRES_USERuser - POSTGRES_PASSWORDpassword - POSTGRES_DBlitellm volumes: - pgdata:/var/lib/postgresql/data redis: image: redis:7-alpine volumes: pgdata:默认情况下litellm会使用SQLite作为存储用在本地调试没问题但生产环境我强烈建议切换成PostgreSQL尤其当你开启了虚拟密钥、预算管理、日志审计之后SQLite的并发写能力会成为瓶颈。Redis在这个架构里承担的是限流计数和部分缓存功能如果你是单机部署、并发量不大不配Redis也能跑但一旦你用了rpm/tpm限流或负载均衡策略建议把Redis加上否则多副本部署时限流数据不在同一个存储里会出现统计偏差。性能方面很多人关心单台机器能扛多少并发。litellm本身是个转发层它的瓶颈主要在网络I/O和上游服务的限流上。我们内部做过压测一台4核8G的普通云主机在开启详细日志和成本统计的情况下实测能稳定处理每秒几百个请求峰值可以到每秒上千作为参考这个量级对大多数中小团队完全够用。如果你们团队的调用量远超这个级别优先考虑多副本部署通过负载均衡把流量分给多个litellm实例。4.2 需要重点关注的参数生产环境配置litellm有一个参数清单需要你过一遍我按优先级列出来参数默认值我的建议说明master_key无必须设置管理端和业务端的统一入口密钥database_urlsqlitePostgreSQL存储日志、密钥、预算数据redis_url无建议设置支撑限流和分布式计数max_retries按服务商3重试次数过多会放大上游压力timeout按服务商业务可接受的等待时长建议设置全局timeout避免卡死cooldown_time30秒30~60秒上游故障后进入冷却时间store_model_in_dbfalsetrue开启后可通过UI/接口动态管理模型drop_pending_paramsfalsetrue过滤上游不支持的参数避免报错这里重点说两个容易被忽略的参数。第一个是drop_pending_params。很多模型对未知参数会直接报错比如你在通用请求里带了一个A厂商识别但B厂商不认识的参数转发过去就会收到400错误。开启drop_pending_params后litellm会在转发前剥离不支持的参数尽管这可能导致某些参数在特定模型上失效但换来的是更高的可用性业务侧不用再为了兼容不同厂商去裁剪请求体。第二个是cooldown_time。当一个上游实例连续出现超时或5xx错误时litellm会把它加入冷却名单在冷却期间不再往这个实例分发请求。这个值的设置要综合考虑你的上游容错能力。设太短故障实例恢复前就会被再次分配流量设太长可能让其他正常实例承担不必要的压力。我一般从30秒开始压测中观察错误恢复速度再调整。4.3 实战踩坑记录聊几个真实遇到的问题和处理过程。第一个坑是成本统计为0。之前接入一个新的自建模型时接口调用和返回都是正常的日志里也有token记录但成本始终为0。排查下来发现litellm对已知供应商的模型内置了价目表但对自建模型必须手动配置price信息。我在model_info里补上了input_cost_per_token和output_cost_per_token之后成本数据才正常显示。如果你以后也遇到成本统计不对第一反应就是检查模型有没有配价格。第二个坑是上下文超限没有触发回退。业务侧传入的长文本超出了主模型的上下文窗口按理说应该自动切到上下文更大的备用模型但实际请求直接报错挂了。原因是litellm的context_window_fallbacks配置和普通的fallbacks是两套机制后者处理的是接口异常前者专门处理context window超限。只配了下半部分没有配置针对窗口超限的回退自然就不会触发。我把两个配置都加上才解决问题。第三个坑是某个上游账号被限流打爆。团队内部做活动推广时某个模型的请求量突然暴涨虽然litellm做了负载均衡但还是有大量429错误。后来定位发现是同一个账号被拆成了多个虚拟密钥但真正的上游并发上限只有一个负载均衡只是让请求分散到不同虚拟key上并没有突破真实服务的并发瓶颈。解决方式是在这个模型的litellm_params里增加max_parallel_requests参数限制同一时刻丢给上游的请求并发数超出部分排队重试。第四个坑是Docker容器里日志时间不对。容器时区默认是UTC排障时看到的时间和本地时间对不上很容易误导。解决方式很简单在容器环境变量里设置TZAsia/Shanghai确保日志时间戳和本地一致。第五个坑是日志表无限制增长。litellm每一条请求都记录刚开始不觉得一个月后数据库可能膨胀到几个GB查询都变慢而且磁盘成本也在涨。我后来做了一次日志归档方案定期清理历史日志只保留最近45天的详细日志更早的数据汇总成报表后归档。建议你们上线前就把日志保留策略设计好。排查问题时的通用思路也分享一下吧litellm的日志字段很丰富出问题时先看litellm返回的错误码和消息然后再去服务日志里查具体的上游URL、耗时、失败类型。如果上游返回了5xx大概率是厂商侧的问题如果是429要看是litellm自带的限流拦下来的还是上游返回的如果业务侧超时而litellm日志显示上游正常返回那就要检查整体链路里是否有别的网络组件拖慢了速度。4.4 把litellm纳入日常运维的几点建议litellm部署好只是第一步后续的日常运维才是决定这个系统能不能长期稳定跑下去的关键。第一定期轮换和检查虚拟密钥。密钥不要一次性签发很多个然后长期不管建议定期检查每个虚拟密钥的过期时间和预算消耗及时回收不用的key。尤其是外包项目或者临时合作结束后第一时间禁用对应的虚拟密钥。第二建立模型上线和下线流程。每次新模型接入先在litellm配置里加上并用一个内部测试key试用几天确认效果和成本后再开放给业务侧。下线模型时也要同步检查还有哪些业务在用这个模型组避免出现业务请求全量失败。第三为litellm自身搭建监控。虽然litellm有日志和UI但网关本身的存活状态、请求成功率、平均延迟也需要纳入你的监控体系。我习惯加一个轻量的健康检查接口定时探测配合消息通知出现问题第一时间能感知到。最后说一点我个人的实际体会。litellm给我最大的改变其实不是省了多少代码而是改变了团队协作的方式。以前算法和业务因为“这么简单的接口怎么又改了”经常来回拉扯现在模型层的变动完全隔离在网关内部大家各自专注自己的事情。哪怕你目前只是一个人在做小项目我也建议你从代理服务模式入手把litellm用起来因为你迟早会遇到多模型并存、成本失控、密钥泄露之类的问题早一天搭好这个基础设施后面就少踩一天的坑。

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

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

免费获取报价 →
↑