LangChain Middleware
Middleware lets you intercept and control what happens inside the agent loop — before/after model calls, before/after tool calls, and at the start/end of the full agent run. Configure it via the middleware parameter of create_agent.
In this project, middleware is the mechanism for tracking off-topic inputs and terminating the conversation after too many are received. It is also used to manage the @wrap_model_call decorator for dynamic model selection (see langchain-skill for context, and Example 5 in examples.md for @wrap_model_call usage).
Common Middleware Uses
- Tracking agent behavior with logging, analytics, and debugging.
- Transforming prompts, tool selection, and output formatting.
- Adding retries, fallbacks, and early termination logic.
- Applying rate limits, guardrails, and PII detection.
Hook Types
The core agent loop calls a model, lets the model choose tools, and finishes when no more tools are called. Middleware exposes hooks before and after each step. There are two styles:
Node-Style Hooks
Run sequentially at specific execution points. Use for logging, validation, and state updates.
| Hook |
When it runs |
Good for |
before_agent |
Once, before the first model call |
Initializing custom state |
before_model |
Before each model call |
Prompt injection, context trimming |
after_model |
After each model call |
Logging responses, updating counters |
after_agent |
Once, after the last tool call |
Order summary finalization, cleanup |
Wrap-Style Hooks
Intercept execution and control when the inner handler is called. Use for retries, caching, and transformation.
| Hook |
Wraps |
Good for |
wrap_model_call |
Each model call |
Retries, dynamic model selection, token tracking |
wrap_tool_call |
Each tool call |
Error handling, caching, rate limiting |
Best Practices
- Keep middleware focused — each component should do one thing well.
- Handle errors gracefully — don’t let middleware errors crash the agent.
- Use appropriate hook types:
- Node-style for sequential logic (logging, validation)
- Wrap-style for control flow (retry, fallback, caching)
- Clearly document any custom state properties.
- Unit test middleware independently before integrating.
- Consider execution order — place critical middleware first in the list.
- Use built-in middleware when possible.
Additional Resources
Source: chicagopeabodydev-sudo/minimal-llm-usage-agent — distributed by TomeVault.
1---2name: langchain-middleware-skill3description: LangChain uses Middleware as a way to more tightly control what happens inside the agent. There are many built-in middleware components supplied by LangChain for common needs, and custom middleware can be created. Use when this capability is needed.4---56# LangChain Middleware78Middleware lets you intercept and control what happens inside the agent loop — before/after model calls, before/after tool calls, and at the start/end of the full agent run. Configure it via the `middleware` parameter of `create_agent`.910In this project, middleware is the mechanism for tracking off-topic inputs and terminating the conversation after too many are received. It is also used to manage the `@wrap_model_call` decorator for dynamic model selection (see `langchain-skill` for context, and Example 5 in `examples.md` for `@wrap_model_call` usage).1112## Common Middleware Uses1314- Tracking agent behavior with logging, analytics, and debugging.15- Transforming prompts, tool selection, and output formatting.16- Adding retries, fallbacks, and early termination logic.17- Applying rate limits, guardrails, and PII detection.1819## Hook Types2021The core agent loop calls a model, lets the model choose tools, and finishes when no more tools are called. Middleware exposes hooks before and after each step. There are two styles:2223### Node-Style Hooks24Run sequentially at specific execution points. Use for logging, validation, and state updates.2526| Hook | When it runs | Good for |27|---|---|---|28| `before_agent` | Once, before the first model call | Initializing custom state |29| `before_model` | Before each model call | Prompt injection, context trimming |30| `after_model` | After each model call | Logging responses, updating counters |31| `after_agent` | Once, after the last tool call | Order summary finalization, cleanup |3233### Wrap-Style Hooks34Intercept execution and control when the inner handler is called. Use for retries, caching, and transformation.3536| Hook | Wraps | Good for |37|---|---|---|38| `wrap_model_call` | Each model call | Retries, dynamic model selection, token tracking |39| `wrap_tool_call` | Each tool call | Error handling, caching, rate limiting |4041## Best Practices4243- Keep middleware focused — each component should do one thing well.44- Handle errors gracefully — don’t let middleware errors crash the agent.45- Use appropriate hook types:46 - Node-style for sequential logic (logging, validation)47 - Wrap-style for control flow (retry, fallback, caching)48- Clearly document any custom state properties.49- Unit test middleware independently before integrating.50- Consider execution order — place critical middleware first in the list.51- Use built-in middleware when possible.525354## Additional Resources55- For usage examples, see [examples.md](examples.md)56- [Built-in Middleware documentation](https://docs.langchain.com/oss/python/langchain/middleware/built-in)57- [Custom Middleware documentation](https://docs.langchain.com/oss/python/langchain/middleware/custom)5859---60> Source: [chicagopeabodydev-sudo/minimal-llm-usage-agent](https://github.com/chicagopeabodydev-sudo/minimal-llm-usage-agent) — distributed by [TomeVault](https://tomevault.io).61<!-- tomevault:4.0:skill_md:2026-06-16 -->