When to reach for it
- Actions have irreversible or expensive consequences.
- Compliance mandates human decisions.
- Model uncertainty must be surfaced.
/pattern/hitl-gate/
Critical steps are reviewed and approved by a human before execution. The system suspends, persists state, poses a structured question, and resumes once the human replies. Best framed as graduated autonomy — oversight set per action class by stakes (full automation for low-stakes, supervised for moderate, human-led for high-stakes) rather than a single on/off gate.
When to reach for it
When it backfires
The tradeoff
Higher control is achieved against slower operational workflows.
Before any irreversible action, the agent pauses on a gate. A human inspects, approves, or rewrites.
from langgraph.graph import StateGraph, END
from langgraph.types import interrupt, Command
class State(TypedDict):
order: dict
refund: dict | None
approved: bool | None
def draft_refund(state):
return {"refund": refund_llm(state["order"])}
def human_gate(state):
# Suspends execution; resumes when human replies
return interrupt({
"question": "Approve refund?",
"payload": state["refund"],
})
def execute_refund(state):
if state["approved"]:
process_refund(state["refund"])
return state
g = StateGraph(State)
g.add_node("draft", draft_refund)
g.add_node("gate", human_gate)
g.add_node("execute", execute_refund)
g.add_edge("draft", "gate")
g.add_edge("gate", "execute")
g.add_edge("execute", END)
g.set_entry_point("draft")
# Resume with: graph.invoke(None, config, stream_mode="values")
# after human calls Command(resume={"approved": True, ...})
hitl = g.compile()Every low-risk action triggers a gate. Humans develop approval fatigue and start clicking 'approve' without reading.
Fix · Gate only on irreversible or high-cost actions. Use a risk classifier to auto-approve low-risk operations.
The gate shows the final state but not what changed. The human can't tell if the refund amount is correct.
Fix · Include a clear diff in the interrupt payload: 'Proposed change: $249.00 → $199.00. Reason: duplicate charge.'
Search patterns, frameworks, and pages.