
1. 从一个“模型调用中间层”说起第一次接触 litellm 是在一个多模型混用的项目里。当时的需求很朴素同一个业务逻辑今天调 A 家的模型明天可能要换成 B 家的后天又得接一个本地部署的开源模型做兜底。如果每换一次都要改一遍业务代码那维护成本会高到让人崩溃。litellm 就是在这个背景下进入视野的——它本质上是一个统一的模型调用中间层用一套 OpenAI 风格的接口去适配几十种不同的模型服务让上层业务代码只写一次底层换模型只改配置。这个定位听起来简单但真正用起来之后会发现它解决的问题远不止“换模型不改代码”这么表面。它把多模型路由、成本追踪、失败重试、密钥管理、流式输出、日志回调这些原本需要自己手写一堆胶水代码的事情收敛到了一个库里面。对于做 AI 应用的人来说这意味着你可以把精力放在业务逻辑上而不是天天跟各家 SDK 的差异较劲。这篇文章适合几类人看一是正在做多模型接入、被各家 API 差异折磨的开发者二是想给现有应用加一层模型抽象、方便后续切换或做 A/B 测试的工程师三是想搞清楚“统一接口”这件事到底怎么落地、有哪些坑的人。我会从设计思路、核心机制、实操步骤、常见问题几个角度把 litellm 拆开讲透尽量做到看完就能上手抄作业。2. 为什么需要统一模型调用层2.1 多模型接入的真实痛点先说清楚问题才能理解 litellm 的价值。假设你手头有三个模型服务要接一个 OpenAI 风格的云端接口、一个本地部署的开源模型、一个第三方厂商的推理服务。这三家的 SDK 各不相同认证方式不一样请求体结构不一样返回体结构更不一样连流式输出的分片格式都可能对不上。如果不用中间层你的代码里会充斥大量 if-else 分支每个分支处理一家的调用逻辑。更麻烦的是当你想加一个“失败自动切换备用模型”的功能时得在每个分支里都写一遍重试逻辑。想统计每个模型的 token 消耗和费用时又得在每个分支里埋一遍埋点。这种代码写出来能跑但几乎没法维护加一个新模型就是一次小型重构。litellm 的思路是把这些差异全部吃掉对外只暴露一套接口。你调用的时候传一个模型名比如gpt-4o或者claude-3-5-sonnet或者ollama/llama3它内部根据前缀和配置去路由到对应的适配器。上层代码完全不用关心底层是谁。2.2 统一接口的核心设计取舍这里有个关键的设计选择值得说litellm 没有自己发明一套全新的请求格式而是直接对齐 OpenAI 的 Chat Completions 格式。这个决定非常聪明原因有几个。第一OpenAI 的接口格式事实上已经成了行业通用语。绝大多数模型服务商都提供了兼容 OpenAI 的接口或者至少有社区适配。对齐它意味着学习成本几乎为零你原来怎么调 OpenAI现在就怎么调 litellm。第二生态兼容性好。大量现成的工具、框架、示例代码都是围绕 OpenAI 格式写的litellm 对齐之后可以直接复用这些生态。比如你想用一个基于 OpenAI 格式的评测工具直接指向 litellm 就行。第三迁移路径平滑。如果你原本就在用 OpenAI接入 litellm 只需要改 base_url 和 api_key代码几乎不动。这种“无痛迁移”是它被广泛采用的重要原因。当然对齐 OpenAI 格式也有代价。有些模型服务有自己独特的能力比如特殊的函数调用格式、多模态输入的特殊字段这些在统一格式下可能需要额外的适配层来处理。litellm 的做法是在保持核心格式一致的前提下通过额外的参数和 provider-specific 的透传机制来支持这些特性。2.3 它到底解决了哪些具体问题把价值说得再具体一点。用了 litellm 之后下面这些事情从“需要自己写”变成了“配置一下就行”。模型切换改一个字符串从gpt-4o换成claude-3-5-sonnet业务代码零改动。失败重试与降级配置一个 fallback 列表主模型挂了自动切备用不用写重试逻辑。成本与用量追踪内置了各模型的计价表调用后自动算出花了多少钱、用了多少 token。密钥管理多个模型的密钥统一在配置里管理不用散落在代码各处。流式输出统一不管底层是什么格式对外都是统一的流式分片。可观测性通过回调机制把每次调用的日志、耗时、结果送到你指定的地方。这些能力单拎出来都不算黑科技但组合在一起就构成了一个相当扎实的工程基础设施。尤其是当你的应用开始规模化、开始在意成本和稳定性的时候这些东西的价值会成倍放大。3. 核心机制拆解路由、适配与回调3.1 模型名到适配器的路由逻辑litellm 最核心的机制是基于模型名前缀的路由。当你传入一个模型名它内部会解析这个名字决定用哪个适配器、走哪个 API 端点、用什么认证方式。规则大致是这样的如果模型名里带有 provider 前缀比如anthropic/claude-3-5-sonnet、ollama/llama3、azure/gpt-4它会根据前缀选择对应的适配器。如果没有前缀它会根据模型名的特征去猜测比如gpt-开头默认走 OpenAIclaude-开头默认走 Anthropic。这个设计的好处是显式且可预测。你写ollama/llama3就明确知道走本地 Ollama不会因为环境变量配错而跑到别的地方去。对于生产环境来说这种确定性很重要。实操中我建议始终带前缀哪怕默认能猜对。原因很简单显式前缀让代码可读性更好别人一看就知道这个调用走的是哪家排查问题时也少一层猜测。而且当你想做批量替换时带前缀的写法更容易用正则处理。3.2 请求与响应的标准化过程路由确定之后litellm 会把你的请求“翻译”成目标服务需要的格式。这个过程包括几个层面。参数映射是最基础的一层。比如 OpenAI 用的max_tokens在某些服务里叫max_output_tokenslitellm 会帮你转换。temperature、top_p、stop这些通用参数也会做归一化处理。消息格式的转换是另一层。OpenAI 的 messages 数组里每条消息有 role 和 contentcontent 可以是字符串也可以是数组多模态。litellm 会把这个结构转换成目标服务能理解的格式比如某些服务需要把 system 消息单独拎出来某些服务对图片输入的字段名不一样。响应标准化则是反向的过程。目标服务返回的结果会被转换成统一的 OpenAI 风格响应对象包含choices、usage、model等字段。这样你的上层代码拿到的永远是同一种结构不用为每家写不同的解析逻辑。注意标准化不是万能的。有些服务特有的字段在转换过程中可能会丢失。如果你依赖某个服务的独有能力需要确认 litellm 是否支持透传或者用extra_body之类的机制手动传递。3.3 回调机制与可观测性litellm 的回调系统是我个人觉得最实用的功能之一。它允许你在调用的各个生命周期节点挂上自定义逻辑比如请求前、请求后、成功时、失败时。常见的用法有这么几种。一是成本追踪每次调用后把 usage 和计算出的费用写到一个数据库或日志系统里方便后续做成本分析。二是日志记录把完整的请求和响应存下来用于调试和审计。三是监控告警当失败率或延迟超过阈值时触发通知。回调的配置方式很灵活可以全局配置也可以针对单次调用配置。全局配置适合做统一的日志和成本追踪单次配置适合做特定场景的埋点。这里有个实操心得回调函数里不要做耗时操作。因为回调是在调用链路上同步执行的如果你在里面做网络请求或者复杂计算会直接拖慢整体响应。正确的做法是把数据丢到一个队列里由后台任务异步处理。4. 从零搭建一个多模型调用服务4.1 环境准备与依赖安装先把环境搭起来。litellm 是一个 Python 库安装很直接。pip install litellm如果你需要用到某些特定 provider 的 SDK可能还需要额外安装。比如走 Azure 的话需要azure-identity走某些云服务可能需要对应的 SDK。不过 litellm 的设计是尽量用 HTTP 直连减少对各家 SDK 的依赖所以大部分情况下一个 litellm 就够了。版本选择上建议用较新的稳定版。litellm 迭代比较快新版本通常会支持更多模型、修复一些适配问题。但生产环境不要盲目追最新先在测试环境验证过再上。环境变量是配置密钥的主要方式。litellm 会读取一系列约定好的环境变量名比如OPENAI_API_KEY、ANTHROPIC_API_KEY、AZURE_API_KEY等。把密钥放在环境变量里而不是代码里是最基本的安