资讯详情

资讯详情

litellm:统一多模型API的LLM网关实践与部署指南

做后端一年多了从最早接各种大模型 API 一个个写 SDK 封装到后来维护一套又一套接口代理我算是被这类“重复造轮子”的活折磨过不少次。如果你最近也在折腾 LLM 应用大概率听过一个叫litellm的名字。这东西最早是作为“把所有模型 API 转换成 OpenAI 格式”的工具被大家认识的后来越用越深才发现它根本就是一个完整的 LLM 网关统一鉴权、负载均衡、成本追踪、重试兜底全都能干。这篇文章就围绕 litellm 这个项目把我实际部署和二次开发中积累的经验、踩过的坑、常用配置一并拆开讲清楚。内容适用对象是正在做 AI 应用开发、需要同时接多家模型服务比如 OpenAI、Anthropic、Azure OpenAI、Google Gemini、各种国产模型和开源模型的开发者也适合刚入门想搞清楚“团队里到底该怎么统一管理大模型 API”的人。文章会覆盖它能做什么、设计上有哪些巧思、真实场景下的部署配置以及我在实际使用中遇到的问题排查记录。1. litellm 到底是干什么的一个偏向“网关”而不是“SDK”的定位1.1 先说清楚它和普通 SDK 封装的区别很多人在第一次接触 litellm 的时候最直观的印象是“它能用一套 OpenAI 风格的接口调用所有模型”。这话没错但它绝不是一个简单的 SDK。你可以把它理解为所有 SDK 调用的中间层。传统的做法是你为要用的每个模型服务商单独拉一个 SDK每家 SDK 有各自的初始化方式、超时设置、重试机制和异常类型。项目刚起步还好等模型方一多维护成本立刻上来。更麻烦的是如果线上某个模型服务超时了或者一个供应商被调用频率太高触发限流你只能自己写一堆异常分支来判断“这个错误是从哪家返回的”。litellm 把这个中间层抽出来之后你的代码只管对接它它内部再去适配各家模型服务商的协议。你的上游业务拿到的是统一格式的响应对象、统一格式的异常这样下游任何模型变了你只需要改配置而不用改业务代码。我实际维护过的项目里最早接了三家模型服务SDK 版本、异步模式、stream 参数格式都不一样。用 litellm 之后所有调用统一走一个 4000 端口业务侧只认识 OpenAI 风格的 request 和 response。后面再加模型我只需要往配置里加一段 provider 描述不需要重新发版这一步体验是非常直接的。1.2 为什么选择“OpenAI 格式”作为统一标准litellm 对外暴露的接口长得很像 OpenAI 官方接口比如 /v1/chat/completions、/v1/embeddings、/v1/completions。这不是偷懒而是刻意为之。因为 OpenAI 格式已经事实性地成为大模型调用领域的“普通话”——大量开源项目、框架比如各种 AI Agent 项目、函数调用类项目都默认用 OpenAI 格式来对接模型。这么设计有几个直接好处第一团队接入成本极低。新同事只要写过 OpenAI 接口就能直接写 litellm 的代码不用额外学一套奇怪的调用方式。第二生态兼容性好。很多现成工具比如支持自定义 OpenAI API base 的客户端、监控面板、测试脚本都能直接指向 litellm不需要做任何适配。第三迁移成本可控。以后如果你自研了一个完全兼容 OpenAI 的模型服务你甚至可以绕过 litellm代码都不用改。我遇到过一些团队想用国产模型但开发文档和 OpenAI 不一致调起来想骂人。用 litellm 之后它负责把国产模型的请求参数翻译成 OpenAI 风格业务开发的人根本感知不到差异。1.3 它和“模型聚合平台”之间的边界感这里要有清晰的认知litellm 不是模型聚合平台它不负责训练模型也不内置任何模型。它本质上是帮你把流量管理起来的那一层。模型聚合平台关心的是模型选择界面、定价方案、用户配额litellm 关心的是 API 格式转换、密钥管理、路由转发、成本统计、限流熔断。它解决的问题发生在“你的业务代码”与“模型服务商 API”之间。一个比较容易混淆的点是有些团队会直接把 litellm 当作生产环境的“网关”在它前面再挂一层业务 API。也有人把它嵌入到内部工具里作为 sidecar。两种用法我都试过。前者适合团队规模大、多个后端服务都要共用模型能力的场景后者适合单体项目但不想把代理单独部署的场景。明白这个边界之后你对它的定位和使用方式就会比较清晰。2. 核心功能逐一拆解从接口代理到成本治理2.1 统一接口转换多模型接入协议适配litellm 支持几十家模型提供商包括 OpenAI、Anthropic、Azure OpenAI、Google Gemini、AWS Bedrock、各种国产闭源模型以及通过 Ollama、vLLM、TGI 之类的自托管开源模型。它怎么做到统一格式转换的在内部它维护了一个模型映射表把每个 model 名称比如gpt-4o、claude-3-5-sonnet和对应的 provider、请求参数模板、响应解析器绑定起来。你请求的时候它先根据 model 名判断要走哪条线路然后把 OpenAI 风格的请求体改写为目标 provider 需要的格式再转发出去。响应回来之后再改写回 OpenAI 风格。这里有一个在项目里容易忽略的细节不是所有模型都能完整映射 OpenAI 格式的全部字段。比如有的模型不支持frequency_penalty有的对max_tokens的命名不一样有的是max_tokens、有的叫max_tokens_to_sample。litellm 的做法是在配置里允许你指定自定义映射也可以选择丢弃不支持的参数。这个功能如果你只是简单调用默认模型基本感知不到但一旦你要接入一个比较小众的自部署模型必须搞清楚这一层。我在实操中曾经接一个自托管模型它的参数里没有max_tokens只有max_new_tokens然后处理方式是写了一段自定义配置把这个参数映射过去才把调用调通。2.2 密钥管理与多 Key 负载均衡最关键的生产功能团队用一个账号的 key 开发结果被限流这是非常常见的生产事故。litellm 提供了秘钥管理机制主要解决两件事一是虚拟 API Key。你可以在 litellm 里生成自己的 key把它发给团队内部的不同人、不同项目或不同服务这些 key 背后可以绑定真实的 provider key也可以配置各自的预算。也就是说真实 provider key 被安全地放在 litellm 后端不暴露给终端用户最多只暴露一个虚拟 key 给调用方。万一这个虚拟 key 泄露了你直接在管理端吊销它一条命令的事。二是多 Key 轮询负载均衡。同一个模型比如gpt-4o你可以配置多个真实 keylitellm 会在请求进来时按照策略轮换使用。默认是简单的轮询也支持根据剩余额度、响应延迟、失败次数自动选择。这个功能的实用性在于你可以把多个账号的额度聚合起来支撑更大的并发而不会被单个账号的速率限制卡死。我上过生产环境的一个项目最初只用了单个账号结果每小时都被限流后来在 litellm 里挂了四个 key 做轮询问题直接消失。2.3 Token 计量、成本追踪与预算控制litellm 对每次调用都会记录 token 消耗。它不仅是记录输入输出 token还会根据你配置的模型单价自动计算成本。你在管理后台甚至能看到每个虚拟 key、每个用户、每个团队每天/每月的用量曲线和花费金额。预算控制这块可以给虚拟 key 设置以下几种限制每分钟最大请求数RPM每分钟最大 token 数TPM单日/单月最大成本美元或者其他币种最大并发数超过限制之后litellm 默认返回 429 限流错误你可以自定义错误提示。从工程角度看token 统计和成本追踪特别适合用在“多租户/多部门”的场景。我给公司内部搭过一个统一入口不同部门用不同虚拟 key 接入月底直接导出成本报表省掉了原来一群人手工统计 Excel 的麻烦。2.4 模型重试、超时与熔断生产高可用的关键模型服务商时不时会出问题网络波动、5xx、限流、响应变慢。litellm 内置了多层次的错误处理。请求失败自动重试可配置重试次数和重试间隔。支持自定义重试策略比如某个模型持续 429自动切换到一个备选模型。内置超时控制避免一个慢模型拖垮整个业务链路。支持异常熔断连续失败超过阈值后自动将流量切到健康实例。这里想特别说明 “模型回退fallback” 的价值。你配置了gpt-4o和claude-3-5-sonnet两个模型作为主备当 litellm 检测到主模型连续报错它会自动把请求转发给备选模型对业务方完全透明。整个过程你的业务代码只需要感知到“这次请求成功了”而不必知道背后发生了什么。这类能力属于典型的“网关职责”如果靠业务代码自行实现一是每处调用都要写一套复杂容错逻辑二是很容易遗漏异常类型。交给 litellm 之后我只在配置里写清楚策略剩下的全部交给网关层。2.5 流式响应与工具调用Function Calling的支持很多人在评估 litellm 的时候会担心“我的场景要流式输出还要用 function calling它能 hold 住吗”我的实测结论是都能。流式输出这块litellm 不仅只是转发流它还会把流内容重新组装成 OpenAI 的 SSE 格式。你在业务侧可以像接 OpenAI 的流式响应一样处理。Function calling 同样支持。你需要把 tools 定义透传给模型litellm 会原样转发给目标 provider并在响应里把 tool call 的结果转回统一格式。我在实际项目中用 litellm 做 Agent 场景让模型调用内部查询接口响应里拿到标准结构化 tool call 数据整体稳定。不过有一点要注意不同模型对 function calling 的支持程度差异极大。有的模型格式遵循 OpenAI 标准有的偏差很大。litellm 能做的是尽力转换但如果底层模型本身不支持函数调用那无论网关怎么转换都无能为力。3. 部署 litellm 的完整实操安装、起步配置与调用演示3.1 环境准备本地跑通最小实例litellm 用 Python 编写发布在 PyPI 上安装非常简单。官方推荐 Python 3.8 以上。本地快速体验的流程如下# 使用 pip 安装 pip install litellm[proxy] # 或者通过 docker 运行生产环境更推荐 docker run -d \ --name litellm-proxy \ -p 4000:4000 \ -v $(pwd)/config.yaml:/app/config.yaml \ ghcr.io/berriai/litellm:main-latest \ --config /app/config.yaml安装完可以通过命令行快速验证litellm --model gpt-4o --port 4000这条命令会在 4000 端口启动一个最小代理走默认配置。这时候你本地就可以用任何 OpenAI SDK 来调用它curl http://localhost:4000/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-xxx \ -d { model: gpt-4o, messages: [{role: user, content: 你好}], stream: false }也就是说你在本地只需要一条命令就拥有了一个 OpenAI 兼容的 API 入口。3.2 配置文件编写从单模型走到多模型本地验证没问题之后下一步就是正式写 config.yaml。这个文件是整个网关的“智商核心”它决定 litellm 如何路由、如何鉴权、如何限流。下面是一个典型的生产配置示例model_list: - model_name: gpt-4o litellm_params: model: gpt-4o api_key: os.environ/OPENAI_API_KEY model_info: supports_function_calling: true - model_name: claude-3-5-sonnet litellm_params: model: anthropic/claude-3-5-sonnet api_key: os.environ/ANTHROPIC_API_KEY - model_name: azure-gpt-4o litellm_params: model: azure/gpt-4o api_base: https://xxx.openai.azure.com/ api_key: os.environ/AZURE_OPENAI_API_KEY router_settings: routing_strategy: usage-based # 可选 simple-shuffle / usage-based / latency-based num_retries: 3 request_timeout: 60 fallbacks: [ {gpt-4o: [claude-3-5-sonnet]}, {azure-gpt-4o: [gpt-4o]} ] litellm_settings: drop_params: true set_verbose: false general_settings: master_key: sk-master-123 database_url: postgresql://user:passlocalhost:5432/litellm几个关键点解释一下。model_name是暴露给客户的模型名litellm_params.model是实际发给 provider 的底层名。两者解耦之后你完全可以在业务里叫它gpt-4o后端实际走的却是经过企业内部网关的 Azure OpenAI 通道。这在企业里很有用处业务侧不用感知底层供应商的切换。fallbacks配置会按照顺序找备选模型主模型连续报错时自动切换。router_settings.request_timeout是每个请求的超时上限。不要太短流式场景下模型首字返回时间可能较长也不要太长否则一个慢模型会拖满线程池。drop_params设为 true 表示当某个请求带了目标 provider 不支持的参数时直接丢弃而不是报错。这个开关务必打开否则你可能在调用某个不支持response_format参数的小众模型时直接遇到 400。3.3 用 Python SDK 和 OpenAI SDK 分别调用 litellmlitellm 自带一个 Python 客户端同时也兼容 OpenAI SDK。两者我都跑通过这里都给出示例。方式一直接用 litellm 的 Python 包import litellm response litellm.completion( modelgpt-4o, messages[{role: user, content: 你好请介绍一下自己}], api_basehttp://localhost:4000, api_keysk-xxx ) print(response.choices[0].message.content)方式二用 OpenAI SDK 指向 litellmfrom openai import OpenAI client OpenAI( base_urlhttp://localhost:4000/v1, api_keysk-xxx ) resp client.chat.completions.create( modelgpt-4o, messages[{role: user, content: 你好}] ) print(resp.choices[0].message.content)两种方式中我实际更推荐第二种因为业务团队通常已经在用 OpenAI SDK 了改成 litellm 的 base_url 成本是最低的。流式调用同样兼容stream client.chat.completions.create( modelgpt-4o, messages[{role: user, content: 讲个故事}], streamTrue ) for chunk in stream: if chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end)3.4 虚拟 Key 与成本预算的配置流程生产环境里强烈建议开启数据库和虚拟 key 功能。round-robin 注册的步骤如下首次启动 litellm 之前在 config.yaml 里配置master_key和database_url。master key 是管理员的最高权限密钥database_url 用来持久化存储 key、用户、日志、预算等数据。启动后通过管理 API 创建虚拟 keycurl http://localhost:4000/key/generate \ -H Content-Type: application/json \ -H Authorization: Bearer sk-master-123 \ -d { models: [gpt-4o, claude-3-5-sonnet], max_budget: 20.0, budget_duration: 1mo, rpm_limit: 60, tpm_limit: 100000 }返回结果里会给你一个sk-xxx格式的虚拟 key。这个虚拟 key 就是你可以发给团队、发给测试环境、或者嵌入到不同项目里的凭证。max_budget和budget_duration组合使用就实现了“这个 key 一个月最多用 20 美元”。rpm_limit和tpm_limit则是分钟级别的速率控制。这块尤其适合做事后成本分摊每个部门一个 key月底在 litellm 后台按 key 导出用量和费用直接财务对账。4. 实战经验我在生产环境里遇到的典型问题与排查方法4.1 问题一模型参数不一致导致的 400 或空响应在接一个开源模型的时候我遇到了响应空内容的情况。排查发现是因为请求参数里带上了response_format而这个模型没有实现该参数直接忽略了导致返回结果非常奇怪。这类问题常常发生在你从 GPT 切换到一个非 OpenAI 系模型时。修改方案是开启drop_params: true或者针对该模型在配置里自定义参数过滤。从那以后我把所有模型的配置文件里都加上了drop_params遇到参数不支持时宁可丢弃也不要带错。4.2 问题二流式响应在某些模型上速度极慢我排查过一个现象同样网络环境调用 gpt-4o 流式响应很快换成某个自部署模型后首字延迟高达十几秒。分析 litellm 的日志发现请求在网关层等待了很久才收到目标服务的响应最后定位到是自部署服务本身首 token 生成慢不是网关问题。这里给个经验遇到流式慢的问题先看目标 provider 的直接响应时间而不是一开始就怀疑 litellm 转发有问题。网络层、模型推理层、网关转发层三个环节依次排查。4.3 问题三不同虚拟 Key 资源互相抢占多个团队共用同一个 litellm 实例时如果一个团队发起了大量请求另一个团队的关键业务可能被影响。litellm 提供了 per-key RPM/TPM 限制我后来给不同关键业务配置了独立的虚拟 key并对每个 key 单独限流保证任何一个团队的突发流量都不会影响其他人。如果你的团队里既有实时交互型业务又有离线批处理任务强烈建议把离线任务和实时业务放到不同 key、不同模型甚至不同网络出入口上避免流量“内耗”。4.4 问题四认证信息泄露与轮换生产环境里虚拟 key 泄露是迟早的事。litellm 的管理后台提供了 key 生命周期管理能力。你可以定期执行以下操作定期遍历所有虚拟 key 的最近使用时间对不再使用的 key 进行吊销对疑似泄露的 key 快速吊销并生成新 key。这里有一个需要注意的操作轮换 key 的时候最好在业务低峰期做否则可能出现大部分请求瞬间报 401 的情况。我采用的方式是先停旧 key 对应服务的定时任务再切换新 key再逐步观察。4.5 常用运维命令速查下面整理一批我经常用到的运维命令# 查看已注册模型列表 curl http://localhost:4000/v1/models \ -H Authorization: Bearer sk-master-123 # 查看某个 key 的用量 curl http://localhost:4000/key/info \ -H Authorization: Bearer sk-master-123 \ -d {key: sk-xxx} # 生成新 key curl http://localhost:4000/key/generate \ -H Authorization: Bearer sk-master-123 \ -d {models: [gpt-4o], max_budget: 50} # 删除 key curl http://localhost:4000/key/delete \ -H Authorization: Bearer sk-master-123 \ -d {key: sk-xxx}管理后台还可以直接看实时的日志、用量和错误分布。我个人建议把 litellm 的管理后台访问控制在一个内网网段不要暴露到公网除非你配置了足够严格的认证。5. 进阶使用多路由策略与自定义扩展5.1 路由策略怎么选litellm 支持多种路由策略配置在 router_settings 的 routing_strategy 里。simple-shuffle在所有健康 key/模型间均匀轮询适合多个 key 能力对等的场景。usage-based优先选择剩余 token 配额最多的 key适合账号配额不同、希望“先用掉不心疼的额度”的场景。latency-based追踪历史延迟自动优先选择延迟最低的模型实例适合对响应速度敏感的业务。举例来说你手里有一个账号配额还剩 99%另一个账号只剩 1%simple-shuffle 会让两个账号工作量差不多而使用次数计数会因为配额不平衡很快把剩下 1% 的账号打挂。usage-based 则会尽量让大额账号承担更多请求。这个参数没有绝对最优只有结合自己的业务流量特征去调。我倾向于对并发稳定、延迟优先的业务用 latency-based对成本敏感、多 key 预算不均的业务用 usage-based。5.2 自定义 provider 接入有一些模型服务商不在 litellm 官方支持列表里。此时可以通过litellm_params里的custom_llm_provider和api_base来适配。配置示意- model_name: my-custom-model litellm_params: model: openai/my-custom-model api_base: http://10.0.0.20:8000/v1 api_key: local-test custom_llm_provider: openai如果这个模型本身暴露的是 OpenAI 兼容接口绝大多数情况直接这么配置就可接入。如果目标服务的接口不是 OpenAI 格式那就只能写一段自定义代码利用 litellm 的 handler 机制做请求改写和响应解析。5.3 与企业内部系统的集成litellm 本身可以作为一个独立服务部署但如果企业内部有统一的 SSO 认证系统人人各自搞一套 key 是不现实的。litellm 支持自定义认证逻辑你可以通过编写一个 callable 来校验请求头比如从企业内部 SSO 解析用户身份再映射到对应的预算和模型权限。这个能力在生产环境中非常实用。我的做法是在 litellm 前挂一层企业内部认证网关网关负责 SSO 登录、用户身份识别再透传一个内部签名头让 litellm 信任。litellm 侧配置好虚拟 key把它当作内部服务级凭证而不是用户级凭证。业务上用户身份本身不接触 litellm 的任何一个 key只在业务系统内部流转。整体的安全边界很清晰。6. 避坑清单与个人的一点心得6.1 容易踩的坑不要在生产环境直接用默认内存存储跑多实例。litellm 默认支持 SQLite 等本地存储模式但多实例部署时状态不共享会导致 key 校验、用量统计各节点不一致。生产环境老老实实接 PostgreSQL。不要把 master key 当成普通请求 key 使用。它的权限非常大如果泄露整个代理链路的 key 管理都会失控。我一般把 master key 放到专门的密钥管理服务里只在自动化脚本和管理后台中使用。不要忽略模型名称前缀。比如anthropic/claude-3-5-sonnet和claude-3-5-sonnet可能映射到不同的 provider 行为。配置的时候最好显式写出 provider 前缀避免 litellm 猜错。不要在重试逻辑里开启无限重试。如果某个模型已经整体故障无限重试只会让 litellm 的线程池被占满进而拖垮所有请求。给重试加上次数上限和熔断阈值。不要把所有后端直接指向一个 litellm 实例而不做高可用。litellm 本身是无状态代理你完全可以部署两个实例前面挂一层负载均衡数据库共享同一份 Postgres。6.2 关于扩展方向litellm 的生态一直在长。除了最基本的请求代理社区里还有人在做基于它扩展企业内部的模型评测平台、把 litellm 接入现有的可观测性系统比如 Prometheus 指标导出等。从我个人的视角看更值得关注的是它把模型调用层的通用能力沉淀下来让应用开发真正聚焦在业务逻辑上。你在自己的项目里后续也可以按自己的业务形态在它上面扩展属于自己的审计、配额、审批流。就我个人而言用了一段时间之后我对“网关”这个词的理解比之前深了不少。真正的网关并不是多一层请求转发而是把所有的横向能力认证、限流、成本、高可用、可观测集成到一个地方让下游业务变得干净、可控。litellm 在这个方向做得非常扎实。如果你正在建设自己的 AI 应用基础设施强烈建议拿它做一次小范围试点先把两三个模型接进去跑通然后逐步叠加虚拟 key、预算、路由策略。最后说一个小细节接入 litellm 之后一定要把日志级别打开它会清晰打印每一跳的耗时、请求参数、响应码。生产环境出现诡异问题的时候这些日志往往比任何监控面板都更能帮你定位原因。先把日志看明白再去怀疑网络和模型大概率能少走很多弯路。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →