Human-in-the-loop (HITL) for AI agents is an execution-control pattern that pauses an agent before a specified decision or action, routes a bounded request to an authorized human reviewer, and resumes only after an explicit, valid decision. It is not simply a “please confirm” message in a chatbot. In enterprise systems, the approval must be connected to an enforceable authorization boundary, durable workflow state, and an auditable record.
A well-designed agent can read data, draft work, and perform low-risk actions autonomously. It should not silently execute a payment, delete records, grant access, or publish a customer-facing policy because its language model is confident. Human oversight allows autonomy within limits without treating every tool call as a meeting.
Architecture rule: An approval changes what the workflow is allowed to execute; it does not grant the model authority to invent a new action, bypass authorization, or reuse approval for changed parameters.

Human-in-the-loop, human-on-the-loop, and human-in-command
These terms describe different oversight roles, and an enterprise workflow may use all three.
| Pattern | Human role | Suitable example | Primary limitation |
|---|---|---|---|
| In the loop | Reviews a particular proposed action before it proceeds | Approve a customer refund above a limit | Can create a queue and delay |
| On the loop | Supervises ongoing automation and intervenes on anomalies | Review a dashboard of agent-generated support tickets | Cannot reliably prevent an irreversible action already executed |
| In command | Sets policy, authorizes capabilities, can stop or override the system | Security operator disables the deployment tool | Requires reliable kill switches and organizational ownership |
This is an architectural choice, not a model toggle. A read-only research agent might run with monitoring alone. A payments agent can still operate autonomously for information gathering while requiring pre-action approval for money movement.
The NIST AI Risk Management Framework treats human–AI configuration as a risk-dependent design choice rather than a one-size-fits-all setting.
Choose an approval pattern based on consequences
Pre-action approval
The agent proposes an action, but the side effect has not happened yet. A separate enforcement component checks policy, gathers approval, revalidates the action, and only then calls the tool. Use this for transfers, deletion, privileged configuration changes, sensitive external communications, or actions difficult to undo.
Post-action review
The agent completes a reversible, permitted action and places the result in a review queue. This is useful for drafting internal summaries, tagging records, or updating low-risk metadata when a safe rollback path exists. It is not a substitute for pre-approval of irreversible actions.
Conditional escalation
The agent operates inside a bounded policy, escalating on triggers such as large amounts, unusual destinations, missing evidence, conflicts, or exceptional customer impact. Calibrated model uncertainty may be one supporting signal, but never the only authorization test.
A clean design separates risk gates (what requires approval) from routing rules (which authorized reviewer should decide).
Classify agent actions before writing prompts
Start with a tool/action inventory rather than a generic instruction such as “ask a human for anything risky.” The following tiers are illustrative starting points, not universally valid regulatory categories.
| Tier | Example action | Default treatment | Evidence to retain |
|---|---|---|---|
| Read-only | Retrieve an approved policy document | Automated with permission checks | Source, actor, trace |
| Low-impact reversible | Add a private draft label | Automated or sampled post-review | Before/after state |
| External side effect | Send email, issue a modest refund | Conditional pre-approval according to policy | Recipient, amount, content, reviewer |
| Privileged / irreversible | Delete customer data, alter IAM roles, transfer funds | Mandatory pre-action approval plus independent authorization | Signed-off action fingerprint and execution result |
Policy must consider who owns the resource, sensitivity, size of change, reversibility, external exposure, tenant, and the human accountable for the decision. This classification belongs in agent governance, but the HITL design is where policy becomes a working pause-and-resume process.
Production reference architecture: propose, pause, approve, execute
User goal → Agent plans → Proposed tool call
↓
Policy evaluation
↓
┌────────────┼────────────┐
↓ ↓ ↓
Allow Deny Require review
↓ ↓ ↓
Execute Return safe Save checkpoint
error ↓
Approval queue
↓
Authorized UI
↓
Decision + audit
↓
Reauthorize/revalidate
↓
Execute once safely
↓
Resume agent workflow
The control plane should be outside the model. The agent's proposal is untrusted input to an authorization service; its own statements about permissions or confidence are not permissions. Reuse the tool and function integration architecture to enforce validation where real APIs are called.
The seven steps of a durable approval
- Propose: capture a normalized tool name and exact arguments, including tenant, resource, amount, recipient, and expected preconditions.
- Policy check: decide allow, deny, or require review using versioned server-side rules.
- Checkpoint: persist execution state and create an approval request. Do not keep a web request open for hours.
- Route: resolve reviewer identity and scope through enterprise IAM; the agent must not select an arbitrary approver.
- Decide: approve, reject, request edits, or escalate, with a reason and a deadline.
- Revalidate: verify the reviewer's authority, approval expiry, exact action fingerprint, current resource state, and policy version before execution.
- Commit and audit: execute with idempotency controls, record the outcome, and resume or terminate safely.
OpenAI's Agents SDK human-in-the-loop guide documents per-tool approvals, run interruptions, persisted run state, and resume behavior. LangGraph's interrupts documentation likewise describes pause/resume using persisted graph state. Those framework features supply workflow mechanics; application-level authentication and authorization remain your responsibility.
Build an approval request the reviewer can actually understand
A reviewer should not see only “Approve tool call?” The interface needs enough trusted context to make a decision without copying sensitive secrets or trusting agent-authored prose.
{
"approval_id": "apr_84bc",
"run_id": "run_1902",
"tenant_id": "enterprise_12",
"tool": "issue_refund",
"resource_id": "order_9031",
"proposed_arguments": {
"amount_usd": "175.00",
"destination": "original_payment_method"
},
"risk_tier": "external_side_effect",
"policy_id": "refund-approval-v3",
"action_fingerprint": "sha256:...",
"required_reviewer_role": "refund_supervisor",
"expires_at": "2026-10-14T23:00:00Z",
"decision": "pending"
}
The fingerprint is computed by the backend over a canonical action representation; it is not generated by the model. Display the specific amount, destination, source evidence, impact, and what happens if rejected. Require the reviewer to see a diff for edits and to approve the final edited payload, not the original one.
Avoid approval-dialog deception. Retrieved webpages, document text, tool outputs, and model summaries can contain attacker-controlled instructions. The server should render verified tool arguments and policy context in separate, clearly labeled UI fields. The OWASP guidance on approval-dialog forgery describes why even a human approval step can be manipulated when untrusted content controls what the human sees.
Authorization is still required after approval
The approval service should validate all of the following:
- the reviewer is authenticated and allowed to authorize this operation for this tenant;
- the request has not expired, been revoked, changed, or already been consumed;
- the proposed call's canonical argument hash matches the approved call;
- the current order, account, permissions, or external state still satisfies the original preconditions;
- the executing tool credential has only the permissions required for the action;
- the backend has not already completed the operation during a retry.
The approval identifier is an opaque reference, not proof of authority. Never let the browser send a serialized agent-run snapshot and treat it as trusted state. Keep checkpoints in server-controlled storage, and make a rejection an enforceable block instead of text the model can ignore. The official OpenAI SDK documentation explicitly warns about the trust boundary around serialized run state and reviewer interfaces.
Exactly-once outcomes are harder than exactly-once approval decisions
A database can atomically mark an approval as consumed. But an external API call may succeed and its response may be lost. After a timeout, do not blindly retry a payment or refund.
Use an operation idempotency key when the downstream API supports it. Persist a stable execution ID, query the downstream system for uncertain outcomes, and reconcile before retrying. If the external system does not provide safe deduplication, surface the ambiguous state to a human rather than assuming failure. See agent reliability engineering for broader recovery design.
Pseudocode: a backend-owned approval gate
The following is framework-independent pseudocode showing the security boundary; it is not a copy-paste SDK implementation.
async def execute_proposed_action(run_id, proposed_call):
decision = policy_engine.check(proposed_call)
if decision == "deny":
return block("policy_denied")
if decision == "allow":
return await execute_authorized_tool(proposed_call)
approval = approvals.create_pending(
run_id=run_id,
canonical_action=canonicalize(proposed_call),
action_hash=hash_action(proposed_call),
policy_version=policy_engine.version,
deadline=policy_engine.deadline(proposed_call),
)
checkpoints.pause(run_id, approval.id)
return {"status": "awaiting_approval", "approval_id": approval.id}
async def on_reviewer_decision(identity, approval_id, verdict):
with database.transaction():
request = approvals.lock_pending(approval_id)
authorize_reviewer(identity, request)
require_not_expired(request)
require_decision_allowed(verdict, request)
approvals.record_decision(request, identity, verdict)
if verdict != "approve":
return checkpoints.resume_denied(request.run_id)
# A worker, not the web request, rechecks state and executes the exact action.
return enqueue_execution(request.id)
The worker should acquire a single-use execution lease, verify authorization and preconditions again, and reconcile uncertain downstream effects. Agent observability should correlate request, reviewer, approval event, tool span, and external transaction ID in one trace.
Design escalation SLAs around business context, not arbitrary confidence
A queue becomes a hidden failure mode if nothing owns it. Set response objectives based on reversibility, customer impact, and reviewer availability. The sample policy below is illustrative only:
| Queue | Example | Illustrative target | On timeout |
|---|---|---|---|
| Routine | Internal draft revision | 1 business day | Leave pending / notify requestor |
| Time-sensitive | Moderate-value refund | 2 business hours | Escalate to authorized supervisor |
| Critical | Privileged production configuration | As defined by incident runbook | Block and page authorized on-call |
Avoid “silence equals approval.” If a deadline passes, fail closed for protected actions, notify the requestor, and allow a new authorized review. If business continuity demands a break-glass route, make it separate, constrained, logged, and governed by explicit policy.
Prevent review fatigue
Measure review arrivals, queue age, and approval concentration by user and tool. Reduce unnecessary prompts by narrowing action permissions and moving truly low-risk actions to a preapproved envelope. But never relax a protective gate solely because the queue is long; evaluate incident rates, false approvals, and business loss as well.
Evaluate both the agent and the human control
A HITL system can show high agent task success while failing to enforce its guardrails. Test the entire workflow with a dedicated AI agent evaluation suite.
| Metric | What it detects | Suggested test |
|---|---|---|
| Approval bypass rate | Protected actions ran without valid approval | Inject tool calls directly against backend |
| Unauthorized approval rejection | Reviewer/tenant boundaries | Cross-tenant, expired-role scenarios |
| Action-binding correctness | Changed arguments after approval | Approve $100, mutate to $1,000 |
| Duplicate-side-effect rate | Resume/retry safety | Kill worker after API succeeds |
| Queue wait time (p50/p95) | Operational bottlenecks | Measure by risk tier |
| Reviewer edit/reject rate | Poor agent proposals or overly broad rules | Compare by tool and model version |
| Approval outcome quality | Whether approved actions were appropriate | Periodic human audit |
| End-to-end task success | Whether workflow achieves user outcome | Verify downstream state |
Seed regression tests for prompt injection inside a retrieved policy page, compromised tool results, malformed arguments, reviewer role removal, deadline expiry, stale inventory or exchange rates, and concurrent reviewers. Use AI agent security controls to limit what an attacker could cause even if one approval decision goes wrong.
Do not confuse verbal confidence with probability
An agent writing “90% confident” does not establish a calibrated 90% success rate. A model's self-reported confidence may be unrelated to empirical correctness; validate estimates against labeled outcomes for the precise task. Even if three independent steps each truly succeed 75% of the time, the chance all three succeed is 0.75³, or about 42%. That is an illustration under an independence assumption, not a general formula for correlated agent steps.
High-impact actions should have hard policy gates even if the model sounds certain. Low confidence can trigger extra review, but high confidence should not waive authorization.
Multi-agent approvals: preserve one accountable decision
An agent might delegate document discovery to a research agent and transaction preparation to another agent. Approval must remain bound to the final concrete operation and the authenticated reviewer, even across handoffs.
For multi-agent orchestration, keep a stable root run ID and an immutable approval lineage. A sub-agent must not transform a denied request into a new privileged tool call under a different name. Shared agent memory may record facts about an approval, but memory is never itself a credential or permission grant.
Enterprise example: a customer-support refund agent
Suppose a support agent has read-only access to order history, can draft replies, and can propose refunds. A backend policy allows a small refund only when the customer, order, payment method, and reason satisfy specific conditions. Larger or unusual refunds require a supervisor.
- The agent gathers evidence using read-only tools.
- It proposes a refund with an exact order ID, amount, and payment destination.
- The policy engine checks both eligibility and the pre-action approval threshold.
- The server saves the pending request and shows the reviewer relevant records, expected effect, and policy basis.
- The supervisor approves the exact payload or edits it; any edit is reevaluated and may require new approval.
- Before execution, the backend rechecks that the order is still eligible and that the action has not already happened.
- The payment tool executes once or enters a reconciliation state if the outcome is uncertain.
- Only after confirmation does the agent tell the customer that the refund was issued.
The key distinction: “I submitted your refund for review” and “Your refund was processed” are different states. The customer-facing message should reflect verified tool state, not agent intent.
A pragmatic 30-day implementation roadmap
Week 1 : inventory and policy. Identify side-effecting tools, owners, tenant boundaries, reversible operations, required reviewers, and denial defaults. Keep risky tools inaccessible to the agent until rules exist.
Week 2 : durable workflow. Build checkpointing, pending-approval storage, server-side reviewer authorization, timeouts, and execution locks. Implement allow/deny/review branches.
Week 3 : reviewer experience and evidence. Create trustworthy, minimal-diff approval cards; expose resource state, user impact, risk reason, policy version, and reviewer actions. Record immutable audit events.
Week 4 : abuse and failure testing. Run tool-bypass tests, duplicate-execution simulations, stale-state scenarios, malicious-document cases, and reviewer-revocation tests. Add dashboards for queue health and outcome quality.
Version every approval policy and review the effect of proposed changes in staging before expanding autonomy. Connect policy changes to safe agent deployment so the team can canary, compare, and roll back.
KONTROLS: turn human oversight into an enforced boundary
DataKnobs KONTROLS is the relevant governance layer for this problem: policy boundaries, risk classification, access and privacy controls, monitoring, and auditability. In an enterprise implementation, connect those responsibilities to the approval service so an agent cannot bypass required review merely by issuing a different prompt.
Next step: inventory three side-effecting tools in one agent, define who may approve each action, and test that the backend rejects unapproved execution: even when the agent insists it has permission.
Frequently Asked Questions
What does human-in-the-loop mean for AI agents?
It means an agent pauses a defined decision or action so an authorized person can approve, reject, edit, or escalate it. The application must enforce the decision before the protected action executes.
Should every AI agent tool call require human approval?
No. Approval should reflect the action's permissions, risk, irreversibility, and business consequences. Routine read-only operations may run automatically; sensitive external or privileged actions may require a specific reviewer.
How do you resume an AI agent after human approval?
Persist the workflow's state and a pending approval ID in a trusted backend, obtain an authorized decision, recheck policy and current state, and resume the workflow from its saved checkpoint. Durable agent frameworks provide interrupt-and-resume primitives but not your application's reviewer identity model.
What happens when nobody approves before the deadline?
Protected actions should remain blocked. A typical design expires the request, escalates to another authorized reviewer when appropriate, and records the timeout. Approval by silence is unsafe for consequential changes.
Is a human approval enough to prevent prompt injection?
No. Malicious retrieved content can manipulate an approval summary or persuade the reviewer. Render canonical tool arguments from trusted backend fields, enforce authorization independently, and limit tool privileges. Human review is one layer in a defense-in-depth system.
How do you measure whether HITL is working?
Track prevented policy violations, bypass test outcomes, duplicate side effects, reviewer accuracy, queue wait time, expiration rates, rejected or edited proposals, and downstream task success. The safest system balances guardrail strength with usable workflows.
Conclusion
Human-in-the-loop design is not about slowing an agent down. It is about making authority explicit at the moments where software crosses from suggestion into consequential action. Classify operations by risk, place enforceable approval gates before side effects, persist state durably, bind decisions to exact actions, revalidate on resume, and measure both quality and control effectiveness. That architecture lets useful autonomy scale without treating the language model as an authorization server.
Sources
- OpenAI Agents SDK : Human-in-the-loop approvals, interruptions, and server-owned run state
- LangGraph : Interrupts and durable resume
- NIST : AI Risk Management Framework
- OWASP : Human-in-the-loop dialog forgery
- OWASP Cornucopia : Agent security change-control guidance
Technical architecture guidance; organizational, regulatory, and contractual controls should be reviewed for the specific deployment.