CTCaliberTek
Course: LangChain: Step by Step (9 Modules) · Lesson 8 of 9Log in to track your progress and earn a certificate when you finish the course.
AI & Machine Learning

LangChain Module 8: Middleware, Limits, and Human Approval

Published October 17, 2026·Updated October 29, 2026·9 min read

Edited by , Senior Data Analyst. How we make our content

Like SaveLog in to like, save, and track progress.

Introduction

Middleware lets you plug logic into the agent loop without rewriting it: condense history, ask a human before a risky action, limit how many calls an agent can make, or log what is happening. This module introduces the built-in options and shows how to write a simple hook of your own.

Prerequisites

  • Modules 4 and 5 completed

Step-by-Step Guide

Step 1: Attach middleware to an agent

Pass a list to the middleware argument of create_agent. Middleware runs around the model and tool calls, and the order of the list matters when pieces interact, such as tool retries and tool error handling.

from langchain.agents import create_agent
from langchain.agents.middleware import SummarizationMiddleware

agent = create_agent(
    model=model,
    tools=[...],
    middleware=[SummarizationMiddleware(model="anthropic:claude-haiku-5-5",
                                        trigger=("tokens", 4000),
                                        keep=("messages", 20))],
)

Step 2: Know what is built in

LangChain ships middleware for tool retries and tool errors, model retries and fallbacks, summarization, human approval, limits on model calls and tool calls, PII detection, to-do lists, tool selection, and context editing. Check the built-in middleware page for the exact class names and options in your version before using them.

Step 3: Require human approval for risky tools

HumanInTheLoopMiddleware pauses the agent before the tools you list and lets a person approve, edit, or reject the call. It needs a checkpointer, because the agent must save its state while it waits. Setting a tool to False lets it run without approval.

from langchain.agents.middleware import HumanInTheLoopMiddleware
from langgraph.checkpoint.memory import InMemorySaver

agent = create_agent(
    model=model,
    tools=[send_email, read_email],
    checkpointer=InMemorySaver(),
    middleware=[
        HumanInTheLoopMiddleware(
            interrupt_on={
                "send_email": {"allowed_decisions": ["approve", "edit", "reject"]},
                "read_email": False,
            }
        )
    ],
)

Step 4: Resume a paused run

When an approval is pending, the run stops and reports the interrupt. You resume it with the same thread_id by sending a decision back using LangGraph's Command(resume=...), which Module 6 of the LangGraph course explains in depth. The exact shape of the decision payload for this middleware is in the human-in-the-loop documentation, so follow it for your version.

Step 5: Write a simple custom hook

Decorators such as before_model create middleware from a function. The function receives the agent state and a runtime, and returns a dictionary of state changes, or None to change nothing. This one only logs, which is a safe way to start.

from typing import Any
from langchain.agents import AgentState
from langchain.agents.middleware import before_model
from langgraph.runtime import Runtime

@before_model
def log_message_count(state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
    print("Messages going to the model:", len(state["messages"]))
    return None

agent = create_agent(model=model, tools=[...], middleware=[log_message_count])

FAQs

When should I use middleware instead of changing the prompt?
Use middleware for behavior that must hold regardless of what the model says: limits, approvals, redaction, and logging. Prompts are suggestions, but middleware is enforced in code.
Does human approval require a database?
It requires a checkpointer. InMemorySaver is fine for testing, but production needs a persistent one so a pending approval survives restarts.

Summary

Middleware adds enforced behavior to the agent loop. Use summarization for long chats, human approval for risky tools, limits and retries for reliability, and small decorator hooks for custom logic.

Related tutorials

Comments

Log in or create a free account to join the discussion.

  • No comments yet. Be the first to comment.