← 返回首页目录
# 解决 litellm.BadRequestError: 未提供 LLM 提供者错误

作者:吉祥法师

在设计、开发并部署基于大型语言模型(LLM)的智能应用时,开发者常常会依赖一些高级框架来简化工作流程。LangChain、CrewAI 以及 LiteLLM 等工具库提供了强大的抽象层,允许我们以更少的代码调用不同来源的模型。然而,当这些抽象层出现配置错误时,往往会导致难以立即理解的报错信息。本文将深入剖析一个在 CrewAI 和 LangChain 使用场景中常见的错误——`litellm.BadRequestError: LLM Provider NOT provided`,并系统地阐述其成因、解决方案以及背后的核心原理。

## 一、问题背景与错误解析

### 1.1 错误现象

开发者在使用 CrewAI 构建智能体(Agent)时,通常会指定使用一个具体的大语言模型,例如 Google 的 Gemini 1.5 Flash。当一切 API 密钥和参数看似正确的情况下,执行流程却突然中断,并在控制台输出以下错误信息:

```
ERROR: LiteLLM call failed: litellm.BadRequestError: LLM Provider NOT provided. Pass in the LLM provider you are trying to call.
```

错误信息还详细地展示了传递给 LiteLLM 的参数:

```python
You passed model=model='models/gemini-1.5-flash'
google_api_key=SecretStr('**********')
temperature=0.5
...
```

随后,错误信息给出了一个使用示例,暗示模型名称的格式可能存在严重问题,即需要提供具体的服务提供商信息。

### 1.2 错误根源分析

LiteLLM 是一个非常流行的 Python 库,它的核心功能之一是提供一个统一的接口,让开发者可以通过相同的函数签名调用来自 OpenAI、Anthropic、Google、Replicate、HuggingFace、Ollama 等几十家提供商的模型。为了实现这一目标,LiteLLM 内部维护着一个路由表,它必须准确知道某个模型字符串对应的后端服务商是谁。

当 LiteLLM 接收到一个模型名称时,它会试图通过模型名的前缀或特定模式来解析提供者。例如,模型名 `gpt-4` 会被自动识别为 OpenAI;`claude-3-opus` 会被识别为 Anthropic。但是对于某些模型,尤其是来自 Google 的模型(如 `gemini-1.5-flash`),如果开发者仅仅传递了 `models/gemini-1.5-flash` 或类似的字符串,LiteLLM 的内置解析逻辑是无法直接将其与正确的提供商关联起来的。这主要是因为 Google 的服务存在多个入口,包括 Google AI Studio 和 Vertex AI,LiteLLM 无法自动判断用户意图是使用哪一条路径。因此,LiteLLM 抛出了 `BadRequestError`,明确要求用户“传递您尝试调用的 LLM 提供商”。

简而言之,这个错误的本质是 **模型标识符不明确**。虽然开发者提供了正确的 API Key 和模型参数,但在传递给 LiteLLM 时未能遵循其规定的命名空间约定,导致其缺乏足够的上下文信息来初始化正确的底层客户端。

## 二、解决方案与核心步骤

解决该问题的核心在于正确配置模型标识符。根据 Stack Overflow 上的高票回答以及社区的最佳实践,主要有以下两条必须遵守的原则。

### 2.1 使用 CrewAI 的 LLM 封装类

对于 CrewAI 用户而言,最直接且推荐的做法是利用 CrewAI 提供的 `LLM` 类。该类专门用于在 CrewAI 生态系统中管理模型配置,它在后台正确地封装了与 LiteLLM 的交互。直接向 `Agent` 传递原始的模型名称字符串(或者从 `langchain` 的 `ChatGoogleGenerativeAI` 等外部客户端)非常容易导致配置不匹配,从而引发 LiteLLM 路由错误。

正确做法是实例化一个 `crewai.LLM` 对象,并将其传递给智能体。

### 2.2 正确设置 LLM 提供者前缀

这是解决问题的关键细节。LiteLLM 通过模型字符串的特定前缀来识别提供者。对于 Google AI Studio(即 Gemini API 的个人版),需要在模型名称前加上 `gemini/` 前缀。

以下是一个经过验证的成功配置实例,用于配置使用 Gemini 1.5 Flash 的 CrewAI 智能体:

```python
from crewai import Agent, LLM
import os

# 确保环境变量已设置
# GEMINI_API_KEY 应该指向你的 Google API 密钥

# 正确实例化 LLM 对象
my_llm = LLM(
    api_key=os.getenv("GEMINI_API_KEY"),
    model="gemini/gemini-1.5-flash",  # 关键修正:添加了 "gemini/" 前缀
)

# 将配置好的 LLM 传递给 Agent
my_agent = Agent(
    role="研究分析师",
    goal="分析最新的AI趋势",
    backstory="你是一个专注于AI领域的资深分析师。",
    llm=my_llm,
)
```

对照之前的错误信息,原来传递的 `model='models/gemini-1.5-flash'` 是不正确的。LiteLLM 需要的是 `gemini/gemini-1.5-flash`。这里的 `gemini/` 就是告诉 LiteLLM:这个请求应该路由到 Google Gemini(Google AI Studio)的端点,并使用 `google.generativeai` 客户端库。

### 2.3 其他常见提供商的格式模板

为了提供一个更全面的参考,以下是目前主流 LLM 提供商在 LiteLLM 中的模型字符串命名规范。遵循这些格式可以有效避免同类错误。

-   **OpenAI**: `gpt-4o` 或 `gpt-4-turbo`。通常不需要显式指定提供商,LiteLLM 能自动识别。但为了保险,亦可写作 `openai/gpt-4o`。
-   **Azure OpenAI**: `azure/your-deployment-name`。必须包含 `azure/` 前缀,并使用你的部署名而非标准模型名。
-   **Anthropic**: `anthropic/claude-3-opus-20240229`。必须包含 `anthropic/` 前缀。
-   **Mistral API**: `mistral/mistral-large-latest`。必须包含 `mistral/` 前缀。
-   **Groq**: `groq/llama3-70b-8192`。必须包含 `groq/` 前缀。
-   **Ollama**: `ollama/llama2`。必须包含 `ollama/` 前缀。该模式支持本地运行的模型。
-   **HuggingFace**: `huggingface/mistralai/Mistral-7B-Instruct-v0.1`。必须包含 `huggingface/` 前缀。
-   **Replicate**: `replicate/meta/meta-llama-3-8b-instruct`。必须包含 `replicate/` 前缀。
-   **Together AI**: `together_ai/togethercomputer/llama-2-70b-chat`。必须包含 `together_ai/` 前缀。
-   **Vertex AI (Google Cloud)**: `vertex_ai/gemini-1.5-pro`。必须包含 `vertex_ai/` 前缀。
-   **Bedrock (AWS)**: `bedrock/anthropic.claude-3-sonnet-20240229-v1:0`。必须包含 `bedrock/` 前缀。
-   **Cohere**: `cohere/command-r-plus`。必须包含 `cohere/` 前缀。
-   **Databricks**: `databricks/databricks-llama-2-70b-chat`。必须包含 `databricks/` 前缀。
-   **Fireworks AI**: `fireworks_ai/accounts/fireworks/models/llama-v3-70b-instruct`。必须包含 `fireworks_ai/` 前缀。
-   **NVIDIA NIM**: `nvidia_nim/nvidia/llama-3.1-8b-instruct`。必须包含 `nvidia_nim/` 前缀。

请注意,上述列表是动态变化的,随着新提供商的加入,命名规范可能会更新。遇到错误时,最可靠的参考来源是 LiteLLM 官方文档的 Providers 页面。

### 2.4 一个更广泛的案例:LiteLLM UI 中的配置

除了在代码中使用 CrewAI 和 LangChain,很多团队也会使用 LiteLLM 自带的 UI(用户界面)作为代理服务器(Proxy)来管理和路由请求。在这种情况下,同样可能遇到类似的错误。

如上文 Stack Overflow 回答中的提及,当用户在 LiteLLM UI 的“添加新模型”界面中配置模型时,需要正确填写两个字段。

-   **公共模型名称 (Public Model Name)**:这是供用户选择或 API 调用时使用的名称,例如 `llama`。
-   **LiteLLM 模型名称 (LiteLLM Model Name)**:这是实际需要传递给 LiteLLM 后端路由引擎的字符串。

错误的配置方式是:公共模型名称写 `llama:latest`,而 LiteLLM 模型名称只写 `llama`。这样 LiteLLM 无法获知其来自哪个提供商。

正确的配置应该是在 LiteLLM Model Name(s) 字段中填入完整的带前缀字符串,例如 `ollama/llama`(如果模型托管在 Ollama)。完成此修正后,健康检查和密钥测试都将顺利通过。这再次印证了核心原则:**LiteLLM 模型名称必须包含提供商标识符**。

## 三、深度原理与最佳实践

### 3.1 为什么需要显式声明提供商?

LiteLLM 的设计哲学是“开箱即用”与“灵活性”的平衡。虽然它能自动识别 `gpt` 和 `claude` 系列,但现代 LLM 生态系统极其庞杂。同样一个模型名称(如 `llama2`)可以运行在多个平台上:本地 Ollama、云端 Together AI、AWS Bedrock 或者 Replicate。如果不通过前缀指明提供商,LiteLLM 的无状态路由逻辑无法做出准确判断。

此外,每个提供商的 API 端点、请求格式、认证方式以及 SDK 都完全不同。LiteLLM 在解析出提供商后,会动态加载相应的适配器(Adapter)来构造请求。例如,调用 Gemini 模型需要构造 `genai.GenerativeModel` 并设置 `safety_settings` 等参数;而调用 OpenAI 模型则需要构造 `openai.ChatCompletion` 并可能设置 `response_format`。因此,在没有提供商信息的情况下,LiteLLM 根本无法完成这一底层适配过程。

### 3.2 预防措施与调试建议

为了提升开发效率并避免此类错误反复出现,建议开发者养成以下良好习惯。

-   **始终检查模型字符串格式**:在将模型名称硬编码或作为环境变量传入之前,查阅 LiteLLM 官方支持的模型列表,或者直接使用 `litellm.supported_providers` 和 `litellm.model_cost` 来验证格式。
-   **优先使用框架内置的 LLM 类**:无论是 CrewAI、LangChain 还是其他框架,它们提供的 `LLM` 类通常已经处理了与 LiteLLM 的兼容性问题。尽可能绕开直接使用 `ChatOpenAI` 或 `ChatGooglePalm` 等特定提供商的类来初始化 Agent,除非你非常确定底层路由。
-   **启用详细的日志记录**:如果遇到难以定位的 LiteLLM 相关错误,可以尝试启用 debug 级别的日志输出。
    ```python
    import logging
    logging.basicConfig(level=logging.DEBUG)
    ```
    这会打印出 LiteLLM 内部解析模型名称、获取配置、尝试连接等所有细节,通常能准确指出是哪一步解析失败。
-   **注意版本兼容性**:框架和 SDK 的版本更新频繁。特别是 LiteLLM 和 CrewAI 的版本演进,可能会调整模型命名规则。在项目初期就锁定关键依赖的版本(例如使用 `requirements.txt` 或 `pyproject.toml` 指定版本号),可以避免因新版 API 变更引发的意外错误。
-   **环境变量与密钥管理**:确保所有敏感的 API 密钥是通过环境变量(如 `.env` 文件配合 `python-dotenv` 库)加载,而不是直接写在代码里。错误信息中已经展示 `google_api_key=SecretStr('**********')`,这说明密钥已被正确遮蔽,但加载路径仍须确保无误。

## 四、总结

`litellm.BadRequestError: LLM Provider NOT provided` 错误是使用多层 LLM 抽象框架时极易遭遇的典型配置问题。其根源在于,以简化多模型调用为目标的 LiteLLM,其工作方式极度依赖于一个包含提供商前缀的精确模型标识符。

本文详细阐述了该错误的产生环境、根本原因以及多层级的解决方案。对于 CrewAI 用户,核心修复是多采用框架自带的 `LLM` 类,并确保模型名称使用正确的命名空间格式,例如 `gemini/gemini-1.5-flash` 而非 `models/gemini-1.5-flash`。同时,文章也整理了一张涵盖主流 LLM 服务商的命名前缀速查表,供开发者快速参考,避免在细微的字符串差异上浪费时间。

理解这一错误的本质,不仅有助于我们快速解决问题,更能加深对现代 LLM 应用架构中抽象层工作原理的认识。每一次看似繁琐的配置要求背后,都隐藏着为了兼容性和灵活性所做的精细设计。通过遵循这些规范,开发者能够更顺畅地利用这些强大工具,构建出可靠和高效的 AI 应用。最终,请始终记得,唯一的权威信息来源是 LiteLLM 官方的文档页面。遇到疑惑时,查阅官方文档是最为稳妥和高效的决策。