资讯动态

litellm实战:统一大模型API与网关部署全解析

发布时间:2026/10/13 21:30:19 来源:尧图企业网站定制
1. 多家大模型API来回切换的痛苦才是litellm真正的用武之地过去一年我先后在几个项目里接入了不同的大模型服务商。说实话最让人头疼的不是模型效果本身而是API的调用方式五花八门。有的用messages数组传对话历史有的用input字段有的返回choices[0].message.content有的返回completions[0].text流式输出的格式更是各家有各家的规矩。每换一家供应商就要重写一遍调用层再写一堆适配代码心情极其烦躁。后来我注意到GitHub上这个叫litellm的开源项目star数涨得很快。它的思路很直接把市面上主流大模型供应商的API格式全部统一成OpenAI的格式这样上层业务只需要维护一套调用代码底层想换哪家就换哪家。简单说litellm做的事情有三层统一调用接口用OpenAI的Python SDK或Node SDK去调Anthropic、Gemini、Cohere、Bedrock、Azure OpenAI等几十家服务商的模型。代理服务器模式本地起一个兼容OpenAI接口的网关服务所有请求打到这个网关由它负责转发到真正的模型供应商。工程化配套能力包括成本追踪、限流、重试、负载均衡、多key管理、预算控制等相当于把生产环境调用大模型的脏活累活一并解决了。如果你只是写个脚本调一次模型litellm确实帮不上什么大忙——直接装个原生SDK更省事。但如果你要在真实项目里接入多个模型、要切换供应商、要控制成本、要处理限流和重试litellm几乎是把这些事打包成了一个标准答案。这篇文章我想从原理到部署再到我实际用下来的踩坑记录完整聊一遍。2. litellm的工作原理一个翻译层加一个网关2.1 它本质上做的是协议转换要理解litellm我建议先抛开“框架”“平台”这些大词抓住一个核心它是个API翻译层。各家模型服务商的请求格式、响应格式、鉴权方式、错误码都不一样。litellm在中间做了一层映射把OpenAI格式的请求翻译成目标服务商的要求再把目标服务商的响应翻译回OpenAI格式。你拿到手里的永远是OpenAI风格的response[choices][0][message][content]。我用一个非常生活化的类比litellm像个同声传译。你和他说中文他去跟说英语、法语、日语的人交流回来再用中文告诉你结果。你不需要学英语、法语和日语只需要会说中文。这种设计的直接好处是业务代码的稳定性提高了。供应商A的SDK升级了、废弃了某个参数、改了返回字段只要litellm跟上适配你的业务代码一行都不用动。2.2 两种使用方式SDK直连和代理网关litellm提供两种接入方式对应不同的使用场景。第一种是SDK方式。from litellm import completion response completion( modelclaude-3-5-sonnet-20240620, messages[ {role: user, content: 用一句话解释什么是API网关} ] ) print(response[choices][0][message][content])你看completion函数和OpenAI的ChatCompletion.create几乎一模一样但model参数传的是Anthropic的模型名。litellm内部根据模型名路由到对应供应商自动处理鉴权和格式转换。这种方式适合在脚本、函数、后端服务里直接集成。第二种是代理网关模式。litellm --model gpt-4o --port 4000这条命令会在本地4000端口起一个OpenAI兼容的代理服务。然后你的代码里只需要把base_url指向http://localhost:4000from openai import OpenAI client OpenAI( api_keyanything_you_want, base_urlhttp://localhost:4000 ) response client.chat.completions.create( modelgpt-4o, messages[{role: user, content: 你好}] )注意这里用的是OpenAI官方SDK但实际请求会被litellm网关转发到配置好的模型供应商。网关模式的好处在于业务方拿到的就是一个标准的OpenAI兼容endpoint不管后端接的是哪家模型、接了几家模型、怎么做负载均衡业务方完全无感知。生产环境我建议用网关模式。原因有三个业务代码完全和具体供应商解耦供应商切换只改网关配置。可以在网关层统一做限流、预算、日志、缓存代码只写一遍。多个服务共享同一个网关不用每个服务各自管理API key。2.3 支持几百家供应商背后的路由逻辑litellm支持几百家供应商靠的是一个命名约定模型名的前缀即供应商。比如gpt-4o是OpenAIclaude-3-5-sonnet-20240620是Anthropicgemini-1.5-pro是Googlebedrock/claude-3-haiku是AWS Bedrockollama/llama3.1是本地Ollama。litellm解析模型名里的provider/前缀来匹配路由规则。这个设计有个好处是心智负担小。你不需要额外传一个provider参数模型名里自带了。bedrock/前缀的意思是模型本身是claude-3-haiku但走的是Bedrock的通道。生产中如果不确定模型名前缀怎么写直接做一次空的completion调用报错信息里通常会列出目前支持的供应商列表和正确的模型名格式。3. 从零部署一个litellm代理网关环境准备、配置管理与API key体系3.1 安装与最小化启动litellm是纯Python项目安装很简单pip install litellm装完先验证一下litellm --help看到版本号之后可以先用最简单的方式起一个代理litellm --model gpt-4o --port 4000如果环境变量里配了OPENAI_API_KEY这个代理就能直接转发请求。测试一下curl http://localhost:4000/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer test-key \ -d { model: gpt-4o, messages: [{role: user, content: 你好}] }返回的JSON结构和OpenAI官方接口一致。到这里一个最小可用的代理网关已经跑起来了。3.2 config.yaml才是生产环境的正确玩法直接用命令行参数起服务适合测试生产环境必须用配置文件。litellm的配置文件是YAML格式逻辑很简单定义哪些模型可以被访问以及每个模型走哪个供应商、用什么key。model_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY - model_name: claude-3-5-sonnet litellm_params: model: anthropic/claude-3-5-sonnet-20240620 api_key: os.environ/ANTHROPIC_API_KEY - model_name: llama-3-70b litellm_params: model: ollama/llama3.1:70b api_base: http://localhost:11434用这个配置启动litellm --config config.yaml --port 4000这里model_name是暴露给使用方的模型别名litellm_params里的model才是真实的供应商模型名。这样设计的价值在于你可以在不通知业务方的情况下把model_name: gpt-4o背后从OpenAI换成Azure OpenAI甚至换成某个自部署的开源模型。3.3 API key体系主key与虚拟key的隔离网关本身也需要鉴权不然谁拿到端口都能白嫖你的模型额度。litellm提供虚拟key机制相当于在真实供应商API key前面再加一层。设置管理员keyexport LITELLM_MASTER_KEYsk-1234 litellm --config config.yaml --port 4000 --master_key sk-1234然后可以通过管理接口创建只能访问特定模型的虚拟keycurl http://localhost:4000/key/generate \ -H Authorization: Bearer sk-1234 \ -H Content-Type: application/json \ -d { models: [gpt-4o], max_budget: 10.0 }返回的key就是你发给业务方使用的虚拟key。这个key只能调用gpt-4o且总预算10美金。这样即便key泄漏了损失也限制在10美金以内。生产环境中我强烈建议为每个业务线单独生成虚拟key配上独立的预算和限流阈值。出了任何费用问题看key就能定位到是哪个业务、哪个服务、哪个时间段冒的尖。4. 接入实战统一SDK、流式输出、多供应商切换与成本追踪4.1 SDK接入的具体写法网关跑起来之后业务侧接入是很舒服的。Python侧用OpenAI SDKfrom openai import OpenAI client OpenAI( api_keysk-virtual-key-xxx, base_urlhttp://localhost:4000 ) def chat(prompt: str) - str: resp client.chat.completions.create( modelclaude-3-5-sonnet, messages[{role: user, content: prompt}], temperature0.7 ) return resp.choices[0].message.contentNode.js侧也一样import OpenAI from openai; const client new OpenAI({ apiKey: sk-virtual-key-xxx, baseURL: http://localhost:4000, }); const resp await client.chat.completions.create({ model: gpt-4o, messages: [{ role: user, content: 你好 }], }); console.log(resp.choices[0].message.content);只要团队里约定好base_url和虚拟key所有服务都按OpenAI的标准写。以后模型从Claude换成GPT代码里改一个model参数字符串就完事。4.2 流式输出的坑大模型应用几乎离不开流式输出。litellm对OpenAI格式的流式透传做得不错但有几个细节必须留意。Python侧流式调用stream client.chat.completions.create( modelgpt-4o, messages[{role: user, content: 写一篇800字的短文}], streamTrue ) for chunk in stream: if chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end)Node侧也类似用for await遍历。第一个容易踩的坑是litellm某些模式下流式响应里第一个chunk可能带role字段但没有content如果你的解析逻辑只处理choices[0].delta.content没问题但如果你习惯性读choices[0].delta整体判断要注意做空值保护。第二个坑是finish_reason的兼容性。不同供应商对流结束的标记有细微差别litellm虽然统一成了OpenAI格式但个别供应商在你stop之后还会多推一个空chunk。这需要你自己做幂等处理。4.3 切换模型供应商的完整示例假设业务里原本用GPT-4o现在想部分流量切到Anthropic的Claude测试效果。整个过程只动配置不改代码。先在config.yaml里加上Claude的模型model_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY - model_name: claude-3-5-sonnet litellm_params: model: anthropic/claude-3-5-sonnet-20240620 api_key: os.environ/ANTHROPIC_API_KEY重启网关业务方调用时把model参数从gpt-4o换成claude-3-5-sonnet完事。如果你想做灰度还可以利用litellm的负载均衡让同一模型名随机路由到多个后端供应商。这个后面展开讲。4.4 成本追踪不看报表的成本控制都是空谈litellm内置了一套成本追踪机制可以自动按模型、按key、按天、按用户维度记录token消耗和费用。它维护了一个模型价格表大部分主流模型的价格已经内置了不需要手动配置。查看网关运行统计curl http://localhost:4000/spend/logs \ -H Authorization: Bearer sk-1234还可以按月看总花费curl http://localhost:4000/spend?start_date2025-01-01end_date2025-12-31 \ -H Authorization: Bearer sk-1234如果接入了Prometheuslitellm也暴露了/metrics端点token用量、请求延迟、错误率这些指标都能直接抓。我自己习惯在Grafana里配一个按小时聚合的token消耗面板——大模型项目的成本失控从来不是某一天突然爆的而是每天涨一点你没注意月底一看傻眼。5. 生产环境必须考虑的工程化配置负载均衡、重试、限流与预算5.1 多key负载均衡当你单个模型的调用量上来了一个API key可能触发供应商限流。litellm允许给同一个模型配多个API key轮询使用。model_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY_2注意写法同一个model_name配了两条每条对应一个keylitellm收到gpt-4o请求后在两个key之间做轮询。这种配置在开源模型自托管场景下更有意思——你可以把同一模型部署在多台机器上通过api_base指到不同实例litellm帮你做流量分发。5.2 重试策略与退避大模型接口偶尔会返回5xx或者429限流。litellm在litellm_params里支持重试配置model_list: - model_name: llama-3-70b litellm_params: model: ollama/llama3.1:70b api_base: http://192.168.1.10:11434 num_retries: 3 retry_after: 5 fallbacks: [gpt-4o]这里num_retries是重试次数retry_after是重试间隔秒数。fallbacks更有意思——如果这个本地模型挂了自动降级到gpt-4o。这个机制对稳定性要求高的服务来说价值极大。有一点需要提醒重试要配合幂等设计。如果你的请求里有非幂等操作比如让模型生成之后直接扣费重试可能造成重复扣费或重复业务动作。这种情况建议在业务侧做请求ID去重而不是完全依赖网关层重试。5.3 限流与预算控制litellm的限流配置在key层面curl http://localhost:4000/key/generate \ -H Authorization: Bearer sk-1234 \ -H Content-Type: application/json \ -d { models: [gpt-4o], max_budget: 50.0, rpm_limit: 100, tpm_limit: 50000 }rpm_limit是每分钟请求数tpm_limit是每分钟token数。配置后超过阈值的请求会被网关拒绝并返回429。这套机制能够防止单个调用方因为代码bug疯狂循环调用把整个项目的成本拉爆。5.4 生产部署systemd与Docker真实服务不可能用一个前台进程挂着。我建议用Docker起网关docker run -d \ --name litellm-gateway \ -p 4000:4000 \ -v $(pwd)/config.yaml:/app/config.yaml \ -e LITELLM_MASTER_KEYsk-1234 \ ghcr.io/berriai/litellm:main-latest \ --config /app/config.yaml多个供应商的API key通过-e传进去config.yaml里用os.environ/XXX引用。这样key不会写死在文件里也方便在CI/CD里做密钥管理。内存方面要特别留意。litellm会为每个请求分配一些临时数据高并发场景下内存上涨比较明显建议给容器至少512MB内存并且做内存上限限制。6. 实测中的高频问题与排查思路6.1 请求超时的定位与调整前几天一个服务反馈说流式输出经常卡住。我去看litellm日志发现一个现象请求转发到了后端后端也正常返回了但客户端过了很久才收到第一个token。问题出在litellm的timeout配置上。默认的超时时间对某些供应商来说偏长导致在超时未触发时看起来像卡死。解法是显式配置response client.chat.completions.create( modelgpt-4o, messages[{role: user, content: 你好}], timeout30 )网关侧也可以通过环境变量调整export LITELLM_REQUEST_TIMEOUT30还有一次是上游供应商自身响应慢网关已经在等但客户端那边read timeout设置了5秒。两边超时时间不匹配会造成客户端先放弃、网关还在等上游的情况。建议客户端读超时设得比网关整体超时略长链路里就统一了。6.2 模型名解析失败又一个高频问题提示模型不存在。litellm.exceptions.BadRequestError: litellm.provider_not_found: provider not found这种基本就是模型前缀写错了。litellm能自动识别的是带正确供应商前缀的模型名比如anthropic/claude-3-5-sonnet-20240620。如果你直接写claude-3-5-sonnet-20240620它可能识别不了。注意在litellm的config.yaml里除非你配了model_name作为别名否则真实模型名必须带供应商前缀。排查这类问题最快的办法是把报错信息完整贴出来看它提示的provider not found指的是哪个字段。如果确认模型名没问题就检查环境变量里对应的key是否设置了很多provider not found其实是API key not found的连带报错。6.3 前后端不一致流式模式下finish_reason的坑我在做某个聊天应用时发现部分响应结束后客户端没有收到finish_reason为stop的chunk导致前端一直显示生成中。逐个对比了多家供应商的原始流式输出后发现Anthropic的流式响应里message_stop事件的形态和OpenAI的格式差异较大。litellm虽然做了映射但个别版本里对stream_options: {include_usage: true}的支持不够完整。如果你用了这个参数建议确认litellm版本是否支持不支持就升级。6.4 日志排查的实用技巧litellm的日志默认是打到标准输出的能看到每一次请求的目标模型、供应商、耗时和token数。排查问题时我一般直接过滤关键字journalctl -u litellm.service | grep modelmodel后面跟着的就是实际路由到的模型和供应商。如果发现路由结果和预期不一致问题多半出在config.yaml里model_list的匹配逻辑上。还可以用debug模式看更详细的内部请求litellm --config config.yaml --port 4000 --detailed_debug这个模式下日志里会打印litellm发送给上游供应商的完整请求体方便确认请求在翻译层有没有被改坏。7. 总结一些我实际用下来的体会这套方案在我们这里稳定跑了快一年我最大的感受是litellm解决的不只是API格式统一的问题它把大模型接入从每换一家供应商就要重新适配一次变成了改配置、重启、验证三个动作。这个改变对团队效率的提升是很直观的——原来开发侧要专门留一个同学维护各种SDK适配层现在这些工作被吸收掉了大家可以把精力放到业务逻辑上。两件我觉得值得注意的事第一不要一上来就全量迁移。litellm的很多高级功能比如负载均衡、预算控制、多key轮询需要一定的理解成本。建议先让一个团队用一个模型跑通链路确认稳定和收益之后再推广。第二关注版本迭代。litellm迭代速度极快三天一个小版本、两周一个大版本很常见。升级前一定要先看changelog特别是涉及路由规则和配置格式的变更。我这边就遇到过升级后旧配置兼容性出问题的情况好在都有备份回滚很快。有人可能会说我直接写个适配层不就完了何必引入一个框架如果只接两三家供应商自己写适配层确实够用。但当你后面要接的模型越来越多、要处理的问题从格式转换上升到成本、限流、预算、灰度、可观测性这些工程问题时自己写的适配层会变得越来越重。这时候litellm这种社区活跃、更新频繁、踩坑人多的方案反而更省事。以上就是我个人在litellm上从了解到落地使用的完整经历。如果你们团队也在纠结多模型接入怎么搞希望这篇能帮上忙。

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

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

免费获取报价 →
↑