Skip to main content

Human-in-the-Loop & Checkpointing

For high-stakes applications (e.g. executing financial transactions, modifying production databases, sending emails), autonomous agents must not execute destructive actions without explicit human verification.

LangGraph Checkpointing

LangGraph includes built-in checkpointers (SQLite, PostgreSQL, Memory) that snapshot agent state at every step, allowing execution to pause, wait for human input, and resume seamlessly.


State Persistence with Checkpointers

By compiling a graph with a checkpointer, every state transition is recorded under a unique thread_id:

from langgraph.checkpoint.memory import MemorySaver

memory = MemorySaver()
graph = builder.compile(checkpointer=memory)

config = {"configurable": {"thread_id": "session_123"}}

# First turn
events = graph.stream({"messages": [("user", "My name is Harsh")]}, config)

# Second turn retains previous state automatically using thread_id!
events = graph.stream({"messages": [("user", "What is my name?")]}, config)

Interrupting Execution (interrupt_before)

Pause execution before executing critical nodes (like a financial transfer tool node):

# Compile with interrupt before specific node
graph = builder.compile(
checkpointer=memory,
interrupt_before=["execute_bank_transfer_node"]
)

# Run graph until interrupt
graph.invoke(input_data, config)

# Human reviews the state
current_state = graph.get_state(config)
print("Pending Action:", current_state.next)

# Resume after approval
graph.invoke(None, config)

Time Travel & State Rewinding

Because state snapshots are saved at each step, developers can inspect historical state steps, modify previous inputs, or fork execution paths to recover from errors.