Human-in-the-Loop Patterns for AI Agents
Approval is a budget, not a default — a person asked to confirm forty actions reads the first three. Triage by reversibility rather than risk, and why making an action undoable beats gating it every time.
Human in the loop
is the phrase every AI safety section reaches for and almost none of them define. It usually means a confirmation dialog bolted on at the end, which is the least useful version of the idea and the one users click through fastest.
The useful question is not whether a human is involved. It is where in the loop they sit, and what they are actually able to judge at that point.
Approval fatigue is the failure mode, not under-approval
Start here, because it determines everything else.
A confirmation prompt only works if the person reads it. A person asked to approve forty actions in a session reads the first three. By the fifth they are pattern-matching on the shape of the dialog, and by the tenth they are clicking Approve as a reflex. You have not added a control; you have added latency and a false sense of one.
So approval is a budget, not a default. Every prompt you add makes the others less effective. Spend them on the actions where a human can actually add judgement, and get out of the way everywhere else.
Which means the design problem is triage.
Triage by reversibility, not by risk
The common approach is to score actions by risk and gate the high ones. This produces long arguments about what counts as risky.
A sharper axis: can I undo this, and how fast?
| Class | Examples | Pattern |
|---|---|---|
| Reversible, cheap | Read a file, run a query, search | Let it run |
| Reversible, annoying | Create a draft, add a label, open a branch | Let it run, make it visible |
| Irreversible, contained | Delete a record, merge a PR | Approve, or make it undoable first |
| Irreversible, external | Send an email, charge a card, post publicly | Approve, always |
The third row is where most of the design work is, because there is usually a way to move an action up the table. An agent that moves a file to a trash folder instead of unlinking it has converted an approval into a non-event. An agent that opens a pull request instead of pushing to main has done the same thing.
Making an action reversible is almost always better than gating it. It costs you one engineering decision once, instead of a human decision every time.
The fourth row is where the external
matters more than the irreversible
. You can delete an email from your own database. You cannot delete it from someone's inbox, and no amount of internal tooling changes that. Anything that leaves your system and touches a third party is the one place approval is unambiguously correct.
The patterns, in increasing order of trust
Approve each action. The model proposes, a person confirms, the action runs. Correct for the fourth row, exhausting anywhere else. Use it for the small number of actions that genuinely warrant it.
Approve the plan. The agent produces its intended sequence, a person approves the whole thing, then it executes. Far better ergonomics — one decision instead of nine — and the human sees the shape of the work rather than a decontextualised step. The weakness is real: plans change on contact, and an agent that re-plans mid-run has escaped the approval you gave. Cap what it may do without returning.
Act, then review. The agent works freely and produces something a human inspects before it counts: a draft, a branch, a staged change. This is how coding agents actually get used, and it is the highest-throughput pattern that still has a human deciding. It requires an artifact — somewhere the work can sit, complete, without being live.
Escalate on uncertainty. The agent proceeds alone until it hits something it cannot resolve, then asks. Excellent when the agent's self-assessment is calibrated; models are frequently confidently wrong, so treat this as a supplement rather than the primary control.
Sample and audit. No per-run human. A percentage of runs get reviewed after the fact, and the review feeds evals. The only pattern that survives volume. Everything above is scaffolding for getting here safely.
Most production systems use three or four of these at once, chosen per action rather than per system.
Ask at the moment of judgement, not at the end
A prompt that says the agent wants to run 47 operations, approve?
is not a control. Neither is one that appears after twenty minutes of work, when the sunk cost makes rejection expensive.
The best moment to ask is the point where a person actually has something to decide — before the irreversible step, with the specific thing named. Send this email to 340 recipients?
beats Allow agent to use email tools?
by a wide margin, because only one of them is a question a human can answer.
The MCP specification's elicitation primitive is built around this: a server can pause mid-request and ask for input, and the client retries the original call with the answer attached. See what changed in MCP 2026-07-28 for the mechanics.
It also carries a rule worth borrowing whether or not you use MCP. Elicitation has a form mode and a URL mode, and the spec is explicit that form mode must not be used for passwords, API keys, tokens or payment credentials — those belong in URL mode, out of band, so the data never passes through the client or into a model's context.
That is the general principle: a credential should never be something an agent collects. Route the human to the real thing, and let the agent learn only whether it succeeded.
Show what will happen, not what was requested
The most common way a confirmation step fails is that it describes the request instead of the effect.
Run `deploy` tool
tells a person nothing. Deploy commit a3f9c2 to production, replacing the build from 14 minutes ago
is a decision. The second one is more work to build and it is the entire value of the step.
For anything with a computable effect, show the diff. A file change, a config edit, a database mutation — render before and after. People are very good at spotting a wrong diff and very bad at spotting a wrong intent statement.
Two things this also protects against, which pure risk-scoring does not:
Prompt injection. If an agent has been talked into something by text it read, the instruction looks reasonable in isolation and wrong in context. A person seeing send the deployment logs to an external host
catches it precisely because it doesn't match what they asked for. That is why prompt injection is an argument for well-placed approval rather than against automation — it is one of the few defences that doesn't depend on the model behaving.
Confused tools. The wrong argument to the right tool is invisible in an intent statement and obvious in a diff.
The controls that are not approval
Approval is one instrument. It works badly alone, and the others cost the user nothing.
Caps. Maximum iterations, maximum spend, maximum tool calls per run. An agent that cannot exceed twelve steps has a bounded failure mode regardless of what it decides.
Least privilege. Most tools should be read-only. Most credentials should be scoped narrower than they are. An agent that cannot delete does not need a delete confirmation. This is the same argument as MCP scope minimisation — the blast radius of a compromise is set long before anyone clicks anything.
Staging by default. Sandbox mode, draft mode, dry run. Several MCP servers ship this — Intuit's QuickBooks server has explicit DISABLE_WRITE, DISABLE_UPDATE and DISABLE_DELETE switches, and PayPal publishes a separate sandbox endpoint. Use them while you are learning what the agent does.
Observability. You cannot review what you cannot see, and sample-and-audit is impossible without traces. See how to trace and debug an AI agent.
Guardrails and safety for AI agents covers the layered version.
How this goes wrong in practice
Everything is gated. Nobody reads anything. The most dangerous action gets the same reflex click as the ninth harmless one. Worse than gating three things well.
The gate is a formality. A dialog with no real information, defaulting to Approve, dismissible with Enter. Present but not functioning.
Approval was granted once and never bounded. A user approves a plan and the agent treats that as standing authorisation for whatever the plan turns into. Approval should cover a defined scope and expire.
The human is asked to judge something they cannot. Is this SQL correct?
to someone who doesn't read SQL. If the reviewer cannot evaluate the artifact, the step is theatre — either change the artifact or change the reviewer.
Where to start
Take the list of things your agent can do and sort it by the table above. Anything irreversible and external gets approval, with the effect shown. Anything you can make reversible, make reversible. Everything else runs free, with a cap and a trace.
Then watch what your reviewers actually do. If they are approving everything without reading, you have too many gates, and the fix is to remove some — not to add a bigger warning to the ones you have.