# How to Configure the interrupt_on Parameter in DeepAgents for Human-in-the-Loop Workflows

> Learn to configure the interrupt_on parameter in DeepAgents for custom human approval workflows. This guide explains how to set up middleware for efficient human-in-the-loop processes.

- Repository: [LangChain/deepagents](https://github.com/langchain-ai/deepagents)
- Tags: how-to-guide
- Published: 2026-03-17

---

**To configure custom human-approval workflows, supply a dictionary mapping tool names to boolean values or `InterruptOnConfig` objects via the `interrupt_on` parameter in `create_deep_agent` or individual subagent definitions, and ensure you configure a checkpointer such as `MemorySaver`.**

The `interrupt_on` parameter in the [langchain-ai/deepagents](https://github.com/langchain-ai/deepagents) repository enables **Human-in-the-Loop (HITL)** workflows by specifying which tool calls require human approval before execution. This middleware configuration automatically injects `HumanInTheLoopMiddleware` into the agent graph, creating interrupt points that pause execution until a reviewer provides a decision. You can define these interrupts at the top-level agent configuration or override them for specific subagents to create granular approval workflows.

## Understanding the interrupt_on Parameter

The `interrupt_on` parameter accepts a mapping where keys are tool names and values indicate whether to pause for human review. According to the source code in [`libs/deepagents/deepagents/middleware/subagents.py`](https://github.com/langchain-ai/deepagents/blob/main/libs/deepagents/deepagents/middleware/subagents.py) (lines 74-76), the type signature is `dict[str, bool | InterruptOnConfig]`, allowing either simple boolean flags or detailed configuration objects.

When a tool call triggers an interrupt, the middleware records an entry in the agent's state under the `interrupts` field. This payload contains:

- `action_requests` – A list of pending tool calls awaiting approval
- `review_configs` – Per-action configuration specifying allowed reviewer decisions

## Prerequisites for Human-in-the-Loop Workflows

Before configuring `interrupt_on`, you must satisfy two critical requirements:

1. **Checkpoint Saver**: The `HumanInTheLoopMiddleware` requires a checkpointer to persist interrupt state. Use `MemorySaver` or any compatible checkpoint store when initializing your agent.
2. **Automatic Middleware Injection**: You do not manually add `HumanInTheLoopMiddleware`. The framework automatically inserts it via `SubAgentMiddleware` and `create_deep_agent` when `interrupt_on` is present (as implemented in [`libs/deepagents/deepagents/middleware/subagents.py`](https://github.com/langchain-ai/deepagents/blob/main/libs/deepagents/deepagents/middleware/subagents.py), lines 353-355).

## Configuration Methods

You can configure interrupts at three levels of granularity, each overriding the previous when specified.

### Top-Level Agent Configuration

Define default interrupt behavior for all tools used by the main agent and default-generated subagents by passing `interrupt_on` to `create_deep_agent` in [`libs/deepagents/deepagents/graph.py`](https://github.com/langchain-ai/deepagents/blob/main/libs/deepagents/deepagents/graph.py) (lines 180-284):

```python
from deepagents import create_deep_agent
from langgraph.checkpoint.memory import MemorySaver
from tests.utils import sample_tool, get_weather

# Top-level interrupt configuration

interrupt_cfg = {
    "sample_tool": True,                         # always ask before running

    "get_weather": {"allowed_decisions": ["approve", "reject"]},
}

agent = create_deep_agent(
    model="gpt-4o-mini",
    tools=[sample_tool, get_weather],
    interrupt_on=interrupt_cfg,          # ← key parameter

    checkpointer=MemorySaver(),          # required for HITL

)

```

### Per-Subagent Overrides

Override top-level settings for specific subagents by including `interrupt_on` in the subagent definition dictionary. In [`libs/deepagents/deepagents/middleware/subagents.py`](https://github.com/langchain-ai/deepagents/blob/main/libs/deepagents/deepagents/middleware/subagents.py) (line 652), the framework extracts this configuration and creates a dedicated `HumanInTheLoopMiddleware` for that subagent (line 654):

```python
from deepagents import create_deep_agent
from langgraph.checkpoint.memory import MemorySaver
from tests.utils import sample_tool, get_weather, get_soccer_scores

agent = create_deep_agent(
    model="claude-sonnet-4-20250514",
    tools=[sample_tool, get_weather, get_soccer_scores],
    interrupt_on={                     # default for the main agent

        "sample_tool": True,
        "get_weather": False,
    },
    checkpointer=MemorySaver(),
    subagents=[
        {
            "name": "task_handler",
            "description": "Handles complex tasks",
            "system_prompt": "You are a task handler.",
            "tools": [sample_tool, get_weather, get_soccer_scores],
            # Sub-agent overrides: sample_tool disabled, others require approval

            "interrupt_on": {
                "sample_tool": False,
                "get_weather": True,
                "get_soccer_scores": True,
            },
        }
    ],
)

```

### Advanced Configuration with InterruptOnConfig

For fine-grained control over available reviewer decisions, use the `InterruptOnConfig` class instead of boolean values. This allows you to restrict the human reviewer to specific actions such as `approve`, `edit`, or `reject`:

```python
from deepagents import create_deep_agent, InterruptOnConfig
from langgraph.checkpoint.memory import MemorySaver
from tests.utils import sample_tool, get_soccer_scores

# Custom config allowing only "approve" or "reject"

soccer_cfg = InterruptOnConfig(allowed_decisions=["approve", "reject"])

agent = create_deep_agent(
    model="gpt-4o",
    tools=[sample_tool, get_soccer_scores],
    interrupt_on={"sample_tool": True, "get_soccer_scores": soccer_cfg},
    checkpointer=MemorySaver(),
)

```

## Resuming Execution After Human Review

When the agent interrupts, execution pauses until you send a `Command` with resume instructions. The test file [`libs/deepagents/tests/evals/test_hitl.py`](https://github.com/langchain-ai/deepagents/blob/main/libs/deepagents/tests/evals/test_hitl.py) (lines 78-80) demonstrates this pattern:

```python
from langgraph.types import Command

# After the agent pauses, the UI (or API) sends a resume command:

resume_cmd = Command(
    resume={"decisions": [
        {"type": "approve"},   # for sample_tool

        {"type": "approve"},   # for get_soccer_scores

    ]}
)

result = agent.invoke(resume_cmd, config={"configurable": {"thread_id": thread_id}})

```

The `result` contains the tool messages generated after the approvals are processed.

## Summary

- **Configure `interrupt_on`** as a dictionary mapping tool names to `True`, `False`, or `InterruptOnConfig` objects to enable human approval workflows.
- **Set at the top level** in `create_deep_agent` for default behavior across all tools and subagents, or **override per-subagent** for specific approval requirements.
- **Always include a checkpointer** such as `MemorySaver`; the `HumanInTheLoopMiddleware` requires checkpointing to store interrupt state.
- **Resume interrupted workflows** by sending a `Command(resume={"decisions": [...]})` containing the reviewer's choices for each pending action.
- **Reference implementation** details in [`libs/deepagents/deepagents/middleware/subagents.py`](https://github.com/langchain-ai/deepagents/blob/main/libs/deepagents/deepagents/middleware/subagents.py) (lines 74-76, 353-355, 652-654) and [`libs/deepagents/deepagents/graph.py`](https://github.com/langchain-ai/deepagents/blob/main/libs/deepagents/deepagents/graph.py).

## Frequently Asked Questions

### What happens if I don't provide a checkpointer with interrupt_on?

The `HumanInTheLoopMiddleware` will fail to function correctly because it relies on checkpointing to persist the interrupt state between steps. Always pass a checkpointer such as `MemorySaver` to `create_deep_agent` when using `interrupt_on`.

### Can I use interrupt_on with multiple subagents simultaneously?

Yes. You can define different `interrupt_on` configurations for each subagent in the `subagents` list parameter. According to [`libs/deepagents/deepagents/middleware/subagents.py`](https://github.com/langchain-ai/deepagents/blob/main/libs/deepagents/deepagents/middleware/subagents.py) (line 652), the framework extracts per-subagent configurations and creates individual middleware instances for each (line 654), allowing granular control over which tools require approval in different agent contexts.

### How do I restrict the human reviewer to only specific decisions?

Instead of setting a tool's value to `True`, pass an `InterruptOnConfig` object with the `allowed_decisions` parameter set to a list of permitted actions (e.g., `["approve", "reject"]` or `["approve", "edit", "reject"]`). This configuration appears in the `review_configs` field of the interrupt state.

### Do I need to manually add HumanInTheLoopMiddleware to my graph?

No. When you provide the `interrupt_on` parameter to `create_deep_agent` or a subagent definition, the framework automatically injects `HumanInTheLoopMiddleware` via `SubAgentMiddleware` (as implemented in [`libs/deepagents/deepagents/middleware/subagents.py`](https://github.com/langchain-ai/deepagents/blob/main/libs/deepagents/deepagents/middleware/subagents.py), lines 353-355). Manual middleware insertion is unnecessary and may cause conflicts.