AI agents

Sampling Approvals: How Often to Review Agent Output by Task Risk

Antonio Evans10 min read

A three-lane conveyor belt where every item passes under a magnifying glass in the high-risk lane, one in ten stops in the sampled lane, and nothing stops in the auto-approve lane.
Key points

Key points

  1. 1Assign every agent task a risk tier from two inputs: the cost of one bad output and the number of actions per day.
  2. 2Full review is for actions that move money, change customer-facing data or deploy code, because those are hard or impossible to reverse.
  3. 3Random sampling is for visible, cheap-to-fix errors, and the sample size should come from the failure rate you are willing to tolerate, not from habit.
  4. 4Auto-approve is a decision to revisit, not a permanent setting, and it should break whenever volume or scope changes.

The three review modes and what each one is for

Every agent action ends in one of three states: a human approves it before it runs, a human reviews a random sample after it runs, or nobody looks. Most teams drift into one mode for everything, usually full review during a pilot and then silent auto-approval once the queue backs up. The fix is to make the mode a property of the task type, not of the team's mood.

Full review is implemented in code. In Microsoft's Agent Framework, a function is marked as needing approval by wrapping it in an ApprovalRequiredAIFunction, and the run returns a ToolApprovalRequestContent instead of executing the call until a human approves or rejects it per the Microsoft Learn tutorial. LangChain's Deep Agents exposes the same idea through an interrupt_on dictionary that maps tool names to approval behavior, with per-tool settings for which decisions (approve, edit, reject, respond) a reviewer may make through LangGraph interrupts.

Sampling and auto-approval are not framework features in the same way, which is why they need policy. You implement them by intercepting the tool call, deciding whether this invocation falls into today's sample, and either pausing it or letting it through while logging the trace.

The insight most teams miss: full review and sampling answer different questions. Full review prevents a specific bad action. Sampling estimates a failure rate across a population, which is the number you need to decide whether the agent is still trustworthy. An approval log with no sampling tells you nothing about the actions nobody looked at.

Tiering tasks on cost and volume

Two inputs decide the tier.

Cost of a bad output. Not the cost of the task, the cost of the error. A bad draft email costs a minute. A bad refund costs the amount plus the dispute plus the auditor's question. The Aembit team frames the same split as read-only intelligence work versus write actions and external communications, where autonomy for the second category should be earned rather than assumed in its guardrail writeup. Salesforce makes the parallel point that the question shifts from "did it say the right thing?" to "did it do the right thing?" once the agent can call tools and update records in its guardrail guide.

Volume. A low-volume action that is expensive to reverse deserves full review even at two actions a day, because reviewer cost is trivial. A high-volume action with a cheap error should be sampled, because full review at that volume becomes either a rubber stamp or a backlog. The worst combination is high volume plus expensive errors plus full review: reviewers approve hundreds of items in a row without reading them. That looks like a control and produces no signal.

TierCost of one bad outputTypical volumeReview modeExample
0Negligible, internal onlyAnyNone, log the traceSummarize a ticket thread
1Visible, cheap to fixHigh (hundreds per day)Random sample, 5 to 10 percentDraft a reply for an internal queue
2Moderate, reversible with effortMedium (tens to low hundreds per day)Random sample, 20 to 30 percentUpdate a CRM field, create a ticket
3High, hard to reverseLow to mediumFull review, plus sampling of the reviewed setSend an external email, change a customer attribute
4Severe, irreversible or regulatedAnyFull review with dual approvalMove money, provision admin access, deploy to production

The StackAI approval guide draws a similar line, requiring approval when the next action is irreversible, costly, regulated or high blast radius, and lists payment initiation, access provisioning and production database writes among its examples in its decision framework. The table above turns that list into rungs you can assign a task type to on a Monday morning.

Two rules keep tiers honest. A task inherits the tier of its worst consequence, not its typical one: an agent that usually writes internal notes but occasionally emails a customer is tier 3. And tier changes require a recorded decision, never a drift. If the sample rate is 10 percent and the backlog is growing, that is a signal to raise automation after evidence, not to quietly stop looking.

Sizing the sample: what 10 percent actually buys you

The common starting point of 10 percent sounds reassuring and often is not. What matters is what the sample can detect.

If the true failure rate is p and you review n random actions, the chance you see at least one failure is 1 minus (1 minus p)^n. At n equal to 10 percent of 500 daily actions, you review 50 items. A 5 percent failure rate gives roughly a 92 percent chance of catching at least one failure that day. A 1 percent rate gives roughly 39 percent. A 0.2 percent rate gives roughly 9 percent. A 10 percent sample on modest daily volume is a fair detector of widespread breakage and a poor detector of rare, serious breakage. Rare and serious belongs in full review, not sampling.

For a population proportion, the required sample size at a chosen confidence level and margin of error is n equal to z squared times p times (1 minus p) over the margin of error squared, rounded up as shown in this worked example. A statistics text notes the same tradeoff directly: a smaller sample is cheaper and less accurate in this chapter on sample size. At 95 percent confidence, z is 1.96, and assume p equals 0.5 until you have a baseline, because that maximizes the required size.

Run the numbers. To estimate a failure rate within plus or minus 5 percentage points at 95 percent confidence with no prior estimate, you need 385 reviewed actions. Within plus or minus 3 points, roughly 1,067. That sets your cadence: at 200 actions a day and a 10 percent sample, 385 reviews is a two to three week rolling window, not a daily check.

import math

def reviews_needed(confidence_z=1.96, margin=0.05, assumed_rate=0.5):
    n = (confidence_z ** 2) * assumed_rate * (1 - assumed_rate) / (margin ** 2)
    return math.ceil(n)

def chance_of_seeing_a_failure(p, n):
    return 1 - (1 - p) ** n

print(reviews_needed(margin=0.05))   # 385
print(reviews_needed(margin=0.03))   # 1067
print(round(chance_of_seeing_a_failure(0.01, 50), 2))  # 0.39

The decision rule: for tier 1, sample whichever is larger, 10 percent of daily volume or the number that gives a 5 point margin across your review cadence. For tier 2, target a 3 point margin. For tier 3 and above, review everything, then sample the reviews to check reviewer quality.

Weighing reviewer cost against failure cost

A sampling policy is an economic decision, so write it as one. Compare the daily cost of reviewing against the daily expected cost of the failures review would catch.

Worked example. A tier 2 task runs 1,000 actions a day. A reviewer handles 60 items an hour at about 40 dollars an hour loaded, so a review costs about 0.67 dollars. Suppose one bad output costs 300 dollars to fix and the failure rate is 3 percent: 30 failures a day, 9,000 dollars of expected damage. Full review costs about 667 dollars a day and catches most of it, but only if reviewers read carefully. A 20 percent sample costs about 133 dollars, about 200 reviews, enough to estimate the rate within a couple of points and catch any failure mode occurring in more than roughly 1.5 percent of actions. Sampling wins by a factor of seven. Change the failure cost to 5,000 dollars and full review is trivially worth it, with dual approval for the worst subset cheaper than one incident.

The rule that falls out: automate when the expected cost of caught failures exceeds review cost by the margin you need; review everything when a single failure's cost exceeds a week of review cost. In between, sample and watch the trend.

This is where the approval log earns its keep. MLflow's review queues describe the practical version: capture each interaction as a trace, route flagged traces into a shared queue, have a human answer a pass or fail question, and accumulate judgments into a dataset of real failure modes that can later train an automated judge in the review queue writeup. Guidance on agent evaluation makes the same point from the other side, stressing that human review and automated evals should share one instrumentation path so the traces you review are the traces your graders see in the Confident AI guide. Sampling is how you generate that labeled data at a defensible cost.

What the reviewer must see, and what the log must keep

A sampling policy fails quietly if the review is thin. A reviewer shown a one-line summary will approve almost everything. The approval should arrive with the proposed action, its arguments, the context that produced it and, for anything with a side effect, the likely blast radius.

The security framing helps. Guardrails for agents are described as enforceable technical boundaries covering what an agent can access, which tools it may run, and when actions should be blocked or escalated, with dynamic authorization evaluating each tool call at the moment of execution per this guardrail overview. Review is one of those boundaries and needs the same rigor as an access rule.

The audit side is where most teams are weakest. An LLM trace tells you what the model said; an authorization record tells you whether the action was permitted, for which agent, on whose behalf, under which policy, with who approved it and when as argued in this audit trail guide. That matters when a reviewer approves a hundred items a day: months later you must reconstruct that a specific person approved a specific action at a specific time. A Dataiku survey of data leaders found that only 5 percent say AI output is traceable 100 percent of the time, a fair warning that the log is usually thinner than the team believes per the Dataiku governance writeup.

FieldWhy it exists
Agent identity and task typeTells you which tier rule applied
Human principal or delegation chainAnswers "on whose authority"
Tool, arguments and target resourceShows what actually happened
Policy version and review modeProves the rule in force at that moment
Decision, reviewer and timestampThe approval record itself
Outcome of the side effectSeparates "approved" from "worked"
Trace or correlation IDJoins review, logs and audit

If you cannot fill a row for an action, it was not reviewed in any meaningful sense, even if someone clicked approve.

Choosing the implementation pattern

There are a few established ways to pause an agent for a human.

Interrupt and resume pauses the run at a defined point, hands the proposed action and context to a reviewer, and continues after a decision. It is the strongest control and the easiest to explain to an auditor, and it is what frameworks expose as approval-required tools through approval wrappers or per-tool interrupt configuration in Deep Agents. The cost is latency and state management, since a paused run must be persisted and resumed.

Human as a tool exposes the approval as a call the agent makes, so the agent decides when to ask. It is flexible for demos, but the agent's judgment becomes part of the control, a weak place to put it. Early discussion in the Pydantic AI project made this point: prompting inside a tool call works when you are happy for the run to hang, while returning structured data for a human to confirm before executing is more durable as discussed in this issue thread.

Exception-only review lets mature, low-risk workflows run and routes only flagged items to a person, batched so reviewers see many small items at once. It is the right default for tier 1 and tier 2 once you have a baseline, and it keeps the human step from becoming a bottleneck, since delays usually come from routing and missing context rather than the review itself per the StackAI guide.

Fallback escalation routes to a person when confidence is low or a rule fires, the natural companion to sampling: the sample is baseline measurement, escalation is the safety net.

A production build uses at least two. Approval gates on tier 3 and 4, exception-only review with sampling on tier 1 and 2, and a shared review queue so human judgments feed back into evaluation. If agents run across several providers, logging and routing are easier when calls come through one endpoint; Quanta Inference puts text, image, audio and embedding models behind one OpenAI-compatible key, keeping the trace format consistent whichever model produced the action.

Operating the policy

A sampling policy is only real if it has a cadence and a trigger to change.

Weekly: read the sample, record the observed failure rate and review count, compare with last week. Check approval time too: reviewers averaging two seconds per item are clicking, not reviewing.

Monthly: re-check tier assignments. A task whose volume tripled, whose scope widened, or whose failure rate rose by more than a point should be re-tiered, usually upward. A task at or below its target rate for several consecutive months with no missed failures in the sample can move down one tier, with the decision recorded.

On any incident: an incident from an auto-approved action is an immediate downgrade until you can explain why the sample missed it. An incident a reviewer approved is a signal to improve the evidence pack, not necessarily the sample rate.

Writing this down prevents two failure modes: review theater, where everything is "reviewed" and nothing is checked, and silent autonomy, where the review mode changed one config commit at a time and nobody can say when. Both show up in the same place: the ratio of logged actions to reviewed actions, by task type, over time. If that ratio moves without a recorded decision, the policy is fiction.

If you would rather have someone run this with you than design it from scratch, the Quanta team builds and reviews agent systems and hands back working software; describe the workflow and scope on the main Quanta page and a specialist picks it up.

FAQ

FAQ

How do I choose between full review and sampling for a task I am unsure about?

Ask whether one bad output is cheap to reverse. If it is, and the action runs at meaningful volume, sample it and let the observed rate tell you whether the agent is ready. If it is not cheap to reverse, review every action and add sampling only to check the reviewers.

Is a 10 percent sample enough to trust an agent?

It depends on the failure rate you worry about and the volume. At 50 reviewed actions, a 10 percent sample has roughly a 39 percent chance of seeing at least one failure if the true rate is 1 percent, and roughly 9 percent if the rate is 0.2 percent. It detects widespread breakage well and rare serious problems poorly, which is why the latter belongs in full review.

How many reviews do I need to measure a failure rate accurately?

To estimate a rate within plus or minus 5 percentage points at 95 percent confidence with no prior estimate, you need 385 reviews; within plus or minus 3 points, about 1,067. That is a rolling window, not a daily quota. Work out how many reviews per day your volume supports and set the sample to fill the window over a defined cadence.

What should happen when a reviewer rejects an action?

Log the rejection with the same trace ID as the original call, so the action, the proposed arguments and the human decision stay joined. The rejected case is the most valuable item in the queue: a labeled failure you can use to build an automated judge, and the evidence you need when someone asks why the agent is or is not trusted for that task.

When can I move a task to auto-approve?

After a documented period at or below your target failure rate, with no missed failures in the sample and a stable scope, and with the downgrade recorded as a decision rather than applied quietly. Pair it with a trigger that reverses the decision automatically if volume or scope changes, and keep logging traces so the exit ramp works in both directions.

Sources

Sources

  1. Using function tools with human in the loop approvals - Microsoft Learn
  2. Human-in-the-loop - Docs by LangChain
  3. Agentic AI Guardrails: What They Are and How to Implement Them - Aembit
  4. AI Guardrails: A Guide to Responsible AI - Salesforce
  5. Human-in-the-Loop AI Agents: How to Design Approval ...
  6. Determining a Sample Size for a Confidence Interval ...
  7. 7.5 Calculating the Sample Size for a Confidence Interval
  8. Review Queues: The Human Step Towards Better AI - MLflow
  9. AI Agent Evaluation: Metrics, Traces, Human Review, and ...
  10. Guardrails for AI Agents: Types, Benefits & How to Implement
  11. AI Agent Audit Trail: Proving What an Agent Did and Why
  12. Human-in-the-loop AI agents: design patterns for governance
  13. Interrupt before making a tool call (human in the loop) #642 - GitHub
About the author

About the author

Antonio Evans
Antonio Evans

Antonio Evans is the founder of Quanta Intelligence and a fractional CTO who builds HIPAA-ready AI systems for health and life-science companies. Before that he was technical co-founder of FriendsEAT for twenty years, CEO of Socialdraft, and a data engineer at IBM. Antonio lives with his dog Santino in Lisbon, Portugal.

All articles