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

# 智能体

智能体将语言模型与 [工具](/oss/python/langchain/tools) 结合，创建能够推理任务、决定使用哪些工具并迭代寻求解决方案的系统。

[`create_agent`](https://reference.langchain.com/python/langchain/agents/factory/create_agent) 提供了一个生产就绪的智能体实现。

[LLM 智能体通过循环运行工具来实现目标](https://simonwillison.net/2025/Sep/18/agents/)。
智能体会一直运行直到满足停止条件——即当模型输出最终结果或达到迭代限制时。

```mermaid theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
%%{
  init: {
    "fontFamily": "monospace",
    "flowchart": {
      "curve": "curve"
    }
  }
}%%
graph TD
  %% Outside the agent
  QUERY([input])
  LLM{model}
  TOOL(tools)
  ANSWER([output])

  %% Main flows (no inline labels)
  QUERY --> LLM
  LLM --"action"--> TOOL
  TOOL --"observation"--> LLM
  LLM --"finish"--> ANSWER

  classDef blueHighlight fill:#DBEAFE,stroke:#2563EB,color:#1E3A8A;
  classDef greenHighlight fill:#DCFCE7,stroke:#16A34A,color:#14532D;
  class QUERY blueHighlight;
  class ANSWER blueHighlight;
  class LLM greenHighlight;
  class TOOL greenHighlight;
```

<Info>
  [`create_agent`](https://reference.langchain.com/python/langchain/agents/factory/create_agent) 使用 [LangGraph](/oss/python/langgraph/overview) 构建基于**图**的智能体运行时。图由节点（步骤）和边（连接）组成，定义了智能体如何处理信息。智能体在此图中移动，执行节点如模型节点（调用模型）、工具节点（执行工具）或中间件。

  了解更多关于 [Graph API](/oss/python/langgraph/graph-api)。
</Info>

## 核心组件

### 模型

[model](/oss/python/langchain/models) 是智能体的推理引擎。它可以通过多种方式指定，支持静态和动态模型选择。

#### 静态模型

静态模型在创建智能体时配置一次，并在整个执行过程中保持不变。这是最常见且直接的方法。

要从 <Tooltip tip="遵循 `provider:model` 格式的字符串（例如 openai:gpt-5）" cta="查看映射" href="https://reference.langchain.com/python/langchain/models/#langchain.chat_models.init_chat_model(model)">模型标识符字符串</Tooltip> 初始化静态模型：

```python wrap theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langchain.agents import create_agent

agent = create_agent("openai:gpt-5", tools=tools)
```

<Tip>
  模型标识符字符串支持自动推断（例如，`"gpt-5"` 将被推断为 `"openai:gpt-5"`）。参考 [reference](https://reference.langchain.com/python/langchain/chat_models/base/init_chat_model) 查看完整的模型标识符字符串映射列表。
</Tip>

为了更精细地控制模型配置，可以直接使用 provider 包初始化模型实例。在本例中，我们使用 [`ChatOpenAI`](https://reference.langchain.com/python/langchain-openai/chat_models/base/ChatOpenAI)。参见 [聊天模型](/oss/python/integrations/chat) 了解其他可用的聊天模型类。

```python wrap theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI

model = ChatOpenAI(
    model="gpt-5",
    temperature=0.1,
    max_tokens=1000,
    timeout=30
    # ... (other params)
)
agent = create_agent(model, tools=tools)
```

模型实例让您完全控制配置。当您需要在特定 [参数](/oss/python/langchain/models#parameters) 上设置值，如 `temperature`、`max_tokens`、`timeouts`、`base_url` 和其他 provider 特定设置时使用它们。参考 [reference](/oss/python/integrations/providers/all_providers) 查看您的模型上可用的参数和方法。

#### 动态模型

动态模型根据当前的 <Tooltip tip="智能体的执行环境，包含在整个智能体执行期间持久存在的不可变配置和上下文数据（例如用户 ID、会话详情或应用程序特定配置）。">runtime</Tooltip> 和 <Tooltip tip="流经智能体执行的数据，包括消息、自定义字段以及任何需要在处理期间跟踪和可能修改的信息（例如用户偏好或工具使用情况统计）。">state</Tooltip> 进行选择。这启用了复杂的路由逻辑和成本优化。

要使用动态模型，请使用 [`@wrap_model_call`](https://reference.langchain.com/python/langchain/agents/middleware/types/wrap_model_call) 装饰器创建中间件来修改请求中的模型：

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langchain_openai import ChatOpenAI
from langchain.agents import create_agent
from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse


basic_model = ChatOpenAI(model="gpt-4.1-mini")
advanced_model = ChatOpenAI(model="gpt-4.1")

@wrap_model_call
def dynamic_model_selection(request: ModelRequest, handler) -> ModelResponse:
    """Choose model based on conversation complexity."""
    message_count = len(request.state["messages"])

    if message_count > 10:
        # Use an advanced model for longer conversations
        model = advanced_model
    else:
        model = basic_model

    return handler(request.override(model=model))

agent = create_agent(
    model=basic_model,  # Default model
    tools=tools,
    middleware=[dynamic_model_selection]
)
```

<Warning>
  已绑定的模型（已调用 [`bind_tools`](https://reference.langchain.com/python/langchain-core/language_models/chat_models/BaseChatModel/bind_tools) 的模型）在使用结构化输出时不受支持。如果您需要带结构化输出的动态模型选择，请确保传递给中间件的模型不是预先绑定的。
</Warning>

<Tip>
  有关模型配置的详细信息，请参阅 [Models](/oss/python/langchain/models)。有关动态模型选择模式，请参阅 [Dynamic model in middleware](/oss/python/langchain/middleware#dynamic-model)。
</Tip>

### 工具

工具赋予智能体采取行动的能力。智能体超越了简单的仅模型工具绑定，通过促进以下内容：

* 按顺序进行多次工具调用（由单个提示触发）
* 在适当时并行调用工具
* 根据先前结果动态选择工具
* 工具重试逻辑和错误处理
* 跨工具调用的状态持久化

更多信息，请参阅 [Tools](/oss/python/langchain/tools)。

#### 静态工具

静态工具在创建智能体时定义，并在整个执行过程中保持不变。这是最常见且直接的方法。

要定义带有静态工具的智能体，请将工具列表传递给智能体。

<Tip>
  工具可以指定为纯 Python 函数或 <Tooltip tip="一种可以挂起执行并在稍后恢复的方法">协程</Tooltip>。

  [tool decorator](/oss/python/langchain/tools#create-tools) 可用于自定义工具名称、描述、参数架构和其他属性。
</Tip>

```python wrap theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langchain.tools import tool
from langchain.agents import create_agent


@tool
def search(query: str) -> str:
    """Search for information."""
    return f"Results for: {query}"

@tool
def get_weather(location: str) -> str:
    """Get weather information for a location."""
    return f"Weather in {location}: Sunny, 72°F"

agent = create_agent(model, tools=[search, get_weather])
```

如果提供空工具列表，智能体将仅包含一个没有工具调用能力的 LLM 节点。

#### 动态工具

使用动态工具，智能体可用的工具集在运行时进行修改，而不是全部预先定义。并非所有工具都适用于每种情况。工具过多可能会使模型不堪重负（过载上下文）并增加错误；工具过少则限制能力。动态工具选择使得能够根据认证状态、用户权限、功能标志或对话阶段调整可用工具集。

有两种方法取决于工具是否提前已知：

<Tabs>
  <Tab title="过滤预注册的工具">
    当所有可能的工具在智能体创建时已知时，您可以预先注册它们，并根据状态、权限或上下文动态过滤向模型暴露的工具。

    <Tabs>
      <Tab title="状态">
        仅在达到某些对话里程碑后启用高级工具：

        ```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
        from langchain.agents import create_agent
        from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse
        from typing import Callable

        @wrap_model_call
        def state_based_tools(
            request: ModelRequest,
            handler: Callable[[ModelRequest], ModelResponse]
        ) -> ModelResponse:
            """Filter tools based on conversation State."""
            # Read from State: check if user has authenticated
            state = request.state
            is_authenticated = state.get("authenticated", False)
            message_count = len(state["messages"])

            # Only enable sensitive tools after authentication
            if not is_authenticated:
                tools = [t for t in request.tools if t.name.startswith("public_")]
                request = request.override(tools=tools)
            elif message_count < 5:
                # Limit tools early in conversation
                tools = [t for t in request.tools if t.name != "advanced_search"]
                request = request.override(tools=tools)

            return handler(request)

        agent = create_agent(
            model="gpt-4.1",
            tools=[public_search, private_search, advanced_search],
            middleware=[state_based_tools]
        )
        ```
      </Tab>

      <Tab title="存储">
        根据 Store 中的用户偏好或功能标志过滤工具：

        ```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
        from dataclasses import dataclass
        from langchain.agents import create_agent
        from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse
        from typing import Callable
        from langgraph.store.memory import InMemoryStore

        @dataclass
        class Context:
            user_id: str

        @wrap_model_call
        def store_based_tools(
            request: ModelRequest,
            handler: Callable[[ModelRequest], ModelResponse]
        ) -> ModelResponse:
            """Filter tools based on Store preferences."""
            user_id = request.runtime.context.user_id

            # Read from Store: get user's enabled features
            store = request.runtime.store
            feature_flags = store.get(("features",), user_id)

            if feature_flags:
                enabled_features = feature_flags.value.get("enabled_tools", [])
                # Only include tools that are enabled for this user
                tools = [t for t in request.tools if t.name in enabled_features]
                request = request.override(tools=tools)

            return handler(request)

        agent = create_agent(
            model="gpt-4.1",
            tools=[search_tool, analysis_tool, export_tool],
            middleware=[store_based_tools],
            context_schema=Context,
            store=InMemoryStore()
        )
        ```
      </Tab>

      <Tab title="运行时上下文">
        根据运行时上下文中的用户权限过滤工具：

        ```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
        from dataclasses import dataclass
        from langchain.agents import create_agent
        from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse
        from typing import Callable

        @dataclass
        class Context:
            user_role: str

        @wrap_model_call
        def context_based_tools(
            request: ModelRequest,
            handler: Callable[[ModelRequest], ModelResponse]
        ) -> ModelResponse:
            """Filter tools based on Runtime Context permissions."""
            # Read from Runtime Context: get user role
            if request.runtime is None or request.runtime.context is None:
                # If no context provided, default to viewer (most restrictive)
                user_role = "viewer"
            else:
                user_role = request.runtime.context.user_role

            if user_role == "admin":
                # Admins get all tools
                pass
            elif user_role == "editor":
                # Editors can't delete
                tools = [t for t in request.tools if t.name != "delete_data"]
                request = request.override(tools=tools)
            else:
                # Viewers get read-only tools
                tools = [t for t in request.tools if t.name.startswith("read_")]
                request = request.override(tools=tools)

            return handler(request)

        agent = create_agent(
            model="gpt-4.1",
            tools=[read_data, write_data, delete_data],
            middleware=[context_based_tools],
            context_schema=Context
        )
        ```
      </Tab>
    </Tabs>

    这种方法最适合以下情况：

    * 所有可能的工具在编译/启动时已知
    * 您希望根据权限、功能标志或对话状态进行过滤
    * 工具是静态的，但其可用性是动态的

    有关更多示例，请参阅 [Dynamically selecting tools](/oss/python/langchain/middleware/custom#dynamically-selecting-tools)。
  </Tab>

  <Tab title="运行时工具注册">
    当工具在运行时被发现或创建时（例如，从 MCP 服务器加载、根据用户数据生成或从远程注册表获取），您需要同时注册工具并动态处理其执行。

    这需要两个中间件钩子：

    1. `wrap_model_call` - 将动态工具添加到请求中
    2. `wrap_tool_call` - 处理动态添加的工具的执行

    ```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    from langchain.tools import tool
    from langchain.agents import create_agent
    from langchain.agents.middleware import AgentMiddleware, ModelRequest, ToolCallRequest

    # A tool that will be added dynamically at runtime
    @tool
    def calculate_tip(bill_amount: float, tip_percentage: float = 20.0) -> str:
        """Calculate the tip amount for a bill."""
        tip = bill_amount * (tip_percentage / 100)
        return f"Tip: ${tip:.2f}, Total: ${bill_amount + tip:.2f}"

    class DynamicToolMiddleware(AgentMiddleware):
        """Middleware that registers and handles dynamic tools."""

        def wrap_model_call(self, request: ModelRequest, handler):
            # Add dynamic tool to the request
            # This could be loaded from an MCP server, database, etc.
            updated = request.override(tools=[*request.tools, calculate_tip])
            return handler(updated)

        def wrap_tool_call(self, request: ToolCallRequest, handler):
            # Handle execution of the dynamic tool
            if request.tool_call["name"] == "calculate_tip":
                return handler(request.override(tool=calculate_tip))
            return handler(request)

    agent = create_agent(
        model="gpt-4o",
        tools=[get_weather],  # Only static tools registered here
        middleware=[DynamicToolMiddleware()],
    )

    # The agent can now use both get_weather AND calculate_tip
    result = agent.invoke({
        "messages": [{"role": "user", "content": "Calculate a 20% tip on $85"}]
    })
    ```

    这种方法最适合以下情况：

    * 工具在运行时被发现（例如，来自 MCP 服务器）
    * 工具根据用户数据或配置动态生成
    * 您正在集成外部工具注册表

    <Note>
      `wrap_tool_call` 钩子是必需的，用于运行时注册的工具，因为智能体需要知道如何执行原始工具列表中不存在的工具。如果没有它，智能体将不知道如何调用动态添加的工具。
    </Note>
  </Tab>
</Tabs>

<Tip>
  要了解有关工具的更多信息，请参阅 [Tools](/oss/python/langchain/tools)。
</Tip>

#### 工具错误处理

要自定义工具错误的处理方式，请使用 [`@wrap_tool_call`](https://reference.langchain.com/python/langchain/agents/middleware/types/wrap_tool_call) 装饰器创建中间件：

```python wrap theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langchain.agents import create_agent
from langchain.agents.middleware import wrap_tool_call
from langchain.messages import ToolMessage


@wrap_tool_call
def handle_tool_errors(request, handler):
    """Handle tool execution errors with custom messages."""
    try:
        return handler(request)
    except Exception as e:
        # Return a custom error message to the model
        return ToolMessage(
            content=f"Tool error: Please check your input and try again. ({str(e)})",
            tool_call_id=request.tool_call["id"]
        )

agent = create_agent(
    model="gpt-4.1",
    tools=[search, get_weather],
    middleware=[handle_tool_errors]
)
```

当工具失败时，智能体将返回带有自定义错误消息的 [`ToolMessage`](https://reference.langchain.com/python/langchain-core/messages/tool/ToolMessage)：

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
[
    ...
    ToolMessage(
        content="Tool error: Please check your input and try again. (division by zero)",
        tool_call_id="..."
    ),
    ...
]
```

#### ReAct 循环中的工具使用

智能体遵循 ReAct（“推理 + 行动”）模式，在简短的推理步骤（带有针对性的工具调用）和将 resulting observations 反馈到后续决策之间交替，直到能够提供最终答案。

<Accordion title="ReAct 循环示例">
  **提示：** 识别当前最流行的无线耳机并验证库存。

  ```
  ================================ Human Message =================================

  Find the most popular wireless headphones right now and check if they're in stock
  ```

  * **推理**：“流行度是时间敏感的，我需要使用提供的搜索工具。”
  * **行动**：调用 `search_products("wireless headphones")`

  ```
  ================================== Ai Message ==================================
  Tool Calls:
    search_products (call_abc123)
   Call ID: call_abc123
    Args:
      query: wireless headphones
  ```

  ```
  ================================= Tool Message =================================

  Found 5 products matching "wireless headphones". Top 5 results: WH-1000XM5, ...
  ```

  * **推理**：“在回答之前，我需要确认排名最高项目的库存情况。”
  * **行动**：调用 `check_inventory("WH-1000XM5")`

  ```
  ================================== Ai Message ==================================
  Tool Calls:
    check_inventory (call_def456)
   Call ID: call_def456
    Args:
      product_id: WH-1000XM5
  ```

  ```
  ================================= Tool Message =================================

  Product WH-1000XM5: 10 units in stock
  ```

  * **推理**：“我已经有了最流行的型号及其库存状态。我现在可以回答用户的问题了。”
  * **行动**：生成最终答案

  ```
  ================================== Ai Message ==================================

  I found wireless headphones (model WH-1000XM5) with 10 units in stock...
  ```
</Accordion>

### 系统提示词

您可以通过提供提示词来塑造智能体处理任务的方式。[`system_prompt`](https://reference.langchain.com/python/langchain/agents/#langchain.agents.create_agent\(system_prompt\)) 参数可以作为字符串提供：

```python wrap theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
agent = create_agent(
    model,
    tools,
    system_prompt="You are a helpful assistant. Be concise and accurate."
)
```

当未提供 [`system_prompt`](https://reference.langchain.com/python/langchain/agents/#langchain.agents.create_agent\(system_prompt\)) 时，智能体将直接从消息中推断其任务。

[`system_prompt`](https://reference.langchain.com/python/langchain/agents/#langchain.agents.create_agent\(system_prompt\)) 参数接受 `str` 或 [`SystemMessage`](https://reference.langchain.com/python/langchain-core/messages/system/SystemMessage)。使用 `SystemMessage` 可以让您对提示词结构有更多的控制，这对于 provider 特定功能如 [Anthropic 的提示词缓存](/oss/python/integrations/chat/anthropic#prompt-caching) 很有用：

```python wrap theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langchain.agents import create_agent
from langchain.messages import SystemMessage, HumanMessage

literary_agent = create_agent(
    model="anthropic:claude-sonnet-4-5",
    system_prompt=SystemMessage(
        content=[
            {
                "type": "text",
                "text": "You are an AI assistant tasked with analyzing literary works.",
            },
            {
                "type": "text",
                "text": "<the entire contents of 'Pride and Prejudice'>",
                "cache_control": {"type": "ephemeral"}
            }
        ]
    )
)

result = literary_agent.invoke(
    {"messages": [HumanMessage("Analyze the major themes in 'Pride and Prejudice'.")]}
)
```

具有 `{"type": "ephemeral"}` 的 `cache_control` 字段告诉 Anthropic 缓存该内容块，减少重复请求的延迟和成本，这些请求使用相同的系统提示词。

#### 动态系统提示词

对于需要根据运行时上下文或智能体状态修改系统提示词的更高级用例，您可以使用 [middleware](/oss/python/langchain/middleware)。

[`@dynamic_prompt`](https://reference.langchain.com/python/langchain/agents/middleware/types/dynamic_prompt) 装饰器创建中间件，根据模型请求生成系统提示词：

```python wrap theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from typing import TypedDict

from langchain.agents import create_agent
from langchain.agents.middleware import dynamic_prompt, ModelRequest


class Context(TypedDict):
    user_role: str

@dynamic_prompt
def user_role_prompt(request: ModelRequest) -> str:
    """Generate system prompt based on user role."""
    user_role = request.runtime.context.get("user_role", "user")
    base_prompt = "You are a helpful assistant."

    if user_role == "expert":
        return f"{base_prompt} Provide detailed technical responses."
    elif user_role == "beginner":
        return f"{base_prompt} Explain concepts simply and avoid jargon."

    return base_prompt

agent = create_agent(
    model="gpt-4.1",
    tools=[web_search],
    middleware=[user_role_prompt],
    context_schema=Context
)

# The system prompt will be set dynamically based on context
result = agent.invoke(
    {"messages": [{"role": "user", "content": "Explain machine learning"}]},
    context={"user_role": "expert"}
)
```

<Tip>
  有关消息类型和格式的更多详细信息，请参阅 [Messages](/oss/python/langchain/messages)。有关全面的中间件文档，请参阅 [Middleware](/oss/python/langchain/middleware)。
</Tip>

### 名称

为智能体设置可选的 [`name`](https://reference.langchain.com/python/langchain/agents/factory/create_agent)。这是在 [多智能体系统](/oss/python/langchain/multi-agent) 中将智能体作为子图添加时用作节点标识符：

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
agent = create_agent(
    model,
    tools,
    name="research_assistant"
)
```

<Warning>
  优先使用 `snake_case` 作为智能体名称（例如 `research_assistant` 而不是 `Research Assistant`）。某些模型提供商会拒绝包含空格或特殊字符的名称并报错。仅使用字母数字字符、下划线和连字符可确保在所有提供商之间的兼容性。这也适用于 [工具名称](/oss/python/langchain/tools)。
</Warning>

## 调用

您可以通过传递更新到其 [`State`](/oss/python/langgraph/graph-api#state) 来调用智能体。所有智能体在其状态中都包含 [消息序列](/oss/python/langgraph/use-graph-api#messagesstate)；要调用智能体，请传递新消息：

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
result = agent.invoke(
    {"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]}
)
```

有关从智能体流式传输步骤和/或令牌，请参阅 [streaming](/oss/python/langchain/streaming) 指南。

否则，智能体遵循 LangGraph [Graph API](/oss/python/langgraph/use-graph-api) 并支持所有相关方法，如 `stream` 和 `invoke`。

<Tip>
  使用 [LangSmith](/langsmith/home) 来追踪、调试和评估您的智能体。
</Tip>

## 高级概念

### 结构化输出

在某些情况下，您可能希望智能体以特定格式返回输出。LangChain 通过 [`response_format`](https://reference.langchain.com/python/langchain/agents/factory/create_agent) 参数提供结构化输出策略。

#### ToolStrategy

`ToolStrategy` 使用人工工具调用来生成结构化输出。这适用于支持工具调用的任何模型。当 provider 原生结构化输出（通过 [`ProviderStrategy`](#providerstrategy)）不可用或不可靠时应使用 `ToolStrategy`。

```python wrap theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from pydantic import BaseModel
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy


class ContactInfo(BaseModel):
    name: str
    email: str
    phone: str

agent = create_agent(
    model="gpt-4.1-mini",
    tools=[search_tool],
    response_format=ToolStrategy(ContactInfo)
)

result = agent.invoke({
    "messages": [{"role": "user", "content": "Extract contact info from: John Doe, john@example.com, (555) 123-4567"}]
})

result["structured_response"]
# ContactInfo(name='John Doe', email='john@example.com', phone='(555) 123-4567')
```

#### ProviderStrategy

`ProviderStrategy` 使用模型提供商的原生结构化输出生成。这更可靠，但仅适用于支持原生结构化输出的提供商：

```python wrap theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langchain.agents.structured_output import ProviderStrategy

agent = create_agent(
    model="gpt-4.1",
    response_format=ProviderStrategy(ContactInfo)
)
```

<Note>
  截至 `langchain 1.0`，仅传递架构（例如 `response_format=ContactInfo`）如果模型支持原生结构化输出将默认为 `ProviderStrategy`。否则它将回退到 `ToolStrategy`。
</Note>

<Tip>
  要了解有关结构化输出的信息，请参阅 [Structured output](/oss/python/langchain/structured-output)。
</Tip>

### 记忆

智能体通过消息状态自动维护对话历史。您还可以配置智能体使用自定义状态架构在对话期间记住额外信息。

存储在状态中的信息可以被视为智能体的 [短期记忆](/oss/python/langchain/short-term-memory)：

自定义状态架构必须扩展 [`AgentState`](https://reference.langchain.com/python/langchain/agents/middleware/types/AgentState) 作为 `TypedDict`。

有两种定义自定义状态的方法：

1. 通过 [middleware](/oss/python/langchain/middleware)（推荐）
2. 通过 [`state_schema`](https://reference.langchain.com/python/langchain/middleware/#langchain.agents.middleware.AgentMiddleware.state_schema) 上的 [`create_agent`](https://reference.langchain.com/python/langchain/agents/factory/create_agent)

#### 通过中间件定义状态

当您的自定义状态需要被特定的中间件钩子和附加到该中间件的工具访问时，使用中间件定义自定义状态。

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langchain.agents import AgentState
from langchain.agents.middleware import AgentMiddleware
from typing import Any


class CustomState(AgentState):
    user_preferences: dict

class CustomMiddleware(AgentMiddleware):
    state_schema = CustomState
    tools = [tool1, tool2]

    def before_model(self, state: CustomState, runtime) -> dict[str, Any] | None:
        ...

agent = create_agent(
    model,
    tools=tools,
    middleware=[CustomMiddleware()]
)

# The agent can now track additional state beyond messages
result = agent.invoke({
    "messages": [{"role": "user", "content": "I prefer technical explanations"}],
    "user_preferences": {"style": "technical", "verbosity": "detailed"},
})
```

#### 通过 `state_schema` 定义状态

使用 [`state_schema`](https://reference.langchain.com/python/langchain/middleware/#langchain.agents.middleware.AgentMiddleware.state_schema) 参数作为快捷方式来定义仅在工具中使用的自定义状态。

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langchain.agents import AgentState


class CustomState(AgentState):
    user_preferences: dict

agent = create_agent(
    model,
    tools=[tool1, tool2],
    state_schema=CustomState
)
# The agent can now track additional state beyond messages
result = agent.invoke({
    "messages": [{"role": "user", "content": "I prefer technical explanations"}],
    "user_preferences": {"style": "technical", "verbosity": "detailed"},
})
```

<Note>
  截至 `langchain 1.0`，自定义状态架构**必须**是 `TypedDict` 类型。Pydantic 模型和数据类不再受支持。有关更多详细信息，请参阅 [v1 migration guide](/oss/python/migrate/langchain-v1#state-type-restrictions)。
</Note>

<Note>
  通过中间件定义自定义状态优于通过 [`create_agent`](https://reference.langchain.com/python/langchain/agents/factory/create_agent) 上的 [`state_schema`](https://reference.langchain.com/python/langchain/middleware/#langchain.agents.middleware.AgentMiddleware.state_schema) 定义，因为它允许您将状态扩展概念性地限定在相关的中间件和工具范围内。

  [`state_schema`](https://reference.langchain.com/python/langchain/middleware/#langchain.agents.middleware.AgentMiddleware.state_schema) 仍受支持以保持向后兼容 [`create_agent`](https://reference.langchain.com/python/langchain/agents/factory/create_agent)。
</Note>

<Tip>
  要了解有关记忆的更多信息，请参阅 [Memory](/oss/python/concepts/memory)。有关实施跨会话持久化的长期记忆的信息，请参阅 [Long-term memory](/oss/python/langchain/long-term-memory)。
</Tip>

### 流式传输

我们已经看到如何使用 `invoke` 调用智能体以获得最终响应。如果智能体执行多个步骤，这可能需要一段时间。为了显示中间进度，我们可以流式传输发生的消息。

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langchain.messages import AIMessage, HumanMessage

for chunk in agent.stream({
    "messages": [{"role": "user", "content": "Search for AI news and summarize the findings"}]
}, stream_mode="values"):
    # Each chunk contains the full state at that point
    latest_message = chunk["messages"][-1]
    if latest_message.content:
        if isinstance(latest_message, HumanMessage):
            print(f"User: {latest_message.content}")
        elif isinstance(latest_message, AIMessage):
            print(f"Agent: {latest_message.content}")
    elif latest_message.tool_calls:
        print(f"Calling tools: {[tc['name'] for tc in latest_message.tool_calls]}")
```

<Tip>
  有关流式传输的更多详细信息，请参阅 [Streaming](/oss/python/langchain/streaming)。
</Tip>

### 中间件

[Middleware](/oss/python/langchain/middleware) 为在不同执行阶段自定义智能体行为提供了强大的可扩展性。您可以使用中间件来：

* 在调用模型之前处理状态（例如，消息修剪、上下文注入）
* 修改或验证模型的响应（例如，护栏、内容过滤）
* 使用自定义逻辑处理工具执行错误
* 根据状态或上下文实现动态模型选择
* 添加自定义日志记录、监控或分析

中间件无缝集成到智能体的执行中，允许您在关键点拦截和修改数据流，而无需更改核心智能体逻辑。

<Tip>
  有关全面的中间件文档，包括 [`@before_model`](https://reference.langchain.com/python/langchain/agents/middleware/types/before_model)、[`@after_model`](https://reference.langchain.com/python/langchain/agents/middleware/types/after_model) 和 [`@wrap_tool_call`](https://reference.langchain.com/python/langchain/agents/middleware/types/wrap_tool_call) 等装饰器，请参阅 [Middleware](/oss/python/langchain/middleware)。
</Tip>

***

<div className="source-links">
  <Callout icon="edit">
    [Edit this page on GitHub](https://github.com/langchain-ai/docs/edit/main/src/i18n\zh-CN\oss\langchain\agents.mdx) or [file an issue](https://github.com/langchain-ai/docs/issues/new/choose).
  </Callout>

  <Callout icon="terminal-2">
    [Connect these docs](/use-these-docs) to Claude, VSCode, and more via MCP for real-time answers.
  </Callout>
</div>
