How to Configure the interrupt_on Parameter in DeepAgents for Human-in-the-Loop Workflows
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 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 (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 approvalreview_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:
- Checkpoint Saver: The
HumanInTheLoopMiddlewarerequires a checkpointer to persist interrupt state. UseMemorySaveror any compatible checkpoint store when initializing your agent. - Automatic Middleware Injection: You do not manually add
HumanInTheLoopMiddleware. The framework automatically inserts it viaSubAgentMiddlewareandcreate_deep_agentwheninterrupt_onis present (as implemented inlibs/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 (lines 180-284):
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 (line 652), the framework extracts this configuration and creates a dedicated HumanInTheLoopMiddleware for that subagent (line 654):
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:
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 (lines 78-80) demonstrates this pattern:
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_onas a dictionary mapping tool names toTrue,False, orInterruptOnConfigobjects to enable human approval workflows. - Set at the top level in
create_deep_agentfor default behavior across all tools and subagents, or override per-subagent for specific approval requirements. - Always include a checkpointer such as
MemorySaver; theHumanInTheLoopMiddlewarerequires 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(lines 74-76, 353-355, 652-654) andlibs/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 (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, lines 353-355). Manual middleware insertion is unnecessary and may cause conflicts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →