# Middleware stack
```python
from langchain.agents import create_agent
from langchain.agents.middleware import (
PIIMiddleware,
SummarizationMiddleware,
HumanInTheLoopMiddleware,
)
agent = create_agent(
model="claude-sonnet-4-6",
tools=[read_email, send_email],
middleware=[
PIIMiddleware("email", strategy="redact", apply_to_input=True),
SummarizationMiddleware(model="claude-sonnet-4-6", trigger={"tokens": 500}),
HumanInTheLoopMiddleware(
interrupt_on={"send_email": {"allowed_decisions": ["approve", "edit", "reject"]}}
),
],
)
```
## Rules
- Order matters: PII redaction belongs early so sensitive data never reaches the model or the trace. Summarization sits in the middle. Approval gates wrap the tools they guard.
- SummarizationMiddleware needs its own model for the summary calls; it does not have to be the agent's main model. Set the token trigger with headroom below the context limit.
- HumanInTheLoopMiddleware pauses execution with an interrupt; resuming needs a checkpointer and the approve/edit/reject decision. Test the full interrupt-resume path, not just the happy path.
- Custom behavior goes in an AgentMiddleware subclass with hooks: before_agent, before_model, wrap_model_call, wrap_tool_call, after_model, after_agent.