Skip to content

All lessons

Area 03 // AI AgentsLesson 59 / 14013 min read

Human in the loop

Human in the loop means the agent pauses at important moments (before a risky action, when it's unsure, or to get missing information) so a person can approve, edit or reject, and the agent resumes from exactly where it stopped.

Think of it like this

Analogy

A junior accountant prepares payments all day, but anything over £1,000 sits in a "waiting for sign-off" tray until the finance manager approves it, edits the amount, or sends it back with a note. The accountant then carries on exactly where they left off. The tray holds the paperwork overnight if needed.

Human in the loop is that sign-off tray for agents.

The problem it solves

Agents make mistakes and can be manipulated (prompt injection). For many actions (sending money, emailing customers, deleting records, merging code) a mistake is costly or irreversible. On the other hand, asking for approval at every step makes an agent slower than doing the work by hand.

You need to pause at the right moments, show people exactly what's about to happen, and resume reliably, even if the answer comes the next morning.

How it works, step by step

  1. Choose pause points for human in the loop:
    • Before irreversible or high-impact actions (payments, deletions, external emails, production changes).
    • When confidence is low or a check failed.
    • For policy-sensitive topics (legal, medical, HR).
    • When the agent needs information only a person has.
  2. Pause with an interrupt: the agent stops before the action and saves its full state (checkpoints).
  3. Show a clear request in an approval flow: what the agent wants to do, with which arguments, why, and the consequences. Route it to the right person (the user, a manager, a reviewer queue).
  4. Let the human respond: approve, edit (change arguments or the draft), reject with a reason, or answer a question.
  5. Resume the agent with the response; it continues from the saved state, using the human's input.
  6. Handle timeouts: if nobody answers, expire, escalate or cancel safely.
  7. Log everything (who approved what, when) for audit, and use approval data to tune where pauses are needed.
The agent pauses, its state is saved, and a person decides before anything risky happens.

See it in code

Install
pip install langgraph
Needs
Python 3.10+. Runs offline.

A LangGraph agent that pauses for refund approval, saves its state, and resumes when a person answers.

approval_interrupt.py
from typing import TypedDict
 
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.graph import END, START, StateGraph
from langgraph.types import Command, interrupt
 
class State(TypedDict):
    order_id: str
    refund: float
    status: str
 
def check_order(state: State) -> dict:
    return {"refund": 129.0}                       # a real app would look the order up
 
def approve(state: State) -> dict:
    # Pause the graph and wait for a human. The state is saved by the checkpointer.
    decision = interrupt({"question": f"Refund {state['refund']} GBP for {state['order_id']}?"})
    return {"status": "approved" if decision == "yes" else "rejected"}
 
graph = StateGraph(State)
graph.add_node("check_order", check_order)
graph.add_node("approve", approve)
graph.add_edge(START, "check_order")
graph.add_edge("check_order", "approve")
graph.add_edge("approve", END)
app = graph.compile(checkpointer=InMemorySaver())  # checkpoints after every step
 
config = {"configurable": {"thread_id": "ticket-42"}}   # one thread = one saved conversation
first = app.invoke({"order_id": "A1234", "refund": 0, "status": "new"}, config)
print("paused, asking:", first["__interrupt__"][0].value["question"])
print("saved state   :", app.get_state(config).values)
 
final = app.invoke(Command(resume="yes"), config)   # later, maybe from another server
print("after resume  :", final)
Output
paused, asking: Refund 129.0 GBP for A1234?
saved state   : {'order_id': 'A1234', 'refund': 129.0, 'status': 'new'}
after resume  : {'order_id': 'A1234', 'refund': 129.0, 'status': 'approved'}

In production the checkpointer is a database, the question goes to a review UI or Slack, and the reviewer's click calls invoke(Command(resume=...)) for that thread. Other frameworks offer the same idea (approval callbacks in tool runners, tool_confirmation events in hosted agent platforms).

A real example

Example

An accounts-payable agent with a sign-off threshold

A company's AP agent matches invoices to purchase orders and schedules payments. Rules: payments under £500 to known suppliers run automatically; anything over £500, any new supplier, or any changed bank details pauses for a finance manager, who sees the invoice, the PO match, the bank details diff and the agent's reasoning, and can approve, edit the amount, or reject.

In the first month, managers rejected 3% of flagged payments, including one invoice from a fraudster who had changed a supplier's bank details by email. The agent would have paid it; the pause caught it.

The easy way

Start here

Wrap your riskiest tool in a confirmation step: before running it, show the user the action and arguments with "Approve / Cancel" buttons. For short waits that's enough. For long waits, use a framework with durable checkpoints.

When you grow: the production setup

Production approval systems define risk tiers per action, route requests to the right approver with context, support edits and comments, enforce timeouts and escalation, persist state durably, write audit logs, and review approval statistics regularly to move low-risk actions to automatic and add pauses where incidents happened (human approval for actions).

Trade-offs

What you gain

  • Prevents costly or irreversible mistakes and catches manipulation.
  • Builds trust, so agents get adopted for higher-stakes work.
  • Approvals and edits become training and eval data.

What it costs you

  • Slower: tasks wait for people.
  • Approval fatigue: people start clicking "approve" without reading.
  • Needs durable state, review UIs and routing.

When not to use it

  • Low-risk, reversible, high-volume actions where review adds little and slows everything.

Common mistakes

  • Approving everything (fatigue) or nothing (risk) instead of tiering by risk.
  • Approval prompts that don't show the actual arguments.
  • Pausing in memory, so a restart loses the pending action.
  • No timeout or escalation, leaving tasks stuck forever.
  • Not logging who approved what.

Interview questions

Try answering out loud first, then open the model answer.

How would you add human approval to an agent that can issue refunds?

Model answer

Classify refund actions by risk (amount, customer history, policy match). For risky ones, interrupt before executing: persist state with a checkpointer, send a review request with the order, amount, reason and policy evidence to the right queue, allow approve/edit/reject, resume with the decision, enforce timeouts and escalation, and audit-log every decision. Low-risk refunds within policy can be automatic, monitored by sampling.

What makes a good approval UX for agent actions?

Model answer

It shows exactly what will happen (action, arguments, target, amount), why the agent wants to do it (evidence, reasoning), the consequences and reversibility, and offers approve, edit and reject with a comment. It's routed to someone qualified, has a deadline, is fast to act on, and records the decision. It should be rare enough to avoid rubber-stamping.

Why do human-in-the-loop systems need checkpointing?

Model answer

Human responses can take minutes to days, during which processes restart, deploy or scale. Without durable state the pending action and context would be lost or need recomputation (possibly differently). Checkpoints persist the exact state at the pause so the agent resumes deterministically with the human's input.

Quiz

Pick an answer to see whether it’s right and why.

  1. 01When should an agent pause for a human?
  2. 02Why does human-in-the-loop require saved state (checkpoints)?
  3. 03What should the approval screen show?
  4. 04Besides approve and reject, what useful option should a human have?
  5. 05Your logs show humans approve 99.8% of "send FAQ link" actions without changes. What could you do?

0 of 5 answered

Key terms

Human in the loop
Designing an AI system to pause for a person to approve, edit, reject or add information at important moments.
Interrupt
Pausing an agent run at a specific step, saving its state, until a person or system provides input to resume it.
Checkpoint
A saved snapshot of an agent's state after a step, so it can pause, resume, recover from crashes or be inspected.
Approval flow
The process and UI by which a person reviews a proposed agent action and approves, edits or rejects it.

Before and after

Progress is saved in this browser only.