Skip to content

LangChain 和 Deep Agents 为常见用例提供了预构建中间件。每个中间件都已为生产就绪,并且可以针对你的具体需求进行配置。

与提供商无关的中间件 ​

以下中间件可配合任何 LLM 提供商使用:

中间件描述
摘要在接近 token 限制时自动对对话历史进行摘要。
人在回路暂停执行,等待人工批准工具调用。
模型调用限制限制模型调用次数以防止成本过高。
工具调用限制通过限制调用次数来控制工具执行。
模型回退当主模型失败时自动回退到替代模型。
PII 检测检测并处理个人身份信息(PII)。
待办事项列表为智能体配备任务规划和追踪能力。
LLM 工具选择器在调用主模型之前使用 LLM 选择相关工具。
工具错误捕获工具执行异常并将其转换为供模型查看的错误消息。
工具重试以指数退避自动重试失败的工具调用。
模型重试以指数退避自动重试失败的模型调用。
LLM 工具模拟器出于测试目的使用 LLM 模拟工具执行。
上下文编辑通过裁剪或清除工具使用来管理对话上下文。
提供商工具搜索将工具延迟到提供商的服务器端工具搜索之后,按需呈现。
Shell 工具向智能体暴露一个持久 shell 会话用于执行命令。
文件搜索提供针对文件系统文件的 Glob 和 Grep 搜索工具。
文件系统为智能体提供用于存储上下文和长期记忆的文件系统。
子智能体添加生成子智能体的能力。
Rubric 评分(Beta)应用 LLM-as-a-judge 评分,使智能体自我评估并迭代,直到满足 Rubric。
中间件描述
摘要在接近 token 限制时自动对对话历史进行摘要。
人在回路暂停执行,等待人工批准工具调用。
模型调用限制限制模型调用次数以防止成本过高。
工具调用限制通过限制调用次数来控制工具执行。
模型回退当主模型失败时自动回退到替代模型。
PII 检测检测并处理个人身份信息(PII)。
待办事项列表为智能体配备任务规划和追踪能力。
LLM 工具选择器在调用主模型之前使用 LLM 选择相关工具。
工具重试以指数退避自动重试失败的工具调用。
模型重试以指数退避自动重试失败的模型调用。
LLM 工具模拟器出于测试目的使用 LLM 模拟工具执行。
上下文编辑通过裁剪或清除工具使用来管理对话上下文。
提供商工具搜索将工具延迟到提供商的服务器端工具搜索之后,按需呈现。
文件系统为智能体提供用于存储上下文和长期记忆的文件系统。
子智能体中间件添加生成子智能体的能力。

摘要 ​

在接近 token 限制时自动对对话历史进行摘要,压缩较旧的上下文,同时保留最近的消息。摘要适用于以下场景:

  • 超出上下文窗口的长时间运行的对话。
  • 具有大量历史记录的多轮对话。
  • 需要保留完整对话上下文的应用程序。

INFO

摘要是面向文本的上下文压缩。它不会调整大小、降采样或以其他方式压缩图像/音频/视频负载。由 keep 保留的最近消息仍包含其原始多模态块,而被摘要的较旧多模态消息则仅由生成的文本摘要表示。对于图像密集的应用程序,请将媒体存储在文件系统或对象存储中,并通过消息历史传递 URL 或文件引用。

API 参考: SummarizationMiddleware

python
from langchain.agents import create_agent
from langchain.agents.middleware import SummarizationMiddleware

agent = create_agent(
    model="gpt-5.5",
    tools=[your_weather_tool, your_calculator_tool],
    middleware=[
        SummarizationMiddleware(
            model="gpt-5.4-mini",
            trigger=("tokens", 4000),
            keep=("messages", 20),
        ),
    ],
)
typescript
import { createAgent, summarizationMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-5.5",
  tools: [weatherTool, calculatorTool],
  middleware: [
    summarizationMiddleware({
      model: "gpt-5.4-mini",
      trigger: { tokens: 4000 },
      keep: { messages: 20 },
    }),
  ],
});

配置选项 ​

TIP

如果使用 langchain>=1.1,trigger 和 keep 的 fraction 条件(如下所示)依赖于对话模型的配置档案数据。如果数据不可用,请使用其他条件或手动指定:

python
from langchain.chat_models import init_chat_model

custom_profile = {
    "max_input_tokens": 100_000,
    # ...
}
model = init_chat_model("gpt-5.5", profile=custom_profile)
  • model (string | BaseChatModel)(必填):用于生成摘要的模型。可以是模型标识符字符串(例如 'openai:gpt-5.4-mini')或 BaseChatModel 实例。更多信息参见 init_chat_model。

  • trigger (ContextSize | TriggerClause | list[ContextSize | TriggerClause] | None):触发摘要的条件。可以是: - 单个 ContextSize 元组(必须满足指定的阈值) - 单个 TriggerClause 字典(必须满足所有指定的阈值 - AND 逻辑) - 混合两种形式的列表(满足任意一项即可 - OR 逻辑) 支持的阈值为: - fraction(float):模型上下文大小的比例(0-1) - tokens(int):绝对 token 数量 - messages(int):消息数量 ContextSize 元组表示恰好一个阈值。TriggerClause 字典可以包含一个或多个阈值,例如 {"tokens": 4000, "messages": 10},并且字典中的所有阈值都必须满足(AND)。 每个 TriggerClause 字典必须指定至少一个阈值。如果未提供 trigger,则不会自动触发摘要。 更多信息参见 ContextSize 和 TriggerClause 的 API 参考。

  • keep (ContextSize)(默认:('messages', 20)):摘要后保留多少上下文。只指定其中一项: - fraction(float):要保留的模型上下文大小的比例(0-1) - tokens(int):要保留的绝对 token 数量 - messages(int):要保留的最近消息数量 更多信息参见 ContextSize 的 API 参考。

  • token_counter (function):自定义 token 计数函数。默认为基于字符的计数。

  • summary_prompt (string):用于摘要的自定义提示词模板。如果未指定,则使用内置模板。模板应包含 {messages} 占位符,对话历史将插入其中。

  • trim_tokens_to_summarize (number)(默认:4000):生成摘要时包含的最大 token 数量。在摘要之前,消息将被裁剪以适配此限制。

  • summary_prefix (string):已弃用: 请改用 summary_prompt 提供完整提示词。

  • max_tokens_before_summary (number):已弃用: 请改用 trigger: ("tokens", value)。触发摘要的 token 阈值。

  • messages_to_keep (number):已弃用: 请改用 keep: ("messages", value)。要保留的最近消息。

TIP

如果使用 langchain@1.1.0,trigger 和 keep 的 fraction 条件(如下所示)依赖于对话模型的配置档案数据。如果数据不可用,请使用其他条件或手动指定:

typescript
const customProfile: ModelProfile = {
    maxInputTokens: 100_000,
    // ...
}
model = await initChatModel("...", {
    profile: customProfile,
});
  • model (string | BaseChatModel)(必填):用于生成摘要的模型。可以是模型标识符字符串(例如 'openai:gpt-5.4-mini')或 BaseChatModel 实例。

  • trigger (object | object[]):触发摘要的条件。可以是: - 单个条件对象(必须满足所有属性 - AND 逻辑) - 条件对象数组(满足任意一个条件即可 - OR 逻辑) 每个条件可以包含: - fraction(number):模型上下文大小的比例(0-1) - tokens(number):绝对 token 数量 - messages(number):消息数量 每个条件必须至少指定一个属性。如果未提供,则不会自动触发摘要。

  • keep (object)(默认:{messages: 20}):摘要后保留多少上下文。只指定其中一项: - fraction(number):要保留的模型上下文大小的比例(0-1) - tokens(number):要保留的绝对 token 数量 - messages(number):要保留的最近消息数量

  • tokenCounter (function):自定义 token 计数函数。默认为基于字符的计数。

  • summaryPrompt (string):用于摘要的自定义提示词模板。如果未指定,则使用内置模板。模板应包含 {messages} 占位符,对话历史将插入其中。

  • trimTokensToSummarize (number)(默认:4000):生成摘要时包含的最大 token 数量。在摘要之前,消息将被裁剪以适配此限制。

  • summaryPrefix (string):添加到摘要消息的前缀。如果未提供,则使用默认前缀。

  • maxTokensBeforeSummary (number):已弃用: 请改用 trigger: { tokens: value }。触发摘要的 token 阈值。

  • messagesToKeep (number):已弃用: 请改用 keep: { messages: value }。要保留的最近消息。

完整示例 ​

摘要中间件会监控消息的 token 数量,并在达到阈值时自动摘要较旧的消息。

触发条件控制摘要何时运行:

  • 单个阈值在该阈值满足时触发
  • 包含多个阈值的触发子句仅在所有阈值都满足时触发(AND 逻辑)
  • 触发条件列表在满足任意一项时触发(OR 逻辑)
  • 每个阈值可以使用 fraction(模型上下文大小的比例)、tokens(绝对数量)或 messages(消息数量)

保留条件控制保留多少上下文(只指定一项):

  • fraction - 要保留的模型上下文大小的比例
  • tokens - 要保留的绝对 token 数量
  • messages - 要保留的最近消息数量
python
from langchain.agents import create_agent
from langchain.agents.middleware import SummarizationMiddleware

# 单一条件:当 tokens >= 4000 时触发
agent = create_agent(
    model="gpt-5.5",
    tools=[your_weather_tool, your_calculator_tool],
    middleware=[
        SummarizationMiddleware(
            model="gpt-5.4-mini",
            trigger=("tokens", 4000),
            keep=("messages", 20),
        ),
    ],
)

# 多个条件:当 tokens >= 3000 或 messages >= 6 时触发
agent2 = create_agent(
    model="gpt-5.5",
    tools=[your_weather_tool, your_calculator_tool],
    middleware=[
        SummarizationMiddleware(
            model="gpt-5.4-mini",
            trigger=[
                ("tokens", 3000),
                ("messages", 6),
            ],
            keep=("messages", 20),
        ),
    ],
)

# AND 逻辑:仅当 tokens >= 4000 且 messages >= 10 时触发
agent3 = create_agent(
    model="gpt-5.5",
    tools=[your_weather_tool, your_calculator_tool],
    middleware=[
        SummarizationMiddleware(
            model="gpt-5.4-mini",
            trigger={"tokens": 4000, "messages": 10},
            keep=("messages", 20),
        ),
    ],
)

# 组合 AND 和 OR:当(tokens >= 5000 且 messages >= 3)时触发
# 或(tokens >= 3000 且 messages >= 6)
agent4 = create_agent(
    model="gpt-5.5",
    tools=[your_weather_tool, your_calculator_tool],
    middleware=[
        SummarizationMiddleware(
            model="gpt-5.4-mini",
            trigger=[
                {"tokens": 5000, "messages": 3},
                {"tokens": 3000, "messages": 6},
            ],
            keep=("messages", 20),
        ),
    ],
)

# 使用比例限制
agent5 = create_agent(
    model="gpt-5.5",
    tools=[your_weather_tool, your_calculator_tool],
    middleware=[
        SummarizationMiddleware(
            model="gpt-5.4-mini",
            trigger=("fraction", 0.8),
            keep=("fraction", 0.3),
        ),
    ],
)
typescript
import { createAgent, summarizationMiddleware } from "langchain";

// 单一条件
const agent = createAgent({
  model: "gpt-5.5",
  tools: [weatherTool, calculatorTool],
  middleware: [
    summarizationMiddleware({
      model: "gpt-5.4-mini",
      trigger: { tokens: 4000, messages: 10 },
      keep: { messages: 20 },
    }),
  ],
});

// 多个条件
const agent2 = createAgent({
  model: "gpt-5.5",
  tools: [weatherTool, calculatorTool],
  middleware: [
    summarizationMiddleware({
      model: "gpt-5.4-mini",
      trigger: [
        { tokens: 3000, messages: 6 },
      ],
      keep: { messages: 20 },
    }),
  ],
});

// 使用比例限制
const agent3 = createAgent({
  model: "gpt-5.5",
  tools: [weatherTool, calculatorTool],
  middleware: [
    summarizationMiddleware({
      model: "gpt-5.4-mini",
      trigger: { fraction: 0.8 },
      keep: { fraction: 0.3 },
    }),
  ],
});

人在回路 ​

在工具调用执行之前暂停智能体执行,等待人工批准、编辑或拒绝。人在回路适用于以下场景:

  • 需要人工批准的高风险操作(例如数据库写入、金融交易)。
  • 必须有人工监督的合规工作流。
  • 需要人工反馈引导智能体的长时间运行的对话。

API 参考: HumanInTheLoopMiddleware

WARNING

人在回路中间件需要检查点来在中断之间维护状态。

python
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
from langgraph.checkpoint.memory import InMemorySaver

def your_read_email_tool(email_id: str) -> str:
    """Mock function to read an email by its ID."""
    return f"Email content for ID: {email_id}"

def your_send_email_tool(recipient: str, subject: str, body: str) -> str:
    """Mock function to send an email."""
    return f"Email sent to {recipient} with subject '{subject}'"

agent = create_agent(
    model="gpt-5.5",
    tools=[your_read_email_tool, your_send_email_tool],
    checkpointer=InMemorySaver(),
    middleware=[
        HumanInTheLoopMiddleware(
            interrupt_on={
                "your_send_email_tool": {
                    "allowed_decisions": ["approve", "edit", "reject"],
                },
                "your_read_email_tool": False,
            }
        ),
    ],
)
typescript
import { createAgent, humanInTheLoopMiddleware } from "langchain";

function readEmailTool(emailId: string): string {
  /** 按 ID 读取电子邮件的模拟函数。 */
  return `Email content for ID: ${emailId}`;
}

function sendEmailTool(recipient: string, subject: string, body: string): string {
  /** 发送电子邮件的模拟函数。 */
  return `Email sent to ${recipient} with subject '${subject}'`;
}

const agent = createAgent({
  model: "gpt-5.5",
  tools: [readEmailTool, sendEmailTool],
  middleware: [
    humanInTheLoopMiddleware({
      interruptOn: {
        sendEmailTool: {
          allowedDecisions: ["approve", "edit", "reject"],
        },
        readEmailTool: false,
      }
    })
  ]
});

TIP

完整的示例、配置选项和集成模式参见人在回路文档。

观看此视频指南,了解人在回路中间件的行为演示。

观看此视频指南,了解人在回路中间件的行为演示。

模型调用限制 ​

限制模型调用次数,以防止无限循环或成本过高。模型调用限制适用于以下场景:

  • 防止失控的智能体发出过多的 API 调用。
  • 对生产部署实施成本控制。
  • 在特定的调用预算内测试智能体行为。

API 参考: ModelCallLimitMiddleware

python
from langchain.agents import create_agent
from langchain.agents.middleware import ModelCallLimitMiddleware
from langgraph.checkpoint.memory import InMemorySaver

agent = create_agent(
    model="gpt-5.5",
    checkpointer=InMemorySaver(),  # 线程限制所必需
    tools=[],
    middleware=[
        ModelCallLimitMiddleware(
            thread_limit=10,
            run_limit=5,
            exit_behavior="end",
        ),
    ],
)
typescript
import { createAgent, modelCallLimitMiddleware } from "langchain";
import { MemorySaver } from "@langchain/langgraph";

const agent = createAgent({
  model: "gpt-5.5",
  checkpointer: new MemorySaver(), // 线程限制所必需
  tools: [],
  middleware: [
    modelCallLimitMiddleware({
      threadLimit: 10,
      runLimit: 5,
      exitBehavior: "end",
    }),
  ],
});

观看此视频指南,了解模型调用限制中间件的行为演示。

观看此视频指南,了解模型调用限制中间件的行为演示。

配置选项 ​

  • thread_limit (number):一个线程内所有运行中的最大模型调用次数。默认为无限制。

  • run_limit (number):单次调用中的最大模型调用次数。默认为无限制。

  • exit_behavior (string)(默认:end):达到限制时的行为。选项:'end'(优雅终止)或 'error'(引发异常)

  • threadLimit (number):一个线程内所有运行中的最大模型调用次数。默认为无限制。

  • runLimit (number):单次调用中的最大模型调用次数。默认为无限制。

  • exitBehavior (string)(默认:end):达到限制时的行为。选项:'end'(优雅终止)或 'error'(抛出异常)

工具调用限制 ​

通过限制工具调用次数来控制智能体执行,可以全局应用于所有工具,也可以应用于特定工具。工具调用限制适用于以下场景:

  • 防止对昂贵的外部 API 进行过多调用。
  • 限制网络搜索或数据库查询。
  • 对特定工具的使用实施限流。
  • 防止失控的智能体循环。

API 参考: ToolCallLimitMiddleware

python
from langchain.agents import create_agent
from langchain.agents.middleware import ToolCallLimitMiddleware

agent = create_agent(
    model="gpt-5.5",
    tools=[search_tool, database_tool],
    middleware=[
        # 全局限制
        ToolCallLimitMiddleware(thread_limit=20, run_limit=10),
        # 特定工具的限制
        ToolCallLimitMiddleware(
            tool_name="search",
            thread_limit=5,
            run_limit=3,
        ),
    ],
)
typescript
import { createAgent, toolCallLimitMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-5.5",
  tools: [searchTool, databaseTool],
  middleware: [
    toolCallLimitMiddleware({ threadLimit: 20, runLimit: 10 }),
    toolCallLimitMiddleware({
      toolName: "search",
      threadLimit: 5,
      runLimit: 3,
    }),
  ],
});

观看此视频指南,了解工具调用限制中间件的行为演示。

观看此视频指南,了解工具调用限制中间件的行为演示。

配置选项 ​

  • tool_name (string):要限制的特定工具的名称。如果未提供,则限制应用于所有工具(全局)。

  • thread_limit (number):一个线程(对话)内所有运行中的最大工具调用次数。会在具有相同线程 ID 的多次调用之间持续存在。需要检查点来维护状态。None 表示没有线程限制。

  • run_limit (number):单次调用(一个用户消息 → 响应周期)内的最大工具调用次数。每次新的用户消息都会重置。None 表示没有运行限制。 注意: 必须至少指定 thread_limit 或 run_limit 之一。

  • exit_behavior (string)(默认:continue):达到限制时的行为: - 'continue'(默认)- 用错误消息阻止超限的工具调用,让其他工具和模型继续运行。模型根据错误消息决定何时结束。 - 'error' - 引发 ToolCallLimitExceededError 异常,立即停止执行 - 'end' - 立即停止执行,为超限的工具调用生成 ToolMessage 和 AI 消息。仅在限制单个工具时有效;如果其他工具有挂起的调用,则引发 NotImplementedError。

  • toolName (string):要限制的特定工具的名称。如果未提供,则限制应用于所有工具(全局)。

  • threadLimit (number):一个线程(对话)内所有运行中的最大工具调用次数。会在具有相同线程 ID 的多次调用之间持续存在。需要检查点来维护状态。undefined 表示没有线程限制。

  • runLimit (number):单次调用(一个用户消息 → 响应周期)内的最大工具调用次数。每次新的用户消息都会重置。undefined 表示没有运行限制。 注意: 必须至少指定 threadLimit 或 runLimit 之一。

  • exitBehavior (string)(默认:continue):达到限制时的行为: - 'continue'(默认)- 用错误消息阻止超限的工具调用,让其他工具和模型继续运行。模型根据错误消息决定何时结束。 - 'error' - 抛出 ToolCallLimitExceededError 异常,立即停止执行 - 'end' - 立即停止执行,为超限的工具调用生成 ToolMessage 和 AI 消息。仅在限制单个工具时有效;如果其他工具有挂起的调用,则抛出错误。

完整示例 ​

使用以下方式指定限制:

  • 线程限制 - 一个对话中所有运行的最大调用次数(需要检查点)
  • 运行限制 - 单次调用的最大调用次数(每轮重置)

退出行为:

  • 'continue'(默认)- 用错误消息阻止超限的调用,智能体继续运行
  • 'error' - 立即引发异常
  • 'end' - 以 ToolMessage + AI 消息停止(仅限单工具场景)
python
from langchain.agents import create_agent
from langchain.agents.middleware import ToolCallLimitMiddleware

global_limiter = ToolCallLimitMiddleware(thread_limit=20, run_limit=10)
search_limiter = ToolCallLimitMiddleware(tool_name="search", thread_limit=5, run_limit=3)
database_limiter = ToolCallLimitMiddleware(tool_name="query_database", thread_limit=10)
strict_limiter = ToolCallLimitMiddleware(tool_name="scrape_webpage", run_limit=2, exit_behavior="error")

agent = create_agent(
    model="gpt-5.5",
    tools=[search_tool, database_tool, scraper_tool],
    middleware=[global_limiter, search_limiter, database_limiter, strict_limiter],
)
typescript
import { createAgent, toolCallLimitMiddleware } from "langchain";

const globalLimiter = toolCallLimitMiddleware({ threadLimit: 20, runLimit: 10 });
const searchLimiter = toolCallLimitMiddleware({ toolName: "search", threadLimit: 5, runLimit: 3 });
const databaseLimiter = toolCallLimitMiddleware({ toolName: "query_database", threadLimit: 10 });
const strictLimiter = toolCallLimitMiddleware({ toolName: "scrape_webpage", runLimit: 2, exitBehavior: "error" });

const agent = createAgent({
  model: "gpt-5.5",
  tools: [searchTool, databaseTool, scraperTool],
  middleware: [globalLimiter, searchLimiter, databaseLimiter, strictLimiter],
});

模型回退 ​

当主模型失败时自动回退到替代模型。模型回退适用于以下场景:

  • 构建能够处理模型中断的弹性智能体。
  • 通过回退到更便宜的模型来优化成本。
  • 在 OpenAI、Anthropic 等提供商之间实现冗余。

API 参考: ModelFallbackMiddleware

python
from langchain.agents import create_agent
from langchain.agents.middleware import ModelFallbackMiddleware

agent = create_agent(
    model="gpt-5.5",
    tools=[],
    middleware=[
        ModelFallbackMiddleware(
            "gpt-5.4-mini",
            "claude-3-5-sonnet-20241022",
        ),
    ],
)
typescript
import { createAgent, modelFallbackMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-5.5",
  tools: [],
  middleware: [
    modelFallbackMiddleware(
      "gpt-5.4-mini",
      "claude-3-5-sonnet-20241022"
    ),
  ],
});

观看此视频指南,了解模型回退中间件的行为演示。

配置选项 ​

  • first_model (string | BaseChatModel)(必填):主模型失败时首先尝试的回退模型。可以是模型标识符字符串(例如 'openai:gpt-5.4-mini')或 BaseChatModel 实例。

  • *additional_models (string | BaseChatModel):如果之前的模型失败,按顺序尝试的额外回退模型

该中间件接受可变数量的字符串参数,按顺序表示回退模型:

  • ...models (string[])(必填):主模型失败时按顺序尝试的一个或多个回退模型字符串 typescript modelFallbackMiddleware( "first-fallback-model", "second-fallback-model", // ... 更多模型 )

PII 检测 ​

使用可配置的策略检测并处理对话中的个人身份信息(PII)。PII 检测适用于以下场景:

  • 有合规要求的医疗和金融应用程序。
  • 需要对日志进行清理的客户服务智能体。
  • 任何处理敏感用户数据的应用程序。

INFO

使用 apply_to_output=True 时,PIIMiddleware 还会通过注册的流式转换器对流式传输的线上输出(文本增量、工具调用参数、工具输出和状态快照)进行脱敏。需要 langchain>=1.3.2。参见 在中间件上注册转换器。

API 参考: PIIMiddleware

python
from langchain.agents import create_agent
from langchain.agents.middleware import PIIMiddleware

agent = create_agent(
    model="gpt-5.5",
    tools=[],
    middleware=[
        PIIMiddleware("email", strategy="redact", apply_to_input=True),
        PIIMiddleware("credit_card", strategy="mask", apply_to_input=True),
    ],
)
typescript
import { createAgent, piiMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-5.5",
  tools: [],
  middleware: [
    piiMiddleware("email", { strategy: "redact", applyToInput: true }),
    piiMiddleware("credit_card", { strategy: "mask", applyToInput: true }),
  ],
});

自定义 PII 类型 ​

你可以通过提供 detector 参数来创建自定义 PII 类型。这使你能检测到内置类型之外、针对你用例的特定模式。

创建自定义检测器的三种方式:

  1. 正则表达式模式字符串 - 简单的模式匹配
  2. RegExp 对象 - 对正则表达式标志有更多控制
  3. 自定义函数 - 带验证的复杂检测逻辑
python
from langchain.agents import create_agent
from langchain.agents.middleware import PIIMiddleware
import re

# 方法 1:正则表达式模式字符串
agent1 = create_agent(
    model="gpt-5.5",
    tools=[],
    middleware=[
        PIIMiddleware(
            "api_key",
            detector=r"sk-[a-zA-Z0-9]{32}",
            strategy="block",
        ),
    ],
)

# 方法 2:已编译的正则表达式模式
agent2 = create_agent(
    model="gpt-5.5",
    tools=[],
    middleware=[
        PIIMiddleware(
            "phone_number",
            detector=re.compile(r"\+?\d{1,3}[\s.-]?\d{3,4}[\s.-]?\d{4}"),
            strategy="mask",
        ),
    ],
)

# 方法 3:自定义检测器函数
def detect_ssn(content: str) -> list[dict[str, str | int]]:
    """Detect SSN with validation.

    Returns a list of dictionaries with 'text', 'start', and 'end' keys.
    """
    import re
    matches = []
    pattern = r"\d{3}-\d{2}-\d{4}"
    for match in re.finditer(pattern, content):
        ssn = match.group(0)
        # 验证:前 3 位数字不应该是 000、666 或 900-999
        first_three = int(ssn[:3])
        if first_three not in [0, 666] and not (900 <= first_three <= 999):
            matches.append({
                "text": ssn,
                "start": match.start(),
                "end": match.end(),
            })
    return matches

agent3 = create_agent(
    model="gpt-5.5",
    tools=[],
    middleware=[
        PIIMiddleware(
            "ssn",
            detector=detect_ssn,
            strategy="hash",
        ),
    ],
)
typescript
import { createAgent, piiMiddleware, type PIIMatch } from "langchain";

// 方法 1:正则表达式模式字符串
const agent1 = createAgent({
  model: "gpt-5.5",
  tools: [],
  middleware: [
    piiMiddleware("api_key", {
      detector: "sk-[a-zA-Z0-9]{32}",
      strategy: "block",
    }),
  ],
});

// 方法 2:RegExp 对象
const agent2 = createAgent({
  model: "gpt-5.5",
  tools: [],
  middleware: [
    piiMiddleware("phone_number", {
      detector: /\+?\d{1,3}[\s.-]?\d{3,4}[\s.-]?\d{4}/,
      strategy: "mask",
    }),
  ],
});

// 方法 3:自定义检测器函数
function detectSSN(content: string): PIIMatch[] {
  const matches: PIIMatch[] = [];
  const pattern = /\d{3}-\d{2}-\d{4}/g;
  let match: RegExpExecArray | null;

  while ((match = pattern.exec(content)) !== null) {
    const ssn = match[0];
    // 验证:前 3 位数字不应该是 000、666 或 900-999
    const firstThree = parseInt(ssn.substring(0, 3), 10);
    if (firstThree !== 0 && firstThree !== 666 && !(firstThree >= 900 && firstThree <= 999)) {
      matches.push({
        text: ssn,
        start: match.index ?? 0,
        end: (match.index ?? 0) + ssn.length,
      });
    }
  }
  return matches;
}

const agent3 = createAgent({
  model: "gpt-5.5",
  tools: [],
  middleware: [
    piiMiddleware("ssn", {
      detector: detectSSN,
      strategy: "hash",
    }),
  ],
});

自定义检测器函数签名:

检测器函数必须接受一个字符串(内容)并返回匹配项:

返回包含 text、start 和 end 键的字典列表:

python
def detector(content: str) -> list[dict[str, str | int]]:
    return [
        {"text": "matched_text", "start": 0, "end": 12},
        # ... 更多匹配项
    ]

返回 PIIMatch 对象数组:

typescript
interface PIIMatch {
  text: string;    // 匹配的文本
  start: number;   // 内容中的起始索引
  end: number;      // 内容中的结束索引
}

function detector(content: string): PIIMatch[] {
  return [
    { text: "matched_text", start: 0, end: 12 },
    // ... 更多匹配项
  ];
}

TIP

对于自定义检测器:

  • 对于简单的模式,使用正则表达式字符串
  • 当你需要标志时(例如不区分大小写的匹配),使用 RegExp 对象
  • 当你需要超出模式匹配的验证逻辑时,使用自定义函数
  • 自定义函数让你完全控制检测逻辑,并可以实现复杂的验证规则

配置选项 ​

  • pii_type (string)(必填):要检测的 PII 类型。可以是内置类型(email、credit_card、ip、mac_address、url)或自定义类型名称。

  • strategy (string)(默认:redact):如何处理检测到的 PII。选项: - 'block' - 检测到时引发异常 - 'redact' - 替换为 [REDACTED_{PII_TYPE}] - 'mask' - 部分掩码(例如 ****-****-****-1234) - 'hash' - 替换为确定性哈希

  • detector (function | regex):自定义检测器函数或正则表达式模式。如果未提供,则使用该 PII 类型的内置检测器。

  • apply_to_input (boolean)(默认:True):在模型调用之前检查用户消息

  • apply_to_output (boolean)(默认:False):在模型调用之后检查 AI 消息。使用 langchain>=1.3.2 时,还会通过注册的流式转换器对流式传输的线上输出(文本增量、工具调用参数、工具输出、状态快照)进行脱敏。参见事件流。

  • apply_to_tool_results (boolean)(默认:False):在执行之后检查工具结果消息

  • piiType (string)(必填):要检测的 PII 类型。可以是内置类型(email、credit_card、ip、mac_address、url)或自定义类型名称。

  • strategy (string)(默认:redact):如何处理检测到的 PII。选项: - 'block' - 检测到时抛出错误 - 'redact' - 替换为 [REDACTED_TYPE] - 'mask' - 部分掩码(例如 ****-****-****-1234) - 'hash' - 替换为确定性哈希(例如 <email_hash:a1b2c3d4>)

  • detector (RegExp | string | function):自定义检测器。可以是: - RegExp - 用于匹配的正则表达式模式 - string - 正则表达式模式字符串(例如 "sk-[a-zA-Z0-9]{32}") - function - 自定义检测器函数 (content: string) => PIIMatch[] 如果未提供,则使用该 PII 类型的内置检测器。

  • applyToInput (boolean)(默认:true):在模型调用之前检查用户消息

  • applyToOutput (boolean)(默认:false):在模型调用之后检查 AI 消息

  • applyToToolResults (boolean)(默认:false):在执行之后检查工具结果消息

待办事项列表 ​

为智能体配备任务规划和追踪能力,用于复杂的多步骤任务。待办事项列表适用于以下场景:

  • 需要跨多个工具协调的复杂多步骤任务。
  • 进度可见性很重要的长时间运行的操作。

INFO

该中间件会自动为智能体提供 write_todos 工具和系统提示词,以引导有效的任务规划。

API 参考: TodoListMiddleware

python
from langchain.agents import create_agent
from langchain.agents.middleware import TodoListMiddleware

agent = create_agent(
    model="gpt-5.5",
    tools=[read_file, write_file, run_tests],
    middleware=[TodoListMiddleware()],
)
typescript
import { createAgent, todoListMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-5.5",
  tools: [readFile, writeFile, runTests],
  middleware: [todoListMiddleware()],
});

观看此视频指南,了解待办事项列表中间件的行为演示。

观看此视频指南,了解待办事项列表中间件的行为演示。

配置选项 ​

  • system_prompt (string):用于引导待办事项使用的自定义系统提示词。如果未指定,则使用内置提示词。

  • tool_description (string):write_todos 工具的自定义描述。如果未指定,则使用内置描述。

没有可用的配置选项(使用默认值)。

LLM 工具选择器 ​

在调用主模型之前使用 LLM 智能地选择相关工具。LLM 工具选择器适用于以下场景:

  • 拥有许多工具(10 个以上)的智能体,其中大多数工具与每次查询无关。
  • 通过过滤不相关的工具来减少 token 使用量。
  • 提高模型的专注度和准确性。

该中间件使用结构化输出来询问 LLM 哪些工具与当前查询最相关。结构化输出 schema 定义了可用的工具名称和描述。模型提供商通常会在后台将此结构化输出信息添加到系统提示词中。

API 参考: LLMToolSelectorMiddleware

python
from langchain.agents import create_agent
from langchain.agents.middleware import LLMToolSelectorMiddleware

agent = create_agent(
    model="gpt-5.5",
    tools=[tool1, tool2, tool3, tool4, tool5, ...],
    middleware=[
        LLMToolSelectorMiddleware(
            model="gpt-5.4-mini",
            max_tools=3,
            always_include=["search"],
        ),
    ],
)
typescript
import { createAgent, llmToolSelectorMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-5.5",
  tools: [tool1, tool2, tool3, tool4, tool5, ...],
  middleware: [
    llmToolSelectorMiddleware({
      model: "gpt-5.4-mini",
      maxTools: 3,
      alwaysInclude: ["search"],
    }),
  ],
});

配置选项 ​

  • model (string | BaseChatModel):用于工具选择的模型。可以是模型标识符字符串(例如 'openai:gpt-5.4-mini')或 BaseChatModel 实例。更多信息参见 init_chat_model。 默认为智能体的主模型。

  • system_prompt (string):给选择模型的指令。如果未指定,则使用内置提示词。

  • max_tools (number):最多选择的工具数量。如果模型选择了更多,则只使用前 max_tools 个。如果未指定,则无限制。

  • always_include (list[string]):无论选择结果如何都始终包含的工具名称。这些不计入 max_tools 限制。

  • model (string | BaseChatModel):用于工具选择的模型。可以是模型标识符字符串(例如 'openai:gpt-5.4-mini')或 BaseChatModel 实例。默认为智能体的主模型。

  • systemPrompt (string):给选择模型的指令。如果未指定,则使用内置提示词。

  • maxTools (number):最多选择的工具数量。如果模型选择了更多,则只使用前 maxTools 个。如果未指定,则无限制。

  • alwaysInclude (string[]):无论选择结果如何都始终包含的工具名称。这些不计入 maxTools 限制。

工具错误 ​

捕获工具执行期间引发的异常,并将其转换为模型可以看到并从中间恢复的错误 ToolMessage,而不是中止智能体运行。工具错误适用于以下场景:

  • 让模型使用修正后的参数重试失败的工具调用。
  • 呈现受控、清理过的错误消息,而不是原始的异常详细信息。
  • 防止意外的工具异常导致智能体崩溃。

INFO

工具错误中间件不会自动重试失败的调用。如需重试,请将 工具重试 中间件放在内层(位于 middleware 列表更靠前的位置),并配置 on_failure="error",这样异常才会到达工具错误中间件。参见下面的完整示例。

API 参考: ToolErrorMiddleware

INFO

ToolErrorMiddleware 需要 langchain>=1.3.14。

python
from langchain.agents import create_agent
from langchain.agents.middleware import ToolErrorMiddleware

def on_error(exc: Exception, request: ToolCallRequest) -> str | None:
    if isinstance(exc, ValueError):
        return f"`{request.tool_call['name']}` failed with {type(exc).__name__}."
    # 其他一切异常都继续传播

agent = create_agent(
    model="gpt-5.5",
    tools=[your_tools],
    middleware=[ToolErrorMiddleware(on_error)],
)

配置选项 ​

  • on_error (Callable[[Exception, ToolCallRequest], str | list[ContentBlock] | None]):为工具执行引发的每个异常调用的同步处理函数。返回内容(str 或内容块列表)可将异常转换为 ToolMessage(status="error")。返回 None 或省略 return 语句可让异常继续传播。用于同步路径,并且除非提供了 aon_error,否则也用于异步路径。

  • aon_error (Callable[[Exception, ToolCallRequest], Awaitable[str | list[ContentBlock] | None]]):可选的异步处理函数,用于异步执行路径。未提供时回退到 on_error。

  • tools (list[BaseTool | str]):可选的工具或工具名称列表,用于应用错误处理。如果为 None,则应用于所有工具。

工具错误完整示例 ​

on_error 处理函数接收异常和 ToolCallRequest(其中包含带名称、参数和调用 ID 的工具调用字典)。对于你不想处理的异常,返回 None,它们将正常传播。

python
from langchain.agents import create_agent
from langchain.agents.middleware import ToolErrorMiddleware, ToolRetryMiddleware

def on_error(exc: Exception, request: ToolCallRequest) -> str | None:
    # 将 ValueError 呈现给模型,以便它修正输入
    if isinstance(exc, ValueError):
        return f"`{request.tool_call['name']}` failed: {type(exc).__name__}. Fix the input and retry."
    # 让所有其他异常继续传播(停止运行)
    return None

# 仅异步用法
async def aon_error(exc: Exception, request: ToolCallRequest) -> str | None:
    if isinstance(exc, ConnectionError):
        return f"Tool `{request.tool_call['name']}` encountered a connection error."
    return None

agent = create_agent(
    model="gpt-5.5",
    tools=[search_tool, database_tool],
    middleware=[
        # 将重试放在内层,这样在重试耗尽后异常会到达 ToolErrorMiddleware
        ToolRetryMiddleware(max_retries=3, on_failure="error"),
        ToolErrorMiddleware(on_error=on_error, tools=["search_tool"]),
    ],
)

# 仅异步:只传 aon_error(不要传 on_error)
async_agent = create_agent(
    model="gpt-5.5",
    tools=[api_tool],
    middleware=[ToolErrorMiddleware(aon_error=aon_error)],
)

INFO

相比可能携带敏感或内部细节的原始异常消息,更推荐返回标明异常类型的内容。on_error 处理函数控制信息的披露:原始异常消息绝不会发送给模型,除非你选择包含它。

工具重试 ​

以可配置的指数退避自动重试失败的工具调用。工具重试适用于以下场景:

  • 处理外部 API 调用中的瞬时故障。
  • 提高依赖网络的工具的可靠性。
  • 构建能够优雅处理临时错误的弹性智能体。

API 参考: ToolRetryMiddleware

python
from langchain.agents import create_agent
from langchain.agents.middleware import ToolRetryMiddleware

agent = create_agent(
    model="gpt-5.5",
    tools=[search_tool, database_tool],
    middleware=[
        ToolRetryMiddleware(
            max_retries=3,
            backoff_factor=2.0,
            initial_delay=1.0,
        ),
    ],
)

API 参考: toolRetryMiddleware

typescript
import { createAgent, toolRetryMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-5.5",
  tools: [searchTool, databaseTool],
  middleware: [
    toolRetryMiddleware({
      maxRetries: 3,
      backoffFactor: 2.0,
      initialDelayMs: 1000,
    }),
  ],
});

配置选项 ​

  • max_retries (number)(默认:2):初始调用之后的最大重试次数(默认总共 3 次尝试)

  • tools (list[BaseTool | str]):可选的工具或工具名称列表,用于应用重试逻辑。如果为 None,则应用于所有工具。

  • retry_on (tuple[type[Exception], ...] | callable)(默认:(Exception,)):要么是用于重试的异常类型元组,要么是可调用对象,它接受一个异常,如果应重试则返回 True。默认情况下,所有异常都会被重试。不匹配的异常会立即传播,并且不会被 on_failure 处理。

  • on_failure (string | callable)(默认:continue):所有重试都耗尽时的行为。选项: - 'continue'(默认)- 返回包含错误详细信息的 ToolMessage,让 LLM 处理失败 - 'error' - 重新引发异常,停止智能体执行 - 自定义可调用对象 - 接受异常并返回 ToolMessage 内容字符串的函数 已弃用的值: 'return_message'(请改用 'continue')和 'raise'(请改用 'error')。

  • backoff_factor (number)(默认:2.0):指数退避的乘数。每次重试等待 initial_delay * (backoff_factor ** retry_number) 秒。设置为 0.0 表示恒定延迟。

  • initial_delay (number)(默认:1.0):第一次重试之前的初始延迟(秒)

  • max_delay (number)(默认:60.0):重试之间的最大延迟(秒)(限制指数退避的增长)

  • jitter (boolean)(默认:true):是否在延迟中添加随机抖动(±25%)以避免惊群效应

  • maxRetries (number)(默认:2):初始调用之后的最大重试次数(默认总共 3 次尝试)。必须 >= 0。

  • tools ((ClientTool | ServerTool | string)[]):可选的工具或工具名称数组,用于应用重试逻辑。可以是 BaseTool 实例或工具名称字符串的列表。如果为 undefined,则应用于所有工具。

  • retryOn (((error: Error) => boolean) | (new (...args: any[]) => Error)[])(默认:() => true):要么是用于重试的错误构造函数数组,要么是接受错误并在应重试时返回 true 的函数。默认重试所有错误。

  • onFailure ('error' | 'continue' | ((error: Error) => string))(默认:continue):所有重试都耗尽时的行为。选项: - 'continue'(默认)- 返回包含错误详细信息的 ToolMessage,让 LLM 处理失败并可能恢复 - 'error' - 重新引发异常,停止智能体执行 - 自定义函数 - 接受异常并返回 ToolMessage 内容字符串的函数,允许自定义错误格式 已弃用的值: 'raise'(请改用 'error')和 'return_message'(请改用 'continue')。这些已弃用的值仍然有效,但会显示警告。

  • backoffFactor (number)(默认:2.0):指数退避的乘数。每次重试等待 initialDelayMs * (backoffFactor ** retryNumber) 毫秒。设置为 0.0 表示恒定延迟。必须 >= 0。

  • initialDelayMs (number)(默认:1000):第一次重试之前的初始延迟(毫秒)。必须 >= 0。

  • maxDelayMs (number)(默认:60000):重试之间的最大延迟(毫秒)(限制指数退避的增长)。必须 >= 0。

  • jitter (boolean)(默认:true):是否在延迟中添加随机抖动(±25%)以避免惊群效应

完整示例 ​

该中间件以指数退避自动重试失败的工具调用。

关键配置:

  • max_retries - 重试次数(默认:2)
  • backoff_factor - 指数退避的乘数(默认:2.0)
  • initial_delay - 起始延迟(秒)(默认:1.0)
  • max_delay - 延迟增长的上限(默认:60.0)
  • jitter - 添加随机变化(默认:True)

失败处理:

  • on_failure='continue'(默认)- 返回错误消息
  • on_failure='error' - 重新引发异常
  • 自定义函数 - 返回错误消息的函数 关键配置:
  • maxRetries - 重试次数(默认:2)
  • backoffFactor - 指数退避的乘数(默认:2.0)
  • initialDelayMs - 起始延迟(毫秒)(默认:1000ms)
  • maxDelayMs - 延迟增长的上限(默认:60000ms)
  • jitter - 添加随机变化(默认:true)

失败处理:

  • onFailure: "continue"(默认)- 返回错误消息
  • onFailure: "error" - 重新引发异常
  • 自定义函数 - 返回错误消息的函数
python
from langchain.agents import create_agent
from langchain.agents.middleware import ToolRetryMiddleware

agent = create_agent(
    model="gpt-5.5",
    tools=[search_tool, database_tool, api_tool],
    middleware=[
        ToolRetryMiddleware(
            max_retries=3,
            backoff_factor=2.0,
            initial_delay=1.0,
            max_delay=60.0,
            jitter=True,
            tools=["api_tool"],
            retry_on=(ConnectionError, TimeoutError),
            on_failure="continue",
        ),
    ],
)
typescript
import { createAgent, toolRetryMiddleware } from "langchain";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

// 使用默认设置的基本用法(2 次重试、指数退避)
const agent = createAgent({
  model: "gpt-5.5",
  tools: [searchTool, databaseTool],
  middleware: [toolRetryMiddleware()],
});

// 只重试特定异常
const retry = toolRetryMiddleware({
  maxRetries: 4,
  retryOn: [TimeoutError, NetworkError],
  backoffFactor: 1.5,
});

// 自定义异常过滤
function shouldRetry(error: Error): boolean {
  // 只重试 5xx 错误
  if (error.name === "HTTPError" && "statusCode" in error) {
    const statusCode = (error as any).statusCode;
    return 500 <= statusCode && statusCode < 600;
  }
  return false;
}

const retryWithFilter = toolRetryMiddleware({
  maxRetries: 3,
  retryOn: shouldRetry,
});

// 应用于带有自定义错误处理的特定工具
const formatError = (error: Error) =>
  "Database temporarily unavailable. Please try again later.";

const retrySpecificTools = toolRetryMiddleware({
  maxRetries: 4,
  tools: ["search_database"],
  onFailure: formatError,
});

// 使用 BaseTool 实例应用于特定工具
const searchDatabase = tool(
  async ({ query }) => {
    // 搜索实现
    return results;
  },
  {
    name: "search_database",
    description: "Search the database",
    schema: z.object({ query: z.string() }),
  }
);

const retryWithToolInstance = toolRetryMiddleware({
  maxRetries: 4,
  tools: [searchDatabase], // 传入 BaseTool 实例
});

// 恒定退避(无指数增长)
const constantBackoff = toolRetryMiddleware({
  maxRetries: 5,
  backoffFactor: 0.0, // 无指数增长
  initialDelayMs: 2000, // 始终等待 2 秒
});

// 失败时抛出异常
const strictRetry = toolRetryMiddleware({
  maxRetries: 2,
  onFailure: "error", // 重新抛出异常而不是返回消息
});

模型重试 ​

以可配置的指数退避自动重试失败的模型调用。模型重试适用于以下场景:

  • 处理模型 API 调用中的瞬时故障。
  • 提高依赖网络的模型请求的可靠性。
  • 构建能够优雅处理临时模型错误的弹性智能体。

API 参考: ModelRetryMiddleware

python
from langchain.agents import create_agent
from langchain.agents.middleware import ModelRetryMiddleware

agent = create_agent(
    model="gpt-5.5",
    tools=[search_tool, database_tool],
    middleware=[
        ModelRetryMiddleware(
            max_retries=3,
            backoff_factor=2.0,
            initial_delay=1.0,
        ),
    ],
)

API 参考: modelRetryMiddleware

typescript
import { createAgent, modelRetryMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-5.5",
  tools: [searchTool, databaseTool],
  middleware: [
    modelRetryMiddleware({
      maxRetries: 3,
      backoffFactor: 2.0,
      initialDelayMs: 1000,
    }),
  ],
});

配置选项 ​

  • max_retries (number)(默认:2):初始调用之后的最大重试次数(默认总共 3 次尝试)

  • retry_on (tuple[type[Exception], ...] | callable)(默认:(Exception,)):要么是用于重试的异常类型元组,要么是可调用对象,它接受一个异常,如果应重试则返回 True。

  • on_failure (string | callable)(默认:continue):所有重试都耗尽时的行为。选项: - 'continue'(默认)- 返回包含错误详细信息的 AIMessage,让智能体可能优雅地处理失败 - 'error' - 重新引发异常(停止智能体执行) - 自定义可调用对象 - 接受异常并返回 AIMessage 内容字符串的函数

  • backoff_factor (number)(默认:2.0):指数退避的乘数。每次重试等待 initial_delay * (backoff_factor ** retry_number) 秒。设置为 0.0 表示恒定延迟。

  • initial_delay (number)(默认:1.0):第一次重试之前的初始延迟(秒)

  • max_delay (number)(默认:60.0):重试之间的最大延迟(秒)(限制指数退避的增长)

  • jitter (boolean)(默认:true):是否在延迟中添加随机抖动(±25%)以避免惊群效应

  • maxRetries (number)(默认:2):初始调用之后的最大重试次数(默认总共 3 次尝试)。必须 >= 0。

  • retryOn (((error: Error) => boolean) | (new (...args: any[]) => Error)[])(默认:() => true):要么是用于重试的错误构造函数数组,要么是接受错误并在应重试时返回 true 的函数。默认重试所有错误。

  • onFailure ('error' | 'continue' | ((error: Error) => string))(默认:continue):所有重试都耗尽时的行为。选项: - 'continue'(默认)- 返回包含错误详细信息的 AIMessage,让智能体可能优雅地处理失败 - 'error' - 重新引发异常,停止智能体执行 - 自定义函数 - 接受异常并返回 AIMessage 内容字符串的函数,允许自定义错误格式

  • backoffFactor (number)(默认:2.0):指数退避的乘数。每次重试等待 initialDelayMs * (backoffFactor ** retryNumber) 毫秒。设置为 0.0 表示恒定延迟。必须 >= 0。

  • initialDelayMs (number)(默认:1000):第一次重试之前的初始延迟(毫秒)。必须 >= 0。

  • maxDelayMs (number)(默认:60000):重试之间的最大延迟(毫秒)(限制指数退避的增长)。必须 >= 0。

  • jitter (boolean)(默认:true):是否在延迟中添加随机抖动(±25%)以避免惊群效应

完整示例 ​

该中间件以指数退避自动重试失败的模型调用。

python
from langchain.agents import create_agent
from langchain.agents.middleware import ModelRetryMiddleware

# 使用默认设置的基本用法(2 次重试、指数退避)
agent = create_agent(
    model="gpt-5.5",
    tools=[search_tool],
    middleware=[ModelRetryMiddleware()],
)

# 自定义异常过滤
class TimeoutError(Exception):
    """Custom exception for timeout errors."""
    pass

class ConnectionError(Exception):
    """Custom exception for connection errors."""
    pass

# 只重试特定异常
retry = ModelRetryMiddleware(
    max_retries=4,
    retry_on=(TimeoutError, ConnectionError),
    backoff_factor=1.5,
)

def should_retry(error: Exception) -> bool:
    # 只重试限流错误
    if isinstance(error, TimeoutError):
        return True
    # 或者检查特定的 HTTP 状态码
    if hasattr(error, "status_code"):
        return error.status_code in (429, 503)
    return False

retry_with_filter = ModelRetryMiddleware(
    max_retries=3,
    retry_on=should_retry,
)

# 返回错误消息而不是抛出异常
retry_continue = ModelRetryMiddleware(
    max_retries=4,
    on_failure="continue",  # 返回带错误的 AIMessage,而不是抛出异常
)

# 自定义错误消息格式
def format_error(error: Exception) -> str:
    return f"Model call failed: {error}. Please try again later."

retry_with_formatter = ModelRetryMiddleware(
    max_retries=4,
    on_failure=format_error,
)

# 恒定退避(无指数增长)
constant_backoff = ModelRetryMiddleware(
    max_retries=5,
    backoff_factor=0.0,  # 无指数增长
    initial_delay=2.0,  # 始终等待 2 秒
)

# 失败时抛出异常
strict_retry = ModelRetryMiddleware(
    max_retries=2,
    on_failure="error",  # 重新抛出异常而不是返回消息
)
typescript
import { createAgent, modelRetryMiddleware } from "langchain";

// 使用默认设置的基本用法(2 次重试、指数退避)
const agent = createAgent({
  model: "gpt-5.5",
  tools: [searchTool],
  middleware: [modelRetryMiddleware()],
});

class TimeoutError extends Error {
    // ...
}
class NetworkError extends Error {
    // ...
}

// 只重试特定异常
const retry = modelRetryMiddleware({
  maxRetries: 4,
  retryOn: [TimeoutError, NetworkError],
  backoffFactor: 1.5,
});

// 自定义异常过滤
function shouldRetry(error: Error): boolean {
  // 只重试限流错误
  if (error.name === "RateLimitError") {
    return true;
  }
  // 或者检查特定的 HTTP 状态码
  if (error.name === "HTTPError" && "statusCode" in error) {
    const statusCode = (error as any).statusCode;
    return statusCode === 429 || statusCode === 503;
  }
  return false;
}

const retryWithFilter = modelRetryMiddleware({
  maxRetries: 3,
  retryOn: shouldRetry,
});

// 返回错误消息而不是抛出异常
const retryContinue = modelRetryMiddleware({
  maxRetries: 4,
  onFailure: "continue", // 返回带错误的 AIMessage,而不是抛出异常
});

// 自定义错误消息格式
const formatError = (error: Error) =>
  `Model call failed: ${error.message}. Please try again later.`;

const retryWithFormatter = modelRetryMiddleware({
  maxRetries: 4,
  onFailure: formatError,
});

// 恒定退避(无指数增长)
const constantBackoff = modelRetryMiddleware({
  maxRetries: 5,
  backoffFactor: 0.0, // 无指数增长
  initialDelayMs: 2000, // 始终等待 2 秒
});

// 失败时抛出异常
const strictRetry = modelRetryMiddleware({
  maxRetries: 2,
  onFailure: "error", // 重新抛出异常而不是返回消息
});

LLM 工具模拟器 ​

出于测试目的使用 LLM 模拟工具执行,用 AI 生成的响应替代实际的工具调用。LLM 工具模拟器适用于以下场景:

  • 在不执行真实工具的情况下测试智能体行为。
  • 在外部工具不可用或成本高昂时开发智能体。
  • 在实现实际工具之前对智能体工作流进行原型设计。

API 参考: LLMToolEmulator

python
from langchain.agents import create_agent
from langchain.agents.middleware import LLMToolEmulator

agent = create_agent(
    model="gpt-5.5",
    tools=[get_weather, search_database, send_email],
    middleware=[
        LLMToolEmulator(),  # 模拟所有工具
    ],
)
typescript
import { createAgent, toolEmulatorMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-5.5",
  tools: [getWeather, searchDatabase, sendEmail],
  middleware: [
    toolEmulatorMiddleware(), // 模拟所有工具
  ],
});

配置选项 ​

  • tools (list[str | BaseTool]):要模拟的工具名称(str)或 BaseTool 实例列表。如果为 None(默认),将模拟所有工具。如果为空列表 [],则不模拟任何工具。如果为包含工具名称/实例的数组,则只模拟这些工具。

  • model (string | BaseChatModel):用于生成模拟工具响应的模型。可以是模型标识符字符串(例如 'google_genai:gemini-3.6-flash')或 BaseChatModel 实例。如果未指定,则默认为智能体的模型。更多信息参见 init_chat_model。

  • tools ((string | ClientTool | ServerTool)[]):要模拟的工具名称(string)或工具实例列表。如果为 undefined(默认),将模拟所有工具。如果为空数组 [],则不模拟任何工具。如果为包含工具名称/实例的数组,则只模拟这些工具。

  • model (string | BaseChatModel):用于生成模拟工具响应的模型。可以是模型标识符字符串(例如 'google_genai:gemini-3.6-flash')或 BaseChatModel 实例。如果未指定,则默认为智能体的模型。

完整示例 ​

该中间件使用 LLM 为工具调用生成合理的响应,而不是执行实际工具。

python
from langchain.agents import create_agent
from langchain.agents.middleware import LLMToolEmulator
from langchain.tools import tool

@tool
def get_weather(location: str) -> str:
    """Get the current weather for a location."""
    return f"Weather in {location}"

@tool
def send_email(to: str, subject: str, body: str) -> str:
    """Send an email."""
    return "Email sent"

# 模拟所有工具(默认行为)
agent = create_agent(
    model="gpt-5.5",
    tools=[get_weather, send_email],
    middleware=[LLMToolEmulator()],
)

# 只模拟特定工具
agent2 = create_agent(
    model="gpt-5.5",
    tools=[get_weather, send_email],
    middleware=[LLMToolEmulator(tools=["get_weather"])],
)

# 使用自定义模型进行模拟
agent4 = create_agent(
    model="gpt-5.5",
    tools=[get_weather, send_email],
    middleware=[LLMToolEmulator(model="claude-sonnet-4-6")],
)
typescript
import { createAgent, toolEmulatorMiddleware, tool } from "langchain";
import * as z from "zod";

const getWeather = tool(
  async ({ location }) => `Weather in ${location}`,
  {
    name: "get_weather",
    description: "Get the current weather for a location",
    schema: z.object({ location: z.string() }),
  }
);

const sendEmail = tool(
  async ({ to, subject, body }) => "Email sent",
  {
    name: "send_email",
    description: "Send an email",
    schema: z.object({
      to: z.string(),
      subject: z.string(),
      body: z.string(),
    }),
  }
);

// 模拟所有工具(默认行为)
const agent = createAgent({
  model: "gpt-5.5",
  tools: [getWeather, sendEmail],
  middleware: [toolEmulatorMiddleware()],
});

// 按名称模拟特定工具
const agent2 = createAgent({
  model: "gpt-5.5",
  tools: [getWeather, sendEmail],
  middleware: [
    toolEmulatorMiddleware({
      tools: ["get_weather"],
    }),
  ],
});

// 通过传入工具实例来模拟特定工具
const agent3 = createAgent({
  model: "gpt-5.5",
  tools: [getWeather, sendEmail],
  middleware: [
    toolEmulatorMiddleware({
      tools: [getWeather],
    }),
  ],
});

// 使用自定义模型进行模拟
const agent5 = createAgent({
  model: "gpt-5.5",
  tools: [getWeather, sendEmail],
  middleware: [
    toolEmulatorMiddleware({
      model: "claude-sonnet-4-6",
    }),
  ],
});

上下文编辑 ​

通过删除较旧的工具调用输出来管理对话上下文,同时保留最近的结果。这有助于在包含大量工具调用的长时间对话中保持上下文窗口可控。上下文编辑适用于以下场景:

  • 包含许多工具调用且超出 token 限制的长时间对话
  • 通过删除不再相关的较旧工具输出以降低 token 成本
  • 在上下文中只保留最近的 N 个工具结果

API 参考: ContextEditingMiddleware, ClearToolUsesEdit

python
from langchain.agents import create_agent
from langchain.agents.middleware import ContextEditingMiddleware, ClearToolUsesEdit

agent = create_agent(
    model="gpt-5.5",
    tools=[],
    middleware=[
        ContextEditingMiddleware(
            edits=[
                ClearToolUsesEdit(
                    trigger=100000,
                    keep=3,
                ),
            ],
        ),
    ],
)
typescript
import { createAgent, contextEditingMiddleware, ClearToolUsesEdit } from "langchain";

const agent = createAgent({
  model: "gpt-5.5",
  tools: [],
  middleware: [
    contextEditingMiddleware({
      edits: [
        new ClearToolUsesEdit({
          triggerTokens: 100000,
          keep: 3,
        }),
      ],
    }),
  ],
});

配置选项 ​

  • edits (list[ContextEdit])(默认:[ClearToolUsesEdit()]):要应用的 ContextEdit 策略列表

  • token_count_method (string)(默认:approximate):token 计数方法。选项:'approximate' 或 'model'

ClearToolUsesEdit 选项:

  • trigger (number)(默认:100000):触发编辑的 token 数量。当对话超过此 token 数量时,较旧的工具输出将被清除。

  • clear_at_least (number)(默认:0):编辑运行时至少要回收的 token 数量。如果设置为 0,则按需清除尽可能多。

  • keep (number)(默认:3):必须保留的最近工具结果的数量。这些永远不会被清除。

  • clear_tool_inputs (boolean)(默认:False):是否清除 AI 消息上发起调用的工具参数。当为 True 时,工具调用参数会被替换为空对象。

  • exclude_tools (list[string])(默认:()):要从清除中排除的工具名称列表。这些工具的输出永远不会被清除。

  • placeholder (string)(默认:[cleared]):为被清除的工具输出插入的占位符文本。它会替换原始的工具消息内容。

  • edits (ContextEdit[])(默认:[new ClearToolUsesEdit()]):要应用的 ContextEdit 策略数组

ClearToolUsesEdit 选项:

  • triggerTokens (number)(默认:100000):触发编辑的 token 数量。当对话超过此 token 数量时,较旧的工具输出将被清除。

  • clearAtLeast (number)(默认:0):编辑运行时至少要回收的 token 数量。如果设置为 0,则按需清除尽可能多。

  • keep (number)(默认:3):必须保留的最近工具结果的数量。这些永远不会被清除。

  • clearToolInputs (boolean)(默认:false):是否清除 AI 消息上发起调用的工具参数。当为 true 时,工具调用参数会被替换为空对象。

  • excludeTools (string[])(默认:[]):要从清除中排除的工具名称列表。这些工具的输出永远不会被清除。

  • placeholder (string)(默认:[cleared]):为被清除的工具输出插入的占位符文本。它会替换原始的工具消息内容。

完整示例 ​

该中间件在达到 token 限制时应用上下文编辑策略。最常见的策略是 ClearToolUsesEdit,它清除较旧的工具结果,同时保留最近的结果。

工作原理:

  1. 监控对话中的 token 数量
  2. 达到阈值时,清除较旧的工具输出
  3. 保留最近的 N 个工具结果
  4. 可选地保留工具调用参数以供上下文使用
python
from langchain.agents import create_agent
from langchain.agents.middleware import ContextEditingMiddleware, ClearToolUsesEdit

agent = create_agent(
    model="gpt-5.5",
    tools=[search_tool, your_calculator_tool, database_tool],
    middleware=[
        ContextEditingMiddleware(
            edits=[
                ClearToolUsesEdit(
                    trigger=2000,
                    keep=3,
                    clear_tool_inputs=False,
                    exclude_tools=[],
                    placeholder="[cleared]",
                ),
            ],
        ),
    ],
)
typescript
import { createAgent, contextEditingMiddleware, ClearToolUsesEdit } from "langchain";

const agent = createAgent({
  model: "gpt-5.5",
  tools: [searchTool, calculatorTool, databaseTool],
  middleware: [
    contextEditingMiddleware({
      edits: [
        new ClearToolUsesEdit({
          triggerTokens: 2000,
          keep: 3,
          clearToolInputs: false,
          excludeTools: [],
          placeholder: "[cleared]",
        }),
      ],
    }),
  ],
});

提供商工具搜索 ​

将选定的工具延迟到模型提供商的服务器端工具搜索之后,让模型按需发现它们,而不是预先接收每个工具 schema。提供商工具搜索适用于:

  • 在使用大量工具时减少上下文膨胀。
  • 通过只呈现相关工具来提高工具选择的准确性。

INFO

需要支持服务器端工具搜索的模型:Anthropic(Claude Sonnet 4+/Opus 4+/Haiku 4.5+)或 OpenAI(gpt-5.5+)。其他提供商会引发 ValueError。

API 参考: ProviderToolSearchMiddleware

python
from langchain.agents import create_agent
from langchain.agents.middleware import ProviderToolSearchMiddleware

agent = create_agent(
    model="anthropic:claude-opus-4-8",
    tools=[get_weather, lookup_order],
    middleware=[
        ProviderToolSearchMiddleware(searchable_tools=["lookup_order"]),
    ],
)

配置选项 ​

  • searchable_tools (list[str | BaseTool]):要延迟到提供商工具搜索之后的工具,按名称或实例给出。被延迟的工具在提供商的搜索发现它们之前不会提供给模型。使用 extras={"defer_loading": True} 构造的工具无论此选项如何都会被延迟;如果省略 searchable_tools,则只有这些预先标记的工具会被延迟。

完整示例 ​

该中间件将 searchable_tools 中包含的所有工具纳入延迟和搜索。工具也可以在构造时通过设置 extras={"defer_loading": True} 来选择延迟。

python
from langchain.agents import create_agent
from langchain.agents.middleware import ProviderToolSearchMiddleware
from langchain.tools import tool

# 在构造时标记了 `defer_loading`,因此它会自行延迟加载 —
# 无需在 `searchable_tools` 中列出它。
@tool(extras={"defer_loading": True})
def send_email(to: str) -> str:
    """Send an email."""
    return "sent"

agent = create_agent(
    model="anthropic:claude-opus-4-8",
    tools=[send_email],
    middleware=[ProviderToolSearchMiddleware()],
)

提供商工具搜索 ​

将选定的工具延迟到模型提供商的服务器端工具搜索之后,让模型按需发现它们,而不是预先接收每个工具 schema。提供商工具搜索适用于:

  • 在使用大量工具时减少上下文膨胀。
  • 通过只呈现相关工具来提高工具选择的准确性。

INFO

需要支持服务器端工具搜索的模型:Anthropic(Claude Sonnet 4+/Opus 4+/Haiku 4.5+)或 OpenAI(gpt-5.5+)。其他提供商将抛出错误。

API 参考: providerToolSearchMiddleware

typescript
import { createAgent, providerToolSearchMiddleware } from "langchain";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

const getWeather = tool(async () => "Sunny, 22C", {
  name: "get_weather",
  description: "Get the current weather for a city",
  schema: z.object({ city: z.string() }),
});

const lookupOrderStatus = tool(async () => "OUT_FOR_DELIVERY", {
  name: "lookup_order_status",
  description: "Look up the current delivery status of a customer order by ID",
  schema: z.object({ orderId: z.string() }),
});

const nicheTools = [lookupOrderStatus];

const agent = createAgent({
  model: "anthropic:claude-opus-4-8",
  tools: [getWeather, ...nicheTools],
  middleware: [
    providerToolSearchMiddleware({ searchableTools: nicheTools }),
  ],
});

配置选项 ​

  • searchableTools ((string | StructuredToolInterface)[]):要延迟到提供商工具搜索之后的工具,按名称或实例给出。被延迟的工具在提供商的搜索发现它们之前不会提供给模型。使用 extras.defer_loading: true 构造的工具无论此选项如何都会被延迟;如果省略 searchableTools,则只有这些预先标记的工具会被延迟。

完整示例 ​

该中间件将 searchableTools 中包含的所有工具纳入延迟和搜索。工具也可以在构造时通过设置 extras.defer_loading: true 来选择延迟

typescript
import { createAgent, providerToolSearchMiddleware } from "langchain";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

// 在构造时标记了 `defer_loading`,因此它会自行延迟加载 —
// 无需在 `searchableTools` 中列出它。
const sendEmail = tool(async () => "sent", {
  name: "send_email",
  description: "Send an email",
  schema: z.object({ to: z.string() }),
  extras: { defer_loading: true },
});

const agent = createAgent({
  model: "anthropic:claude-opus-4-8",
  tools: [sendEmail],
  middleware: [providerToolSearchMiddleware()],
});

Shell 工具 ​

向智能体暴露一个持久 shell 会话用于执行命令。Shell 工具中间件适用于以下场景:

  • 需要执行系统命令的智能体
  • 开发和部署自动化任务
  • 测试和验证工作流
  • 文件系统操作和脚本执行

WARNING

安全注意事项:使用适当的执行策略(HostExecutionPolicy、DockerExecutionPolicy 或 CodexSandboxExecutionPolicy)以匹配你部署的安全要求。

INFO

限制:持久 shell 会话目前无法与中断(人在回路)配合使用。我们预计未来会增加对此的支持。

API 参考: ShellToolMiddleware

python
from langchain.agents import create_agent
from langchain.agents.middleware import (
    ShellToolMiddleware,
    HostExecutionPolicy,
)

agent = create_agent(
    model="gpt-5.5",
    tools=[search_tool],
    middleware=[
        ShellToolMiddleware(
            workspace_root="/workspace",
            execution_policy=HostExecutionPolicy(),
        ),
    ],
)

配置选项 ​

  • workspace_root (str | Path | None):shell 会话的基础目录。如果省略,则会在智能体启动时创建临时目录,并在其结束时删除。

  • startup_commands (tuple[str, ...] | list[str] | str | None):会话启动后按顺序执行的可选命令

  • shutdown_commands (tuple[str, ...] | list[str] | str | None):会话关闭之前执行的可选命令

  • execution_policy (BaseExecutionPolicy | None):控制超时、输出限制和资源配置的执行策略。选项: - HostExecutionPolicy - 完整的主机访问权限(默认);最适合智能体已在容器或虚拟机内运行的受信任环境 - DockerExecutionPolicy - 为每次智能体运行启动单独的 Docker 容器,提供更强的隔离 - CodexSandboxExecutionPolicy - 复用 Codex CLI 沙箱以获得额外的 syscall/文件系统限制

  • redaction_rules (tuple[RedactionRule, ...] | list[RedactionRule] | None):可选的脱敏规则,用于在将命令输出返回给模型之前进行清理。 脱敏规则在执行后应用,使用 HostExecutionPolicy 时无法防止机密或敏感数据被泄露。

  • tool_description (str | None):对注册的 shell 工具描述的可选覆盖

  • shell_command (Sequence[str] | str | None):用于启动持久会话的可选 shell 可执行文件(字符串)或参数序列。默认为 /bin/bash。

  • env (Mapping[str, Any] | None):提供给 shell 会话的可选环境变量。在执行命令之前,值会被强制转换为字符串。

完整示例 ​

该中间件提供一个单一的持久 shell 会话,智能体可以按顺序执行命令。

执行策略:

  • HostExecutionPolicy(默认)- 具有完整主机访问权限的本机执行
  • DockerExecutionPolicy - 隔离的 Docker 容器执行
  • CodexSandboxExecutionPolicy - 通过 Codex CLI 进行沙箱化执行
python
from langchain.agents import create_agent
from langchain.agents.middleware import (
    ShellToolMiddleware,
    HostExecutionPolicy,
    DockerExecutionPolicy,
    RedactionRule,
)

# 带主机执行的基本 shell 工具
agent = create_agent(
    model="gpt-5.5",
    tools=[search_tool],
    middleware=[
        ShellToolMiddleware(
            workspace_root="/workspace",
            execution_policy=HostExecutionPolicy(),
        ),
    ],
)

# 带启动命令的 Docker 隔离
agent_docker = create_agent(
    model="gpt-5.5",
    tools=[],
    middleware=[
        ShellToolMiddleware(
            workspace_root="/workspace",
            startup_commands=["pip install requests", "export PYTHONPATH=/workspace"],
            execution_policy=DockerExecutionPolicy(
                image="python:3.11-slim",
                command_timeout=60.0,
            ),
        ),
    ],
)

# 带输出脱敏(在执行后应用)
agent_redacted = create_agent(
    model="gpt-5.5",
    tools=[],
    middleware=[
        ShellToolMiddleware(
            workspace_root="/workspace",
            redaction_rules=[
                RedactionRule(pii_type="api_key", detector=r"sk-[a-zA-Z0-9]{32}"),
            ],
        ),
    ],
)

文件搜索 ​

提供针对文件系统的 Glob 和 Grep 搜索工具。文件搜索中间件适用于以下场景:

  • 代码探索和分析
  • 按名称模式查找文件
  • 使用正则表达式搜索代码内容
  • 需要文件发现功能的大型代码库

API 参考: FilesystemFileSearchMiddleware

python
from langchain.agents import create_agent
from langchain.agents.middleware import FilesystemFileSearchMiddleware

agent = create_agent(
    model="gpt-5.5",
    tools=[],
    middleware=[
        FilesystemFileSearchMiddleware(
            root_path="/workspace",
            use_ripgrep=True,
        ),
    ],
)

配置选项 ​

  • root_path (str)(必填):要搜索的根目录。所有文件操作都相对于此路径。

  • use_ripgrep (bool)(默认:True):是否使用 ripgrep 进行搜索。如果 ripgrep 不可用,则回退到 Python 正则表达式。

  • max_file_size_mb (int)(默认:10):要搜索的最大文件大小(MB)。大于此大小的文件将被跳过。

完整示例 ​

该中间件为智能体添加两个搜索工具:

Glob 工具 - 快速的文件模式匹配:

  • 支持诸如 **/*.py、src/**/*.ts 之类的模式
  • 返回按修改时间排序的匹配文件路径

Grep 工具 - 使用正则表达式进行内容搜索:

  • 完整的正则表达式语法支持
  • 使用 include 参数按文件模式过滤
  • 三种输出模式:files_with_matches、content、count
python
from langchain.agents import create_agent
from langchain.agents.middleware import FilesystemFileSearchMiddleware
from langchain.messages import HumanMessage

agent = create_agent(
    model="gpt-5.5",
    tools=[],
    middleware=[
        FilesystemFileSearchMiddleware(
            root_path="/workspace",
            use_ripgrep=True,
            max_file_size_mb=10,
        ),
    ],
)

# 智能体现在可以使用 glob_search 和 grep_search 工具
result = agent.invoke({
    "messages": [HumanMessage("Find all Python files containing 'async def'")]
})

# 智能体将使用:
# 1. glob_search(pattern="**/*.py") 查找 Python 文件
# 2. grep_search(pattern="async def", include="*.py") 查找 async 函数

文件系统中间件 ​

上下文工程是构建高效智能体时的一个主要挑战。在使用返回变长结果的工具(例如 web_search 和 RAG)时尤其困难,因为较长的工具结果会迅速填满你的上下文窗口。

来自 Deep Agents 的 FilesystemMiddleware 提供四个用于与短期和长期记忆交互的工具:

  • ls:列出文件系统中的文件
  • read_file:读取整个文件或从文件中读取一定数量的行
  • write_file:向文件系统写入新文件
  • edit_file:编辑文件系统中已有的文件
python
from langchain.agents import create_agent
from deepagents.middleware.filesystem import FilesystemMiddleware

# FilesystemMiddleware 默认包含在 create_deep_agent 中
# 如果你正在构建自定义智能体,可以自定义它
agent = create_agent(
    model="claude-sonnet-4-6",
    middleware=[
        FilesystemMiddleware(
            backend=None,  # 可选:自定义后端(默认为 StateBackend)
            system_prompt="Write to the filesystem when...",  # 可选:对系统提示词的自定义补充
            custom_tool_descriptions={
                "ls": "Use the ls tool when...",
                "read_file": "Use the read_file tool to..."
            },  # 可选:文件系统工具的自定义描述
            tools=["read_file", "ls", "glob", "grep"],  # 可选:允许列表,限制暴露哪些文件系统工具
        ),
    ],
)
typescript
import { createAgent } from "langchain";
import { createFilesystemMiddleware } from "deepagents";

// FilesystemMiddleware 默认包含在 createDeepAgent 中
// 如果你正在构建自定义智能体,可以自定义它
const agent = createAgent({
  model: "claude-sonnet-4-6",
  middleware: [
    createFilesystemMiddleware({
      backend: undefined,  // 可选:自定义后端(默认为 StateBackend)
      systemPrompt: "Write to the filesystem when...",  // 可选:自定义系统提示词覆盖
      customToolDescriptions: {
        ls: "Use the ls tool when...",
        read_file: "Use the read_file tool to...",
      },  // 可选:文件系统工具的自定义描述
    }),
  ],
});

短期与长期文件系统 ​

默认情况下,这些工具写入图状态中的本地"文件系统"。要启用跨线程的持久存储,请配置一个 CompositeBackend,将特定路径(如 /memories/)路由到 StoreBackend。

python
from langchain.agents import create_agent
from deepagents.middleware import FilesystemMiddleware
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
from langgraph.store.memory import InMemoryStore

store = InMemoryStore()

agent = create_agent(
    model="claude-sonnet-4-6",
    store=store,
    middleware=[
        FilesystemMiddleware(
            backend=CompositeBackend(
                default=StateBackend(),
                routes={"/memories/": StoreBackend()}
            ),
            custom_tool_descriptions={
                "ls": "Use the ls tool when...",
                "read_file": "Use the read_file tool to..."
            }  # 可选:文件系统工具的自定义描述
        ),
    ],
)
typescript
import { createAgent } from "langchain";
import { createFilesystemMiddleware, CompositeBackend, StateBackend, StoreBackend } from "deepagents";
import { InMemoryStore } from "@langchain/langgraph-checkpoint";

const store = new InMemoryStore();

const agent = createAgent({
  model: "claude-sonnet-4-6",
  store,
  middleware: [
    createFilesystemMiddleware({
      backend: new CompositeBackend(
        new StateBackend(),
        { "/memories/": new StoreBackend() }
      ),
      systemPrompt: "Write to the filesystem when...", // 可选:自定义系统提示词覆盖
      customToolDescriptions: {
        ls: "Use the ls tool when...",
        read_file: "Use the read_file tool to...",
      }, // 可选:文件系统工具的自定义描述
    }),
  ],
});

当你为 /memories/ 配置带 StoreBackend 的 CompositeBackend 时,任何以 /memories/ 为前缀的文件都会保存到持久存储中,并在不同线程之间保留。没有此前缀的文件则保留在临时状态存储中。

子智能体 ​

将任务交接给子智能体可以隔离上下文,在保持主(主管)智能体上下文窗口清洁的同时,仍然能够深入处理任务。

来自 Deep Agents 的子智能体中间件允许你通过 task 工具提供子智能体。

python
from langchain.tools import tool
from langchain.agents import create_agent
from deepagents.middleware.subagents import SubAgentMiddleware

@tool
def get_weather(city: str) -> str:
    """Get the weather in a city."""
    return f"The weather in {city} is sunny."

agent = create_agent(
    model="claude-sonnet-4-6",
    middleware=[
        SubAgentMiddleware(
            default_model="claude-sonnet-4-6",
            default_tools=[],
            subagents=[
                {
                    "name": "weather",
                    "description": "This subagent can get weather in cities.",
                    "system_prompt": "Use the get_weather tool to get the weather in a city.",
                    "tools": [get_weather],
                    "model": "gpt-5.5",
                    "middleware": [],
                }
            ],
        )
    ],
)
typescript
import { tool } from "langchain";
import { createAgent } from "langchain";
import { createSubAgentMiddleware } from "deepagents";
import { z } from "zod";

const getWeather = tool(
  async ({ city }: { city: string }) => {
    return `The weather in ${city} is sunny.`;
  },
  {
    name: "get_weather",
    description: "Get the weather in a city.",
    schema: z.object({
      city: z.string(),
    }),
  },
);

const agent = createAgent({
  model: "claude-sonnet-4-6",
  middleware: [
    createSubAgentMiddleware({
      defaultModel: "claude-sonnet-4-6",
      defaultTools: [],
      subagents: [
        {
          name: "weather",
          description: "This subagent can get weather in cities.",
          systemPrompt: "Use the get_weather tool to get the weather in a city.",
          tools: [getWeather],
          model: "gpt-5.5",
          middleware: [],
        },
      ],
    }),
  ],
});

子智能体由名称、描述、系统提示词和工具定义。你还可以为子智能体提供自定义的模型,或额外的中间件。当你希望为子智能体提供额外的状态键以与主智能体共享时,这尤其有用。

对于更复杂的用例,你还可以提供自己预构建的 LangGraph 图作为子智能体。

python
from langchain.agents import create_agent
from deepagents.middleware.subagents import SubAgentMiddleware
from deepagents import CompiledSubAgent
from langgraph.graph import StateGraph

# 创建一个自定义的 LangGraph 图
def create_weather_graph():
    workflow = StateGraph(...)
    # 构建你的自定义图
    return workflow.compile()

weather_graph = create_weather_graph()

# 将它包装成 CompiledSubAgent
weather_subagent = CompiledSubAgent(
    name="weather",
    description="This subagent can get weather in cities.",
    runnable=weather_graph
)

agent = create_agent(
    model="claude-sonnet-4-6",
    middleware=[
        SubAgentMiddleware(
            default_model="claude-sonnet-4-6",
            default_tools=[],
            subagents=[weather_subagent],
        )
    ],
)
typescript
import { tool, createAgent } from "langchain";
import { createSubAgentMiddleware, type SubAgent } from "deepagents";
import { z } from "zod";

const getWeather = tool(
  async ({ city }: { city: string }) => {
    return `The weather in ${city} is sunny.`;
  },
  {
    name: "get_weather",
    description: "Get the weather in a city.",
    schema: z.object({
      city: z.string(),
    }),
  },
);

const weatherSubagent: SubAgent = {
  name: "weather",
  description: "This subagent can get weather in cities.",
  systemPrompt: "Use the get_weather tool to get the weather in a city.",
  tools: [getWeather],
  model: "gpt-5.5",
  middleware: [],
};

const agent = createAgent({
  model: "claude-sonnet-4-6",
  middleware: [
    createSubAgentMiddleware({
      defaultModel: "claude-sonnet-4-6",
      defaultTools: [],
      subagents: [weatherSubagent],
    }),
  ],
});

除了任何用户定义的子智能体之外,主智能体在任何时候都可以使用一个 general-purpose 子智能体。该子智能体具有与主智能体相同的指令以及它可以访问的所有工具。general-purpose 子智能体的主要用途是上下文隔离——主智能体可以将复杂任务委托给该子智能体,并获得简洁的答案返回,而不会因中间工具调用而膨胀。

Rubric 评分 ​

INFO

RubricMiddleware 需要 deepagents>=0.6.5。它目前处于 beta 阶段;API 未来可能会发生变化。

有些任务有明确的"完成"定义,而智能体无法在第一次尝试时就可靠地达到。RubricMiddleware 让你以 Rubric 的形式声明_完成是什么样的_,并让智能体自我评估和迭代,直到满足 Rubric 或达到最大迭代上限。

API 参考: RubricMiddleware

python
from deepagents import RubricMiddleware, create_deep_agent
from langgraph.checkpoint.memory import InMemorySaver

agent = create_deep_agent(
    model="google_genai:gemini-3.6-flash",
    middleware=[
        RubricMiddleware(
            model="anthropic:claude-haiku-4-5",
            max_iterations=3,
        ),
    ],
    checkpointer=InMemorySaver(),
)
python
from deepagents import RubricMiddleware, create_deep_agent
from langgraph.checkpoint.memory import InMemorySaver

agent = create_deep_agent(
    model="openai:gpt-5.5",
    middleware=[
        RubricMiddleware(
            model="anthropic:claude-haiku-4-5",
            max_iterations=3,
        ),
    ],
    checkpointer=InMemorySaver(),
)
python
from deepagents import RubricMiddleware, create_deep_agent
from langgraph.checkpoint.memory import InMemorySaver

agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    middleware=[
        RubricMiddleware(
            model="anthropic:claude-haiku-4-5",
            max_iterations=3,
        ),
    ],
    checkpointer=InMemorySaver(),
)
python
from deepagents import RubricMiddleware, create_deep_agent
from langgraph.checkpoint.memory import InMemorySaver

agent = create_deep_agent(
    model="openrouter:z-ai/glm-5.2",
    middleware=[
        RubricMiddleware(
            model="anthropic:claude-haiku-4-5",
            max_iterations=3,
        ),
    ],
    checkpointer=InMemorySaver(),
)
python
from deepagents import RubricMiddleware, create_deep_agent
from langgraph.checkpoint.memory import InMemorySaver

agent = create_deep_agent(
    model="fireworks:accounts/fireworks/models/glm-5p2",
    middleware=[
        RubricMiddleware(
            model="anthropic:claude-haiku-4-5",
            max_iterations=3,
        ),
    ],
    checkpointer=InMemorySaver(),
)
python
from deepagents import RubricMiddleware, create_deep_agent
from langgraph.checkpoint.memory import InMemorySaver

agent = create_deep_agent(
    model="baseten:zai-org/GLM-5.2",
    middleware=[
        RubricMiddleware(
            model="anthropic:claude-haiku-4-5",
            max_iterations=3,
        ),
    ],
    checkpointer=InMemorySaver(),
)
python
from deepagents import RubricMiddleware, create_deep_agent
from langgraph.checkpoint.memory import InMemorySaver

agent = create_deep_agent(
    model="ollama:north-mini-code-1.0",
    middleware=[
        RubricMiddleware(
            model="anthropic:claude-haiku-4-5",
            max_iterations=3,
        ),
    ],
    checkpointer=InMemorySaver(),
)

完整的配置选项、流式事件以及完整的代码生成示例参见 评分 Rubric。

提供商特定的中间件 ​

这些中间件针对特定的 LLM 提供商进行了优化。完整详细信息和示例参见每个提供商的文档。

  • Anthropic — 面向 Claude 模型的提示词缓存、bash 工具、文本编辑器、记忆和文件搜索中间件。

  • AWS — 面向 Amazon Bedrock 模型的提示词缓存中间件。

  • OpenAI — 面向 OpenAI 模型的内容审核中间件。

  • Anthropic — 面向 Claude 模型的提示词缓存、bash 工具、文本编辑器、记忆和文件搜索中间件。

  • AWS — 面向 Amazon Bedrock 模型的提示词缓存中间件。