外观
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
完整的示例、配置选项和集成模式参见人在回路文档。
观看此[视频指南](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_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"
),
],
});观看此[视频指南](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 类型。这使你能检测到内置类型之外、针对你用例的特定模式。
创建自定义检测器的三种方式:
- 正则表达式模式字符串 - 简单的模式匹配
- RegExp 对象 - 对正则表达式标志有更多控制
- 自定义函数 - 带验证的复杂检测逻辑
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()],
});观看此[视频指南](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,它清除较旧的工具结果,同时保留最近的结果。
工作原理:
- 监控对话中的 token 数量
- 达到阈值时,清除较旧的工具输出
- 保留最近的 N 个工具结果
- 可选地保留工具调用参数以供上下文使用
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 提供商进行了优化。完整详细信息和示例参见每个提供商的文档。