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.1triggerkeepfraction 条件(如下所示)依赖于对话模型的配置档案数据。如果数据不可用,请使用其他条件或手动指定:

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,则不会自动触发摘要。 更多信息参见 ContextSizeTriggerClause 的 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.0triggerkeepfraction 条件(如下所示)依赖于对话模型的配置档案数据。如果数据不可用,请使用其他条件或手动指定:

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

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

观看此[视频指南](https://www.youtube.com/watch?v=SpfT6-YAVPk),了解人在回路中间件的行为演示。

观看此[视频指南](https://www.youtube.com/watch?v=tdOeUVERukA),了解人在回路中间件的行为演示。

模型调用限制

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

  • 防止失控的智能体发出过多的 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",
    }),
  ],
});
观看此[视频指南](https://www.youtube.com/watch?v=nJEER0uaNkE),了解模型调用限制中间件的行为演示。

观看此[视频指南](https://www.youtube.com/watch?v=x5jLQTFXR0Y),了解模型调用限制中间件的行为演示。

配置选项

  • 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,
    }),
  ],
});
观看此[视频指南](https://www.youtube.com/watch?v=6gYlaJJ8t0w),了解工具调用限制中间件的行为演示。

观看此[视频指南](https://www.youtube.com/watch?v=oL6am5UqODY),了解工具调用限制中间件的行为演示。

配置选项

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

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

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

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

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

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

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

  • 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"
    ),
  ],
});
观看此[视频指南](https://www.youtube.com/watch?v=8rCRO0DUeIM),了解模型回退中间件的行为演示。

配置选项

  • 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",
    }),
  ],
});

自定义检测器函数签名:

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

返回包含 textstartend 键的字典列表:

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 类型。可以是内置类型(emailcredit_cardipmac_addressurl)或自定义类型名称。

  • 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 类型。可以是内置类型(emailcredit_cardipmac_addressurl)或自定义类型名称。

  • 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()],
});
观看此[视频指南](https://www.youtube.com/watch?v=yTWocbVKQxw),了解待办事项列表中间件的行为演示。

观看此[视频指南](https://www.youtube.com/watch?v=dwvhZ1z_Pas),了解待办事项列表中间件的行为演示。

配置选项

  • 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

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

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 工具 - 快速的文件模式匹配:

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

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

  • 完整的正则表达式语法支持
  • 使用 include 参数按文件模式过滤
  • 三种输出模式:files_with_matchescontentcount
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 AgentsFilesystemMiddleware 提供四个用于与短期和长期记忆交互的工具:

  • 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/ 配置带 StoreBackendCompositeBackend 时,任何以 /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 模型的提示词缓存中间件。