Agent Middleware Chain
Wrap every model call, tool call, and memory access in a composable pre/execute/post interceptor pipeline — attach cross-cutting concerns without touching agent code.
Intent & Description
🎯 Intent
Intercept every model/tool/memory call with a composable hook pipeline so cross-cutting concerns register themselves — they don’t get hardcoded.
📋 Context
As an agent grows, you inevitably need the same concerns everywhere: structured logging, rate-limit enforcement, PII redaction, guardrail checks, latency metrics, human-approval gates. Without middleware, each concern reimplements its own wiring across every touchpoint — a maintenance nightmare.
💡 Solution
Define a BaseMiddleware with three hooks: process_request (runs before, can modify or short-circuit), process_response (runs after, can mutate the result), process_error (fires on exception). A MiddlewareChain fans forward through process_request, runs the call, then fans reverse through process_response. Mount it at the runtime layer — everything flows through. Concerns are registered, not embedded.
Real-world Use Case
- Multiple cross-cutting concerns (logging, redaction, rate-limiting) must fire on every model/tool/memory call.
- Execution order between concerns is a policy decision, not a coincidence.
- Teams need to add or remove concerns via config, not code changes.
Source
📌 TL;DR
Middleware Chain turns cross-cutting concerns into plug-in interceptors — bolt on logging, redaction, or guardrails without touching a single agent or orchestrator.
Advantages
- Cross-cutting concerns live in config at the agent layer — zero code changes to add or remove one.
- Execution order is explicit and reviewable in one place.
- Each middleware is independently unit-testable against a synthetic call.
Disadvantages
- A long chain adds latency on every call — the chain itself becomes a critical path.
- Misordered middleware (e.g. redaction after logging) silently leaks what it was supposed to hide.
- Implicit dependencies between middlewares (one expecting another’s mutation) are invisible until they break.