本页还没有译文
本页 259 段还没译成한국어,下面显示的是英文原文。Prebuilt middleware
还没翻译译自英文(docs.langchain.com)本页 259 段都还没译
LangChain provides prebuilt middleware for common use cases. Each middleware is production-ready and configurable for your specific needs.
Note
Using Deep Agents (create_deep_agent / createDeepAgent)? Middleware is added through the customization API instead.
Provider-agnostic middleware
The following middleware work with any LLM provider:
| Middleware | Description |
|---|---|
| Tool error | Catch tool execution exceptions and convert them to error messages for the model. |
| Tool retry | Automatically retry failed tool calls with exponential backoff. |
| Model retry | Automatically retry failed model calls with exponential backoff. |
| Model fallback | Automatically fallback to alternative models when primary fails. |
| Summarization | Automatically summarize conversation history when approaching token limits. |
| Human-in-the-loop | Pause execution for human approval of tool calls. |
| Model call limit | Limit the number of model calls to prevent excessive costs. |
| Tool call limit | Control tool execution by limiting call counts. |
| PII detection | Detect and handle Personally Identifiable Information (PII). |
| To-do list | Equip agents with task planning and tracking capabilities. |
| LLM tool selector | Use an LLM to select relevant tools before calling main model. |
| Provider tool search | Defer tools behind providers' server-side tool search, surfacing them on demand. |
| Shell tool | Expose a persistent shell session to agents for command execution. |
| Filesystem | Provide agents with a filesystem for storing context and long-term memories. |
| Subagent | Add the ability to spawn subagents. |
| Rubric grading (Beta) | Apply LLM-as-a-judge grading so agents self-evaluate and iterate until a rubric is satisfied. |
| File search | Provide Glob and Grep search tools over filesystem files. |
| Context editing | Manage conversation context by trimming or clearing tool uses. |
| LLM tool emulator | Emulate tool execution using an LLM for testing purposes. |
Tool error
Catch exceptions raised during tool execution and convert them into error ToolMessages that the model can see and recover from, instead of halting the agent run. Tool error is useful for the following:
- Letting the model retry a failed tool call with corrected arguments.
- Surfacing controlled, sanitized error messages instead of raw exception details.
- Preventing unexpected tool exceptions from crashing the agent.
Note
Tool error middleware does not automatically retry failed calls. For retries, compose with Tool retry middleware placed inner (later in the middleware list) and configured with on_failure="error" so that exceptions reach the tool error middleware. See the full example below.
API reference: ToolErrorMiddleware
Note
ToolErrorMiddleware requires langchain>=1.3.14.
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__}."
# propagate everything else
agent = create_agent(
model="gpt-5.5",
tools=[your_tools],
middleware=[ToolErrorMiddleware(on_error)],
)Tool retry
Automatically retry failed tool calls with configurable exponential backoff. Tool retry is useful for the following:
- Handling transient failures in external API calls.
- Improving reliability of network-dependent tools.
- Building resilient agents that gracefully handle temporary errors.
API reference: ToolRetryMiddleware
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,
),
],
)Model retry
Automatically retry failed model calls with configurable exponential backoff. Model retry is useful for the following:
- Handling transient failures in model API calls.
- Improving reliability of network-dependent model requests.
- Building resilient agents that gracefully handle temporary model errors.
API reference: ModelRetryMiddleware
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,
),
],
)Model fallback
Automatically fallback to alternative models when the primary model fails. Model fallback is useful for the following:
- Building resilient agents that handle model outages.
- Cost optimization by falling back to cheaper models.
- Provider redundancy across OpenAI, Anthropic, etc.
API reference: ModelFallbackMiddleware
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-sonnet-4-6",
),
],
)Note
Watch this video guide demonstrating Model Fallback middleware behavior.
Summarization
Automatically summarize conversation history when approaching token limits, preserving recent messages while compressing older context. Summarization is useful for the following:
- Long-running conversations that exceed context windows.
- Multi-turn dialogues with extensive history.
- Applications where preserving full conversation context matters.
Note
Summarization is text-oriented context compression. It does not resize, downsample, or otherwise compress image/audio/video payloads. Recent messages retained by keep still include their original multimodal blocks, while older multimodal messages that are summarized are represented only by the generated text summary. For image-heavy applications, store media in a filesystem or object store and pass URLs or file references through message history.
API reference: SummarizationMiddleware
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),
),
],
)Human-in-the-loop
Pause agent execution for human approval, editing, or rejection of tool calls before they execute. Human-in-the-loop is useful for the following:
- High-stakes operations requiring human approval (e.g. database writes, financial transactions).
- Compliance workflows where human oversight is mandatory.
- Long-running conversations where human feedback guides the agent.
API reference: HumanInTheLoopMiddleware
The middleware pauses once per model turn by default. Set interrupt_mode="per_call" to pause once per tool call, with each interrupt answered by its ID. See Set the interrupt mode.
Warning
Human-in-the-loop middleware requires a checkpointer to maintain state across interruptions.
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,
}
),
],
)Tip
For complete examples, configuration options, and integration patterns, see the Human-in-the-loop documentation.
Note
Watch this video guide demonstrating Human-in-the-loop middleware behavior.
Model call limit
Limit the number of model calls to prevent infinite loops or excessive costs. Model call limit is useful for the following:
- Preventing runaway agents from making too many API calls.
- Enforcing cost controls on production deployments.
- Testing agent behavior within specific call budgets.
API reference: ModelCallLimitMiddleware
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(), # Required for thread limiting
tools=[],
middleware=[
ModelCallLimitMiddleware(
thread_limit=10,
run_limit=5,
exit_behavior="end",
),
],
)Note
Watch this video guide demonstrating Model Call Limit middleware behavior.
Tool call limit
Control agent execution by limiting the number of tool calls, either globally across all tools or for specific tools. Tool call limits are useful for the following:
- Preventing excessive calls to expensive external APIs.
- Limiting web searches or database queries.
- Enforcing rate limits on specific tool usage.
- Protecting against runaway agent loops.
API reference: ToolCallLimitMiddleware
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=[
# Global limit
ToolCallLimitMiddleware(thread_limit=20, run_limit=10),
# Tool-specific limit
ToolCallLimitMiddleware(
tool_name="search",
thread_limit=5,
run_limit=3,
),
],
)Note
Watch this video guide demonstrating Tool Call Limit middleware behavior.
PII detection
Detect and handle Personally Identifiable Information (PII) in conversations using configurable strategies. PII detection is useful for the following:
- Healthcare and financial applications with compliance requirements.
- Customer service agents that need to sanitize logs.
- Any application handling sensitive user data.
Note
With apply_to_output=True, PIIMiddleware also redacts streamed wire output—text deltas, tool-call args, tool outputs, and state snapshots—via a registered stream transformer. Requires langchain>=1.3.2. See Register transformers on middleware.
API reference: PIIMiddleware
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),
],
)Custom PII types
You can create custom PII types by providing a detector parameter. This allows you to detect patterns specific to your use case beyond the built-in types.
Three ways to create custom detectors:
-
Regex pattern string - Simple pattern matching
-
Custom function - Complex detection logic with validation
import re
from langchain.agents import create_agent
from langchain.agents.middleware import PIIMatch, PIIMiddleware
# Method 1: Regex pattern string
agent1 = create_agent(
model="gpt-5.5",
tools=[],
middleware=[
PIIMiddleware(
"api_key",
detector=r"sk-[a-zA-Z0-9]{32}",
strategy="block",
),
],
)
# Method 2: Compiled regex pattern
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",
),
],
)
# Method 3: Custom detector function
def detect_ssn(content: str) -> list[PIIMatch]:
"""Detect SSNs with validation."""
matches: list[PIIMatch] = []
pattern = r"\d{3}-\d{2}-\d{4}"
for match in re.finditer(pattern, content):
ssn = match.group(0)
# Validate: first 3 digits shouldn't be 000, 666, or 900-999
first_three = int(ssn[:3])
if first_three not in [0, 666] and not (900 <= first_three <= 999):
matches.append({
"type": "ssn",
"value": 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",
),
],
)
Custom detector function signature:
The detector function must accept a string (content) and return matches:
Returns a list of PIIMatch objects:
from langchain.agents.middleware import PIIMatch
def detector(content: str) -> list[PIIMatch]:
return [
{
"type": "custom_type",
"value": "matched_text",
"start": 0,
"end": 12,
},
# ... more matches
]Tip
For custom detectors:
- Use regex strings for simple patterns
- Use RegExp objects when you need flags (e.g., case-insensitive matching)
- Use custom functions when you need validation logic beyond pattern matching
- Custom functions give you full control over detection logic and can implement complex validation rules
To-do list
Equip agents with task planning and tracking capabilities for complex multi-step tasks. To-do lists are useful for the following:
- Complex multi-step tasks requiring coordination across multiple tools.
- Long-running operations where progress visibility is important.
Note
This middleware automatically provides agents with a write_todos tool and system prompts to guide effective task planning.
API reference: TodoListMiddleware
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()],
)
Note
Watch this video guide demonstrating To-do List middleware behavior.
LLM tool selector
Use an LLM to intelligently select relevant tools before calling the main model. LLM tool selectors are useful for the following:
- Agents with many tools (10+) where most aren't relevant per query.
- Reducing token usage by filtering irrelevant tools.
- Improving model focus and accuracy.
This middleware uses structured output to ask an LLM which tools are most relevant for the current query. The structured output schema defines the available tool names and descriptions. Model providers often add this structured output information to the system prompt behind the scenes.
API reference: LLMToolSelectorMiddleware
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"],
),
],
)
Provider tool search
Defer selected tools behind model providers' server-side tool search, so the model discovers them on demand instead of receiving every tool schema up front. Provider tool search is useful for:
- Reducing context bloat when using many tools.
- Improving tool selection accuracy by surfacing only relevant tools.
Note
Requires a model with server-side tool search support: Anthropic (Claude Sonnet 4+/Opus 4+/Haiku 4.5+) or OpenAI (gpt-5.5+). Other providers raise a ValueError.
API reference: ProviderToolSearchMiddleware
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"]),
],
)
Shell tool
Expose a persistent shell session to agents for command execution. Shell tool middleware is useful for the following:
- Agents that need to execute system commands
- Development and deployment automation tasks
- Testing and validation workflows
- File system operations and script execution
Warning
Security consideration: Use appropriate execution policies (HostExecutionPolicy, DockerExecutionPolicy, or CodexSandboxExecutionPolicy) to match your deployment's security requirements.
Note
Limitation: Persistent shell sessions do not currently work with interrupts (human-in-the-loop). We anticipate adding support for this in the future.
API reference: ShellToolMiddleware
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(),
),
],
)
Filesystem middleware
Context engineering is a main challenge in building effective agents. This is particularly difficult when using tools that return variable-length results (for example, web_search and RAG), as long tool results can quickly fill your context window.
FilesystemMiddleware from Deep Agents provides four tools for interacting with both short-term and long-term memory:
ls: List the files in the filesystemread_file: Read an entire file or a certain number of lines from a filewrite_file: Write a new file to the filesystemedit_file: Edit an existing file in the filesystem
from langchain.agents import create_agent
from deepagents.middleware.filesystem import FilesystemMiddleware
# FilesystemMiddleware is included by default in create_deep_agent
# You can customize it if building a custom agent
agent = create_agent(
model="claude-sonnet-4-6",
middleware=[
FilesystemMiddleware(
backend=None, # Optional: custom backend (defaults to StateBackend)
system_prompt="Write to the filesystem when...", # Optional custom addition to the system prompt
custom_tool_descriptions={
"ls": "Use the ls tool when...",
"read_file": "Use the read_file tool to..."
}, # Optional: Custom descriptions for filesystem tools
tools=["read_file", "ls", "glob", "grep"], # Optional: Allowlist restricting which filesystem tools are exposed
),
],
)
Short-term vs. long-term filesystem
By default, these tools write to a local "filesystem" in your graph state. To enable persistent storage across threads, configure a CompositeBackend that routes specific paths (like /memories/) to a StoreBackend.
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..."
} # Optional: Custom descriptions for filesystem tools
),
],
)
When you configure a CompositeBackend with a StoreBackend for /memories/, any files prefixed with /memories/ are saved to persistent storage and survive across different threads. Files without this prefix remain in ephemeral state storage.
Subagent
Handing off tasks to subagents isolates context, keeping the main (supervisor) agent's context window clean while still going deep on a task.
The subagents middleware from Deep Agents allows you to supply subagents through a task tool.
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": [],
}
],
)
],
)
A subagent is defined with a name, description, system prompt, and tools. You can also provide a subagent with a custom model, or with additional middleware. This can be particularly useful when you want to give the subagent an additional state key to share with the main agent.
For more complex use cases, you can also provide your own prebuilt LangGraph graph as a subagent.
from langchain.agents import create_agent
from deepagents.middleware.subagents import SubAgentMiddleware
from deepagents import CompiledSubAgent
from langgraph.graph import StateGraph
# Create a custom LangGraph graph
def create_weather_graph():
workflow = StateGraph(...)
# Build your custom graph
return workflow.compile()
weather_graph = create_weather_graph()
# Wrap it in a 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],
)
],
)
In addition to any user-defined subagents, the main agent has access to a general-purpose subagent at all times. This subagent has the same instructions as the main agent and all the tools it has access to. The primary purpose of the general-purpose subagent is context isolation—the main agent can delegate a complex task to this subagent and get a concise answer back without bloat from intermediate tool calls.
Rubric grading
Note
RubricMiddleware requires deepagents>=0.6.5. It is in beta; the API may change in the future.
Some tasks have a clear definition of "done" that an agent cannot reliably hit on the first try. RubricMiddleware lets you declare what done looks like as a rubric and have the agent self-evaluate and iterate until the rubric is satisfied or a maximum iteration cap is hit.
API reference: RubricMiddleware
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(),
)
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(),
)
from deepagents import RubricMiddleware, create_deep_agent
from langgraph.checkpoint.memory import InMemorySaver
agent = create_deep_agent(
model="anthropic:claude-sonnet-5",
middleware=[
RubricMiddleware(
model="anthropic:claude-haiku-4-5",
max_iterations=3,
),
],
checkpointer=InMemorySaver(),
)
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(),
)
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(),
)
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(),
)
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(),
)
For full configuration options, streaming events, and a complete code generation example, see Grading rubrics.
File search
Provide Glob and Grep search tools over a filesystem. File search middleware is useful for the following:
- Code exploration and analysis
- Finding files by name patterns
- Searching code content with regex
- Large codebases where file discovery is needed
API reference: FilesystemFileSearchMiddleware
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,
),
],
)
Context editing
Manage conversation context by clearing older tool call outputs when token limits are reached, while preserving recent results. This helps keep context windows manageable in long conversations with many tool calls. Context editing is useful for the following:
- Long conversations with many tool calls that exceed token limits
- Reducing token costs by removing older tool outputs that are no longer relevant
- Maintaining only the most recent N tool results in context
API reference: ContextEditingMiddleware, ClearToolUsesEdit
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,
),
],
),
],
)
LLM tool emulator
Emulate tool execution using an LLM for testing purposes, replacing actual tool calls with AI-generated responses. LLM tool emulators are useful for the following:
- Testing agent behavior without executing real tools.
- Developing agents when external tools are unavailable or expensive.
- Prototyping agent workflows before implementing actual tools.
API reference: LLMToolEmulator
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(), # Emulate all tools
],
)
Provider-specific middleware
These middleware are optimized for specific LLM providers. See each provider's documentation for full details and examples.