AI agents

Sample Rates by Risk Tier: Proving the Audit Was Met

Antonio Evans8 min read

A clean side-view diagram on a pale grid.
Key points

Key points

  1. 1Set a sample rate per risk tier: every action for irreversible or high-impact steps, one in ten for medium-risk reads and writes, one in a hundred for high-volume low-risk tool calls.
  2. 2Log a fixed set of fields (action ID, risk tier, sample rate, decision, timestamp, reviewer, evidence link) for every sampled action so coverage is provable, not asserted.
  3. 3Reconcile logged samples against the expected count (actions times rate) each period; a material shortfall means the audit was not met, regardless of how the samples looked.
  4. 4When a sample fails, raise that action or its tier to the next stricter rate automatically and hold it there until a defined clean run passes.

Why one rate for every action fails

A single review gate in front of every agent action looks safe and behaves badly. Reviewers who face a queue of mostly-benign items stop reading: in a study of 1,053 paid testers, human review caught 13.6% of harmful actions while an automated classifier caught 89%, and Claude Code users approve 93% of permission prompts as reported by Beri. A second study found reviewers approved AI recommendations 19 percentage points more often when given explanations, so better reasoning from the agent made oversight worse, not better per Tianpan's summary of the Harvard Business School work. In a day-in-the-life agent test, human approval blocked 59.6% of overreach, model screeners still let 46.1% through, and user-authored standing rules blocked only 39.6% per RockCyber's reading of the preprint.

The lesson is not that human review is worthless. It is that review capacity is a scarce resource and should be pointed at the actions where a wrong decision is expensive. Audit sampling has handled this tradeoff for decades: testing less than 100% of a population is standard practice, justified by the relative cost of full review against the consequence of an error PCAOB AS 2315. Auditors choose statistical or nonstatistical designs, and statistical methods let them state sampling risk at a confidence level rather than assert it Trullion's guide to audit sampling.

Your agent fleet is a population of transactions. Tier it, rate it, and prove the sample ran.

The three-tier rate table

The core decision is which tier each action belongs to. Sort by two questions: can this be undone, and what is the blast radius if it goes wrong?

TierTest for membershipSample rateExample actions
HighIrreversible, moves money, leaves the organization, changes accessEvery action (100%)Payment or refund, delete record, send external email, grant or revoke permission
MediumReversible but visible or state-changingOne in tenWrite to a record, update a ticket status, post to an internal channel, draft a customer reply
LowRead-only or trivially reversible, high volumeOne in a hundredSearch, fetch page, read file, look up order status, list directory

Two rules keep the tiers honest. First, tier by the action's worst realistic outcome, not its average one: a read that touches regulated personal data is medium at least. Second, never let the agent choose its own tier. The tier is a property of the tool, set in the tool definition and checked by the runtime, the same way approval requirements are attached to a tool rather than inferred by the model Microsoft's agent framework docs. Cloudflare's human-in-the-loop patterns make the same point: an approval gate belongs to a connector or workflow layer, not to the model's judgment Cloudflare Agents docs.

A useful sanity check for a proposed rate: at your current volume, does the tier produce a queue a reviewer can actually finish? If a low-risk tool fires 40,000 calls a week, one in a hundred gives 400 samples, roughly 11 hours of review at 90 seconds each by Beri's timing assumption. If that is too much, cut the tier's rate or narrow what counts as low risk; do not quietly skip samples.

The log fields that prove coverage

A review that happened in a Slack thread leaves no evidence. Each sampled action needs a record with the same fields every time, written by the system rather than the reviewer. The fields below are the minimum to reconstruct who approved what, under which rule, and why.

FieldTypePurpose
action_idstring, uniqueJoins the sample to the originating tool call and its arguments
risk_tierenum (high, medium, low)Shows the tier the action was classified under at decision time
sample_ratenumber or "all"Records the rate applied, so a later rate change does not rewrite history
decisionenum (approved, rejected, escalated)The outcome that let or blocked execution
decided_atISO 8601 UTCTimestamp of the decision, not of the queue entry
reviewerstring identifierNamed human or, for escalations, the receiving role
evidence_linkURLPoints to the captured input, output and reviewer note

Model these on the approval pattern Temporal documents, which carries approver, decision, comments and timestamp as structured data in a signal rather than a bare boolean Temporal approval pattern. Nylas's CLI audit log shows the same shape in a different context: eight structured fields including timestamp, source, status and correlation ID, with sensitive values redacted before writing Nylas audit guide. Redaction matters for your evidence link too: store the reviewer's note and the action summary, not the full payload if it carries personal data.

Write the sample record from the runtime, not from the reviewer's tooling. A reviewer ticking a box in a separate spreadsheet is a second source of truth that will drift.

Reconciling samples against the expected count

Proving the audit was met is arithmetic plus a tolerance you set in advance. For each action and period:

  1. Count executed actions from the runtime's own logs, per action and tier.
  2. Multiply by the sample rate to get the expected sample count. Round half up; state the rounding rule.
  3. Count sample records that carry all seven fields and a non-empty decision.
  4. Compare. Coverage is logged samples divided by expected samples.

A worked example makes the tolerance question concrete. Suppose a low-risk search tool ran 47,300 times in a week at one in a hundred. Expected samples: 473. Logged with a decision: 451. Coverage: 95.3%. Is that met? If your threshold is 98%, no, and the shortfall is 22 samples you cannot account for. Do not estimate them from the period before. Find out whether the sampling function failed, whether decisions were logged without a reviewer, or whether some calls bypassed the runtime entirely.

Use a stored property rather than an ad hoc guess to pick the sampling mechanism, so the expected count is genuinely deterministic. For the low tier you can sample by hash:

import hashlib

def should_sample(action_id: str, rate: int) -> bool:
    """rate=100 means one in a hundred. Deterministic, independent of order."""
    bucket = int(hashlib.sha256(action_id.encode()).hexdigest(), 16) % rate
    return bucket == 0

assert should_sample("act_9f2c", 100) in (True, False)

The same input always lands in the same bucket, so reruns and retries do not inflate the count, and you can recompute the expected sample set from the action log alone. That last property is the one auditors actually want: the ability to re-perform the selection PCAOB AS 2315.

Tolerance should scale with tier. A reasonable starting point is zero tolerance on high (every action has a record, no exceptions) and a small tolerance on medium and low, documented before the period starts. An unreconciled shortfall is a finding even when every sample you did review passed.

Raising the rate when a sample fails

When a sampled action shows a real problem (an unauthorized deletion, a refund outside policy, a customer email with wrong data), the rate for that action, and for its tier if the cause is systemic, moves up one step: low to medium, medium to high, high stays at every action and gains a second reviewer or a hard block. The escalation is automatic because manual escalation is exactly the step that gets skipped during a busy week.

Hold the stricter rate until a defined clean run passes. Define it before you need it, in numbers: for example, 200 consecutive actions or 30 days, whichever is longer, with zero failed samples and no open findings. Then return to the original rate, and record the return in the same log with a reason. The reversibility framing behind this is the same one that decides what happens when an approval times out: internal, reversible actions can default to proceeding, but actions that leave the system or move money should hold and escalate, never auto-approve on silence Orbiresearch on approval timeouts.

A raised rate is a cost you accept, not a punishment. A tool at one in a hundred that fails twice climbs to one in ten and then 100%, which is how Beri's piece recommends treating gates: put expensive human attention on the irreversible few and audit the rest by sample with planted errors to keep reviewers awake Beri. Planting a known-bad action into the medium queue at a low frequency tests the reviewers as well as the agents.

Running the sampling mindfully

A rate table without reviewer discipline reproduces the rubber stamp at a smaller scale. Three practices help.

Keep the queue short and mixed. Review depth drops as queue length grows and attention decays after long sessions; most teams do better with short, frequent review blocks than long sittings CodeAnt on review fatigue. If the 90th percentile wait for a medium-tier decision exceeds your timeout, the timeout fires on normal days and people learn to ignore it Orbiresearch.

Make rejections cheap and countable. Track rejection rate per tier and per reviewer. A reviewer at zero rejections over hundreds of samples is either lucky or not reading; a reviewer whose median decision time is a few seconds probably is not reading either, which Orbiresearch flags as a different and more serious problem than slowness.

Sample the sample. Once a period, pull the evidence link on a handful of approved records and check that the reviewer's note actually addresses the action. This is the same logic as a code review checklist: a repeatable list of what to check reduces cognitive load and catches omissions that open-ended scanning misses CodeAnt.

If your agents call tools across many models and providers, one place to land the runtime that records the fields above is a single inference endpoint; Quanta Inference (https://quantaintelligence.ai/inference) routes text, image, video, audio and embedding models through one OpenAI-compatible key, which keeps the action log in one schema.

A checklist to ship the policy

Before the policy goes live, each item should have an owner and a written answer.

  • Every tool in production has a tier, with a one-line reason.
  • The tier is enforced by the runtime, not suggested in the prompt.
  • Each tier maps to a rate, and the rate is stored with each sample record.
  • The seven log fields are mandatory; a record missing one is not counted as coverage.
  • The selection function is deterministic and re-performable from the action log.
  • Coverage thresholds and rounding rules are documented before the period opens.
  • The escalation ladder (low to medium to high) and the clean-run definition are written down.
  • Timeouts per tier are chosen, with a default action that never auto-approves money movement or external sends.

The first month will surface the mismatches: actions filed under the wrong tier, tools whose volume makes their rate unaffordable, reviewers whose queues exceed their time. Fix the table, not the log. If you need a specialist to build the runtime, the tier enforcement and the reconciliation report with your team, Quanta's experts (https://quantaintelligence.ai/agents) work as a line of business and hand back finished deliverables rather than a design document.

FAQ

FAQ

What is a sample rate in an audit sense?

It is the proportion of a population of actions you review, chosen so the reviewed subset gives a defensible basis for conclusions about the whole population. Professional standards define audit sampling as applying procedures to less than 100% of items and justify that with the cost of full review against the consequence of an error PCAOB AS 2315. In agent operations the population is tool calls, so the rate is actions reviewed divided by actions executed.

Can I use one in ten for everything instead of tiers?

You can, but the tiering exists to protect reviewer attention. At high volume, a flat rate floods the queue with benign items and review quality drops, which studies of approval behavior document as automation bias and decision fatigue Tianpan. Tiering sends the expensive attention to irreversible actions and audits the rest cheaply.

What counts as a failed sample?

Any sampled action where the reviewer finds the action should not have run as it did: wrong scope, wrong recipient, policy violation, or missing authorization. Record the decision as rejected or escalated and write the finding against the action. A failed sample triggers the rate increase; a slow decision does not.

How long do I keep the sample records?

Long enough to cover your audit and regulatory cycles, which commonly means at least 90 days for SOC 2-style evidence Nylas. Keep the summary fields and the evidence link for the full period, and keep the underlying payload only as long as your data policy allows, since the link may point at personal data.

Does sampling replace approval gates for risky actions?

No. Sampling is for the tiers you deliberately leave ungated. Irreversible or external actions should stay gated at every action, because human approval is the only control that stops the mistake before it happens Permit.io. Sampling proves you checked the rest; it does not stand in for the gate on the few.

Sources

Sources

  1. Human-in-the-Loop for AI Agents: Most Approval Gates ...
  2. The HITL Rubber Stamp Problem: Why Human-in-the-Loop ...
  3. Human in the Loop Is a Rubber Stamp. Its Replacements Are ...
  4. AS 2315: Audit Sampling
  5. Audit Sampling: Methods, Risk, and the Case for 100%
  6. Using function tools with human in the loop approvals
  7. Human-in-the-loop patterns · Cloudflare Agents docs
  8. Approval Pattern | Temporal Documentation
  9. Audit AI Agent Activity (Claude, Copilot, MCP)
  10. Approval Timeouts for AI Agents: Defaults by Reversibility
  11. 7 Ways to Reduce Code Review Fatigue and Improve ...
  12. Human in the Loop AI Agents: Approval Workflows That Work
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