单项目深读

LiteLLM:用统一接口把 100 多个 LLM 收进一个网关

LiteLLM 以 OpenAI 兼容格式统一调用 100 多个 LLM API,在多家厂商间做路由与负载均衡,并集中追踪成本、日志与 guardrails,省去为每家重写 SDK

|INS-0012

你团队里现在同时跑着 OpenAI、Anthropic 和 Bedrock 三家模型。代码里有三套 SDK、三种鉴权方式、三种请求体结构、三套错误类型。某天产品说「把那个用 Claude 的功能换成 Gemini 试试」——你要改的不是一行配置,而是一整条调用链。

LiteLLM 就是冲着这个摩擦点来的:它把 100 多个 LLM 供应商收进一个 OpenAI 格式的接口后面。你可以把它当一个 Python 库直接 import,也可以把它部署成一个网关服务,让整个团队共用。

两种形态,一套抽象

README 里把使用方式说得很直白:Python SDK 用于库内直接集成,AI Gateway(Proxy Server) 用于团队或组织级的集中服务。这两者不是两个产品,而是同一套供应商适配层的两种暴露方式。

把它的结构拆开,大致是这么几层:

层职责素材中的对应物
接入层对外暴露统一入口Python SDK 的 completion / acompletion;Proxy 的 /chat/completions、/responses、/embeddings、/images、/audio、/batches、/rerank、/a2a、/messages 等端点
协议适配层把 OpenAI 格式翻译成各家格式,再翻译回来100+ provider 适配;A2A 协议客户端 A2AClient;MCP 工具加载 experimental_mcp_client.load_mcp_tools
网关能力层虚拟密钥、花费追踪、guardrails、负载均衡、管理面板Proxy Server 内置能力
运行时提供 CLI 与部署形态litellm --model gpt-4o;Render / Railway / AWS / GCP 一键部署按钮

请求的流转路径是这样的:客户端始终按 OpenAI 的格式发请求(model + messages),到接入层后由协议适配层根据 model 前缀(例如 openai/gpt-4o、anthropic/claude-sonnet-4-20250514)路由到对应供应商的适配器,适配器负责鉴权、请求体转换、响应归一化。走 Proxy 时,请求还会先经过网关能力层——校验虚拟密钥、记录花费、跑 guardrails——再进适配层。返回时统一收敛成 OpenAI 兼容的响应结构,所以调用方不需要知道背后是谁。

这个设计的核心取舍是:把「供应商差异」这件事收敛到一个地方。README 的 "Why LiteLLM" 段落列的正是这个痛点——每家模型有不同的 SDK、鉴权模式、请求格式和错误类型。LiteLLM 的答案是让这些差异只存在于适配层内部。

装哪个包,是有讲究的

README 里有一段容易被略过但很关键的信息:存在一个独立的 litellm-core 发行版,提供相同的 import litellm API 和运行时依赖,但不含可选 extras、CLI 入口和内置 dashboard。

这意味着安装选择本身就是一次架构决策:

  • 只要库内调用 → 用 litellm-core,干净、无多余依赖。
  • 要跑 Proxy、用 CLI、要 dashboard → 用 litellm。

README 明确提醒:一个环境里只装其中一个,因为 litellm 和 litellm-core 拥有重叠的 Python 文件。这是个真实的坑,不是客套话。

SDK 的最小用法就是这样,换供应商只改 model 字符串:

shell
uv add litellm
python
from litellm import completion import os os.environ["OPENAI_API_KEY"] = "your-openai-key" os.environ["ANTHROPIC_API_KEY"] = "your-anthropic-key" # OpenAI response = completion(model="openai/gpt-4o", messages=[{"role": "user", "content": "Hello!"}]) # Anthropic response = completion(model="anthropic/claude-sonnet-4-20250514", messages=[{"role": "user", "content": "Hello!"}])

两次调用的代码结构完全相同,只有 model 前缀和对应的环境变量不同。这就是「统一接口」的实际含义——不是抽象出一个新协议,而是让你继续用 OpenAI 的写法。

网关形态:调用方甚至不知道 LiteLLM 存在

Proxy Server 的启动只要两行:

shell
uv tool install 'litellm[proxy]' litellm --model gpt-4o

起来之后,客户端用官方 openai SDK 指向本地 4000 端口就行,api_key 填什么都行(网关侧才是真正的鉴权点):

python
import openai client = openai.OpenAI(api_key="anything", base_url="http://0.0.0.0:4000") response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": "Hello!"}] )

这是整个项目最聪明的一处设计:它不要求你换客户端。已有的 OpenAI 代码、已有的 LangChain 调用、已有的工具链,只需要改 base_url。README 的 topics 里同时挂着 openai-proxy 和 ai-gateway,说的就是这同一件事的两种视角。

网关形态真正的价值在能力层。虚拟密钥让每个人拿到自己的 key 而不是共享主密钥;花费追踪把成本按 key、按模型归集;guardrails 在请求进出时做检查;负载均衡在多个部署间分发。这些是「团队共用一套 LLM 出口」时绕不开的东西,LiteLLM 把它们做进了开源版本,而不是只放在企业版里。

不止是 LLM:A2A 与 MCP

README 里有两个 feature 块值得单独看,因为它们说明 LiteLLM 的野心不止于「模型代理」。

A2A(Agent-to-Agent):SDK 侧提供 A2AClient,可以直接向一个 A2A agent 发 SendMessageRequest。网关侧更实用——把 agent 注册进网关后,通过 http://localhost:4000/a2a/my-agent 这样的路径访问,用 LiteLLM 的 master key 或虚拟密钥鉴权。README 提到支持的 agent 来源包括 LangGraph、Vertex AI Agent Engine、Azure AI Foundry、Bedrock AgentCore、Pydantic AI,并要求每个 agent 设置 protocolVersion 为 1.0 或 0.3。

MCP(Model Context Protocol):SDK 侧用 experimental_mcp_client.load_mcp_tools(session=session, format="openai") 把 MCP server 的工具加载成 OpenAI 格式的 tools,然后直接喂给 litellm.acompletion。网关侧则更进一步——直接在 /chat/completions 的请求体里声明 MCP 工具:

bash
curl -X POST 'http://0.0.0.0:4000/v1/chat/completions' \ -H 'Authorization: Bearer <your-master-key>' \ -H 'Content-Type: application/json' \ -d '{ "model": "gpt-4o", "messages": [{"role": "user", "content": "Summarize the latest open PR"}], "tools": [{ "type": "mcp", "server_url": "litellm_proxy/mcp/github", "server_label": "github_mcp", "require_approval": "never" }] }'

注意 server_url 指向的是 litellm_proxy/mcp/github——工具调用被网关接管了。README 还给了 Cursor IDE 的接法,把 LiteLLM 的 /mcp/ 端点当成一个 MCP server 挂上去,用 x-litellm-api-key 头鉴权。

这里有个 README 特意写明的坑:MCP OAuth 场景下,上游可能声称支持动态客户端注册,但实际用 401/403 拒绝请求。如果供应商要求预注册 OAuth 应用,就得在 MCP server 上配 credentials.client_id(必要时加 client_secret),跳过网关登录流程里的动态注册。而且——供应商必须批准这个应用具备 MCP 访问权限,能打开授权页不等于登录和工具调用会成功。这种细节通常只出现在踩过坑的人写的文档里。

和同主题项目比,它站在哪

素材里给的对照项目,其实分属不同层次,放在一起看反而能说清 LiteLLM 的定位:

项目定位与 LiteLLM 的关系
LiteLLMAI Gateway:统一 100+ LLM 调用、路由、成本追踪—
markitdown把各类文档转 Markdown 喂给 LLM上游素材处理,LiteLLM 管的是调用侧
headroom送进模型前压缩内容、省 token优化单次请求的体积,LiteLLM 优化的是跨供应商的调用治理
Langchain-Chatchat本地知识库问答应用应用层,可以建在 LiteLLM 之上
langfuseLLM 追踪、评估、调试平台观测层,与 LiteLLM 的花费/日志有重叠但侧重不同:Langfuse 关心回答质量,LiteLLM 关心调用与成本
deepagentsAgent harness,任务规划与子 agent编排 agent 逻辑,LiteLLM 提供它底下的模型出口

一句话概括差异:其他项目多在「怎么用模型」这一侧做文章——处理输入、压缩上下文、构建 agent、评估输出;LiteLLM 在「怎么连模型」这一侧做文章。 它不关心你的 prompt 写得好不好,只关心你换供应商时要不要改代码、成本能不能按人算清、密钥能不能安全分发。

这也是为什么它的 topics 里同时有 langchain 和 llmops——它天然是这些工具的下游或上游,而不是替代品。

数字与状态

按 GitHub 元数据:61,454 stars、12,438 forks、5,552 open issues,语言 Python,仓库创建于 2023-07-27,最近推送 2026-10-18。License 字段是 NOASSERTION——GitHub 没能自动识别出标准许可证,使用前需要自己去看仓库里的许可文件,这一点不能想当然。

5,552 个 open issues 这个数字值得正视:它说明项目活跃、被大量真实场景使用,同时也说明维护负担不轻。选型时这是要纳入考量的信号,不是可以忽略的噪音。

README 里引用了一个性能数字:1k RPS 下 8ms P95 延迟,并链接到官方 benchmarks 页面。这是项目方自述的指标,有 benchmark 链接可查,但不在本文的事实底座里展开。

该不该用

判断标准其实很窄:

  • 如果你只用一家模型,且短期内不打算换——LiteLLM 是多余的一层。
  • 如果你已经或即将用两家以上,或者需要给团队分发密钥、按人核算成本——那这层抽象的成本很快会被摊薄。
  • 如果你在搭 agent 或 RAG 应用,LiteLLM 提供的是底下那层稳定的模型出口,上面的编排、检索、评估各有专门工具。

最后提醒一句 README 里那个容易被忽略的部署细节:litellm 和 litellm-core 别装进同一个环境。这种「文档里写了但没人读」的约束,往往就是上线前最后一个小时的调试来源。