Workflow:Langchain ai Langgraph Human in the Loop Agent
| Knowledge Sources | |
|---|---|
| Domains | LLM_Ops, Agent_Orchestration, Human_in_the_Loop |
| Last Updated | 2026-02-11 15:00 GMT |
Overview
End-to-end process for building an agent with human oversight using LangGraph's interrupt mechanism to pause execution, surface state to a human reviewer, and resume with approval or modifications.
Description
This workflow demonstrates how to incorporate human oversight into an agent's execution flow using LangGraph's interrupt primitives. The `interrupt()` function pauses graph execution at a designated point, surfaces a value to the client application (e.g., a question, confirmation request, or preview), and waits for a human response before resuming. This requires a checkpointer to persist the paused state. The pattern supports approval gates, content review, interactive editing, and multi-step human guidance. The agent can be interrupted before or after specific nodes, or programmatically within any node.
Usage
Execute this workflow when building agents that need human approval before taking actions, when tool calls should be reviewed before execution, or when the agent needs human input at specific decision points. This is essential for high-stakes scenarios like financial transactions, content publishing, code deployment, or any workflow where automated decisions need human validation.
Execution Steps
Step 1: Configure Checkpointing
Set up a checkpoint saver to persist graph state across interrupt/resume cycles. The checkpointer stores the complete execution state when an interrupt occurs, allowing the graph to resume from exactly where it paused. Without a checkpointer, interrupts cannot function.
Key considerations:
- A checkpointer is mandatory for interrupt functionality
- Use `InMemorySaver` for development and testing
- Use `PostgresSaver` or `SqliteSaver` for production deployments
- Each execution thread needs a unique `thread_id` in the config
Step 2: Define Interrupt Points
Choose where human oversight occurs in the graph. There are three approaches: (1) Use `interrupt_before` or `interrupt_after` at compile time to pause before/after specific nodes. (2) Call `interrupt()` programmatically within a node function. (3) Use the `HumanInterrupt` schema from `langgraph.prebuilt.interrupt` for structured interrupt requests with the Agent Inbox pattern.
Key considerations:
- `interrupt_before=["tools"]` pauses before every tool execution for review
- `interrupt(value)` within a node provides the most flexible control
- The interrupt value can be any serializable data (string, dict, structured request)
- Multiple interrupts in the same node are supported (each gets a unique ID)
Step 3: Build the Agent Graph
Construct the agent graph with interrupt-aware nodes. For the prebuilt ReAct agent, pass `interrupt_before` or `interrupt_after` to `create_react_agent()`. For custom graphs, use `interrupt()` calls within node functions where human input is needed, and compile with a checkpointer.
Key considerations:
- The `interrupt()` function raises `GraphInterrupt` on first execution (pausing)
- On resume, `interrupt()` returns the value provided by the human via `Command(resume=...)`
- Nodes before the interrupt point execute normally
- The graph saves full state at the interrupt point
Step 4: Run Until Interrupt
Execute the graph with `stream()` or `invoke()`. When the graph hits an interrupt point, it yields an `__interrupt__` event containing the interrupt value and pauses execution. The client application receives this event and can present it to the human reviewer.
Key considerations:
- The `__interrupt__` tuple contains `Interrupt` objects with `value` and `id` fields
- The graph state is persisted at the interrupt point
- Use `get_state()` to inspect the current graph state while paused
- Use `update_state()` to modify state before resuming if needed
Step 5: Resume with Human Input
Resume the paused graph by calling `stream()` or `invoke()` with a `Command(resume=value)` using the same thread config. The resume value is delivered to the `interrupt()` call that paused execution, which then returns this value and continues normal execution.
Key considerations:
- Use the same `thread_id` config to resume the correct paused execution
- `Command(resume=value)` delivers the human's response to the interrupt
- Multiple sequential interrupts in a node are resumed one at a time
- The agent continues from exactly where it paused, with the human's input
Step 6: Handle Approval or Rejection
Process the human's response within the node. The resumed `interrupt()` call returns the human's input, which the node uses to decide whether to proceed, modify, or abort the operation. For the `HumanInterrupt` pattern, responses include type indicators like "accept", "reject", "edit", or "response".
Key considerations:
- Branch on the resume value to handle accept/reject/edit scenarios
- Rejected operations can return alternative state updates or route to different nodes
- Edited tool calls can be re-executed with modified parameters
- The graph can have multiple interrupt cycles before completing