RUNLOCALAIv38
->Will it run?Best GPUCompareTroubleshootStartLearnPulseModelsHardwareToolsBench
Run check
RUNLOCALAI

Independently operated catalog for local-AI hardware and software. Hand-written verdicts. Source-cited claims. Reproducible commands when we have them.

OP·Eruo Fredoline
DIR
  • Models
  • Hardware
  • Tools
  • Benchmarks
TOOLS
  • Will it run?
  • Compare hardware
  • Cost vs cloud
  • Choose my GPU
  • Prompting kits
  • Quick answers
REF
  • All buyer guides
  • Learn local AI
  • Methodology
  • Glossary
  • Errors KB
  • Trust
EDITOR
  • About
  • Author
  • How we make money
  • Editorial policy
  • Contact
LEGAL
  • Privacy
  • Terms
  • Sitemap
MAIL · MONTHLY DIGEST
Get monthly local AI changes
Monthly recap. No spam.
DISCLOSURE

Some links on this site are affiliate links (Amazon Associates and other first-class retailers). When you buy through them, we earn a small commission at no extra cost to you. Affiliate links do not influence our verdicts — there are cards we rate highly that we don't have affiliate relationships with, and cards that sell well that we refuse to recommend. Read more →

© 2026 runlocalai.coIndependently operated
RUNLOCALAI · v38
  1. >
  2. Home
  3. /Learn
  4. /Courses
  5. /LangGraph for Local Agents
  6. /Ch. 7
LangGraph for Local Agents

07. Human-in-the-Loop

Chapter 7 of 18 · 15 min
KEY INSIGHT

Human-in-the-loop in LangGraph uses interrupt points backed by a checkpointer. The graph pauses, state survives in the checkpoint store, and `Command(resume=...)` injects human decisions into the resumed execution.

LangGraph supports pausing graph execution mid-run for human review via the interrupt_before and interrupt_after configuration on compile(). When an interrupt fires, execution stops, state is checkpointed, and the graph waits for a resumption signal. This is the primary mechanism for building human-in-the-loop agent systems.

from langgraph.graph import StateGraph
from langgraph.checkpoint.memory import MemorySaver

builder = StateGraph(AgentState)
builder.add_node("execute_trade", execute_trade_node)
builder.add_edge(START, "execute_trade")
builder.add_edge("execute_trade", END)

memory = MemorySaver()
graph = builder.compile(checkpointer=memory, interrupt_before=["execute_trade"])

When you call graph.invoke(state, config={"configurable": {"thread_id": "t1"}}), it pauses before execute_trade runs. To resume after human approval:

approved_state = graph.invoke(Command(resume={"approved": True}), config=config)

The Command object with resume= injects data into the state at the resumption point. The interrupted node sees the resumed data as part of the state it receives. This pattern maps onto approval workflows, content moderation, code review before execution, and anything requiring human judgment in an automated pipeline.

The failure mode: without a checkpointer, interrupt() saves no state and the graph cannot resume from the interruption point—you get an error about a missing checkpoint. Always instantiate MemorySaver (or a persistent checkpointer) and pass it to compile() before using interrupts.

Local verification checkpoint

Run the smallest example from this chapter in a local workspace and record the package version, runtime, data path, and observed output. If the result depends on model size, vector count, CPU/GPU backend, or available memory, note that constraint beside the exercise so the lesson remains reproducible.

Local verification checkpoint

Run the smallest example from this chapter in a local workspace and record the package version, runtime, data path, and observed output. If the result depends on model size, vector count, CPU/GPU backend, or available memory, note that constraint beside the exercise so the lesson remains reproducible.

EXERCISE

Build a graph that interrupts before a send_alert node. Invoke the graph with thread_id "hitl-test", confirm it pauses, then resume with {"confirmed": True}. Print the final state to confirm the alert node received the confirmation.

← Chapter 6
Conditional Edges
Chapter 8 →
Checkpointing