我们来做一次访谈要同时接好几家大模型的API都会头疼。不是模型效果的问题是这些东西实在太难伺候了。OpenAI那边的接口长一个样Claude长一个样各家国内的、海外的模型再长一个样参数名不同返回结构不同连报错格式都不带回重样的。再加上每个平台的Token计费方式也不同项目上线之后还得操心成本控制和额度分配。只要接了两家以上SDK版本冲突、参数格式互转、异常处理分支这些破事就会铺满整个开发排期。今天要聊的litellm当初就是为了干掉这些杂事而生的。litellm不是我瞎编的东西它是个已经在开发者社区里被大规模使用的开源项目。说人话就是它提供一套统一的调用格式帮你把所有主流的大模型API接入工作收拢到一个入口上。你可以通过一套代码随时在多个模型供应商之间来回切换不用改业务逻辑。它还带了一个代理网关模式可以把密钥管理、成本统计、请求限流、缓存这些都集中处理掉。这篇博文适合谁看适合那些准备搞AI应用、但已经被多模型接入折磨过的人。也适合团队里负责技术选型、需要给项目搭一个AI统一入口的人。我会把litellm的安装接入、核心使用方法、代理部署和注意事项全部讲清楚附上我自己实操时碰到的坑和排查方法希望能帮你少走点弯路。1. 这套方案到底解决了什么痛点1.1 多模型接入的混乱局面做AI应用开发越久越能体会什么叫“接口碎片化”。今天这个模型出了新版明天那个平台调整了限流策略后天又有新的模型厂商杀出来。每接一个新模型都要重新读文档、适配SDK、处理鉴权方式、调整请求参数。等接了三家以上你可能会面对这样一段代码顶层是根据不同平台写死的分支每个分支里有各自的参数构造逻辑和返回解析逻辑。真到了要替换供应商的那一天改动量巨大甚至需要重构。我见过不少团队为了解决“模型切换”问题自己封装了一层Adapter。这个做法本身没有错但问题是大模型API的格式差异太大了而且各家还在频繁变动自己维护一套Adapter的成本并不低。时间一长适配代码越堆越多越来越难维护。litellm的切入点就在这里。它把所有支持的大模型API都统一成了OpenAI风格的接口格式。当你调用时只需要用一套客户端、一套请求参数、一套错误码就能连接一百多家模型供应商。至于底层各家API的差异全都被它消化掉了。1.2 为什么是OpenAI格式作为统一标准你可以把litellm的接入方式想象成万能插座转换头。它兼容的“插头”是各家模型原生的API格式而它输出的标准接口选的是OpenAI的格式。这个选择不是随意的。OpenAI的接口结构在行业内已经事实性地成了“通用语”很多模型厂商在设计API时会主动对齐这个格式生态里的工具链、SDK也是最完整的。所以用litellm最大的好处之一就是你只需要熟悉一套API调用方式就能在那些格式完全不同的模型之间自由切换。有些模型API在细节上做不到完全兼容OpenAIlitellm还会在中间层做一些参数映射、字段转换尽量保证接口体验是统一的。1.3 一个死板的比喻和一些亲切的补充如果还是要给不太了解这块的朋友打个比方可以把它想象成外卖平台的聚合页。你平时下单并不需要分别记住每个饭店老板的电话和菜单风格只需要在外卖平台里搜索筛选然后统一完成结算。litellm就是这个聚合页它把各家模型的服务封装好你只需要面向它这一个入口来订餐。模型在平台里怎么换、后厨怎么做那是litellm的事。当然这个比喻只能帮你建立直觉具体到工程上它做的远不止格式转换。代理模式下litellm还承担了密钥管理、请求量统计、成本核算、缓存、LB、熔断等一堆生产环境的脏活累活。这些后边我会逐个展开聊。2. 快速跑通基础接入核心API操作详解2.1 安装与最小调用示例安装litellm很简单用pip直接装就行。不过需要提醒一句它的依赖项比较重建议在虚拟环境或者隔离环境里装不要直接把公司的生产环境当成试验场。pip install litellm装完之后写一个最简调用import litellm response litellm.completion( modelgpt-4o-mini, messages[ {role: user, content: 你好帮我用一句话介绍北京} ] ) print(response.choices[0].message.content)注意这里虽然写的是“gpt-4o-mini”但你完全可以让它调用Claude、Gemini、通义千问这些模型。只需要把model参数值改成对应的模型标识就行核心用法不变。如果你用的是OpenAI官方的key连环境变量名都不用改直接认OPENAI_API_KEY。其他平台的key比如ANTHROPIC_API_KEY、GEMINI_API_KEY、DASHSCOPE_API_KEY这些litellm也会自动去环境变量里找。如果某个平台需要额外的配置项——比如需要填接口地址base_url或者要使用代理——litellm也提供了对应的参数。一般常见格式是response litellm.completion( modelhosted_vllm/Qwen/Qwen2.5-7B-Instruct, api_basehttp://your-llm-server:8000/v1, api_keyyour-key, messages[{role: user, content: 你好}] )2.2 用起来最频繁的几个方法litellm的方法命名整体很顺如果你是靠肌肉记忆写代码的很容易上手。completion()是补全类的文本生成接口几乎所有对话模型都走这里。acompletion()是它的异步版本。如果你的应用里有大量并发的处理场景用异步版本会比较合适可以避免阻塞事件循环。embedding()用于生成向量想要做知识库检索的话会用得到。还有一个容易忽略的是model_list这个工具函数它可以直接列出当前支持的所有模型名称。我建议你把litellm.model_list打出来存到本地笔记里。这个列表的更新频率可能比你想的高过一阵子就会多出不少新模型。顺便多说一句litellm.completion里面还支持一个streamTrue参数。当你把stream打开时接口会以流式的方式返回生成结果。这个在搭建聊天类应用时几乎必用不然用户要干等好几秒才能看到完整回复体验会很生硬。2.3 模型别名与参数透传的妙用litellm支持给模型起别名这在切换模型时特别好用。你可以先在代码里定义一个假名字比如my-main-model然后在初始化配置里把它指向某个具体的模型。哪天想换模型时直接改配置不用动任何业务代码。litellm.model_alias_map { my-main-model: gpt-4o-mini } response litellm.completion( modelmy-main-model, messages[{role: user, content: 你好}] )这样一来业务代码里的模型名就彻底跟具体供应商解耦了。配合环境变量甚至远程配置来切换模型就能做到一套代码在各家模型之间丝滑切换。还有一个细节是参数透传。不同模型总有自己的一些特有参数比如有的模型支持top_p有的模型支持frequency_penalty有的模型还支持自定义的extra_body。litellm允许你把额外参数透传给底层API甚至可以通过litellm.modify_params这个钩子在请求发出前对参数做统一改写。3. 正经生产环境要用代理模式部署与配置3.1 为什么开发模式不够用直接pip装好、在代码里调用这种模式适合开发和本地调试。但它有几个让人头疼的问题首先是密钥分散。如果每个服务实例都要自己配置各家模型的API key那密钥管理就成了一团乱麻。其次是没法统一做成本统计和权限控制。再就是底层模型API如果出了限流或故障缺少一层统一的兜底处理。所以litellm提供了第二个模式代理服务器模式。你把litellm部署成一个独立服务所有内部业务都请求这个代理再由代理去请求各家模型API。代理端负责统一鉴权、转发、限流、记账业务端只需要把它当成一个普通的OpenAI服务来调用就行。3.2 快速启动一个代理实例启动代理之前先准备一个配置文件。下面是一个非常简化的版本model_list: - model_name: gpt-4o-mini litellm_params: model: gpt-4o-mini api_key: os.environ/OPENAI_API_KEY - model_name: claude-3-5-sonnet litellm_params: model: claude-3-5-sonnet-20240620 api_key: os.environ/ANTHROPIC_API_KEY然后跑起来litellm --config config.yaml --port 4000代理默认会监听4000端口。完成后业务侧代码不需要装litellm只需要把base_url指到这个代理地址就行了from openai import OpenAI client OpenAI( api_keysk-any-string, base_urlhttp://localhost:4000/v1 ) response client.chat.completions.create( modelgpt-4o-mini, messages[{role: user, content: 你好}] )是的就是这么简单。因为代理暴露出来的就是OpenAI兼容接口业务侧用任何语言的OpenAI SDK都能直接连上来。3.3 配置文件的进阶玩法上面的只是一个最小配置实际生产环境会考虑更多东西。假设你一个模型供应商想配置多个API key来做负载均衡比如同一个服务买了多个账号不希望单个key被限流打爆。可以通过api_key列表的方式配置多个keylitellm会轮流使用model_list: - model_name: gpt-4o litellm_params: model: gpt-4o api_key: - os.environ/KEY_ONE - os.environ/KEY_TWO还想限制单用户的请求频率可以在配置里加上rpm_limit和tpm_limit分别表示每分钟请求数和每分钟Token数限制。这个在给团队内部统一提供服务时是非常有用的成本控制手段。还有一个很实用的功能是按用户来记账。在代理模式里请求方调用时可以通过请求头带上自己团队的用户IDlitellm会把Token消耗按用户维度打点方便后续做成本分摊。这是很多公司在多部门共用一套模型服务时的刚需。3.4 接入自定义模型不是所有人都在用遥遥领先的大厂云服务。很多人其实在本地或公司内网里跑着开源模型用vLLM或TGI这类推理框架提供OpenAI兼容接口。这类模型litellm也能统一纳管配置方式跟前面说的hosted模型类似。model_list: - model_name: qwen2.5-7b litellm_params: model: openai/qwen2.5-7b-instruct api_base: http://localhost:8000/v1 api_key: dummy在这种场景下代理成了很好的“路由中转站”。外部业务只认得qwen2.5-7b这一个名字哪天你把这个名字映射到云端一个更大的模型业务侧无感知。4. 几个保命功能重试、熔断、缓存与预算控4.1 自动重试和错峰退避模型API偶尔抖一下是常态。你请求发出去可能遇到限流状态码也可能后端临时降级。这种情况下业务侧如果直接报错给用户是很不友好的。litellm对常见的几种限流状态码有内置处理。你可以在参数里配置重试次数和退避策略。比如litellm.num_retries 3 litellm.retry_after 5它的重试不是无脑原地重试而是会在遇到限流状态码时读取响应头里返回的Retry-After字段尽量按服务端建议的时间来等待。这样可以减少对底层API的冲击也能提高重试成功率。我实际用下来的感受是这个机制比自己手写重试要省心得多。4.2 缓存命中省掉真金白银如果你做的是一个问答类应用大概率会碰到大量重复问题——比如频繁出现的客服咨询、产品说明、配置指南。这些重复请求如果每次都真实调用付费模型成本会很失控。litellm的代理模式支持本地缓存和Redis缓存两种方式对完全相同的请求命中缓存后直接返回结果不再调用底层模型。Redis缓存的优势是可以多实例共享适合部署多个代理副本的生产环境。在代理配置里开缓存的方式general_settings: cache: true参数上还有更细的玩法比如litellm.cache True litellm.cache_params { ttl: 3600 }TTL可以按业务需求调整。有些信息实时性要求高缓存时间短一点有些知识库类答案几乎不变可以缓存个把小时甚至更久。4.3 预算控制和费用预警模型API的计费是不透明的黑盒如果应用用量突然暴涨钱烧起来是很恐怖的。litellm提供了一个相对轻量的成本追踪机制它对每次调用都会估算出Token消耗并按模型的实际单价换算成费用记录在日志中。代理模式里你可以给某个团队、某个用户设置预算上限。当额度耗尽之后litellm会拿捏该用户后续的请求而不是让账单一直溜下去。这个机制在给客户做对外服务、或者给公司内部多个部门提供模型调用通道时都属于刚需功能。具体的预算配置很简单general_settings: budget: 500这里的数字单位是美元。当然你也可以按用户维度去配置更细粒度的限制。我建议在正式对外开放之前就把这套预算控制配置好不然真的可能出现审计时才发现费用超支的情况。5. 实测踩过的坑与排查思路5.1 最大的坑模型标识写错这是新手最常碰见的问题没有之一。model参数并不是你随便写一个模型名字就能自动匹配的它内部有一套严格的名称映射规则。不同平台在litellm框架里的模型名称格式并不完全一样。比如同样一个开源模型在某个平台上叫Qwen/Qwen2.5-7B-Instruct在另一个推理框架里可能就叫qwen2.5-7b-instruct。复制粘贴文档里的模型名时一定要核对完整。否则litellm会抛出一个看起来像是网络问题的异常排查半天才发现其实是模型标识不匹配。我建议凡是报错先看一眼model参数。如果用的是代理模式配置里的model_name是代理对外的名字而litellm_params.model才是传给底层API的真实模型名。这两个别搞混。5.2 环境变量与密钥优先级环境变量加载不成功也是个高频问题。尤其在公司内部服务器上用systemd或容器部署时环境变量没有正确注入导致litellm一直报401认证失败。litellm读取API key的优先级是显式传参 环境变量 配置文件中的默认值。有时候你明明在配置文件里写了API key但代码里又传了别的空值就会出现相互覆盖的诡异情况。我建议在写代码和部署时只保留一条密钥注入路径不要同时在多个位置配置。别问我为什么这么说问就是被覆盖过。5.3 代理部署后经常遇到的CORS问题如果你在浏览器端直接调用litellm代理会遇到跨域问题。代理服务需要显式配置允许跨域请求general_settings: allowed_origins: - https://你的前端域名不配置这个浏览器控制台会报一句“跨域请求被阻止”很多人绕了一大圈才发现是这个原因。生产环境多实例部署时还有个很容易踩的坑Redis缓存必须提前配好否则每个实例各自持有一份缓存命中率上不去还会出现不同实例间缓存不一致的边界情况。5.4 流式请求的异常捕获滥用流式响应时你可能会踩到一个语义不明的坑在streamTrue模式下如果底层模型在生成中途断开连接litellm抛出的异常可能不会走常规的错误处理分支。这时我一般会在调用处额外捕获一次生成器迭代异常避免主流程被中断。经验总结下来在处理大规模并发情况下代理模式一定要打开timeout配置。很多底层API响应很慢尤其复杂模型生成长文时超过默认超时时间是常事。适当调高超时时间——比如120秒甚至180秒——能够减少很多没必要的重试。但注意不要把超时调到无穷大否则一旦底层服务挂掉你的代理会跟着卡死。6. 一个更好的工程化思路把它嵌入你的服务统一网关6.1 服务定位的再思考litellm可以当做一个开源工具来用也可以当做一个基础组件来设计。如果你所在的公司或团队正在做AI中台那它大概率可以承担“模型网关”这个角色。代理部署好之后所有模型服务都汇合到一个入口团队内部不需要关心底层是哪个供应商只需要关心调用什么模型、多少预算、能不能完成需求。在AI应用研发里这种“网关”思路的价值远大于给业务代码省几行适配逻辑。它不只是一个SDK而是一个管理平台的前身。你可以在代理的外围补充监控、告警、权限审批等内部系统把模型资源的运维集中管起来。6.2 围绕litellm搭一套简单的内部AI平台一个很朴素但有效的内部AI基础平台的架构可以是最底层是各家模型API和自建的模型推理服务中间是litellm代理负责统一接入、路由、限流、缓存和记账再往上是业务系统它们不直接对着各家模型API调而是只对接中间那层。这个架构的好处是切换模型不再需要业务部门提需求、排期、改代码。平台管理员改一下配置文件甚至调用管理接口就能完成全部切换。这种灵活度我实测下来非常值钱因为业务对模型的需求是经常在变的。今天想试新模型明天想降低某个场景成本只需要在网关层面调整。6.3 后续可以扩展的方向litellm本身支持的功能已经不少但如果你愿意还能进一步扩展。比如你可以定期把litellm记录的Token消耗数据导出来接到自己的报表系统里。比如你可以基于它的预算提醒回调喂给自己的告警系统一旦出现异常高消耗就自动发通知。再比如你要是对某些请求有审核需求也可以利用代理这一层做内容的二次校验在请求发给模型之前或之后塞进一道自定义逻辑。这些扩展听起来有点轻描淡写实际做起来也不复杂核心就是先有一个统一网关后续才能谈得上在网关上做治理。没有网关的项目这些功能全都得在各业务模块里重复实现维护成本不可同日而语。7. 个人总结它适合谁也聊聊不适合谁litellm给我的整体感觉是它不是那种花里胡哨的技术更像个踏实干活的基础设施。API不复杂该有的生产能力都有社区迭代还快。适合它的人有几类第一类是个人开发者手里握着好几个模型平台的Key想在一个项目里灵活切换模型第二类是创业团队想把模型接入的成本和运维复杂度收束起来第三类是公司里的基础架构组或平台组正在规划公司统一的AI能力入口。不适合它的人也有。如果你只是在做一个纯玩具Demo只接一家模型那引入litellm确实会显得多余。另外如果你所在的组织对供应链有极其严格的审查要求那“引入一个第三方开源依赖做统一网关”这件事本身就需要做合规评估。这种时候没有绝对正确答案得结合实际环境来权衡。再补充一个真实的体会litellm最大的价值不是帮你省调用代码而是改变你团队的工作方式。从“遇到模型就写一段适配代码”转变为“所有模型都从统一入口进出”这两个思路带来的长期维护成本差距是数量级的。最后分享一个小技巧每当你准备接入一种新的模型服务时在官方的模型列表里把所有相近的候选模型都翻一圈把它们的中位延迟、价格和上下文长度记到一张表上。之后要切换直接在代理配置里换一个名称就行连业务代码都不用动。这个习惯帮我省掉过无数次临阵改代码的尴尬。