|
|
LangGraph Human-in-the-Loop
Author: Venkata Sudhakar
Human-in-the-loop means pausing an AI agent at a specific point and waiting for a human to review or approve before it continues. This is essential for any agent that takes real-world actions - sending emails, writing to a database, calling paid APIs, or deploying code. Without it, the agent acts autonomously and mistakes are hard to reverse. With it, a human can check the planned action, modify it, or abort entirely. LangGraph supports human-in-the-loop through interrupt_before. When you compile the graph with interrupt_before=[node_name], the graph pauses automatically just before that node runs and raises a GraphInterrupt. You save the graph state using a checkpointer, let the human review, then resume by calling app.invoke() again with the same thread_id. The graph picks up exactly where it left off. The below example shows an agent that plans a database migration step, pauses for human approval, then executes only after the human confirms.
It gives the following output showing the pause,
Agent planned: ALTER TABLE orders ADD COLUMN migrated_at TIMESTAMP DEFAULT NOW()
# Graph is now PAUSED before execute_node
# Human can inspect state["plan"] and decide whether to proceed
It gives the following output after human approves,
Pending plan: ALTER TABLE orders ADD COLUMN migrated_at TIMESTAMP DEFAULT NOW()
Executing: ALTER TABLE orders ADD COLUMN migrated_at TIMESTAMP DEFAULT NOW()
Migration step executed successfully.
To reject the plan instead of approving, update the state before resuming: app.update_state(thread, {"plan": ""}) then call invoke(None, thread). The execute node will receive the updated (empty) plan and can check for it. This pattern is the foundation of any approval workflow - code review, content moderation, financial authorization, or any agent action with real-world consequences.
|
|