
1. 项目缘起与核心定位第一次接触 litellm 是在一个多模型混用的项目里。当时团队同时接入了好几家不同厂商的大模型服务每家的接口协议、鉴权方式、返回结构都不一样代码里到处是 if-else 分支维护起来非常痛苦。后来有人推荐了 litellm用下来确实解决了不少问题。这个项目的核心定位很清晰用一套统一的 OpenAI 格式接口去调用市面上几乎所有主流的大模型服务。你不需要为每家厂商单独写适配层只需要把模型名称和 API Key 配置好剩下的交给 litellm 处理。它解决的核心问题是接口碎片化。不同厂商的 API 在请求体结构、响应字段命名、流式输出格式、错误码定义上都有差异。比如有的用max_tokens有的用max_output_tokens有的返回choices[0].message.content有的返回嵌套更深的结构。litellm 在中间做了一层标准化转换对外暴露统一的 OpenAI 兼容接口对内负责把请求翻译成各家厂商能理解的格式再把响应翻译回来。适合谁来用如果你正在做以下事情litellm 值得认真看一下需要同时对接多家模型服务的应用开发者、想快速切换模型做对比测试的算法工程师、需要统一管理多个 API Key 和配额的后端团队、以及希望在不改业务代码的前提下更换底层模型的架构师。哪怕你只是个人开发者想在自己的小工具里灵活切换模型litellm 也能省掉大量重复劳动。2. 整体架构与设计思路拆解2.1 为什么需要统一接口层在没有 litellm 这类工具之前多模型接入的典型做法是写一个适配器模式定义一个抽象基类每个厂商实现一个子类业务层通过工厂方法获取具体实例。这种做法本身没问题但问题是每接一家新厂商就要写一个新适配器而且各家 API 的细节差异会渗透到适配器实现里测试和维护成本随厂商数量线性增长。litellm 的思路不同。它不是在业务层做适配而是在 HTTP 请求层做转换。你发给 litellm 的请求永远是 OpenAI 格式的litellm 内部根据模型名称路由到对应的处理逻辑完成参数映射、鉴权注入、请求发送、响应解析、错误转换这一整套流程。对业务代码来说它只知道自己在跟一个 OpenAI 兼容的接口说话完全感知不到底层是哪家厂商。这种设计的好处很明显业务代码零改动就能切换模型新增厂商支持只需要在 litellm 内部加一个映射配置不需要动上层。坏处也有litellm 需要紧跟各家 API 的变化一旦某家厂商改了接口litellm 要跟着更新。不过这个问题由社区共同承担比自己维护一套适配器要轻松得多。2.2 核心模块与数据流litellm 的内部结构可以粗略分为几个层次。最上层是接口层提供completion、embedding、image_generation等函数以及一个可选的代理服务器。中间是路由与转换层负责根据模型名称确定目标厂商把 OpenAI 格式的参数转换成厂商特定格式同时处理流式和非流式两种模式。最下层是HTTP 客户端层实际发送请求并接收响应内置了重试、超时、错误处理等机制。数据流大致是这样的你调用completion(model某厂商/某模型, messages[...])litellm 首先解析模型字符串确定厂商和具体模型标识然后加载对应的配置包括 API Base、鉴权方式、参数映射规则接着把 OpenAI 格式的请求体转换成厂商格式发送 HTTP 请求收到响应后再把厂商格式的响应转换回 OpenAI 格式最后返回给你。整个过程对调用方透明。2.3 代理模式与 SDK 模式的选择litellm 提供两种使用方式SDK 模式和代理模式。SDK 模式就是直接在 Python 代码里import litellm然后调用函数适合已经在用 Python 的项目。代理模式是启动一个独立的 HTTP 服务对外暴露 OpenAI 兼容的/v1/chat/completions等端点任何语言的项目都可以通过 HTTP 调用。选哪种取决于你的场景。如果项目是 Python 的且不想多维护一个服务SDK 模式更轻量。如果项目是多语言的或者你希望把模型调用的鉴权、限流、日志统一收口到一个服务里代理模式更合适。代理模式还支持配置文件热加载、多 Key 轮询、预算控制等高级功能适合团队协作场景。注意代理模式下所有请求都会经过 litellm 服务中转网络延迟会略微增加。如果对延迟极其敏感建议用 SDK 模式直连。3. 核心细节解析与实操要点3.1 模型命名规则与路由逻辑litellm 用模型名称来路由请求。命名格式通常是厂商前缀/模型标识比如openai/gpt-4o、anthropic/claude-3-5-sonnet、deepseek/deepseek-chat等。前缀告诉 litellm 该用哪套转换逻辑后面的模型标识会原样传给厂商 API。有些厂商的模型不需要前缀也能识别litellm 内置了一些常见模型的默认路由。但为了清晰和可维护建议始终写完整前缀。如果你用的是自部署的模型服务可以通过设置api_base参数来指定地址模型名称可以自定义只要在配置里做好映射即可。路由逻辑的核心是一张映射表记录了每个厂商的 API Base、鉴权头格式、请求参数映射规则、响应解析规则。这张表在 litellm 源码里以配置形式存在社区会持续更新。如果你用的厂商不在支持列表里也可以通过自定义配置接入后面会讲到。3.2 参数映射与兼容性处理不同厂商对同一功能的参数命名差异很大。比如控制输出长度的参数OpenAI 叫max_tokens某厂商叫max_output_tokens另一家叫max_new_tokens。litellm 在转换层做了统一你始终传max_tokens它会根据目标厂商自动映射成正确的名称。类似的还有温度参数、top_p、停止词、流式开关等。大部分常见参数 litellm 都做了映射但也有一些厂商特有的参数无法完全对齐。这种情况下litellm 支持通过extra_body或厂商特定的参数透传让你在需要时绕过标准化层直接传递原始参数。实操心得遇到参数不生效的情况先检查是不是被 litellm 的映射规则覆盖了。可以在调用时加上drop_paramsTrue让 litellm 自动丢弃目标厂商不支持的参数避免报错。3.3 流式输出的统一处理流式输出是很多应用的核心需求。不同厂商的流式格式差异很大有的用 SSE有的用 JSON Lines有的每个 chunk 包含完整结构有的只包含增量内容。litellm 把这些差异统一成 OpenAI 的流式格式你拿到的每个 chunk 都是choices[0].delta.content这样的结构。实现上litellm 在收到厂商的流式响应后会逐块解析并转换成统一格式再通过生成器返回给你。这意味着你不需要关心底层是 SSE 还是其他协议只需要按 OpenAI 的方式处理流式数据即可。有一个细节需要注意流式模式下某些厂商的错误可能在中途才返回而不是在建立连接时。litellm 会尽量把这些错误转换成统一的异常但偶尔会有厂商特有的错误信息透传出来。建议在流式处理的消费端做好异常捕获不要假设流一定会正常结束。3.4 错误处理与重试机制多厂商接入的一个痛点是错误码不统一。同样是限流有的返回 429有的返回自定义错误码同样是鉴权失败有的返回 401有的返回 403。litellm 把这些错误统一映射成 OpenAI 风格的异常比如RateLimitError、AuthenticationError、APIError等方便你统一处理。重试机制也是内置的。litellm 默认会对可重试的错误如限流、超时进行指数退避重试重试次数和退避策略可以配置。如果你用的是代理模式还可以配置多个 API Key 轮询当一个 Key 触发限流时自动切换到下一个。注意重试不是万能的。对于幂等性没有保证的操作重试可能导致重复执行。建议在业务层做好幂等设计或者对非幂等操作关闭自动重试。4. 实操过程与核心环节实现4.1 环境准备与安装litellm 是一个 Python 包安装很简单pip install litellm如果你需要代理模式还需要安装额外的依赖pip install litellm[proxy]安装完成后建议先设置好各家厂商的 API Key 环境变量。litellm 会自动读取常见的环境变量名比如OPENAI_API_KEY、ANTHROPIC_API_KEY等。这样做的好处是代码里不需要硬编码密钥也方便在不同环境切换。export OPENAI_API_KEY你的密钥 export ANTHROPIC_API_KEY你的密钥4.2 SDK 模式快速上手SDK 模式最简单的用法就是替换 OpenAI 的调用from litellm import completion response completion( modelopenai/gpt-4o, messages[{role: user, content: 你好介绍一下你自己}] ) print(response.choices[0].message.content)切换到另一家厂商只需要改模型名称response completion( modelanthropic/claude-3-5-sonnet, messages[{role: user, content: 你好介绍一下你自己}] )业务代码的结构完全不变。如果你之前用的是 OpenAI 的 SDK甚至可以把import openai换成import litellm然后把openai.chat.completions.create换成litellm.completion其余代码基本不用动。4.3 代理模式部署与配置代理模式需要先写一个配置文件通常叫config.yamlmodel_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 api_key: os.environ/ANTHROPIC_API_KEY general_settings: master_key: sk-your-master-key然后启动服务litellm --config config.yaml --port 4000启动后你就可以用任何 OpenAI 兼容的客户端来调用from openai import OpenAI client OpenAI(base_urlhttp://localhost:4000, api_keysk-your-master-key) response client.chat.completions.create( modelgpt-4o, messages[{role: user, content: 你好}] )代理模式的好处是你的业务代码完全不需要引入 litellm 依赖只需要把 OpenAI 客户端的 base_url 指向 litellm 服务即可。这样即使以后不用 litellm 了切换成本也很低。4.4 多 Key 轮询与预算控制代理模式支持配置多个 API Key 做轮询这在团队共用场景下很有用model_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY_1 - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY_2litellm 会自动在多个 Key 之间做负载均衡当一个 Key 触发限流时切换到另一个。你还可以配置预算控制给每个 Key 或每个用户设置消费上限超过后自动拒绝请求。这对于防止意外超支很有帮助。实操心得多 Key 轮询时建议给每个 Key 设置相同的模型配置否则可能出现请求被路由到不支持该模型的 Key 上导致失败。另外预算控制的数据默认存在内存里重启后会丢失生产环境建议配置持久化存储。4.5 自定义厂商接入如果你用的模型服务不在 litellm 的支持列表里可以通过自定义配置接入。核心是告诉 litellm 这个厂商的 API Base 是什么、鉴权方式是什么、请求和响应怎么转换。最简单的方式是使用 OpenAI 兼容模式。很多厂商都提供了 OpenAI 兼容的接口这种情况下只需要设置api_base即可response completion( modelopenai/你的模型名称, api_basehttps://你的服务地址/v1, api_key你的密钥, messages[{role: user, content: 你好}] )如果厂商的接口不是 OpenAI 兼容的就需要写自定义转换逻辑。litellm 支持通过custom_llm_provider参数指定自定义提供商并在代码里注册转换函数。这部分稍微复杂一些建议先看 litellm 源码里现有厂商的实现照着改。5. 常见问题与排查技巧实录5.1 模型名称报错怎么办最常见的错误是LLM Provider NOT provided或Invalid model name。这通常是因为模型名称没有写前缀litellm 无法识别该路由到哪家厂商。解决方法是补全前缀比如把gpt-4o改成openai/gpt-4o。如果是不支持的厂商检查 litellm 版本是否过旧升级到最新版通常能解决。另一种情况是模型名称拼写错误。litellm 的模型标识必须和厂商 API 接受的名称一致写错了厂商会返回错误。建议先在厂商的文档里确认准确的模型标识再填入 litellm。5.2 鉴权失败排查思路鉴权失败通常表现为 401 或 403 错误。排查顺序如下首先确认环境变量是否设置正确可以用echo $OPENAI_API_KEY检查其次确认 Key 是否有权限访问该模型有些 Key 是限定模型的最后确认 API Base 是否正确特别是用自部署服务时Base URL 写错会导致鉴权失败。如果用的是代理模式还要检查master_key是否配置正确以及客户端传的 Key 是否和服务端配置匹配。代理模式的鉴权是两层客户端到 litellm 是一层litellm 到厂商是另一层两层都要配对。5.3 流式输出中断的处理流式输出中断可能由多种原因导致网络波动、厂商服务不稳定、超时设置过短等。litellm 内置了重试机制但流式请求的重试比较特殊因为已经输出的内容无法撤回。建议在消费端做好容错比如记录已接收的内容中断后可以从头重新请求或者提示用户重试。如果中断频繁发生可以适当增加超时时间或者检查网络环境。另外某些厂商的流式接口对请求频率有限制过于频繁的流式请求可能被限流这种情况下需要降低请求频率或增加 Key 轮询。5.4 参数不生效的常见原因参数不生效通常是因为被 litellm 的映射规则覆盖了或者目标厂商不支持该参数。排查方法是开启 litellm 的调试日志看看实际发送给厂商的请求体是什么。如果参数被丢弃了说明厂商不支持如果参数被改名了说明映射规则生效了这是正常行为。对于厂商特有的参数可以通过extra_body传递response completion( modelopenai/gpt-4o, messages[...], extra_body{custom_param: value} )这样参数会原样透传给厂商不经过 litellm 的映射层。5.5 性能优化与延迟控制litellm 本身的开销很小主要延迟来自厂商 API 的网络往返。如果发现延迟比直连厂商高很多可以从几个方面排查代理模式下多了一层网络转发延迟会增加几十毫秒SDK 模式下如果开启了详细日志日志写入也可能拖慢速度另外重试机制在遇到限流时会增加延迟可以通过调整重试策略来优化。对于延迟敏感的场景建议用 SDK 模式直连关闭不必要的日志并选择地理位置上更近的厂商节点。如果必须用代理模式可以把 litellm 服务和业务服务部署在同一内网减少网络开销。常见问题可能原因解决方法模型名称报错缺少厂商前缀补全前缀如openai/gpt-4o鉴权失败Key 未设置或错误检查环境变量和 Key 权限流式中断网络波动或超时增加超时做好消费端容错参数不生效被映射覆盖或厂商不支持用extra_body透传延迟偏高代理转发或日志开销改用 SDK 模式关闭详细日志6. 进阶用法与扩展思路6.1 统一日志与可观测性litellm 支持把每次调用的日志输出到多种后端包括标准输出、文件、数据库等。代理模式下还可以配置回调函数在请求前后执行自定义逻辑。这对于做成本统计、性能监控、异常告警很有用。你可以配置一个回调记录每次调用的模型、耗时、Token 消耗、成功与否等信息然后汇总到监控系统。litellm 内置了一些常见后端的集成比如 Langfuse、Helicone 等配置起来比较简单。如果没有现成的集成也可以自己写一个回调函数litellm 会把调用信息作为参数传进来。6.2 模型降级与故障转移生产环境中某个厂商服务不可用是常有的事。litellm 支持配置模型降级策略当主模型调用失败时自动切换到备用模型。配置方式是在model_list里给同一个model_name配置多个litellm_paramslitellm 会按顺序尝试。model_list: - model_name: chat litellm_params: model: openai/gpt-4o - model_name: chat litellm_params: model: anthropic/claude-3-5-sonnet这样当gpt-4o不可用时请求会自动落到claude-3-5-sonnet上。需要注意的是不同模型的输出风格和能力有差异降级后业务层可能需要做兼容处理。建议在降级时记录日志方便后续分析。6.3 缓存策略减少重复调用对于重复的请求litellm 支持缓存响应避免重复调用厂商 API。缓存可以配置在内存、Redis 或其他后端。开启缓存后相同的请求会直接返回缓存结果节省成本和延迟。缓存的粒度可以按请求内容做哈希也可以按用户和会话做区分。对于问答类应用缓存命中率可能不高因为用户的问题很少完全重复。但对于某些固定提示词的场景比如分类、摘要缓存效果会很明显。注意缓存会导致响应不是实时的对于需要最新数据的场景要谨慎使用。另外缓存 Key 的设计要考虑模型版本模型升级后旧缓存应该失效。6.4 与现有框架的集成litellm 可以很方便地集成到现有框架里。比如在 LangChain 中可以用 litellm 作为 LLM 的后端在 FastAPI 中可以把 litellm 代理作为独立的服务部署在数据管道中可以用 litellm 统一调用不同厂商的 Embedding 接口。集成的核心思路是把 litellm 当作一个 OpenAI 兼容的接口来用任何支持自定义 OpenAI Base URL 的框架都可以直接对接。这样你不需要改框架代码只需要改配置即可。7. 个人实操体会与建议用了 litellm 一段时间后最大的感受是它把多模型接入的复杂度从业务层转移到了基础设施层。以前每接一家厂商都要改业务代码现在只需要改配置。这对于快速迭代的项目来说节省的时间非常可观。不过也有几个坑要注意。第一litellm 的版本更新比较快不同版本之间偶有行为变化升级前建议先看 changelog在测试环境验证后再上生产。第二代理模式下所有请求都经过一个服务这个服务本身的高可用要做好否则会成为单点故障。第三不同厂商的模型能力差异很大统一接口只是统一了调用方式不代表输出质量一致业务层还是要针对不同模型做适配。最后分享一个小技巧如果你在调试阶段不确定某个参数该怎么传可以开启 litellm 的详细日志它会打印出实际发送给厂商的请求体和收到的原始响应。对照厂商文档一看就知道参数有没有正确传递。这个技巧帮我省了很多排查时间。