LiteLLM:统一调用100+大模型API的轻量级网关路由器

发布时间:2026/10/21 8:34:47
LiteLLM:统一调用100+大模型API的轻量级网关路由器 在接入大模型这件事上我一开始想得特别简单不就是调个 HTTP 接口嘛OpenAI 怎么发请求别的厂商照着抄一遍不就完了真正上手才发现各家 API 的认证方式、模型命名、参数规范、返回结构五花八门同一个应用想切换或对比不同模型要写一大堆适配代码。后来在一个开源项目里看到越来越多人在用 litellm说它是一个轻量的“模型路由器”我一听这个词就来劲了实际用下来确实帮我省掉了大量重复劳动。这篇文章就围绕 litellm 聊透一个事它到底怎么统一接驳各家大模型解决那些天天被 API 碎片化折磨的场景。这个库当前在 GitHub 上相当活跃定位是“一个统一调用 100 模型的服务”核心卖点是把各种大模型接口收敛成一套 OpenAI 风格的调用格式。你只需要学会一种调用方式就能在多个模型之间做转发、切换和兜底。它既是一个 Python SDK也能直接跑成代理服务给团队做统一的模型接入层。如果你手里同时有好几个模型的 Key或者正在做一个需要动态路由用户请求到不同模型的应用litellm 基本属于那种“早用早省心”的工具。1. 为什么我需要一个“模型路由器”先讲一个真实场景。去年年中我在帮某公司做一个跨平台智能客服系统需求很普通用户问一句话系统自动判断语义然后调大模型生成回答。项目刚启动一切正常用某家头部闭源模型的 API 写起来也很顺手。麻烦出在第二周客户突然说有一部分敏感数据必须走私有化部署的开源模型而另一类请求想试试另一家新出的模型看看回答质量有没有提升。这意味着同一个应用要同时适配三套 HTTP 接口而且以后还可能继续增加。这种体验用一句话形容就是“API 方言地狱”。每家厂商都会在标准 OpenAI 风格之外搞点自己的个性比如认证方式有的是 Header 传 Key有的是 Query 参数传 Key还有的先要交换临时 Token模型名称也不同同一个能力在不同厂商那里叫法完全不一样连最基础的流式输出格式都有微妙的差异有的用data:前缀有的直接裸 JSON 行。最头疼的是报错格式不统一有的返回 RFC 7807 风格的错误结构有的就是一个纯文本加状态码。写一个兼容层不难但维护一个每天都在变化、覆盖十几种模型的兼容层真的能把人磨到怀疑人生。我在那段时间查了不少资料搜的最多的就是“统一 LLM 调用层”这类关键词。当时看到 litellm 的 README 第一句话是“Call all LLM APIs using the OpenAI format”说人话就是它把所有模型都包装成 OpenAI 的样子来调用。这正好踩中了我的痛点。它是用 Python 写的底层其实是把各家 API 的 SDK 或 HTTP 客户端做了二次封装对外暴露一套统一入参然后内部自动做参数映射、认证转换、错误标准化。而且它提供的调用入口长这个样子from litellm import completion response completion( modelgpt-4o-mini, messages[{role: user, content: 你好}] )换成其他模型的时候我只需要改model参数前一行代码动都不用动而且返回结果也是统一的response[choices][0][message][content]这种结构。这个设计对我这种还要维护前端展示层的人来说太关键了。1.1 一个接口打遍所有模型背后的代价是什么听到这里你可能想问把 100 多个模型统一成一个接口litellm 内部是不是很复杂其实它的核心逻辑可以概括为三块参数翻译器、认证注入器、输出标准化器。参数翻译器做的是“方言转换”。每个模型都有自己偏好或强制的超参数叫法比如说 OpenAI 管生成随机性叫temperature某些本地部署的模型管这个叫top_p的变体还有的模型支持repetition_penaltyOpenAI 格式里根本不认识这个字段。litellm 接受你传入 OpenAI 风格的参数然后按目标模型的规范做映射不支持的参数它会打日志提醒你被忽略了而不是直接报错。认证注入器是纯工程活。各家 API 的 Key 放法不一样有些放在 Header 的Authorization里有些需要拼成Bearer xxx还有些国内模型服务放在api-key头里。litellm 的做法是在环境变量里配置好你的 Key比如export ANTHROPIC_API_KEYsk-ant-... export OPENROUTER_API_KEYsk-or-... export AZURE_OPENAI_API_KEY...它根据你传入的model前缀自动识别应该用哪组 Key。你只需要在调用的时候用modelazure/gpt-4o这种“厂商/模型名”的格式它就能把前缀拆出来找到对应的认证配置再把后面的模型名翻译成目标服务真正认识的名字。这个设计省了我在业务代码里写一整套配置管理。输出标准化器则是负责把各种不一样的响应格式改成大家熟悉的 OpenAI 结构。比如某家模型返回的choices[0].finish_reason是generation_endOpenAI 是stoplitellm 会帮你转成统一的形式。日志里也能直接看到每个模型的原始响应长什么样方便排查问题。1.2 从 SDK 到网关同一个库的两种用法litellm 有两种打开方式一种是当 Python 库直接在代码里import litellm使用另一种是启动成代理服务跑一个本地网关。这两种方式解决的问题完全不同我觉得大部分人实际面临的情况是先从 SDK 模式切入后来慢慢过渡到网关模式。SDK 模式适合个人开发或单机脚本。你自己的代码里调 litellm代码部署在哪Key 就配在哪门槛极低。这种模式也有个小坑如果你在多人团队里各自写脚本每个人都在自己代码里硬编码各种 Key安全和维护都是问题。代理模式则把 litellm 变成一个真正意义上的独立服务。你启动一个服务进程在服务器某端口项目中所有 AI 请求都打到这个端口业务的 Base URL 指向它Key 统一在服务端配置。这对于团队开发来说几乎是必备的因为前端或者后端服务根本不需要感知你底层用的是哪家模型。前端只需要像调用 OpenAI 一样把 Base URL 改成你的网关地址就行。模型路由的切换改一下服务端配置就可以代码零改动。2. 七分钟跑通一套统一调用层说了那么多概念还是直接上手来得实在。我第一次用 litellm 的时候从安装到跑通一个完整的多模型调用链用的时间不算长。我把关键步骤整理一下你照着做基本不会卡壳。环境默认 Python 3.9 以上需要能访问外网因为要下载依赖和调用在线模型的 API。2.1 安装与基础配置安装 litellm 很简单pip 一行命令pip install litellm[proxy]官方文档里安装方式和普通 pip 包略有不同它有几组可选依赖标签比如[proxy]会额外带上跑代理服务需要的 FastAPI、uvicorn 等组件[redis]带上缓存相关依赖。我只跑 SDK 模式的话直接pip install litellm也是可以的。但既然迟早要试代理模式我建议一步到位装[proxy]。之后是配置环境变量。Windows 系统用setLinux/macOS 用export我是在.env文件里统一维护然后交给进程加载。至少准备两家不同模型的 Key方便后续测试切换效果。配好之后可以先跑一个最小验证脚本import litellm response litellm.completion( modelopenai/gpt-4o-mini, messages[{role: user, content: 说一句你好}] ) print(response.choices[0].message.content)注意这里model我特意写了openai/gpt-4o-mini而不是gpt-4o-mini这是 litellm 约定的“厂商前缀/模型名”格式。如果你直接传gpt-4o-minilitellm 也能通过内部映射找到 OpenAI但我建议养成写前缀的习惯因为很多模型的名称在不同平台间是重复的显式声明厂商能让路由行为更确定排查问题也更方便。2.2 核心调用 API 与参数传递litellm 只学一个函数就能覆盖绝大多数场景就是litellm.completion()。它接受 OpenAI SDK 风格的所有参数然后翻译分发。在代码里第二个模型可以这样写和刚才的调用完全并列response litellm.completion( modelclaude-3-5-sonnet-20241022, messages[{role: user, content: 翻译成英文今天天气很好}], temperature0.7, max_tokens200, )当模型换成某国内大模型平台时只需要把model改成对应平台的前缀加模型名比如在支持 OpenAI 兼容格式的平台上用modelhunyuan/turbos-latest或openrouter/meta-llama/llama-3.3-70b-instruct。剩下的messages、temperature、max_tokens逻辑都不用动输出结构也依然是response.choices[0].message.content。这里有个细节不同模型支持的能力不同比如有的支持max_tokens有的叫max_completion_tokens有的模型默认输出可能只有 50 个 token如果不显式调max_tokens很容易看到回复被截断。litellm 会做字段映射但建议在代码里对每个模型统一显式声明max_tokens别依赖默认值。函数调用也是常见需求litellm 支持传入tools参数这个在对接各种 Agent 框架时特别重要tools [{ type: function, function: { name: get_weather, description: 获取指定城市的天气, parameters: { type: object, properties: { city: {type: string} } } } }] response litellm.completion( modelgpt-4o-mini, messages[{role: user, content: 北京今天冷不冷}], toolstools, )有的模型本身不支持 function callinglitellm 提供了一个litellm.function_to_dict()之类的辅助函数实际上更实用的做法是配合litellm.enable_function_calling之类的开关来做能力降级。这块你在使用中会自己摸索到方向是能用官方接口暴露的能力就尽量走统一格式。2.3 从代码调用到服务端网关SDK 模式验证通过之后我强烈建议你顺手把服务也启动一下。首次体验代理模式只要一条命令litellm --model gpt-4o-mini --port 8000启动成功之后终端会显示一个本地接口地址。你可以直接用 OpenAI 的 SDK 去请求它from openai import OpenAI client OpenAI( api_keysk-any-key, # 只要能通过网关校验就行 base_urlhttp://localhost:8000/v1 ) resp client.chat.completions.create( modelgpt-4o-mini, messages[{role: user, content: 网关模式测试}] ) print(resp.choices[0].message.content)为什么api_key随便填一个都行因为 litellm 在默认配置下不会真的校验这个 Key 是否和上游一致它会把这个 Key 当作客户端标识记到日志里。上游的 Key 已经配置在网关进程的环境变量里了。正式环境如果希望加强安全再开虚拟 Key 校验。这也引出一个设计上的好处前端拿到的只是网关的地址和一个你自己的虚拟 Key上游真实 Key 永远不暴露给客户端安全性高很多。我当时测完这个最小代理实例之后第一反应是之前写的那些适配层代码可以全部删掉重写。只要让项目里所有模块的 OpenAI 客户端 Base URL 都指向 litellm 网关升级模型就变成了修改网关配置这么简单。3. 网关模式的高级玩法负载均衡、预算与记录基础的代理跑通只是热身。litellm 真正值钱的地方在网关模式下的高级配置我实际用下来感觉它自带了一套非常完整的“模型运维中台”能力哪怕只用到三分之一也能让团队的模型使用管理上一个台阶。3.1 模型路由与负载均衡litellm 支持配置多个同样能力或不同能力的模型并通过一定策略路由请求。我个人的做法是给同一家厂商配备两个 Key用加权轮询的方式分摊负载。配置文件可以写成一个 YAML 文件传给它核心片段像下面这样model_list: - model_name: gpt-4o-mini litellm_params: model: openai/gpt-4o-mini api_key: os.environ/OPENAI_API_KEY model_info: mode: completion - model_name: gpt-4o-mini-backup litellm_params: model: openai/gpt-4o-mini api_key: os.environ/OPENAI_API_KEY2 model_info: mode: completion在代码或请求里客户端只需要指定一个虚拟名字gpt-4o-minilitellm 会根据配置把流量分到两个上游 Key。如果其中一个 Key 的额度耗尽另一个能自动顶上。在没有摸清 litellm 的路由逻辑之前我非常担心它是不是有智能负载策略最后测试下来发现它默认就是简单的轮询加失败重试已经够用。官方还支持最少连接数、随机等策略我实际用轮询最多。还有一个很实用的场景是主备降级。比如主模型用某高端闭源模型出问题或超预算时自动降级到便宜的开源模型。这个功能配置一个映射即可router_settings: fallbacks: - {gpt-4o: [llama-3.1-8b-instruct]}意思是当目标是gpt-4o的请求失败时自动转去调用llama-3.1-8b-instruct。这种降级策略在长时间运行的服务中能极大减少因模型服务商故障导致的用户体验中断而且配置完全是声明式的不需要改业务代码。3.2 虚拟密钥、预算与访问控制团队接入模型网关之后最发愁的事情之一就是成本治理。每个人、每个项目都在消耗 Token月底账单出来根本不知道是谁花的。litellm 的虚拟 Key 机制正是解决这个问题的。你可以用它的管理接口生成一组“虚拟 Key”这是一个带前缀的长串字符发给具体的前端或后端服务用。它在 litellm 内部跟某一个真实 Key、某一个模型范围绑定。配置里可以限制这个虚拟 Key 只能访问哪些模型。每分钟最多多少次请求。总预算是多少美元超过就拒绝服务。这种管理模式特别像我们平时用的对象存储的 AccessKey权限被严格控制不直接暴露真实的根 Key。我实际把这个能力用在了公司的多项目隔离上每个项目申请一个虚拟 Key月度成本报表按虚拟 Key 做维度统计谁的消耗占比高一眼就能看见。预算管控精确到什么程度呢比如某个项目的虚拟 Key 预算设为 50 美元当消耗接近上限时litellm 可以选择返回一个特殊错误码也可以让它触发工单通知。它对接的数据库端是 SQLite 或 PostgreSQL看你的数据量和并发决定。小团队先 SQLite 没问题但流量大了还是尽早换 PostgreSQL。3.3 日志、Trace 与可观测性还有一个非常大的使用场景是审计和排查问题。模型服务商那边的调用日志往往只能看总量看不到用户级别或消息级别的明细。litellm 网关默认会把每次请求的关键信息都记录下来谁在什么时间调用了哪个模型、消耗了多少输入输出 token、耗时多长、响应内容是什么、报错信息是什么。当出现异常时排查链路是这样的用户在系统里问了一句奇怪的话系统返回了一个空回复业务方怀疑是模型问题但模型服务商后台看不到具体信息。这时通过网关日志你能看到这几次请求的实际响应内容、token 消耗和可能的截断原因。很多模型输出空内容的原因其实是max_tokens设太小导致生成结束这类问题看日志比猜要快得多。它也能输出标准的 OTEL trace 或价格记账信息但我觉得日常使用只要把日志落库加上一个简单的查询页面就已经比裸调 SDK 时方便太多。4. 常见问题与排查技巧实录网上关于 litellm 的讨论已经很多了但很多新手被卡住的地方往往不是大问题而是几个看起来不起眼的细节。我把这段时间踩过的坑整理成清单按出现频率排序几乎每次线下分享都能对上一半人。4.1 大量请求时报错“RateLimitError”或被限流这是接入后最先遇到的问题之一。很多厂商的 API 有并发上限和每分钟 Token 限制litellm 网关本身不限制的话流量很快就会把配额打爆。解决方法是给模型配置里显式加入客户端限流参数litellm 支持litellm_params: model: openai/gpt-4o-mini rpm: 60 # 每分钟请求数限制 tpm: 120000 # 每分钟 token 数限制还可以开启全局并发控制比如litellm.max_parallel_requests_worker。如果确实需要高并发再用 Redis 做分布式限流。我个人的经验是每个上游服务能承受的并发能力都不一样先看厂商文档里给的默认限额再按 70% 的余量去配置不要贪满给重试留一点缓冲。4.2 同样的输入不同模型给的结果格式差别很大很多人以为统一到 OpenAI 格式之后所有模型返回值就完全一样了。实际上litellm 只是把外层结构统一了不同模型在content里塞的内容格式仍然有差别。比如有的模型就喜欢在回答前加一段免责声明有的模型会把结构化内容直接以 JSON 字符串返回还有的会莫名其妙多出空行。解决办法有两个第一个是在业务层再包一层“语义适配器”专门针对你的下游消费场景做清洗第二个是直接使用 litellm 的litellm.response_cost()等工具但这种工具只解决成本和 token 计算不解决内容格式。说到底统一调用层只解决“能不能调到”和“拿到统一外壳”的问题内容本身的规范化仍需业务侧处理。4.3 代理模式下如何传环境变量跑代理模式时最容易犯的错误是没把上游模型的 Key 设置到启动服务进程的环境变量里。如果你在代码里load_dotenv()没问题但启动litellm子进程时外部环境没带上这些变量就会一直报 401。排查的时候先打印一下启动环境的变量名确认前缀都对得上。在 Docker 或云平台上跑的时候建议用平台自己的 Secret 管理能力注入环境变量别直接把 Key 写在 YAML 里提交到代码仓库。这算基础的安全素养但我在不少项目 review 里还是见过明文 Key。4.4 模型名里带斜杠版本号的情况有的模型名称里本身包含版本号或组织名比如meta-llama/llama-3.3-70b-instruct。如果在 litellm 的model参数里直接写这种原始名称可能被误判为“厂商前缀/模型名”的结构。这时候有两种正确处理方式一是确认平台前缀本身能区分比如openrouter/meta-llama/llama-3.3-70b-instruct这类前缀比较明确的写法是可以的二是配置model_list时给虚拟模型名取一个不含斜杠的别名在系统内部映射到完整名称。使用虚拟别名的方式最稳妥也方便以后换模型。5. 一些实际落地的建议文章写到现在该讲的 API 和配置都过了一遍。最后聊一下我自己沉淀下来的使用心法相当于一个落地清单。第一不要把 litellm 当成“万能适配器”去接每一种冷门模型。虽然它支持数量很多但某些小众或刚出的模型适配质量参差不齐。我建议以主流的几家头部模型和开源模型为核心优先保证一条主链路的稳定性其它模型等真正有需求再去加。一次接入太多模型只会让排查问题的范围变大。第二代理模式和 SDK 模式不要混着用。我一开始图省事业务代码里直接 import litellm往上游调没有问题后来团队大了想上代理发现之前写死的 Key 在代码里到处都是反而增加了改造成本。如果团队规模超过三个人或者有多套环境开发、测试、生产直接一步到位上代理模式多花半小时部署后面省的时间是几何级数的。第三隔离需求要想清楚。虚拟 Key 的隔离粒度、日志保留时间、预算上限这些都要在项目启动前和运维同事对齐。等流量起来之后再改配置不是不行但要考虑历史日志的连续性所以设计阶段多留一点余量比亡羊补牢好。第四有个小技巧值得分享litellm 暴露了一套/v1/models接口你在浏览器或者 Postman 里请求它网关会把所有可用的模型列表返回给你前端也能用它来动态渲染模型选择器。接口形式很稳定兼容 OpenAI 生态团队协作时特别方便。踩过几次坑之后我的体会是litellm 并不是一个“加了就能马上性能飞升”的魔法库它的价值在于把那些繁琐、易错的接入工作收敛到可控范围内让团队真正把时间花在业务逻辑和模型效果上。如果你正在被多模型接入折磨不妨先按这篇文章的步骤搭一个最小代理实测跑通两个模型对比一下效果相信你也会回来把它纳入自己的基础工具清单。