Human-in-the-Loop (in LangGraph)

Some actions are too consequential to let an agent take alone — sending the email, issuing the refund, deleting the records. Human-in-the-loop (HITL) lets a LangGraph agent pause mid-run, wait for a person to approve, edit, or reject, then resume exactly where it stopped. It's the difference between an agent you demo and one you'd let touch production.

💡 In one line: Human-in-the-loop pauses a LangGraph run at a checkpoint so a person can approve, edit, or reject before it continues.

Why HITL?

  • Risky actions — payments, deletion, external emails.
  • Trust and compliance — an audit trail of who approved what.
  • Quality — a human corrects the agent before the mistake ships.
  • Gradual autonomy — start supervised, loosen the gates as confidence grows.

How It Works: Interrupt & Resume

HITL rests on persistence. Because a checkpointer saves state at every step, LangGraph can stop, wait indefinitely (even across a restart), and then resume from the exact checkpoint once a human responds.

No checkpointer, no HITL — that's the hard requirement.

The interrupt Function

Call interrupt() inside a node to pause and surface a payload to the human:


Resume by invoking the graph with a Command:


The Approval Gate

Whiteboard
Whiteboard diagram


HITL Patterns

  • Approve / reject — a gate before a risky tool call.
  • Edit state — the human fixes the agent's draft or arguments.
  • Review output — approve the final answer before it's sent.
  • Provide input — the agent asks a clarifying question.
  • Time travel — rewind to an earlier step and take a different path.

Static vs. Dynamic Interrupts

  • Static — configured at compile time (interrupt_before=["tools"]), always pausing at that node.
  • Dynamic — an interrupt() call inside a node, firing only when conditions warrant (e.g. only for refunds over ₹10,000).

Dynamic is usually better: pause only when it matters.

Durability

Because state is checkpointed, a paused run can wait minutes or days — through restarts and deploys — and still resume correctly. That's what makes HITL practical rather than a demo trick.

Best Practices

  • Gate only genuinely risky actions — approval fatigue is real.
  • Show the human enough context to decide (the full payload).
  • Use a durable checkpointer (Postgres) in production.
  • Log approvals for the audit trail.
  • Prefer dynamic interrupts over pausing on every step.

Summary

  • HITL pauses a run so a human can approve, edit, or reject before it continues.
  • It works via interrupt() + Command(resume=...), and requires a checkpointer.
  • Patterns: approve/reject, edit state, review output, ask for input, and time travel.
  • Dynamic interrupts (condition-based) beat static ones for most workflows.
  • Durable state means a run can wait days and still resume exactly where it stopped.Â