资讯动态

LiteLLM:统一大模型API接入的网关实践与避坑指南

发布时间:2026/10/13 11:31:37 来源:尧图企业网站定制
做后端的人大概都有过这种经历产品经理跑过来说“这次要同时接三家大模型哪个合适用哪个”于是你翻开各家文档发现每个 SDK 长得完全不一样。有的给 Python 封装了一套专门客户端有的只给 REST 接口有的流式返回字段都不一样更别提错误码五花八门。我在做模拟项目X的时候曾经硬写过一层适配器把三家 API 包装成统一接口光联调就折腾了两天后面每次厂商更新版本还要跟进改。后来换成 LiteLLM这一摊子事基本就被收编了。LiteLLM 是一个开源的大模型网关项目核心作用是把 100 多家大模型厂商的 API 统一成一套接口默认兼容 OpenAI 的调用格式。你后端代码只需要写一套逻辑就能同时调用不同厂商的模型模型切换、密钥管理、成本统计、故障回退这些事它都帮你做完了。今天这篇就从什么场景该用它、怎么快速跑通、到生产环境怎么配置把我实际操作过程中总结的东西一次讲清楚。如果你正在被多模型接入、密钥分散、费用对不上这些问题困扰这篇文章应该能帮你省下不少时间。1. LiteLLM 是什么先搞清楚它到底在解决什么问题1.1 多模型接入的混乱现场先还原一下最常见的痛点。比如你要在系统里同时用上两家以上的大模型一家擅长长文本理解一家代码能力更强还有一家价格便宜适合量大。普通做法是对接每一家的 SDK每个 SDK 有自己初始化方式、自己的一套参数命名、自己的鉴权逻辑。例如OpenAI 兼容风格的客户端通常长这样client OpenAI(api_keysk-xxx) client.chat.completions.create(modelgpt-4o, messages...)换另一家的模型SDK 可能长这样client AnotherSDK(api_keyanother-xxx) client.messages.create(modelclaude-3-5-sonnet, messages...)参数不一样还是小事真正麻烦的是异常处理。A 家限流返回这种结构B 家超时返回那种结构C 家直接给你挂掉不返回任何东西。你要为每个厂商写一遍超时重试、错误解析、日志记录。等到月底对账的时候各家计费口径还不一样有的按 token 计费有的按次数计费有的给的是预估费用你需要自己把账单拉出来再手动算一遍。这套逻辑自己写不是不行问题是维护成本会持续增加。今天这个模型下线了明天那个模型出了新版本后天产品说要动态切换模型。每改一次你都要动那层适配代码。1.2 统一接口到底统一了什么LiteLLM 做的事情很简单它就是那层“万能插座”。它把各家厂商的 API 全部翻译成你熟悉的 OpenAI 请求格式底层再各自转换成对应厂商真正需要的协议。举个例子。你在业务代码里这样写from openai import OpenAI client OpenAI( base_urlhttp://localhost:4000, api_keysk-虚拟key ) resp client.chat.completions.create( modelclaude-sonnet, messages[{role: user, content: 你好}] )这里有个关键点你请求的是本地的一个 LiteLLM 代理model 字段写的是“claude-sonnet”而代理在背后帮你把这次调用转换成了对应模型厂商的协议然后厂商的真实结果再原样返回给你。你的业务代码完全感知不到模型厂商的差异。除了统一请求格式LiteLLM 还统一了下面这几层鉴权层每个厂商的 API Key 集中管理在服务端不散落在业务代码和前端。调用方只需要拿一把内部虚拟 Key。费用统计层代理解析了每次请求消耗的 token 数并按照内置的价格表换算成金额哪个用户哪个项目花了多少钱一目了然。路由层主模型失败可以自动切换到备用模型多个 Key 做负载均衡防止单个 Key 被限流。兼容层不仅 OpenAI 格式LiteLLM 还兼容 Anthropic 的 Messages 格式等方便你按原有习惯接入。1.3 什么场景适合用、什么场景别硬上我说下我的判断标准。如果你只是写个个人脚本固定调用某一家的一个模型那 LiteLLM 对你来说确实多余直接用厂商 SDK 更轻快。但一旦出现下面任一情况LiteLLM 的价值就上来了产品里需要同时接入多个模型且随时可能切换。多个人或多团队都需要调用模型但你不想把真实厂商 Key 发给每个人。需要对每次调用做成本统计、用量审计。某个模型偶尔不稳定你想在它挂掉时自动切到备用模型。需要限制某些用户或应用的调用频率和预算上限。反过来如果你有极度定制化的需求比如要改写底层协议的某个细节或者完全离线部署不和任何外部 API 通信那 LiteLLM 的通用模型可能不适合你自己写适配层反而更可控。2. 五分钟上手跑通第一个请求2.1 安装与环境准备LiteLLM 分为两种用法一种是作为 Python SDK 直接内嵌在你的程序里另一种是作为独立的代理服务部署所有请求都打到它上面。两种底层是同一套东西但场景不同。先安装。如果你只需要 SDKpip install litellm如果你要用到代理功能建议直接装带扩展依赖的版本pip install litellm[proxy]装好以后把你手上各家模型的 API Key 设置成环境变量。LiteLLM 的约定是直接读环境变量名字也基本不需要刻意记常用的是这些export OPENAI_API_KEYsk-你的key export ANTHROPIC_API_KEYsk-ant-你的key export GEMINI_API_KEYAIza你的key export AZURE_API_KEY你的azurekey如果你的某个 Key 不在环境变量里也可以临时指定。不过我最建议的做法是放在.env文件里管理LiteLLM 支持加载.env文件这样不会把 Key 写死在代码里。2.2 用 Python SDK 完成第一次调用装好依赖、配好环境变量之后最简单的跑通方式是这样的import litellm response litellm.completion( modelanthropic/claude-3-5-sonnet-20241022, messages[ {role: user, content: 请用一句话介绍你自己} ] ) print(response.choices[0].message.content)这里有个必须理解的约定model参数里的“anthropic/”前缀不是装饰而是告诉 LiteLLM 应该走哪家厂商的适配逻辑。“/”前面是厂商标识后面才是真正的模型名。常见的厂商前缀是这些前缀对应的模型服务openai/OpenAI 官方模型anthropic/Anthropic 的 Claude 系列gemini/Google Gemini 系列azure/Azure 上托管的 OpenAI 兼容模型bedrock/AWS Bedrock 托管的模型ollama/本地 Ollama 部署的开源模型第一次跑通之后你会发现返回的response对象结构和 OpenAI 官方 SDK 基本一模一样包括choices、usage这些字段。换个厂商的模型你只需要改 model 字符串后面的代码一个字都不用动。2.3 通过 OpenAI SDK 直接调 LiteLLMSDK 内嵌模式适合你自己的程序用。但如果你的程序已经是多个团队在维护或者有多个服务都要接模型与其在每个服务里都装 litellm不如起一个代理服务所有服务通过 HTTP 访问统一入口而入口的接口格式就是 OpenAI 兼容风格。先启动代理litellm --model openai/gpt-4o --port 4000启动后你的代码就可以用 OpenAI 官方客户端去访问它from openai import OpenAI client OpenAI( base_urlhttp://localhost:4000, api_keysk-任意值 ) resp client.chat.completions.create( modelgpt-4o, messages[{role: user, content: 你好}] ) print(resp.choices[0].message.content)注意到没有这里连litellm都没 import只是把base_url指到了本地的代理。这种做法的好处是业务代码和模型厂商彻底解耦了。将来你把代理后面的模型换成别的厂商业务代码一行都不用改。2.4 环境变量和配置管理习惯我见过不少人在代码里硬编码 API Key结果 Commit 上去之后 Key 泄漏只能去厂商后台重新生成。这个习惯一定要改。用 LiteLLM 之后更推荐的做法是真实厂商 Key 只放在服务端环境变量或.env中。调用方使用 LiteLLM 生成的虚拟 Key权限和额度都由你控制。不要把真实 Key 拼到前端请求里前端那边只需要 Base URL 和虚拟 Key。关于虚拟 Key 怎么生成我在下一节展开讲这是 LiteLLM 相比你手动写适配层最有价值的部分之一。3. Proxy 模式实操把模型服务做成公司内部网关3.1 一份最小 config.yaml 拆解LiteLLM 代理服务真正的常用姿势是用config.yaml配置文件来定义模型列表、路由策略、缓存参数等。直接命令行指定单个模型只适合测试。这里是一份最基础的配置model_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY - model_name: claude-sonnet litellm_params: model: anthropic/claude-3-5-sonnet-20241022 api_key: os.environ/ANTHROPIC_API_KEY - model_name: gemini-pro litellm_params: model: gemini/gemini-1.5-pro api_key: os.environ/GEMINI_API_KEY注意这里有两层model概念。第一层model_name是你对外暴露的逻辑模型名给调用方看的比如业务方只要记住“gpt-4o”这个名字。第二层litellm_params.model才是真正传给 LiteLLM 的完整模型标识。这种设计非常巧妙。比如厂商明天把模型改名了你只需要更新litellm_params里的真实模型名对外model_name保持不变。所有调用方无感知你也不用半夜通知各团队改代码。3.2 启动代理并用 curl 验证配置写好后启动代理litellm --config config.yaml --port 4000启动时如果没配置LITELLM_MASTER_KEYLiteLLM 会在控制台输出一把主密钥之后管理端操作都要用它。更规范的做法是启动前设置export LITELLM_MASTER_KEYsk-master-123456验证服务是否正常最直接的方式是 curl 打一发curl -X POST http://localhost:4000/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-master-123456 \ -d { model: claude-sonnet, messages: [{role: user, content: 你好介绍一下自己}] }如果返回正常的 OpenAI 风格响应说明代理已经能把 Anthropic 的模型调用转换成 OpenAI 格式给你了。到这一步你已经拥有了一个私有模型网关的雏形。3.3 虚拟密钥给每个成员发一把受限的钥匙这是我最喜欢的功能。在真实项目中你不可能把厂商 Key 分给每个后端同事或前端应用既不安全也没法统计谁用了多少。用虚拟 Key 之后流程是这样的先在代理上创建一把 Key指定它能调哪些模型、最多花多少钱、一分钟允许多少次请求。然后把这把 Key 发给调用方。生成虚拟 Key 用管理 APIcurl -X POST http://localhost:4000/key/generate \ -H Authorization: Bearer sk-master-123456 \ -H Content-Type: application/json \ -d { models: [gpt-4o, claude-sonnet], max_budget: 10, rpm: 60, tpm: 100000 }参数含义很直接models这把 Key 允许调用哪些模型。不在列表里的直接拒绝。max_budget总预算上限单位是美元。到顶之后这把 Key 自动失效防止有人把账单刷爆。rpm每分钟最大请求数限流用。tpm每分钟最大 token 数。这个尤其重要防止某个调用方一次塞超长文本把厂商配额打满。返回结果里会包含一把新的api_key类似sk-abc123...。你把密钥字符串发给对应的同事或应用就行真实厂商 Key 永远不会出现在他们面前。我给团队分 Key 的经验是每个成员一把 Key每个应用单独一把 Key甚至每个测试环境单独一把 Key。这样出了问题比如某个应用流量异常直接吊销对应的那一把 Key 即可不影响其他人在用。3.4 预算和速率限制怎么配预算和限流除了在生成 Key 时指定也可以做成全局配置。比如你希望代理默认对所有调用生效一个限流策略可以在config.yaml里加litellm_settings: max_budget: 100 budget_duration: 30d rpm_limit: 120 tpm_limit: 200000这里的budget_duration: 30d表示每 30 天为一个周期周期内整体预算 100 美元。周期结束后自动重置。限流设置则是所有调用共享的额度避免某个应用突发流量把整个代理拖垮。有一个细节值得注意限流是代理这边的软限制它更多是保护你的成本和下游厂商配额。如果你的业务方确实需要更高的并发你应该在配置层面做负载均衡而不是单纯把单 Key 的限流调大。3.5 每次调用花了多少钱成本追踪费用统计这块我要多说两句因为大多数自研网关都忽略了这件事或者只记录了 token 总数没有算成金额。LiteLLM 内置了各大厂商主流模型的价格表代理每次请求之后会读取响应里的 token 用量按模型单价折算成美元金额再落到数据库里。你可以通过管理 API 查询curl http://localhost:4000/spend/logs \ -H Authorization: Bearer sk-master-123456返回内容包含每次调用的模型、token 数量、估算费用、调用时间、密钥标识等字段。代理还启动了一个管理界面默认路径是/ui你在浏览器打开能看到按 Key 分组的消费列表、预算剩余、请求量曲线。Token 费用的计算逻辑是费用 prompt_tokens × 输入单价/每百万token completion_tokens × 输出单价/每百万token不同厂商的输入和输出单价是不同的甚至同一个厂商不同模型价格也不同。LiteLLM 的价格表默认内置了这些数据。如果你用的是私有模型或者自定义价格也可以在配置里指定model_list: - model_name: my-local-model litellm_params: model: ollama/llama3 model_info: input_cost_per_token: 0.0000001 output_cost_per_token: 0.0000002有了这个基础月底对账就不是痛点。直接导出 spend logs按应用或者按团队一汇总每个项目的模型成本清清楚楚。4. 路由回退和负载均衡单点故障不慌4.1 fallback 配置示例真实投入生产之后你一定遇到过这类事情主用的模型服务端抽风或者单个 Key 触发了限流业务方的请求直接报错。如果没有容灾机制研发就得半夜爬起来改配置切模型。LiteLLM 的回退可以解决这个问题。比如希望 gpt-4o 失败时自动切到 claude-sonnet再不行就切给 gpt-4o-minimodel_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY - model_name: claude-sonnet litellm_params: model: anthropic/claude-3-5-sonnet-20241022 api_key: os.environ/ANTHROPIC_API_KEY - model_name: gpt-4o-mini litellm_params: model: openai/gpt-4o-mini api_key: os.environ/OPENAI_API_KEY router_settings: fallbacks: - model_name: gpt-4o fallbacks: [claude-sonnet, gpt-4o-mini] num_retries: 2 timeout: 30这段配置的含义是调用方请求的模型是gpt-4o代理先尝试真正执行它。如果失败就按顺序尝试claude-sonnet再不行尝试gpt-4o-mini。num_retries: 2指的是同一个模型最多重试两次确认连续失败才切下一个。timeout是单次请求的超时时间超过 30 秒视为失败。回退的价值不只是防故障。比如某段时间某个模型因为活动导致响应变慢回退机制会自动把流量导到备用模型用户侧感知到的就是偶尔变慢但始终可用而不是直接报错。4.2 Router 的方式如果你不是在用代理而是想把路由逻辑集成到自己的 Python 服务里LiteLLM 提供了Router类用法类似。from litellm import Router model_list [ { model_name: gpt-4o, litellm_params: { model: openai/gpt-4o, api_key: ... } }, { model_name: claude-sonnet, litellm_params: { model: anthropic/claude-3-5-sonnet-20241022, api_key: ... } } ] router Router(model_listmodel_list, num_retries2, timeout30) response router.completion( modelgpt-4o, messages[{role: user, content: 你好}] )Router 和代理底层共用一套路由逻辑。如果你的服务已经是一个比较重的后端应用不想再拆一个独立代理进程直接在应用里初始化一个 Router 是很自然的选择。它会把模型列表管理、回退、重试都封装好。4.3 配置策略的心得回退不是配置得越多越好。我建议回退链不要超过三个模型。太长的话第一个模型挂了之后请求会连续变慢用户体验反而更差因为每一个失败模型都要先等超时再切下一个。另外我习惯给主模型和备用模型设置不同的超时时间。主模型给长一点比如 60 秒让它有充足时间生成。备用模型的超时设置短一点比如 20 秒因为备用链路本来就是应急用的与其让它慢慢处理不如快速失败再切更优的模型。这个策略在路由配置里可以通过timeout加在单模型参数上实现。5. 避坑清单这些坑我基本都踩过5.1 模型名写错调用全乱这是新手最容易掉进去的坑。LiteLLM 中模型名有“完整名”和“逻辑名”两套。直接通过 SDK 调用时model 参数要写完整名比如anthropic/claude-3-5-sonnet-20241022少个前缀或者少了版本号都可能报错。通过代理调用时model 参数要用逻辑名也就是你在model_list里配置的model_name比如gpt-4o。我就见过有人代理都配好了还在请求里写openai/gpt-4o结果代理去解析的时候发现找不到这个逻辑模型报了一个奇怪的 404。排查了很久才发现多写了一个openai/前缀。这里的逻辑不难理解代理已经帮你做过一层转译了你传的就是内部约定的名字不应该再把厂商前缀带进来。5.2 密钥管理要重视虚拟 Key 功能很强大但主密钥一定要保管好。主密钥相当于代理的总管理权限能生成 Key能看所有消费记录也能删除配置。一旦泄漏别人可以直接创建一把不限预算的 Key 去刷你的费用。我的建议是主密钥不要出现在任何业务代码和前端请求里只放在部署环境的变量中。创建虚拟 Key 的时候遵循最小权限原则。某个应用只需要调一个模型就只给它配一个模型。定期通过/key/info接口审查一下现有 Key 的使用情况把长期不用的 Key 吊销掉。还有一个容易忽略的细节如果你用 Docker 部署代理环境变量不要直接写在 Dockerfile 里。用部署平台的安全变量功能或者在运行时挂载.env尽量别把密钥留到镜像层。5.3 超时、限流和重试各家模型的响应速度差异非常大同一个模型在不同时段的表现也不一样。如果你按照最快那家的标准设置全局超时那慢速模型很容易被误杀成失败触发一堆不必要的重试和回退浪费额度还增加延迟。我建议针对不同模型设置不同超时。在代理配置里这样写model_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY timeout: 60 - model_name: gpt-4o-mini litellm_params: model: openai/gpt-4o-mini api_key: os.environ/OPENAI_API_KEY timeout: 15不同模型对量级也不一样所以遇到 429 限流不一定是真出问题了而是厂商在保护自己的服务。重试策略要带退避LiteLLM 默认有重试退避逻辑同时你也可以用allowed_fails参数调低节点连续失败的敏感度。5.4 缓存和长上下文有时候你被同一个问题反复问很多遍比如客服系统里用户问“你们物流多久到”答案基本就是那几句。每次重复调用模型既费钱又慢。LiteLLM 支持缓存可以在配置里开启litellm_settings: cache: true cache_params: type: redis host: localhost port: 6379开启之后遇到完全相同的请求代理直接从缓存返回结果不走模型厂商。这个对成本优化非常明显。但要注意缓存开启后业务方可能拿到历史结果敏感场景要注意是否介意数据被短暂缓存必要时可以为特定请求关闭缓存。长上下文是另一个头疼点。模型输入有窗口上限你可以传 12 万 token 的文本进去但输出可能被max_tokens限制。遇到长文本处理我一般建议先做切分或摘要再分段调用模型。不要试图靠调大 max_tokens 一把梭模型输出太长后质量会下降费用也会翻倍增长。6. 生产环境中还可以怎么扩展6.1 用 PostgreSQL 做持久化默认情况下LiteLLM 的虚拟 Key 和消费记录是存在本地 SQLite 里的。单机测试没问题但多副本部署时每个副本数据不一致某个副本上创建的 Key 到另一个副本上可能查不到。生产环境建议接一个 PostgreSQL。配置很简单启动时指定数据库地址export LITELLM_DATABASE_URLpostgresql://user:passwordhost:5432/litellm接上数据库之后多个代理实例共享同一份密钥、配置和消费记录。这样前面架一层负载均衡后面挂多个 LiteLLM 副本就是一个比较可靠的生产架构了。6.2 接入本地模型和自定义 OpenAI 兼容服务很多公司也有私有化部署的需求想把开源模型跑在内网。LiteLLM 支持接入本地 Ollama 服务配置例子model_list: - model_name: llama3-local litellm_params: model: ollama/llama3 api_base: http://localhost:11434 - model_name: internal-compatible litellm_params: model: openai/custom-model api_base: http://internal-api:8080/v1 api_key: sk-internal-key第二个例子很实用如果你内部已经有一套 OpenAI 兼容格式的服务比如用其他框架自建的模型服务你完全可以把它的api_base填进来模型名用openai/前缀加自定义名称。这样所有走 LiteLLM 的请求包括回退、日志、计费都对这个内部服务一视同仁。把开源模型和商业模型放在同一套路由体系里切模型只是改配置的事情。6.3 费用分摊与对账最后说说费用分摊这件事。多人共用一个代理如果不做区分月底账单下来根本不知道哪个项目占了多少钱。LiteLLM 支持在请求里透传用户信息你可以让调用方在请求 body 里带上user字段比如{ model: gpt-4o, user: project-name:order-ai, messages: [...] }这样/spend/logs里就能按用户维度筛选。你也可以在生成虚拟 Key 的时候规划命名比如每个项目固定一把 Key按 Key 汇总消费即可。我的建议是从第一天就让调用方规范传 user 字段哪怕只传一个项目代号。因为历史数据一多回填补录会非常痛苦。这个字段不传系统也不会报错但你要知道先定义好规范永远比事后补救便宜。最后再分享一个实操小技巧不管你是用代理还是 SDK都建议先写一个简单的冒烟测试脚本覆盖主模型调用、回退切换、虚拟 Key 限流这三条路径。脚本留着每次升级 LiteLLM 版本或者改配置后跑一遍能避免很多低级回归问题。这个东西我靠它在模拟项目X里避免过至少两次配置改动引发的线上事故。

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

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

免费获取报价 →
↑