> ## Documentation Index
> Fetch the complete documentation index at: https://langchain.idochub.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# 模型

<Warning>
  **Alpha 版本提示：** 本文档涵盖的是 **v1-alpha** 版本。内容尚不完整，且可能随时变更。

  如需查阅最新稳定版本，请参阅 v0 版本的 [LangChain Python 文档](https://python.langchain.com/docs/introduction/) 或 [LangChain JavaScript 文档](https://js.langchain.com/docs/introduction/)。
</Warning>

[大型语言模型（LLMs）](https://zh.wikipedia.org/wiki/%E5%A4%A7%E5%9E%8B%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B) 是强大的人工智能工具，能够像人类一样理解和生成文本。它们功能多样，无需为每项任务进行专门训练，即可撰写内容、翻译语言、总结信息和回答问题。

除了文本生成，许多模型还支持：

* <Icon icon="hammer" size={16} /> [工具调用](#tool-calling) - 调用外部工具（如数据库查询或 API 调用），并在其响应中使用结果。
* <Icon icon="shapes" size={16} /> [结构化输出](#structured-outputs) - 模型的响应被约束为遵循预定义的格式。
* <Icon icon="image" size={16} /> [多模态](#multimodal) - 处理并返回除文本以外的数据，如图像、音频和视频。
* <Icon icon="brain" size={16} /> [推理](#reasoning) - 模型执行多步推理以得出结论。

有关特定提供商的集成信息和能力，请参阅提供商的[集成页面](/oss/python/integrations/providers)。

## 基本用法

在 LangChain 中开始使用模型最简单的方法是使用 `init_chat_model` 从您选择的[提供商](/oss/python/integrations/providers)初始化一个模型：

```python 初始化聊天模型 theme={null}
from langchain.chat_models import init_chat_model

model = init_chat_model("openai:gpt-5-nano")
response = model.invoke("为什么鹦鹉会说话？")
```

更多详情请参见 [`init_chat_model`](https://python.langchain.com/api_reference/langchain/chat_models/langchain.chat_models.base.init_chat_model.html)。

### 关键方法

<Card title="调用" href="#invoke" icon="paper-plane" arrow="true" horizontal>
  模型以消息作为输入，在生成完整响应后输出消息。
</Card>

<Card title="流式传输" href="#stream" icon="tower-broadcast" arrow="true" horizontal>
  调用模型，但在生成时实时流式传输输出。
</Card>

<Card title="批处理" href="#batch" icon="grip" arrow="true" horizontal>
  批量向模型发送多个请求，以实现更高效的处理。
</Card>

<Info>
  除了聊天模型，LangChain 还支持其他相关技术，例如嵌入模型和向量存储。详情请参阅[集成页面](/oss/python/integrations/providers)。
</Info>

## 参数

聊天模型接受可用于配置其行为的参数。支持的完整参数集因模型和提供商而异，但标准参数包括：

<ParamField body="model" type="string" required>
  您希望与提供商一起使用的特定模型的名称或标识符。
</ParamField>

<ParamField body="api_key" type="string">
  与模型提供商进行身份验证所需的密钥。通常在您注册获取模型访问权限时颁发。通常通过设置<Tooltip tip="在程序外部设置其值的变量，通常通过操作系统或微服务内置的功能。">环境变量</Tooltip>来访问。
</ParamField>

<ParamField body="temperature" type="number">
  控制模型输出的随机性。较高的数值使响应更具创造性；较低的数值使其更具确定性。
</ParamField>

<ParamField body="stop" type="string[]">
  一串字符，指示模型何时应停止生成输出。
</ParamField>

<ParamField body="timeout" type="number">
  在取消请求之前等待模型响应的最长时间（以秒为单位）。
</ParamField>

<ParamField body="max_tokens" type="number">
  限制响应中<Tooltip tip="模型读取和生成的基本单位。提供商的定义可能不同，但通常可以代表一个完整的单词或部分单词。">令牌</Tooltip>的总数，从而有效控制输出的长度。
</ParamField>

<ParamField body="max_retries" type="number">
  如果请求因网络超时或速率限制等问题失败，系统将重试发送请求的最大次数。
</ParamField>

<Info>
  要查找给定聊天模型支持的所有参数，请前往[参考文档](https://python.langchain.com/api_reference/)。
</Info>

***

## 调用

必须调用聊天模型才能生成输出。有三种主要的调用方法，每种方法适用于不同的用例。

<Tip>
  每种调用方法都有一个<Tooltip tip="异步方法对于非阻塞操作非常有用，尤其是在处理多个并发任务的 Web 服务器或应用程序中。">异步</Tooltip>等效方法，通常以字母 `'a'` 为前缀。

  例如：`ainvoke()`、`astream()`、`abatch()`。

  完整的异步方法列表可在[参考文档](https://python.langchain.com/api_reference/)中找到。
</Tip>

### 调用

调用模型最直接的方法是使用 [`invoke()`](https://python.langchain.com/api_reference/core/language_models/langchain_core.language_models.chat_models.BaseChatModel.html#langchain_core.language_models.chat_models.BaseChatModel.invoke) 并传入单条消息或消息列表。

```python 单条消息 theme={null}
response = model.invoke("为什么鹦鹉有彩色的羽毛？")
print(response)
```

可以向模型提供消息列表以表示对话历史。每条消息都有一个角色，模型使用该角色来指示对话中发送消息的人。有关角色、类型和内容的更多详细信息，请参阅[消息](/oss/python/langchain/messages)指南。

```python 对话历史 theme={null}
from langchain.messages import HumanMessage, AIMessage, SystemMessage

conversation = [
    SystemMessage("你是一个将英语翻译成法语的助手。"),
    HumanMessage("翻译：我喜欢编程。"),
    AIMessage("J'adore la programmation."),
    HumanMessage("翻译：我喜欢构建应用程序。")
]

response = model.invoke(conversation)
print(response)  # AIMessage("J'adore créer des applications.")
```

### 流式传输

大多数模型可以在生成输出内容时对其进行流式传输。通过逐步显示输出，流式传输显著改善了用户体验，特别是对于较长的响应。

调用 [`stream()`](https://python.langchain.com/api_reference/core/language_models/langchain_core.language_models.chat_models.BaseChatModel.html#langchain_core.language_models.chat_models.BaseChatModel.stream) 会返回一个<Tooltip tip="一个对象，按顺序逐步提供对集合中每个项目的访问。">迭代器</Tooltip>，该迭代器在生成输出块时产生输出块。您可以使用循环实时处理每个块：

<CodeGroup>
  ```python 基本文本流式传输 theme={null}
  for chunk in model.stream("为什么鹦鹉有彩色的羽毛？"):
      print(chunk.text, end="|", flush=True)
  ```

  ```python 流式传输工具调用、推理和其他内容 theme={null}
  for chunk in model.stream("天空是什么颜色？"):
      for block in chunk.content_blocks:
          if block["type"] == "reasoning" and (reasoning := block.get("reasoning")):
              print(f"推理：{reasoning}")
          elif block["type"] == "tool_call_chunk":
              print(f"工具调用块：{block}")
          elif block["type"] == "text":
              print(block["text"])
          else:
              ...
  ```
</CodeGroup>

与在模型生成完整响应后返回单个 [`AIMessage`](https://python.langchain.com/api_reference/core/messages/langchain_core.messages.ai.AIMessage.html) 的 `invoke()` 不同，`stream()` 返回多个 [`AIMessageChunk`](https://python.langchain.com/api_reference/core/messages/langchain_core.messages.ai.AIMessageChunk.html) 对象，每个对象包含输出文本的一部分。重要的是，流中的每个块都设计为可以通过求和聚合成完整的消息：

```python 构造 AIMessage theme={null}
full = None  # None | AIMessageChunk
for chunk in model.stream("天空是什么颜色？"):
    full = chunk if full is None else full + chunk
    print(full.text)

# 天
# 天空
# 天空是
# 天空通常是
# 天空通常是蓝色的
# ...

print(full.content_blocks)
# [{"type": "text", "text": "天空通常是蓝色的..."}]
```

生成的消息可以像使用 [`invoke()`](#invoke) 生成的消息一样处理——例如，它可以聚合成消息历史并作为对话上下文传回给模型。

<Warning>
  仅当程序中的所有步骤都知道如何处理块流时，流式传输才有效。例如，一个不具备流式传输能力的应用程序是需要在处理之前将整个输出存储在内存中的应用程序。
</Warning>

<Accordion title="高级流式传输主题">
  <Accordion title="&#x22;自动流式传输&#x22;聊天模型">
    LangChain 通过在某些情况下自动启用流式传输模式来简化从聊天模型进行流式传输，即使您没有显式调用流式传输方法。当您使用非流式传输的调用方法但仍希望流式传输整个应用程序（包括聊天模型的中间结果）时，这特别有用。

    例如，在 [LangGraph 代理](/oss/python/langchain/agents) 中，您可以在节点内调用 `model.invoke()`，但如果在流式传输模式下运行，LangChain 会自动委托给流式传输。

    #### 工作原理

    当您 `invoke()` 一个聊天模型时，如果 LangChain 检测到您正在尝试流式传输整个应用程序，它将自动切换到内部流式传输模式。就使用调用的代码而言，调用的结果是相同的；然而，在流式传输聊天模型时，LangChain 将负责在 LangChain 的回调系统中调用 `on_llm_new_token` 事件。

    回调事件允许 LangGraph `stream()` 和 [`astream_events()`](https://python.langchain.com/api_reference/core/language_models/langchain_core.language_models.chat_models.BaseChatModel.html#langchain_core.language_models.chat_models.BaseChatModel.astream_events) 实时显示聊天模型的输出。
  </Accordion>

  <Accordion title="流式传输事件">
    LangChain 聊天模型还可以使用 `astream_events()` 流式传输语义事件。

    这简化了基于事件类型和其他元数据的过滤，并将在后台聚合完整的消息。请参见下面的示例。

    ```python theme={null}
    async for event in model.astream_events("你好"):

        if event["event"] == "on_chat_model_start":
            print(f"输入：{event['data']['input']}")

        elif event["event"] == "on_chat_model_stream":
            print(f"令牌：{event['data']['chunk'].text}")

        elif event["event"] == "on_chat_model_end":
            print(f"完整消息：{event['data']['output'].text}")

        else:
            pass
    ```

    ```txt theme={null}
    输入：你好
    令牌：嗨
    令牌：  那里
    令牌：！
    令牌：  我
    令牌：  可以
    令牌：  我
    ...
    完整消息：嗨那里！我今天能帮什么忙？
    ```

    有关事件类型和其他详细信息，请参见 [`astream_events()`](https://python.langchain.com/api_reference/core/language_models/langchain_core.language_models.chat_models.BaseChatModel.html#langchain_core.language_models.chat_models.BaseChatModel.astream_events) 参考。
  </Accordion>
</Accordion>

### 批处理

对模型的一组独立请求进行批处理可以显著提高性能并降低成本，因为处理可以并行进行：

```python 批处理 theme={null}
responses = model.batch([
    "为什么鹦鹉有彩色的羽毛？",
    "飞机如何飞行？",
    "什么是量子计算？"
])
for response in responses:
    print(response)
```

<Note>
  本节描述的是聊天模型方法 `batch()`，它在客户端并行化模型调用。

  它与推理提供商支持的批处理 API **不同**，例如 [OpenAI](https://platform.openai.com/docs/guides/batch) 或 [Anthropic](https://docs.anthropic.com/en/docs/build-with-claude/batch-processing#message-batches-api)。
</Note>

默认情况下，[`batch()`](https://python.langchain.com/api_reference/core/language_models/langchain_core.language_models.chat_models.BaseChatModel.html#langchain_core.language_models.chat_models.BaseChatModel.batch) 只会返回整个批处理的最终输出。如果您希望在每个输入完成生成时接收其输出，可以使用 [`batch_as_completed()`](https://python.langchain.com/api_reference/core/language_models/langchain_core.language_models.chat_models.BaseChatModel.html#langchain_core.language_models.chat_models.BaseChatModel.batch_as_completed) 流式传输结果：

```python 在完成时生成批处理响应 theme={null}
for response in model.batch_as_completed([
    "为什么鹦鹉有彩色的羽毛？",
    "飞机如何飞行？",
    "什么是量子计算？"
]):
    print(response)
```

<Note>
  使用 `batch_as_completed()` 时，结果可能会乱序到达。每个结果都包含输入索引，以便在需要时匹配以重建原始顺序。
</Note>

<Tip>
  使用 `batch()` 或 `batch_as_completed()` 处理大量输入时，您可能希望控制最大并行调用数。这可以通过在 `RunnableConfig` 字典中设置 `max_concurrency` 属性来完成。

  ```python 带最大并发数的批处理 theme={null}
  model.batch(
      list_of_inputs,
      config={
          'max_concurrency': 5,  # 限制为 5 个并行调用
      }
  )
  ```

  有关支持的属性的完整列表，请参见 [`RunnableConfig`](https://python.langchain.com/api_reference/core/runnables/langchain_core.runnables.config.RunnableConfig.html) 参考。
</Tip>

有关批处理的更多详细信息，请参见 [参考](https://python.langchain.com/api_reference/core/language_models/langchain_core.language_models.chat_models.BaseChatModel.html#langchain_core.language_models.chat_models.BaseChatModel.batch)。

***

## 工具调用

模型可以请求调用执行任务的工具，例如从数据库获取数据、搜索网络或运行代码。工具是以下内容的配对：

1. 一个模式，包括工具的名称、描述和/或参数定义（通常是一个 JSON 模式）
2. 一个函数或<Tooltip tip="一种可以暂停执行并在稍后恢复的方法">协程</Tooltip>来执行。

<Note>
  您可能会听到“函数调用”这个术语。我们将其与“工具调用”互换使用。
</Note>

要使您定义的工具可供模型使用，必须使用 [`bind_tools()`](https://python.langchain.com/api_reference/core/language_models/langchain_core.language_models.chat_models.BaseChatModel.html#langchain_core.language_models.chat_models.BaseChatModel.bind_tools) 将其绑定。在后续调用中，模型可以根据需要选择调用任何绑定的工具。

一些模型提供商提供可以通过模型参数启用的内置工具。有关详细信息，请参阅相应的[提供商参考](/oss/python/integrations/providers)。

<Tip>
  有关创建工具的详细信息和其他选项，请参阅[工具指南](/oss/python/langchain/tools)。
</Tip>

```python 绑定用户工具 highlight={8} theme={null}
from langchain_core.tools import tool

@tool
def get_weather(location: str) -> str:
    """获取某个位置的天气。"""
    return f"{location} 的天气晴朗。"


model_with_tools = model.bind_tools([get_weather])

response = model_with_tools.invoke("波士顿的天气怎么样？")
for tool_call in response.tool_calls:
    # 查看模型进行的工具调用
    print(f"工具：{tool_call['name']}")
    print(f"参数：{tool_call['args']}")
```

绑定用户定义的工具时，模型的响应包括执行工具的**请求**。由您执行请求的操作并将结果返回给模型，以便在后续推理中使用。

下面，我们展示了一些使用工具调用的常见方法。

<AccordionGroup>
  <Accordion title="工具执行循环" icon="arrow-rotate-right">
    当模型返回工具调用时，您需要执行工具并将结果传回给模型。这会创建一个对话循环，模型可以使用工具结果生成其最终响应。

    ```python 工具执行循环 theme={null}
    # 将（可能多个）工具绑定到模型
    model_with_tools = model.bind_tools([get_weather])

    # 第 1 步：模型生成工具调用
    messages = [{"role": "user", "content": "波士顿的天气怎么样？"}]
    ai_msg = model_with_tools.invoke(messages)
    messages.append(ai_msg)

    # 第 2 步：执行工具并收集结果
    for tool_call in ai_msg.tool_calls:
        # 使用生成的参数执行工具
        tool_result = get_weather.invoke(tool_call)
        messages.append(tool_result)

    # 第 3 步：将结果传回给模型以生成最终响应
    final_response = model_with_tools.invoke(messages)
    print(final_response.text)
    # "波士顿当前的天气是 72°F，晴朗。"
    ```

    工具返回的每个 `ToolMessage` 都包含一个 `tool_call_id`，该 ID 与原始工具调用匹配，帮助模型将结果与请求关联起来。
  </Accordion>

  <Accordion title="强制工具调用" icon="asterisk">
    默认情况下，模型可以根据用户的输入自由选择使用哪个绑定工具。但是，您可能希望强制选择工具，确保模型使用特定工具或给定列表中的*任何*工具：

    <CodeGroup>
      ```python 强制使用任何工具 theme={null}
          model_with_tools = model.bind_tools([tool_1], tool_choice="any")
      ```

      ```python 强制使用特定工具 theme={null}
          model_with_tools = model.bind_tools([tool_1], tool_choice="tool_1")
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="并行工具调用" icon="layer-group">
    许多模型在适当的情况下支持并行调用多个工具。这允许模型同时从不同来源收集信息。

    ```python 并行工具调用 theme={null}
    model_with_tools = model.bind_tools([get_weather])

    response = model_with_tools.invoke(
        "波士顿和东京的天气怎么样？"
    )


    # 模型可能会生成多个工具调用
    print(response.tool_calls)
    # [
    #   {'name': 'get_weather', 'args': {'location': 'Boston'}, 'id': 'call_1'},
    #   {'name': 'get_time', 'args': {'location': 'Tokyo'}, 'id': 'call_2'}
    #]


    # 执行所有工具（可以使用异步并行执行）
    results = []
    for tool_call in response.tool_calls:
        if tool_call['name'] == 'get_weather':
            result = get_weather.invoke(tool_call)
        ...
        results.append(result)
    ```

    模型根据所请求操作的独立性智能地确定何时适合并行执行。
  </Accordion>

  <Accordion title="流式传输工具调用" icon="rss">
    流式传输响应时，工具调用通过 `ToolCallChunk` 逐步构建。这允许您在生成工具调用时查看它们，而不是等待完整响应。

    ```python 流式传输工具调用 theme={null}
    for chunk in model_with_tools.stream(
        "波士顿和东京的天气怎么样？"
    ):
        # 工具调用块逐步到达
        if chunk.tool_call_chunks:
            for tool_chunk in chunk.tool_call_chunks:
                print(f"工具：{tool_chunk.get('name', '')}")
                print(f"参数：{tool_chunk.get('args', '')}")

    # 输出：
    # 工具：get_weather            # 循环 1
    # 参数：
    # 工具：                        # 循环 2
    # 参数：{"loc
    # 工具：                        # 循环 3
    # 参数：ation": "BOS"}
    # 工具：get_time               # 循环 4
    # 参数：
    # 参数：
    # 工具：                        # 循环 5
    # 参数：{"timezone": "Tokyo"}
    ```

    您可以累积块以构建完整的工具调用：

    ```python 累积工具调用 theme={null}
    gathered = None
    for chunk in model_with_tools.stream("波士顿的天气怎么样？"):
        gathered = chunk if gathered is None else gathered + chunk
        print(gathered.content_blocks)
    ```
  </Accordion>
</AccordionGroup>

***

## 结构化输出

可以请求模型以匹配给定模式的格式提供其响应。这对于确保输出可以轻松解析并在后续处理中使用非常有用。LangChain 支持多种模式类型和强制执行结构化输出的方法。

<Tabs>
  <Tab title="Pydantic">
    [Pydantic 模型](https://docs.pydantic.dev/latest/concepts/models/#basic-model-usage) 提供最丰富的功能集，包括字段验证、描述和嵌套结构。

    ```python theme={null}
    from pydantic import BaseModel, Field

    class Movie(BaseModel):
        """一部包含详细信息的电影。"""
        title: str = Field(..., description="电影的标题")
        year: int = Field(..., description="电影发行的年份")
        director: str = Field(..., description="电影的导演")
        rating: float = Field(..., description="电影的评分，满分 10 分")

    model_with_structure = model.with_structured_output(Movie)
    response = model_with_structure.invoke("提供电影《盗梦空间》的详细信息")
    print(response)  # Movie(title="盗梦空间", year=2010, director="克里斯托弗·诺兰", rating=8.8)
    ```
  </Tab>

  <Tab title="TypedDict">
    `TypedDict` 提供了一个更简单的替代方案，使用 Python 的内置类型，当您不需要运行时验证时非常理想。

    ```python theme={null}
    from typing_extensions import TypedDict, Annotated

    class MovieDict(TypedDict):
        """一部包含详细信息的电影。"""
        title: Annotated[str, ..., "电影的标题"]
        year: Annotated[int, ..., "电影发行的年份"]
        director: Annotated[str, ..., "电影的导演"]
        rating: Annotated[float, ..., "电影的评分，满分 10 分"]

    model_with_structure = model.with_structured_output(MovieDict)
    response = model_with_structure.invoke("提供电影《盗梦空间》的详细信息")
    print(response)  # {'title': '盗梦空间', 'year': 2010, 'director': '克里斯托弗·诺兰', 'rating': 8.8}
    ```
  </Tab>

  <Tab title="JSON 模式">
    为了获得最大控制权或互操作性，您可以提供原始 JSON 模式。

    ```python theme={null}
    import json

    json_schema = {
        "title": "Movie",
        "description": "一部包含详细信息的电影",
        "type": "object",
        "properties": {
            "title": {
                "type": "string",
                "description": "电影的标题"
            },
            "year": {
                "type": "integer",
                "description": "电影发行的年份"
            },
            "director": {
                "type": "string",
                "description": "电影的导演"
            },
            "rating": {
                "type": "number",
                "description": "电影的评分，满分 10 分"
            }
        },
        "required": ["title", "year", "director", "rating"]
    }

    model_with_structure = model.with_structured_output(
        json_schema,
        method="json_schema",
    )
    response = model_with_structure.invoke("提供电影《盗梦空间》的详细信息")
    print(response)  # {'title': '盗梦空间', 'year': 2010, ...}
    ```
  </Tab>
</Tabs>

以下是您提供的英文技术文档的中文翻译：

***

<Note>
  **结构化输出的关键注意事项：**

  * **方法参数**：部分提供商支持不同的方法（`'json_schema'`、`'function_calling'`、`'json_mode'`）
  * **包含原始响应**：使用 `include_raw=True` 可同时获取解析后的输出和原始 AI 消息
  * **验证机制**：Pydantic 模型提供自动验证，而 `TypedDict` 和 JSON Schema 需要手动验证
</Note>

<Accordion title="示例：消息输出与解析结构并存">
  有时需要同时返回原始 `AIMessage` 对象和解析后的表示形式，以便访问响应元数据（例如 [token 使用量](#token-usage)）：

  ```python highlight={10} theme={null}
  from pydantic import BaseModel, Field

  class Movie(BaseModel):
      """包含详细信息的电影"""
      title: str = Field(..., description="电影名称")
      year: int = Field(..., description="电影上映年份")
      director: str = Field(..., description="导演姓名")
      rating: float = Field(..., description="电影评分（满分10分）")

  model_with_structure = model.with_structured_output(Movie, include_raw=True)
  response = model_with_structure.invoke("提供电影《盗梦空间》的详细信息")
  response
  # {
  #     "raw": AIMessage(...),
  #     "parsed": Movie(title=..., year=..., ...),
  #     "parsing_error": None,
  # }
  ```
</Accordion>

<Accordion title="示例：嵌套结构">
  <CodeGroup>
    ```python Pydantic BaseModel theme={null}
    from pydantic import BaseModel, Field

    class Actor(BaseModel):
        name: str
        role: str

    class MovieDetails(BaseModel):
        title: str
        year: int
        cast: list[Actor]
        genres: list[str]
        budget: float | None = Field(None, description="预算（单位：百万美元）")

    model_with_structure = model.with_structured_output(MovieDetails)
    ```

    ```python TypedDict theme={null}
    from typing_extensions import Annotated, TypedDict

    class Actor(TypedDict):
        name: str
        role: str

    class MovieDetails(TypedDict):
        title: str
        year: int
        cast: list[Actor]
        genres: list[str]
        budget: Annotated[float | None, ..., "预算（单位：百万美元）"]

    model_with_structure = model.with_structured_output(MovieDetails)
    ```
  </CodeGroup>
</Accordion>

***

## 支持的模型

LangChain 支持所有主流模型提供商，包括 OpenAI、Anthropic、Google、Azure、AWS Bedrock 等。每个提供商都提供多种具备不同能力的模型。如需查看 LangChain 支持的完整模型列表，请参阅 [集成页面](/oss/python/integrations/providers)。

***

## 高级配置

### 多模态支持

某些模型可以处理并返回非文本数据，如图像、音频和视频。您可以通过提供 [内容块](/oss/python/langchain/messages#content) 向模型传递非文本数据。

<Tip>
  所有具备底层多模态能力的 LangChain 聊天模型均支持：

  1. 跨提供商的标准数据格式（请参阅 [消息指南](/oss/python/langchain/messages)）
  2. OpenAI 的 [聊天补全格式](https://platform.openai.com/docs/guides/images-vision?api-mode=chat)
  3. 特定提供商的原生格式（例如，Anthropic 模型接受其原生格式）
</Tip>

详情请参阅消息指南中的 [多模态章节](/oss/python/langchain/messages#multimodal)。

某些模型也可以在响应中返回多模态数据。在这种情况下，生成的 `AIMessage` 将包含具有多模态类型的内容块。

```python 多模态输出 theme={null}
response = model.invoke("生成一张猫的图片")
print(response.content_blocks)
# [
#     {"type": "text", "text": "这是一张猫的图片"},
#     {"type": "image", "base64": "...", "mime_type": "image/jpeg"},
# ]
```

有关具体提供商的详细信息，请参阅 [集成页面](/oss/python/integrations/providers)。

### 推理能力

较新的模型能够执行多步推理以得出结论。这包括将复杂问题分解为更小、更易管理的步骤。

如果底层模型支持，您可以暴露这一推理过程，以便更好地理解模型是如何得出最终答案的。

<CodeGroup>
  ```python 流式输出推理步骤 theme={null}
  for chunk in model.stream("为什么鹦鹉羽毛颜色鲜艳？"):
      reasoning_steps = [r for r in chunk.content_blocks if r["type"] == "reasoning"]
      print(reasoning_steps if reasoning_steps else chunk.text)
  ```

  ```python 完整推理输出 theme={null}
  response = model.invoke("为什么鹦鹉羽毛颜色鲜艳？")
  reasoning_steps = [b for b in response.content_blocks if b["type"] == "reasoning"]
  print(" ".join(step["reasoning"] for step in reasoning_steps))
  ```
</CodeGroup>

根据模型的不同，您有时可以指定模型应投入多少精力进行推理。或者，您可以要求模型完全关闭推理功能。这可能以推理“层级”（例如 `'low'` 或 `'high'`）或整数 token 预算的形式体现。

详情请参阅 [集成页面](/oss/python/integrations/providers) 中的相关聊天模型说明。

### 本地模型

LangChain 支持在您自己的硬件上本地运行模型。这在数据隐私要求严格或希望避免使用云端模型成本的场景中非常有用。

[Ollama](/oss/python/integrations/chat/ollama) 是本地运行模型最简单的方式之一。完整的本地集成列表请参阅 [集成页面](/oss/python/integrations/providers)。

### 缓存机制

聊天模型 API 的调用通常较慢且昂贵。为缓解这一问题，LangChain 为聊天模型集成提供了可选的缓存层。

<Accordion title="为模型启用缓存" icon="database">
  默认情况下缓存是禁用的。要启用缓存，请导入：

  ```python theme={null}
  from langchain_core.globals import set_llm_cache
  ```

  接下来，选择一个缓存：

  <AccordionGroup>
    <Accordion title="内存缓存" icon="memory">
      一种临时缓存，将模型调用存储在内存中。环境重启后会被清除，且不跨进程共享。

      ```python InMemoryCache theme={null}
      from langchain_core.caches import InMemoryCache

      set_llm_cache(InMemoryCache())

      response = model.invoke("讲个笑话")
      response = model.invoke("讲个笑话")  # 快速，来自缓存
      ```
    </Accordion>

    <Accordion title="SQLite 缓存" icon="database">
      使用 SQLite 数据库存储响应，重启后依然有效

      ```python SQLite Cache theme={null}
      # 也可以使用 SQLite 缓存
      from langchain_community.cache import SQLiteCache

      set_llm_cache(SQLiteCache(database_path=".langchain.db"))

      response = model.invoke("讲个笑话")
      response = model.invoke("讲个笑话")  # 快速，来自缓存
      ```
    </Accordion>
  </AccordionGroup>
</Accordion>

### 速率限制

许多聊天模型提供商对单位时间内可执行的调用次数设置了限制。如果您触发了速率限制，通常会收到来自提供商的速率限制错误响应，需要等待一段时间后才能继续请求。

为帮助管理速率限制，聊天模型集成在初始化时接受一个 `rate_limiter` 参数，用于控制请求速率。

<Accordion title="初始化并使用速率限制器" icon="gauge-high">
  LangChain 内置（可选）的内存速率限制器。该限制器是线程安全的，可被同一进程中的多个线程共享。

  ```python 定义速率限制器 highlight={12} theme={null}
  from langchain_core.rate_limiters import InMemoryRateLimiter

  rate_limiter = InMemoryRateLimiter(
          requests_per_second=0.1,  # 每10秒1次请求
          check_every_n_seconds=0.1,  # 每100毫秒检查一次是否允许发起请求
          max_bucket_size=10,  # 控制最大突发请求量
  )

  model = init_chat_model(
      model="gpt-5",
      model_provider="openai",
      rate_limiter=rate_limiter
  )
  ```

  <Warning>
    提供的速率限制器只能限制单位时间内的请求数量。如果您还需要根据请求大小进行限制，则无能为力。
  </Warning>
</Accordion>

### 基础 URL 或代理

对于许多聊天模型集成，您可以配置 API 请求的基础 URL，从而使用具有 OpenAI 兼容 API 的模型提供商或通过代理服务器访问。

<Accordion title="基础 URL" icon="link">
  许多模型提供商提供 OpenAI 兼容的 API（例如 [Together AI](https://www.together.ai/)、[vLLM](https://github.com/vllm-project/vllm)）。您可以通过指定适当的 `base_url` 参数，在 `init_chat_model` 中使用这些提供商：

  ```python theme={null}
  model = init_chat_model(
      model="MODEL_NAME",
      model_provider="openai",
      base_url="BASE_URL",
      api_key="YOUR_API_KEY",
  )
  ```

  <Note>
    当直接实例化聊天模型类时，参数名称可能因提供商而异。请查阅相应的 [参考文档](/oss/python/integrations/providers) 以获取详细信息。
  </Note>
</Accordion>

<Accordion title="代理配置" icon="shield">
  对于需要 HTTP 代理的部署，部分模型集成支持代理配置：

  ```python theme={null}
  from langchain_openai import ChatOpenAI

  model = ChatOpenAI(
      model="gpt-4o",
      openai_proxy="http://proxy.example.com:8080"
  )
  ```

  <Note>
    代理支持因集成而异。请查阅具体模型提供商的 [参考文档](/oss/python/integrations/providers) 以了解代理配置选项。
  </Note>
</Accordion>

### 对数概率（Log Probabilities）

某些模型可以配置为返回 token 级别的对数概率，表示给定 token 的可能性。只需在初始化模型时设置 `logprobs` 参数即可访问：

```python 对数概率 theme={null}
model = init_chat_model(
    model="gpt-4o",
    model_provider="openai"
).bind(logprobs=True)

response = model.invoke("为什么鹦鹉会说话？")
print(response.response_metadata["logprobs"])
```

### Token 使用量

许多模型提供商在调用响应中返回 token 使用量信息。当可用时，这些信息将包含在相应模型生成的 `AIMessage` 对象中。更多详情请参阅 [消息指南](/oss/python/langchain/messages)。

<Note>
  某些提供商 API（特别是 OpenAI 和 Azure OpenAI 聊天补全）要求用户在流式传输上下文中主动选择接收 token 使用量数据。详情请参阅集成指南中的 [流式使用量元数据](/oss/python/integrations/chat/openai#streaming-usage-metadata) 部分。
</Note>

您可以使用回调或上下文管理器跟踪应用程序中跨模型的总 token 计数，如下所示：

<Tabs>
  <Tab title="回调处理器">
    ```python 回调处理器 theme={null}
    from langchain.chat_models import init_chat_model
    from langchain_core.callbacks import UsageMetadataCallbackHandler

    llm_1 = init_chat_model(model="openai:gpt-4o-mini")
    llm_2 = init_chat_model(model="anthropic:claude-3-5-haiku-latest")

    callback = UsageMetadataCallbackHandler()
    result_1 = llm_1.invoke("你好", config={"callbacks": [callback]})
    result_2 = llm_2.invoke("你好", config={"callbacks": [callback]})
    callback.usage_metadata
    ```

    ```
    {
        'gpt-4o-mini-2024-07-18': {
            'input_tokens': 8,
            'output_tokens': 10,
            'total_tokens': 18,
            'input_token_details': {'audio': 0, 'cache_read': 0},
            'output_token_details': {'audio': 0, 'reasoning': 0}},
            'claude-3-5-haiku-20241022': {'input_tokens': 8,
            'output_tokens': 21,
            'total_tokens': 29,
            'input_token_details': {'cache_read': 0, 'cache_creation': 0}
        }
    }
    ```
  </Tab>

  <Tab title="上下文管理器">
    ```python 上下文管理器 theme={null}
    from langchain.chat_models import init_chat_model
    from langchain_core.callbacks import get_usage_metadata_callback

    llm_1 = init_chat_model(model="openai:gpt-4o-mini")
    llm_2 = init_chat_model(model="anthropic:claude-3-5-haiku-latest")

    with get_usage_metadata_callback() as cb:
        llm_1.invoke("你好")
        llm_2.invoke("你好")
        print(cb.usage_metadata)
    ```

    ```
    {
        'gpt-4o-mini-2024-07-18': {
            'input_tokens': 8,
            'output_tokens': 10,
            'total_tokens': 18,
            'input_token_details': {'audio': 0, 'cache_read': 0},
            'output_token_details': {'audio': 0, 'reasoning': 0}},
            'claude-3-5-haiku-20241022': {'input_tokens': 8,
            'output_tokens': 21,
            'total_tokens': 29,
            'input_token_details': {'cache_read': 0, 'cache_creation': 0}
        }
    }
    ```
  </Tab>
</Tabs>

### 调用配置

调用模型时，您可以通过 `config` 参数传递额外配置，使用 \[`RunnableConfig`]\[RunnableConfig] 字典。这提供了对执行行为、回调和元数据跟踪的运行时控制。

常见配置选项包括：

```python 带配置的调用 theme={null}
response = model.invoke(
    "讲个笑话",
        config={
        "run_name": "joke_generation",      # 此次运行的自定义名称
        "tags": ["humor", "demo"],          # 用于分类的标签
        "metadata": {"user_id": "123"},     # 自定义元数据
        "callbacks": [my_callback_handler], # 回调处理器
    }
)
```

<Accordion title="关键配置属性">
  <ParamField body="run_name" type="string">
    在日志和追踪中标识此次特定调用。不会被子调用继承。
  </ParamField>

  <ParamField body="tags" type="string[]">
    由所有子调用继承的标签，用于调试工具中的过滤和组织。
  </ParamField>

  <ParamField body="metadata" type="object">
    用于跟踪额外上下文的自定义键值对，由所有子调用继承。
  </ParamField>

  <ParamField body="max_concurrency" type="number">
    使用 `batch()` 或 `batch_as_completed()` 时控制最大并行调用数。
  </ParamField>

  <ParamField body="callbacks" type="array">
    用于监控和响应执行期间事件的处理器。
  </ParamField>

  <ParamField body="recursion_limit" type="number">
    防止复杂管道中出现无限循环的链式调用的最大递归深度。
  </ParamField>
</Accordion>

这些配置值在以下场景中特别有用：

* 使用 [LangSmith](https://docs.smith.langchain.com/) 追踪进行调试
* 实现自定义日志记录或监控
* 在生产环境中控制资源使用
* 在复杂管道中追踪调用

有关所有支持的 `RunnableConfig` 属性的更多信息，请参阅 \[`RunnableConfig`]\[RunnableConfig] 参考文档。

### 可配置模型

您还可以通过指定 `configurable_fields` 创建运行时可配置的模型。如果您未指定模型值，则 `'model'` 和 `'model_provider'` 默认为可配置项。

```python theme={null}
from langchain.chat_models import init_chat_model

configurable_model = init_chat_model(temperature=0)

configurable_model.invoke(
    "你叫什么名字",
        config={"configurable": {"model": "gpt-5-nano"}},  # 使用 GPT-5-Nano 运行
)
configurable_model.invoke(
    "你叫什么名字",
        config={"configurable": {"model": "claude-3-5-sonnet-latest"}},  # 使用 Claude 运行
)
```

<Accordion title="带默认值的可配置模型">
  我们可以创建一个带有默认模型值的可配置模型，指定哪些参数是可配置的，并为可配置参数添加前缀：

  ```python theme={null}
  first_llm = init_chat_model(
          model="gpt-4.1-mini",
          temperature=0,
          configurable_fields=("model", "model_provider", "temperature", "max_tokens"),
          config_prefix="first",  # 当链中有多个模型时非常有用
  )

  first_llm.invoke("你叫什么名字")
  ```

  ```python theme={null}
  first_llm.invoke(
      "你叫什么名字",
          config={
          "configurable": {
              "first_model": "claude-3-5-sonnet-latest",
              "first_temperature": 0.5,
              "first_max_tokens": 100,
          }
      },
  )
  ```
</Accordion>

<Accordion title="声明式使用可配置模型">
  我们可以在可配置模型上调用声明式操作，如 `bind_tools`、`with_structured_output`、`with_configurable` 等，并以与常规实例化聊天模型对象相同的方式链接可配置模型。

  ```python theme={null}
  from pydantic import BaseModel, Field


  class GetWeather(BaseModel):
      """获取指定位置的当前天气"""

          location: str = Field(..., description="城市和州，例如：旧金山，CA")


  class GetPopulation(BaseModel):
      """获取指定位置的当前人口"""

          location: str = Field(..., description="城市和州，例如：旧金山，CA")


  llm = init_chat_model(temperature=0)
  llm_with_tools = llm.bind_tools([GetWeather, GetPopulation])

  llm_with_tools.invoke(
      "2024年洛杉矶和纽约哪个更大", config={"configurable": {"model": "gpt-4.1-mini"}}
  ).tool_calls
  ```

  ```
  [
      {
          'name': 'GetPopulation',
          'args': {'location': 'Los Angeles, CA'},
          'id': 'call_Ga9m8FAArIyEjItHmztPYA22',
          'type': 'tool_call'
      },
      {
          'name': 'GetPopulation',
          'args': {'location': 'New York, NY'},
          'id': 'call_jh2dEvBaAHRaw5JUDthOs7rt',
          'type': 'tool_call'
      }
  ]
  ```

  ```python theme={null}
  llm_with_tools.invoke(
      "2024年洛杉矶和纽约哪个更大",
          config={"configurable": {"model": "claude-3-5-sonnet-latest"}},
  ).tool_calls
  ```

  ```
  [
      {
          'name': 'GetPopulation',
          'args': {'location': 'Los Angeles, CA'},
          'id': 'toolu_01JMufPf4F4t2zLj7miFeqXp',
          'type': 'tool_call'
      },
      {
          'name': 'GetPopulation',
          'args': {'location': 'New York City, NY'},
          'id': 'toolu_01RQBHcE8kEEbYTuuS8WqY1u',
          'type': 'tool_call'
      }
  ]
  ```
</Accordion>
