资讯动态

Litellm实战:统一大模型API接入,搭建LLM网关与多模型路由

发布时间:2026/10/14 8:59:25 来源:尧图企业网站定制
我发现和很多团队聊大模型落地时大家最头疼的往往不是模型能力不够强而是同时接了太多家模型之后代码里全是if-else适配逻辑。今天分享的这个开源项目就是专门解决这类问题的一个叫 litellm 的轻量级工具核心功能就是把国内外主流大模型的API接入方式统一成一套规范让调用端只面对一个接口而底层想换哪家就换哪家。我用了快一年时间从最初只是想省点事到后来把它做成了自建的模型网关整个过程踩了不少坑也有些非常实用的心得这篇文章就当作一次完整复盘希望能给正在折腾多模型接入的朋友一些参考。1. 先弄明白litellm 到底在解决什么“痛点”先说一个很典型的场景。某天老板跟你说“现在这个聊天机器人用的模型太贵了换个便宜点的试试。”你一听就知道麻烦来了。如果代码里直接调的是某一家厂商的官方SDK那换模型就意味着改请求格式、改鉴权方式、改返回解析运气不好还要逐个排查哪些字段不兼容。这类痛点其实有几个共同点第一各家模型的API风格很不一样有的用路径参数区分模型有的要求自定义header有的返回内容里藏着不同结构的元数据第二模型数量一多密钥管理就变得棘手谁用了哪个模型、花了多少钱很难统一统计第三一旦主力模型出故障或者被限流想快速切到备用通道完全没有现成机制。litellm 的思路非常直接它把大模型接入时的两个关键层级解耦了一是面向调用端的接口层二是面向模型提供方的适配层。调用端不需要关心背后连接的是哪家服务只需要按照一套统一的格式发请求剩下的映射、转发、鉴权、计费它全包了。再加上它本身支持以服务方式运行团队里的其他人不需要装Python库直接通过HTTP接口就能用这就变成了一个真正意义上的模型网关。我用下来最大的感受是它不只是帮我在代码里省掉了几十个适配函数这么简单更关键的是让“模型选型”这件事变得可以随时调整而不是绑定在代码里。以前想比较两个模型的效果要写两套调用逻辑现在只需要改配置几分钟就能出一组对比测试。这种灵活性在快速迭代的AI应用开发中特别值钱。市面上类似的方案不是没有但大多要么绑定特定云平台要么功能单一只做接口转换。litellm 把路由、负载均衡、成本追踪、流式转发这些都集成到了一起才让它真正像个基础设施而不是一个小工具库。2. 核心机制拆解统一接口、路由策略和计费体系2.1 统一接口是怎么设计的要理解 litellm 的统一接口最简单的方式是拿 OpenAI 的请求格式当基准。无论你用的是哪家模型litellm 都会把请求转换成OpenAI风格的格式再把各家返回的内容映射回OpenAI风格的结构。这样做的好处是生态兼容性极强市面上绝大多数工具链、框架、开源项目都已经兼容OpenAI接口格式你现有什么就能继续用什么。比如在官方SDK里调用一个模型的补全接口通常长这样from litellm import completion response completion( modelgpt-3.5-turbo, messages[ {role: user, content: 你好介绍一下你自己} ], temperature0.7 ) print(response.choices[0].message.content)这段代码背后对应的是某家的模型但当你把 model 换成其他模型时比如改成某个开源模型的服务商接入请求参数里那些共通的字段比如 temperature、max_tokens、streamlitellm 会自动做转换。各家特殊的参数也保留通过特定的键名透传互不干扰。类似地文本嵌入模型的调用也是一套统一接口from litellm import embedding response embedding( modeltext-embedding-ada-002, input[今天天气怎么样, 明天会下雨吗] ) for item in response.data: print(len(item[embedding]))这种设计最省心的地方在于业务代码可以一直保持稳定模型变了业务逻辑完全不用动。我见过很多团队迁移模型时因为返回字段结构差异导致线上报错用 litellm 做中间层之后这种无谓的返工几乎消失了。2.2 路由、重试和故障转移的运作原理litellm 提供的 Router 模块相当于一个智能分发器。你可以预先设置多个模型通道并给每个通道配置优先级、权重、最大并发。当请求进来时Router 会根据这些配置决定发给哪个通道。实际使用中最常见的是两类设置优先使用性价比高的模型当它不可用时自动切换到备用模型或者在多个相同能力的模型之间做负载均衡。看一下这段配置就能很直观地理解工作方式from litellm import Router model_list [ { model: gpt-4o-mini, api_key: sk-xxx1, rpm: 1000, }, { model: claude-3-5-haiku, api_key: sk-xxx2, rpm: 500, }, { model: gpt-4o-mini, api_key: sk-xxx3, rpm: 300, }, ] router Router(model_listmodel_list) response router.completion( modelgpt-4o-mini, messages[{role: user, content: 请给我一份周报总结}] )这里有个很实用的细节同一个模型在列表里可以配置多个不同密钥Router 会视为多条通道自动分摊负载这样能有效规避单密钥的速率限制。rpm 字段用来声明每分钟最大请求数Router 在做分配时会把通道的剩余额度考虑进去避免把某个通道打满。故障转移也给了几种策略。最常见的是配置 fallback_models当主模型调用失败时自动尝试备用模型response router.completion( modelgpt-4o-mini, messages[{role: user, content: 生成一段产品描述}], fallback_models[claude-3-5-haiku, gpt-3.5-turbo] )一旦主通道抛出异常或超时Router 会立刻把请求转向下一个模型。背后有重试机制和退避策略默认情况下会对限流错误和网络抖动做指数退避重试避免连续故障造成二次雪崩。从我自己的工程实践看故障转移不是万能的不是配了就永不报错。像字段级映射不兼容这种问题并不会触发路由切换因为网关认为请求成功了。真正需要结合的效果是在网关层做好通道健康监测在应用层保留兜底逻辑双层保险才稳妥。2.3 预算、速率限制和成本追踪模型网关一旦面向团队开放成本和配额就是绕不开的问题。litellm 提供了以预算为中心的可观测体系既能设定键级配额也能按用户或项目维度限制甚至可以在总预算耗尽时自动掐断服务。比较常见的基础需要是三个第一限制某个项目的月度总花费第二限制某个用户每分钟调用次数第三追踪每个模型实际花了多少钱。litellm 内置了计费映射表能自动根据模型、输入输出 token 数换算成本不需要自己维护价格表。代理模式下这些能力可以直接通过接口暴露出来。比如设置预算上限并配置回调通知当预算使用率超过某个阈值时发告警这对有一定规模的团队很有价值。很多团队用了大模型后成本完全不可见月底对账才发现某条业务线烧掉了过多预算这类问题如果从一开始就在网关层做了预算管控是完全可以避免的。2.4 嵌入模式与代理模式litellm 有两种使用方式需要先分清。嵌入模式就是前面演示的方式在自己的 Python 进程里直接 importAPI请求直接发出不做额外的本地服务。这种方式适合个人项目、脚本、以及本身就在 Python 环境里跑的自动化流程。代理模式则是在本地或服务器上跑一个独立的服务进程所有请求都发到这个服务上由它转发到真实模型厂商。代理模式有几个明显优点第一调用方可以是任何语言只需支持 HTTP 和 OpenAI 兼容接口第二密钥和配置集中在网关一侧不会散落在各个客户端第三可以在网关层统一做鉴权、限流、成本控制不用每个调用方各自实现。我怎么选这两种方式呢如果是个人脚本、临时测试嵌入模式最方便如果是多个成员协作开发、产品要上线强烈建议直接上代理模式。后期加个新模型只需要在网关配置里加一条记录客户端一行代码也不用改。想自建API网关服务的团队其实用这个低代码就能跑起来。3. 快速部署从零搭建一个自托管 LLM 网关3.1 环境准备和安装litellm 要求 Python 3.8 以上建议直接用 Python 3.11 或更高版本后面跑各种依赖更省心。安装方式很常规直接通过 pippip install litellm[proxy]如果安装时卡在一些编译步骤上多半是当前环境缺少构建依赖换个干净的 Python 环境一般能解决。也可以再用 docker 方式运行官方镜像已经打包好了环境docker run \ -p 4000:4000 \ -v $(pwd)/litellm_config.yaml:/app/config.yaml \ ghcr.io/berriai/litellm:main-latest \ --config /app/config.yaml --port 4000在本地环境验证安装是否成功python -c import litellm; print(litellm.version)能看到版本号就说明装好了。接着要准备至少一家模型厂商的 API 密钥最常见的做法是把密钥放到环境变量里litellm 会自动读取标准方式命名的环境变量比如某一家的密钥键一般以 OPENAI_API_KEY 形式命名。3.2 配置 API 密钥与环境变量在项目目录下创建一个 .env 文件把各家密钥统一管理起来OPENAI_API_KEYsk-your-openai-key ANTHROPIC_API_KEYsk-your-anthropic-key AZURE_API_KEYyour-azure-key AZURE_API_BASEhttps://your-resource.openai.azure.com AZURE_API_VERSION2024-02-15-preview启动代理服务时加一个参数让它自动加载 .env 文件litellm --model gpt-3.5-turbo --port 4000这样跑起来之后本地 4000 端口就多了一个 OpenAI 风格接口可用模型是 gpt-3.5-turbo。不过单个模型的代理配置很简单实际生产环境我们会用 YAML 配置多个模型一次配齐。创建一个配置文件比如 litellm_config.yamlmodel_list: - model_name: gpt-3.5-turbo litellm_params: model: gpt-3.5-turbo api_key: os.environ/OPENAI_API_KEY - model_name: claude-3-5-sonnet litellm_params: model: claude-3-5-sonnet api_key: os.environ/ANTHROPIC_API_KEY用这份配置启动litellm --config /path/to/litellm_config.yaml --port 4000需要留意的是model_name 是暴露给外部调用方使用的别名可以随意定义而 litellm_params 里的 model 才是真正发往厂商的模型标识不能乱填要写厂商那边实际存在的模型名。3.3 客户端库调用代理起来了验证一下是否正常工作。最简单的方式是用 OpenAI SDK 指向本地服务from openai import OpenAI client OpenAI( api_key任意字符串, base_urlhttp://localhost:4000 ) response client.chat.completions.create( modelgpt-3.5-turbo, messages[ {role: user, content: 用一句话解释什么是递归} ] ) print(response.choices[0].message.content)这里 api_key 填什么都行因为 litellm 默认在无网关密钥配置时不做强制校验。如果团队内部使用建议开启虚拟密钥功能把真实厂商密钥隐藏在网关后面调用方只拿一个分配的子密钥这样既能审计用量又能及时吊销某个客户端的访问权。代理模式的透明程度很高原本直连厂商的代码唯一的变化就是把 base_url 改成网关地址其他完全不变。3.4 代理服务器模式不走 SDK直接往 HTTP 接口发请求也能用。curl 测试一下curl --request POST \ --url http://localhost:4000/v1/chat/completions \ --header Authorization: Bearer sk-1234 \ --header Content-Type: application/json \ --data { model: gpt-3.5-turbo, messages: [ {role: system, content: 你是一个耐心的老师}, {role: user, content: 请解释一下什么是大语言模型} ] }返回结果和 OpenAI 官方结构一致。这套接口兼容性意味着任何能调 OpenAI 接口的程序都可以通过改 base_url 切换到自己的网关。代理模式还有个很有价值的用途给传统应用接入AI能力时你不需要去改造那些已经写好的逻辑只需在配置层面把请求转发到新地址旧代码就像没改过一样照常运行。4. 高级配置实测多供应商回退、流式输出和成本控制4.1 配置多供应商回退策略把回退策略做进网关是我认为值得优先落地的能力之一。线上业务最怕模型提供商故障导致服务不可用而回退功能就是一道保险丝。在代理配置里可以这样声明一个分组model_list: - model_name: primary-model litellm_params: model: gpt-4o api_key: os.environ/OPENAI_API_KEY - model_name: fallback-model litellm_params: model: claude-3-5-sonnet api_key: os.environ/ANTHROPIC_API_KEY router_settings: fallbacks: [ {primary-model: [fallback-model]} ]这段配置的意思很明确当 primary-model 触发异常、限流或超时时自动把请求转发给 fallback-model。我在实际生产中经历过一次某个模型通道持续超时的情况当时主模型通道因为上游服务波动一直返回错误回退机制立刻接管客户端无感切换整体业务没有中断。这种体验确实让人安心不少。回退并不等同于零延迟切换过程需要重新发起请求会有额外消耗所以回退模型最好选择能力相近但通道独立的服务避免回退后性能明显下降。4.2 流式输出和函数调用的注意点大模型应用里流式输出几乎成了标配聊天场景要一个字一个字地往外蹦才能有“在思考”的体验。litellm 对流式响应的处理非常直接支持透传流式内容无论底层是哪家模型调用方都按 OpenAI 的流式格式接收。response client.chat.completions.create( modelgpt-3.5-turbo, messages[{role: user, content: 写一首关于大海的诗}], streamTrue ) for chunk in response: delta chunk.choices[0].delta.content if delta: print(delta, end, flushTrue)流式模式下要注意的一个坑是有些模型不支持某些参数比如有的模型不支持 logprobs或对 max_tokens 有上限约束。网关做参数透传时不会拦截这类参数实际请求就会报错。建议在配置层面对不同模型做参数映射或裁剪把明显不兼容的字段提前过滤掉。函数调用方面OpenAI格式的 tools 声明能被正确传递给支持工具调用的模型但不同模型对工具描述的解析效果有差异需要针对目标模型微调提示词和参数格式。这样在网关层做一次适配客户端只需要跟OpenAI格式保持对齐。4.3 集成 LangChain 这类编排框架如果你平时用 LangChain 这类流程编排框架litellm 的适配也很平滑。很多框架本身就支持通过自定义 base_url 接入兼容接口或者在 Python 上直接改用它的客户端类。我这里举个简单例子通过 LangChain 的 ChatOpenAI 指定 base_url 来接入网关from langchain_openai import ChatOpenAI llm ChatOpenAI( modelgpt-3.5-turbo, openai_api_keyany, base_urlhttp://localhost:4000 ) response llm.invoke(请用三句话介绍你自己) print(response.content)把网关作为统一出口之后编排层的代码不再关心底层模型来源只关心逻辑和提示词整个架构的分工更清爽。团队里有人想做模型评估也可以直接用网关对比多个模型的效果数据收集和成本统计天然集中在一个层面。4.4 预算、速率限制和异常处理在一个真实的多项目环境中预算控制需要非常具体的策略。litellm 允许按 key 或者按用户设置预算。例如给A团队分配一个月度20美元的子密钥当这个密钥累计消耗超过阈值后续请求就会被拒绝。这个能力在代理模式里会有独立的管理接口可以通过调用管理API来创建子密钥、设置限额、查看消耗明细。注意子密钥和上游厂商密钥不同子密钥是网关自己生成的用来管理调用方身份和厂商那边无关。速率限制同样可以在网关层做。对每个子密钥设置最大并发请求数或每分钟请求数能有效防止某个调用方把网关占满。这里的关键是速率限制尽量在客户端也做一层网关的限制只能兜底不能完全依赖。合理设置预算和速率限额能让网关在实际运行中处于比较健康的状态避免个别调用方出现突发超量请求影响整体服务。5. 避坑手册我实际踩过的几个错误5.1 模型名称映射不一致去查文档里提到的 aliases 功能。这个功能用来给模型起别名但比别名更重要的是理解真实模型名的映射关系。我遇到过一个情况某模型的接入点在 OpenAI 兼容模式下要求模型名带特定前缀如果不加服务端直接返回404错误。后来我通过配置层把模型名补齐了客户端不感知问题就解决了。在配置里给同一模型映射两个不同入口时也要小心。比如想同时用同一个厂商的基础版和增强版映射名称不能含糊不然容易把一个请求路由到不期望的那个版本上。5.2 密钥权限过大我在内测阶段图省事给所有客户端都用同一个子密钥。后来排查一个异常消耗时才发现某条测试脚本写了个死循环疯狂请求因为共享密钥没有细颗粒度限制直接烧掉了大笔费用。从那以后我严格要求每个调用方甚至在细分功能维度都使用独立子密钥单独设限异常波动一眼就能锁定是谁的问题。5.3 自定义接口和本地模型好多人只用 litellm 接云厂商其实它还支持接入本地或自建的推理服务。比如企业内部部署了一些开源的模型只要暴露兼容接口就能配置进去。配置方式是在 litellm_params 里指定 api_basemodel_list: - model_name: local-llama litellm_params: model: openai/llama-3.1-8b-instruct api_base: http://127.0.0.1:8000/v1 api_key: not-needed这里 model 前缀用了 openai/ 表示走 OpenAI 兼容协议调用本地接口。理解这个机制后可以把云厂商和本地服务统一纳入一套路由体系按价格或优先级灵活调度。很多数据敏感场景会保留本地模型通道先用本地方案快速响应不满足时再路由到外部高能力模型。这类自定义接入点最容易出的问题是参数兼容性。本地服务通常只实现了部分标准参数遇到不支持的参数会被忽略甚至报错。遇到这种问题就优先精简参数集把无关字段过滤掉再做透传。5.4 日志、监控与性能平衡网关在团队内部成为流量中枢之后使用进口数据很大默认日志可能不够用。litellm 支持对接多种可观测性工具比如 Prometheus 指标、Langfuse 追踪等把成本、延迟、错误率这些关键指标打到统一面板上。但我一开始把所有请求的内容都打了全量日志导致存储暴涨后续查询也很慢。后来调整策略只记录请求元数据比如模型名、token数、耗时、成功与否全量内容只针对重点链路保留一段时间。这个平衡点要根据自己的排查需求和存储成本来摸索。最后再分享一个小技巧如果你打算长期维护一个模型网关我建议从第一天就把配置和密钥分离管理。密钥放在环境变量或密钥管理服务里配置放在代码仓库中跟随版本管理。这样每次调整模型通道都像发一次代码变更可回溯、可评审不会变成“谁在服务器上手动改了下配置”之类的悬案。litellm 是一个我很看好的项目因为它在复杂的大模型生态里提供了一个足够简单又足够灵活的中间层。从个人脚本到团队基础设施它都能发挥作用。至少在我这边接入统一网关之后“换个模型试试”终于变成了一件很轻量的小事。

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

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

免费获取报价 →
↑