LiteLLM:一个库统一所有大模型API

说实话,我一开始是拒绝用 LiteLLM 的。

“不就是多套几个 API 吗?我自己封装一下不就行了?”——这是我第一次看到这个库时的想法。

直到上周,我的项目同时接入了 OpenAI、Claude、智谱、通义千问四个模型,代码里到处是 if model == "gpt": ... elif model == "claude": ...。改一个接口要改四个地方,加一个新模型要写一堆适配代码。我终于承认:我错了,LiteLLM 真香。


问题是什么

如果你只用一个 LLM,那这篇文章可以关了。但如果你:

  • 想在不同模型之间切换(比如 GPT-4 太贵,想换成 Claude)
  • 需要调用多个模型做对比测试
  • 想做成本优化(高峰期用便宜模型,低峰期用好模型)
  • 需要容错(一个模型挂了,自动切换到另一个)

那 LiteLLM 基本就是为你准备的。

我之前的做法

# 一坨屎山代码
import openai
from zhipuai import ZhipuAI
from dashscope import Generation

def call_gpt(prompt):
    return openai.ChatCompletion.create(
        model="gpt-4",
        messages=[{"role": "user", "content": prompt}]
    )

def call_claude(prompt):
    # 还要单独装 anthropic 库
    ...

def call_zhipu(prompt):
    client = ZhipuAI()
    return client.chat.completions.create(
        model="glm-4",
        messages=[{"role": "user", "content": prompt}]
    )

# 然后到处 if-else
if model == "gpt":
    return call_gpt(prompt)
elif model == "zhipu":
    return call_zhipu(prompt)
...

每个模型的 SDK 不一样,参数名不一样,返回格式也不一样。维护起来简直是噩梦。


LiteLLM 怎么解决

一句话:统一接口,一个函数调用所有模型。

from litellm import completion

# OpenAI
response = completion(
    model="gpt-4",
    messages=[{"role": "user", "content": "你好"}]
)

# Claude
response = completion(
    model="claude-3-opus-20240229",
    messages=[{"role": "user", "content": "你好"}]
)

# 智谱
response = completion(
    model="zhipu/glm-4",
    messages=[{"role": "user", "content": "你好"}]
)

# 通义千问
response = completion(
    model="qwen/qwen-turbo",
    messages=[{"role": "user", "content": "你好"}]
)

看到了吗?完全一样的调用方式。只需要改 model 参数,其他都一样。

返回格式也统一了

不同模型的返回格式千奇百怪,LiteLLM 把它们都转成了 OpenAI 的格式:

# 不管调用哪个模型,返回都是这个结构
response.choices[0].message.content  # 回复内容
response.usage.total_tokens          # token 用量
response.id                          # 请求 ID

成本优化:自动选择最便宜的模型

这是我用 LiteLLM 最爽的功能。

场景:智能路由

简单任务用便宜模型,复杂任务用好模型:

from litellm import completion_with_split_tests

# 定义路由规则
def route_by_complexity(prompt):
    # 简单问题用 GPT-3.5
    if len(prompt) < 100:
        return "gpt-3.5-turbo"
    # 复杂问题用 GPT-4
    return "gpt-4"

response = completion_with_split_tests(
    models=["gpt-3.5-turbo", "gpt-4"],
    prompt="请解释量子计算",
    split_test_fn=route_by_complexity
)

内置的 fallback 机制

一个模型挂了,自动切换到备用模型:

from litellm import completion

# 设置 fallback
response = completion(
    model="gpt-4",
    messages=[{"role": "user", "content": "你好"}],
    fallbacks=["gpt-3.5-turbo", "claude-3-haiku-20240307"]
)

GPT-4 调用失败?自动试 GPT-3.5。GPT-3.5 也挂?再试 Claude Haiku。三个都挂才报错。


错误处理:不用自己写了

之前我每个模型都要写一套错误处理:

# 之前的屎山
try:
    response = call_gpt(prompt)
except openai.RateLimitError:
    # 等待重试
    ...
except openai.APIConnectionError:
    # 切换模型
    ...
except zhipu.APIError:
    # 又是另一套
    ...

LiteLLM 统一了所有错误类型:

from litellm import completion
from litellm.exceptions import RateLimitError, APIError

try:
    response = completion(model="gpt-4", messages=[...])
except RateLimitError:
    # 所有模型的限流错误都走这里
    print("触发限流,等待重试")
except APIError as e:
    # 所有 API 错误都走这里
    print(f"API 错误: {e}")

内置重试

更爽的是,LiteLLM 自带重试机制:

from litellm import completion

# 自动重试 3 次,指数退避
response = completion(
    model="gpt-4",
    messages=[...],
    num_retries=3,
    retry_after=0.1  # 首次重试等待 0.1 秒,之后指数增长
)

踩坑记录

用了三个月,踩过几个坑,分享一下。

坑 1:模型名称要写对

LiteLLM 用前缀区分不同提供商:

# 正确写法
"openai/gpt-4"           # OpenAI(可省略前缀)
"claude-3-opus-20240229" # Anthropic(可省略前缀)
"zhipu/glm-4"            # 智谱(必须加前缀)
"qwen/qwen-turbo"        # 通义千问(必须加前缀)
"deepseek/deepseek-chat" # DeepSeek(必须加前缀)

写错前缀会报错,而且错误信息不太直观。建议先查文档确认。

坑 2:API Key 要配置好

LiteLLM 从环境变量读取 API Key:

export OPENAI_API_KEY="sk-xxx"
export ANTHROPIC_API_KEY="sk-xxx"
export ZHIPU_API_KEY="xxx"
export DASHSCOPE_API_KEY="xxx"  # 通义千问

也可以在代码里直接传:

response = completion(
    model="zhipu/glm-4",
    messages=[...],
    api_key="your-api-key"
)

坑 3:流式输出要这样用

from litellm import completion

response = completion(
    model="gpt-4",
    messages=[...],
    stream=True
)

for chunk in response:
    print(chunk.choices[0].delta.content, end="", flush=True)

注意 delta.content 而不是 message.content,这个和 OpenAI 原生接口一致。

坑 4:国内模型可能需要代理

智谱、通义千问等国内模型,如果服务器在国外,可能需要配置代理:

import os
os.environ["HTTP_PROXY"] = "http://your-proxy:port"
os.environ["HTTPS_PROXY"] = "http://your-proxy:port"

支持的模型列表

LiteLLM 支持的模型非常多,我常用的这些都没问题:

国外:

  • OpenAI:GPT-4、GPT-3.5、GPT-4o
  • Anthropic:Claude 3 系列
  • Google:Gemini
  • Mistral:Mistral、Mixtral

国内:

  • 智谱:GLM-4、GLM-3-Turbo
  • 阿里:通义千问系列
  • 百度:文心一言
  • DeepSeek:DeepSeek Chat、DeepSeek Coder
  • 月之暗面:Moonshot

完整列表看官方文档,基本主流的都支持。


写在最后

LiteLLM 解决了一个很实际的问题:多模型调用的碎片化

如果你只用一个模型,那确实不需要。但如果你:

  • 想做成本优化
  • 需要容错和 fallback
  • 在多个模型之间做对比测试
  • 不想维护一堆 SDK

那 LiteLLM 真的值得一试。

安装很简单:

pip install litellm

官方文档写得也不错,遇到问题直接搜就行。

一句话总结:早用早享受,别像我一样踩了坑才后悔。


本文基于 LiteLLM v1.x 版本,API 可能有变化,请以官方文档为准。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐