Skip to main content
Some tool operations may be sensitive and require human approval before execution. Deep Agents support human-in-the-loop workflows through LangGraph’s interrupt capabilities. You can configure which tools require approval using the interrupt_on parameter. When interrupt_on is set, HumanInTheLoopMiddleware is added to the default middleware stack. If a run is cancelled or interrupted before a tool returns a result, PatchToolCallsMiddleware in the same stack repairs the message history automatically.

Basic configuration

The interrupt_on parameter accepts a dictionary mapping tool names to interrupt configurations. Each tool can be configured with:
  • True: Enable interrupts with default behavior (approve, edit, reject, respond allowed)
  • False: Disable interrupts for this tool
  • InterruptOnConfig: Custom configuration. Set allowed_decisions to control review options. In Python, add an optional when predicate to interrupt only specific calls (see Conditional interrupts).

Decision types

The allowed_decisions list controls what actions a human can take when reviewing a tool call: Use reject when the human denies a proposed action. Use respond only when the human is acting as the tool, such as answering an ask_user prompt. Do not use respond to deny side-effecting tools, because its message may be treated by the model as a successful tool result.
When editing tool arguments, make changes conservatively. Significant modifications to the original arguments may cause the model to re-evaluate its approach and potentially execute the tool multiple times or take unexpected actions.
You can customize which decisions are available for each tool:

Conditional interrupts

By default, every tool call listed in interrupt_on pauses for review. To pause only some calls, add a when predicate to a tool’s InterruptOnConfig. The predicate receives a ToolCallRequest and returns True to interrupt or False to auto-approve, so you can gate on the tool’s arguments.
Conditional interrupts require langchain>=1.3.3.
When the when predicate returns False, the call runs without interrupting. When it returns True, or when you omit when, the call pauses as usual. Calls that evaluate to False are never added to the interrupt batch, so a reviewer only sees the actions that need a decision. See the LangChain human-in-the-loop documentation for additional configuration options and examples.

Handle interrupts

When an interrupt is triggered, the agent pauses execution and returns control. Check for interrupts in the result and handle them accordingly. If the user rejects an action, include a clear message that tells the agent the tool was not executed and what to do next.

Multiple tool calls

When the agent calls multiple tools that require approval, all interrupts are batched together in a single interrupt. You must provide decisions for each one in order.

Rejection messages

When a reviewer returns a reject decision, Deep Agents skip the tool call and send rejection feedback back to the agent. If you omit message, the default feedback tells the model that the tool was not executed and not to retry the same tool call unless the user asks. For sensitive or side-effecting tools, pass a domain-specific message with the decision. Be explicit about whether the agent should abandon the action, ask a follow-up question, or try a safer alternative.

Edit tool arguments

When "edit" is in the allowed decisions, you can modify the tool arguments before execution:

Subagent interrupts

When using subagents, you can use interrupts on tool calls and within tool calls.

Interrupts on tool calls

Each subagent can have its own interrupt_on configuration that overrides the main agent’s settings:
When a subagent triggers an interrupt, the handling is the same—check for interrupts on the result and resume with Command.

Interrupts within tool calls

Subagent tools can call interrupt() directly to pause execution and await approval:
When run, this produces the following output:

Filesystem permission interrupts

Filesystem permission interrupts require deepagents>=0.6.8.
Beyond interrupt_on, you can pause the built-in filesystem tools by marking a permission rule with mode="interrupt". When the agent calls write_file or edit_file on a path that matches an interrupt-mode rule, create_deep_agent raises the same human-in-the-loop interrupt as a configured tool, using the filesystem tool’s name as the action name.
Handle and resume the interrupt the same way as a tool-call interrupt: run until it pauses, inspect the request, then resume with a decision.
Filesystem-permission interrupts merge with any interrupt_on you pass, so a single review step can cover both custom tools and protected filesystem paths.

Best practices

Always use a checkpointer

Human-in-the-loop requires a checkpointer to persist agent state between the interrupt and resume:

Use the same thread ID

When resuming, you must use the same config with the same thread_id:

Match decision order to actions

The decisions list must match the order of action_requests:

Tailor configurations by risk

Configure different tools based on their risk level: