langchain-agents-middleware
- Repo stars 0
- Author updated Live
- Author repo skills-registry
- Domain
- AI
- Compatible agents
-
- Claude Code
- Cursor
- Cline
- Codex
- Windsurf
- Gemini CLI
- +20
- Trust score
- 88 / 100 · community maintained
- Author / version / license
- @tomevault-io · no license declared
- Token usage
- Moderate
- Setup complexity
- Guided setup
- External API key
- Not required
- Operating systems
- macOS · Linux · Windows
- Runtime requirements
- Node.js · Python
- Permissions
-
- Read-only
- Write / modify
- Shell exec
- Network behavior
- Local-only
- Install commands
- 26 variants
Profile is derived at build time from SKILL.md and install vectors. Subject to drift from author intent.
Heads up: 未限定 allowed-tools,默认拥有全部工具权限。
---
name: langchain-agents-middleware
description: Use when building or productionising any agent — adding retries, fallbacks, summarization, human…
category: ai
runtime: Node.js / Python
---
# langchain-agents-middleware output preview
## PART A: Task fit
- Use case: Use when building or productionising any agent — adding retries, fallbacks, summarization, human-in-the-loop, PII redaction, call limits, or custom hooks. Middleware is THE composition primitive for modern LangChain agents (v1+); covers built-ins plus the custom middleware authoring API..
- Inputs: target material, constraints, expected output, and acceptance criteria.
- Evidence boundary: follow “The model / Lifecycle hooks (for custom middleware) / Built-in middlewares (provider-agnostic)” and do not present inference as author intent.
## PART B: Execution result
- **01** The card summarizes the use case; runtime output centers on “Use when building or productionising any agent — adding retries, fallbacks, summarization, human-in-the-loop, PII redaction, call limits, or custom hooks. Middleware is THE composition primitive for modern LangChain agents (v1+); covers built-ins plus the custom middleware authoring API.”.
- **02** When the source has headings, the agent prioritizes “The model / Lifecycle hooks (for custom middleware) / Built-in middlewares (provider-agnostic)” so the result follows the author’s structure.
- **03** Typical output includes task judgment, concrete steps, required commands or file edits, validation, and follow-up options.
- **04** Risk context follows the fingerprint: read files, write/modify files, run shell commands; mostly runs locally; usually needs no extra API key.
## Running Rules
- read files, write/modify files, run shell commands; mostly runs locally; usually needs no extra API key.
- Validate with a small sample before expanding scope.
- Return the result, validation criteria, and next iteration options. The source does not require a stable slash command. After installation, invoke the skill by name and describe the task.
Name target files or source material, expected output, forbidden changes, and whether network or shell access is allowed. Permission fingerprint: read files, write/modify files, run shell commands.
Start with a small task and check whether the result follows “The model / Lifecycle hooks (for custom middleware) / Built-in middlewares (provider-agnostic)”. Inspect diffs, logs, previews, or tests before expanding scope.
Confirm the final output includes a concrete result, evidence, and next action. If it stays generic, tighten inputs, boundaries, and acceptance criteria.
---
name: langchain-agents-middleware
description: Use when building or productionising any agent — adding retries, fallbacks, summarization, human…
category: ai
source: tomevault-io/skills-registry
---
# langchain-agents-middleware
## When to use
- Use when building or productionising any agent — adding retries, fallbacks, summarization, human-in-the-loop, PII reda…
- Use it when the task has clear inputs, repeatable steps, and validation criteria.
## What to provide
- Target material, scope, expected result, and forbidden changes.
- Whether network, commands, file writes, or external services are allowed.
## Execution rules
- Organize steps around “The model / Lifecycle hooks (for custom middleware) / Built-in middlewares (provider-agnostic)” and keep inference separate from source facts.
- read files, write/modify files, run shell commands; mostly runs locally; usually needs no extra API key.
- Validate with a small sample before expanding the task.
## Output requirements
- Return the deliverable, key evidence, validation method, and next action.
- Mark missing information as unknown; do not invent commands, platforms, or dependencies. The author source anchors workflow facts; repository files anchor sources and commands; Fluxly only adds fit, limitations, and quality judgment.
skill "langchain-agents-middleware" {
input -> user goal + target files + boundaries + acceptance criteria
context -> The model / Lifecycle hooks (for custom middleware) / Built-in middlewares (provider-agnostic)
rules -> SKILL.md triggers / order / output contract
runtime -> Node.js / Python | read files, write/modify files, run shell commands | mostly runs locally
guardrails -> usually needs no extra API key + small-sample validation + diff/log review
output -> copyable result + checklist + next iteration
} Agentic Middleware
Middleware is how you compose cross-cutting agent behavior in LangChain v1+. It plugs into create_agent(...) (and is the underlying implementation of DeepAgents). For any production agent, the question is "which middlewares" — not "do I need middleware".
The model
from langchain.agents import create_agent
from langchain.agents.middleware import (
SummarizationMiddleware,
ModelRetryMiddleware,
ModelFallbackMiddleware,
ModelCallLimitMiddleware,
ToolRetryMiddleware,
PIIMiddleware,
)
agent = create_agent(
model="claude-sonnet-4-6",
tools=[...],
middleware=[
ModelRetryMiddleware(max_retries=3, backoff_factor=2.0, initial_delay=1.0),
ModelFallbackMiddleware("openai:gpt-4o-mini"),
ModelCallLimitMiddleware(run_limit=50),
ToolRetryMiddleware(max_retries=3, backoff_factor=2.0),
SummarizationMiddleware(model="claude-haiku-4-5", trigger=("tokens", 4000), keep=("messages", 20)),
PIIMiddleware("email", strategy="redact", apply_to_input=True),
],
)
create_agent returns a compiled LangGraph. All Runnable semantics apply: .invoke, .ainvoke, .stream, .astream, langgraph dev, langgraph build, etc.
Lifecycle hooks (for custom middleware)
Every middleware can override one or more of these:
| Hook | Fires | Return |
|---|---|---|
before_agent(state, runtime) |
Once, before the loop starts | dict to merge into state, or None |
before_model(state, runtime) |
Before each model call | dict to merge into state, or None |
wrap_model_call(request, handler) |
Wraps the model call | call handler(request) → ModelResponse; return it (possibly modified) |
after_model(state, runtime) |
After each model response | dict to merge into state, or None |
wrap_tool_call(request, handler) |
Wraps each tool call | call handler(request) → ToolMessage | Command; return it (possibly modified) |
after_agent(state, runtime) |
Once, after the loop ends | dict to merge into state, or None |
Node-style hooks (before_* / after_*) run sequentially. Wrap-style hooks compose like Python decorators — first middleware in the list is the outermost wrapper.
Built-in middlewares (provider-agnostic)
Import from langchain.agents.middleware:
| Middleware | Purpose | Constructor |
|---|---|---|
SummarizationMiddleware |
Auto-summarize long conversations to stay under token limits | (model, trigger=("tokens", N), keep=("messages", N)) |
HumanInTheLoopMiddleware |
Pause for human approve/edit/reject on sensitive tool calls | (interrupt_on={"tool_name": {"allowed_decisions": [...]}}) — requires a checkpointer |
ModelCallLimitMiddleware |
Cap model calls per run / per thread (cost containment, infinite-loop guard) | (thread_limit, run_limit, exit_behavior="end") |
ToolCallLimitMiddleware |
Cap tool calls globally or per-tool | (thread_limit, run_limit) or (tool_name, thread_limit, run_limit) |
ModelRetryMiddleware |
Retry transient model failures with exponential backoff | (max_retries, backoff_factor, initial_delay) |
ToolRetryMiddleware |
Retry transient tool failures with exponential backoff | same args |
ModelFallbackMiddleware |
Fall back to alternative models on primary failure | ("model-1", "model-2", ...) |
LLMToolSelectorMiddleware |
Use a small LLM to pick which tools to expose to the main model | (model, max_tools, always_include=[...]) |
PIIMiddleware |
Detect & redact / mask / block PII | ("email"|"credit_card"|..., strategy="redact"|"mask"|"block", apply_to_input=True) |
ContextEditingMiddleware |
Drop old tool outputs from context to free tokens | (edits=[ClearToolUsesEdit(trigger, keep)]) |
TodoListMiddleware |
Adds the write_todos planning tool to the agent |
() |
LLMToolEmulator |
Replace tool execution with LLM-generated outputs (testing) | () — never use in production |
ShellToolMiddleware |
Persistent shell session as a tool, with execution policy | (workspace_root, execution_policy) |
FilesystemFileSearchMiddleware |
Glob + Grep tools over a filesystem | (root_path, use_ripgrep=True) |
DeepAgents-specific (import from deepagents.middleware):
| Middleware | Purpose |
|---|---|
FilesystemMiddleware |
Virtual or backed filesystem for the agent (read/write/edit/ls/glob/grep) |
SubAgentMiddleware |
Adds the task tool with named sub-agents |
create_deep_agent(...) is a thin wrapper over create_agent(...) that pre-installs FilesystemMiddleware + SubAgentMiddleware + TodoListMiddleware. You can compose additional middlewares on top.
Production middleware stack (start here)
For any production agent, this is the default stack to copy and tune:
middleware=[
# Cost containment (set BEFORE retries — limits the multiplier)
ModelCallLimitMiddleware(run_limit=50),
ToolCallLimitMiddleware(run_limit=200),
# Resilience to transient failures
ModelRetryMiddleware(max_retries=3, backoff_factor=2.0, initial_delay=1.0),
ToolRetryMiddleware(max_retries=3, backoff_factor=2.0, initial_delay=1.0),
# Provider-level resilience
ModelFallbackMiddleware("openai:gpt-4o-mini"),
# Long-conversation hygiene
SummarizationMiddleware(model="claude-haiku-4-5", trigger=("tokens", 8000), keep=("messages", 20)),
# Privacy (only if user input may contain PII)
PIIMiddleware("email", strategy="redact", apply_to_input=True),
PIIMiddleware("credit_card", strategy="mask", apply_to_input=True),
]
Add HumanInTheLoopMiddleware for any tool that touches money, sends external messages, or makes irreversible changes. Requires a checkpointer (InMemorySaver for dev, PostgresSaver for production — see the deploy skill).
Custom middleware
Inherit from AgentMiddleware:
from typing import Any, Callable
from langchain.agents.middleware import (
AgentMiddleware, AgentState, ModelRequest, ModelResponse,
)
from langchain.tools.tool_node import ToolCallRequest
from langchain.messages import ToolMessage
from langgraph.types import Command
class TokenBudgetMiddleware(AgentMiddleware):
"""Hard-cap total tokens across the run. Halts the agent when exceeded."""
def __init__(self, budget: int) -> None:
self.budget = budget
def wrap_model_call(
self,
request: ModelRequest,
handler: Callable[[ModelRequest], ModelResponse],
) -> ModelResponse:
used = request.state.get("tokens_used", 0)
if used >= self.budget:
# short-circuit: return a synthetic "stop" response without calling the model
return ModelResponse(
messages=[{"role": "assistant", "content": "Token budget exceeded."}],
command=Command(goto="__end__"),
)
response = handler(request)
# ... extract token count from response.usage and add to state
return response
If you need extra fields in state, declare them on a subclass of AgentState and set state_schema = MyState on the middleware class.
Hard rules
- Order matters. Limits before retries (so retries don't burn through your budget). Privacy redaction before logging. Summarization should run before the model call, not after.
- HumanInTheLoopMiddleware needs a checkpointer. Without one, interrupts have nothing to resume from.
LLMToolEmulatoris a testing-only middleware. Never ship it.- Retries cost money. A
max_retries=3withbackoff_factor=2means up to 4 calls per failure. SetModelCallLimitMiddlewareBEFORE retries to cap the worst-case cost. - Don't roll your own retry/fallback/limit. The built-ins handle the edge cases (jitter, retryable error classification, streaming-aware wrapping). Custom middleware is for app-specific concerns.
Skills to load alongside this one
langchain-agents-deploy— productionisation: durable execution, checkpointers, deployment.langchain-agents-observability— tracing what middleware actually does at runtime.langchain-agents-langgraph-code— when to drop down to rawStateGraph(rare, but real cases exist).
Source: cwijayasundara/agent_cli_langchain — distributed by TomeVault.
Decide Fit First
Design Intent
How To Use It
Boundaries And Review