← Master Index
Vol. 15 Module 15.1 Lecture

Human in the Loop

Agent Fundamentals

How This Lesson Fits the Module & Volume

Every prior 15.1 idea—autonomy, plans, tools, the loop, workflows, and multi-agent—eventually meets a human. Human-in-the-loop (HITL) is how you pause, edit, approve, or reject before irreversible effects. It is not a failure of agency; it is how agency ships.

LangGraph interrupts/resume are the orchestration primitive. AutoGen user-proxy patterns preview conversational HITL. After this capstone, Module 15.2 starts with episodic memory—including storing human decisions as episodes the agent can learn from. Module 15.3 then standardizes tools via MCP.

Learning Objectives

By the end of this lesson, students should be able to:

  • Define HITL as interruptible control with resume, not as “the model is weak.”
  • Choose review modes: approve, edit, reject, escalate, or sample.
  • Place gates on risk (money, PII, prod writes), not on every token.
  • Implement a pause/resume sketch around a write tool.
  • Relate HITL to LangGraph interrupts and AutoGen human proxies.
  • Explain how human decisions become episodic memory in Module 15.2.
Definition

Human-in-the-loop is a control design where the agent must yield to a person at specified decision points—typically before side effects—and then resume with the human’s approve, edit, or reject as a new observation. HITL is part of the agent system, not an external afterthought.

HITL Modes

ModeHuman doesAgent thenTypical use
Approve / denyBinary gateExecute or abortRefunds, deploys
EditRewrites draft/argsUses edited artifactCustomer email, plan steps
EscalateTakes the caseStops; logs handoffAbuse, legal, ambiguity
Sampled reviewAudits a %Continues; metrics feed evalMature low-risk flows
Always-on copilotDrives; agent suggestsNo unsupervised writesIDE assistants

Pause / Resume Sketch

In production, persist this state (LangGraph checkpointer). Here, a queue stands in for the human inbox.

import json from dataclasses import dataclass, field from typing import Any, Literal Decision = Literal["approve", "edit", "reject", "escalate"] @dataclass class PendingWrite: id: str tool: str args: dict reason: str @dataclass class HitlRuntime: queue: list[PendingWrite] = field(default_factory=list) log: list[str] = field(default_factory=list) def request_approval(self, tool: str, args: dict, reason: str) -> str: item = PendingWrite(id=f"w{len(self.queue)+1}", tool=tool, args=args, reason=reason) self.queue.append(item) self.log.append(f"PAUSE {item.id} {tool} {args}") return json.dumps({"status": "paused", "approval_id": item.id, "reason": reason}) def resolve(self, approval_id: str, decision: Decision, edited_args: dict | None = None) -> dict[str, Any]: item = next(x for x in self.queue if x.id == approval_id) self.queue = [x for x in self.queue if x.id != approval_id] if decision == "reject": self.log.append(f"REJECT {approval_id}") return {"status": "rejected"} if decision == "escalate": self.log.append(f"ESCALATE {approval_id}") return {"status": "human_owned"} args = edited_args or item.args self.log.append(f"APPROVE {approval_id} exec {item.tool} {args}") return {"status": "executed", "tool": item.tool, "args": args} hitl = HitlRuntime() pause_msg = hitl.request_approval( "issue_refund", {"order_id": "ORD-1042", "amount_usd": 80}, "amount > auto limit" ) print(pause_msg) # Human edits amount then approves — this observation goes back into the agent loop / memory print(hitl.resolve("w1", "edit", {"order_id": "ORD-1042", "amount_usd": 25}))

Where to Put Gates

Always gate

  • Money movement
  • Prod deploy / delete
  • External customer send
  • PII export

Often auto

  • Read-only search / RAG
  • Sandbox code
  • Internal drafts
  • Tiny refunds under cap

After maturity

  • Sampled audit
  • Tighten via eval metrics
  • Keep emergency stop

Strengths

  • Makes autonomy shippable
  • Captures expert edits as data
  • Fits LangGraph interrupts
  • Reduces catastrophic writes

Tradeoffs

  • Latency (humans are slow)
  • Reviewer fatigue if over-gated
  • Need durable pause state
  • Ambiguous UI → rubber-stamping
Common Misconception

“If it needs a human, it is not a real agent.” Copilots and approval-gated agents are the dominant production form. Unattended loops without HITL on irreversible actions are usually unfinished products. Store the human’s decision as an episode so the next run can avoid the same bad write.

Knowledge Check

  1. Short Answer: What does HITL add to an agent loop? Answer: A pause for human approve/edit/reject/escalate, then resume with that observation.
  2. True/False: HITL means the system is not an agent. Answer: False.
  3. Multiple Choice: LangGraph supports HITL mainly via: (a) pooling, (b) interrupts + resume/checkpoints, (c) WordPiece. Answer: (b).
  4. Short Answer: Name three HITL modes. Answer: Approve/deny, edit, escalate (also sampled review / copilot).
  5. True/False: Every RAG retrieval should wait for a human. Answer: False—gate irreversible/high-risk actions.
  6. Multiple Choice: Over-gating mainly causes: (a) reviewer fatigue / latency, (b) better CNNs, (c) free tokens. Answer: (a).
  7. Short Answer: How does Module 15.2 connect? Answer: Human decisions become episodic (and later long-term) memory.
  8. Short Answer: Why persist pause state? Answer: Processes crash; humans are slow—you must resume later.
  9. Multiple Choice: AutoGen’s user-proxy idea is closest to: (a) conversational HITL, (b) FAISS training, (c) CSS grids. Answer: (a).
  10. True/False: Sampled audit is a valid HITL mode for mature low-risk flows. Answer: True.

Key Takeaways

  • HITL is interrupt–decide–resume, aimed at irreversible or ambiguous steps.
  • Choose approve, edit, escalate, or sample—do not rubber-stamp everything.
  • LangGraph interrupts and durable state make HITL operational, not theatrical.
  • Human decisions are gold for episodic memory (Module 15.2).
  • Module 15.1 complete: continue to 15.2 Episodic Memory, then MCP in 15.3.
Trainer’s Guide

Whiteboard: For your support agent, mark every tool as auto / HITL / forbidden. Revisit after a week of sampled audits.

Lab: Wire HitlRuntime into the agent loop: when issue_refund is proposed, return the pause JSON to the user UI; on approve, resume with a role: tool observation.

Recap: HITL bounds agency so it can ship. Continue with Module 15.2 Episodic Memory.