Patterns

Human in the Loop Patterns for AI Agents

The four human in the loop patterns behind every reliable AI agent — approval gates, review queues, escalation, and human owned decisions — and when to use each.

· 9 min read · by the Yoonet team

Every team that ships an autonomous agent eventually rediscovers the same four patterns. They go by different names in different frameworks — interrupts, approvals, escalations, review queues — but under the surface there are only four shapes a human in the loop can take. Knowing which one you need, before you build, saves weeks of plumbing and a lot of production incidents.

This post names the four patterns, shows where each one earns its keep, and covers the operational question the framework docs skip: who, exactly, is the human?

Pattern 1 — The approval gate

The agent wants to do something irreversible or expensive — send the email, issue the refund, sign the contract, delete the records — and execution pauses until a person says yes. This is the pattern most frameworks now ship natively: LangGraph's interrupt(), the OpenAI Agents SDK's needs_approval, Cloudflare's workflow approvals. The mechanics differ; the shape is identical.

# The agent proposes; a person disposes. result = agent.run(task) if result.risk >= THRESHOLD: decision = ask_a_human(result) # blocks the action, not the agent if not decision.approved: return result.cancel(decision.reason) result.execute()

Use it when the cost of a wrong action is much higher than the cost of a short delay. The gate protects actions, not answers.

The catch: an approval gate is only as good as the approver's attention. If every task stops for a rubber stamp, the human stops reading and the gate becomes theatre. Gate the 5 per cent of actions that carry real risk, and let the rest flow. We wrote up how to build this pattern concretely in LangChain and LangGraph and in the OpenAI Agents SDK.

Pattern 2 — The review queue

The agent's output ships either way, but some slice of it — a random sample, the low confidence cases, the high stakes categories — lands in a queue that a person works through. The review happens alongside or after execution rather than blocking it.

# Sample or filter outputs into a queue a person works through. for output in agent.outputs(): if needs_review(output): # confidence, novelty, stakes, or a % sample queue.put(output) else: ship(output)

Use it when you need quality assurance at volume: classification pipelines, content generation, data enrichment, extraction. The queue gives you a measured error rate, examples for improving prompts or fine tuning, and an audit trail — without putting a human speed bump in front of every output.

The catch: queues silently rot. If nobody owns the queue, review latency grows until findings arrive too late to matter. A review queue is an operational commitment, not a code feature — which is most of the argument in build or buy.

Pattern 3 — Escalation

The agent handles the case until it can't, then hands the whole case — context and all — to a person, and gets the resolution back. This is the customer support shape, but it applies anywhere an agent works cases end to end: claims, onboarding, collections, scheduling.

Escalation differs from an approval gate in what crosses the boundary. A gate asks a yes/no question about one action. An escalation transfers ownership of a task the agent cannot finish: the ambiguous record that needs judgement, the supplier who only responds to a phone call, the exception no prompt anticipated.

Use it when your agent's failure mode is "stuck", not "wrong". The design work is in the handoff: the human needs the case history, the constraint that blocked the agent, and a clear definition of done, or you are just forwarding confusion. Structured task briefs — the kind a task type contract forces — are what make escalations resolvable by someone who wasn't watching the agent work.

Pattern 4 — The human owned decision

Some calls should never be the model's, no matter how confident it is: the medical flag, the credit decision, the contract clause, the sign off a regulator will one day ask about. In this pattern the agent does everything except decide — it gathers, summarises, recommends — and a named person makes the call and stands behind it.

Use it when accountability is the product. A confidence score cannot appear before a review board; a person can. The requirement here is not just "a human clicked approve" but a specific, named, competent person whose decision is recorded with their reasoning. That is a different staffing problem from patterns 1 to 3, and it is the one anonymous crowds categorically cannot solve — the heart of how managed human validation differs from crowdsourcing.

The question the docs skip: who is the human?

Framework documentation demonstrates every one of these patterns with input() — the developer approving their own agent at their own keyboard. That is fine in a notebook. In production, each pattern needs a person who is available inside your latency budget, trained on your domain, consistent across cases, and accountable for the result. Developers reviewing agent output between standups are none of those things for long.

There are three honest answers. Staff it yourself (works, costs headcount and an on call rota). Crowdsource it (fast, but anonymous and inconsistent). Or treat the human step as infrastructure: an API that routes the task to a managed, named specialist and returns a structured result. That third option is what hitl.ph is — one POST /tasks call, a trained person on Yoonet's Balanga floor owns the task, and the answer flows back to your agent by webhook or poll. The API docs show the full request shape.

Whichever answer you choose, choose it deliberately. The pattern is the easy half of human in the loop; the human is the half that decides whether it works.

Read next

Or start with the product: the hitl.ph API docs, the five task types and pricing.