How to Verify Agent Actions Without Killing the Speed That Makes Agents Valuable

Verification is not the enemy of autonomy. Poorly designed verification is. The right design adds a verification layer that runs fast, runs in parallel, and escalates precisely - not one that halts every action for manual review.

B

Balagei G Nagarajan

4 MIN READ


LLMs can't Self-Correct (arXiv:2310.01798, 2023) showed that adding a second LLM call for self-verification adds cost without adding meaningful error detection. The implication isn't that verification should be removed - it's that the right kind of verification (deterministic, external, fast) can provide strong error detection with minimal latency cost. Teams that conflate "verification" with "slow manual review" make an architectural error, not a product tradeoff.
Verification autonomy balance hero
Prior-step verification catches up, or triggers a correction, before step N+2 needs step N's output.
— from “How to Verify Agent Actions Without Killing the Speed That Makes Agents Valuable”

Key facts.

  • LLMs-can't-Self-Correct (arXiv:2310.01798, 2023): same-model self-verification adds cost without meaningful error detection - the wrong kind of verification is expensive and unreliable.
  • Deterministic rule checks add 5-50ms of latency per action - invisible in the latency budget of any enterprise workflow.
  • External ground truth lookups add 50-200ms - visible but acceptable in most asynchronous workflows and in synchronous workflows when cached.
  • The autonomy-killing verification design is the synchronous, blocking manual review for every action. The autonomy-preserving design is fast deterministic checks with a narrow escalation path that activates only on confirmed risk signals.

Three tiers of verification by speed and consequence

Self-checks add cost, not catches, as a class; a better model inherits the gap. (arXiv:2310.01798)

Tier 1: Instant deterministic checks (5-50ms). These run synchronously on every action and never block. Schema validation, range checks, policy rule evaluation, format conformance. These checks don't require model inference, network calls, or human judgment. they're the first line of defense and catch the majority of well-defined failure classes in milliseconds. They don't slow the agent.

Tier 2: Fast external lookups (50-200ms). Synchronous for high-confidence verification, asynchronous for lower-priority checks. CRM lookup to confirm an account ID, pricing query to confirm a quoted price, permissions check to confirm an authorized action. Network calls, but cacheable. Perceptible but acceptable in synchronous flows; invisible in async.

Tier 3: Model-based or human review (seconds to minutes). These activate only when tier 1 and tier 2 checks pass a risk signal that requires judgment: a tier-1 check flags a boundary case, a tier-2 lookup returns an ambiguous result, or a confidence threshold isn't met. This tier is the escalation path, not the default path. When designed correctly, it activates for a small minority of actions - not for every action.

Parallelizing verification with execution

Verification latency disappears when it runs in parallel with the next execution step. In a multi-step pipeline, verification of step N often runs concurrently with preparation for step N+1. The pipeline keeps moving. Prior-step verification catches up, or triggers a correction, before step N+2 needs step N's output.

This requires a non-blocking verification architecture: verification results are delivered as events, not as synchronous return values. The pipeline subscribes to verification events and responds when they arrive. Clear signal: proceed. Risk signal: escalate. The architecture is similar to circuit breakers in distributed systems: fast-path execution with asynchronous health signals that can interrupt the path when needed.

# Non-blocking parallel verification architecture
async def agent_pipeline(steps):
 verification_tasks = []

for i, step in enumerate(steps):

Execute step without waiting for prior verification

result = await step.execute()

Launch verification of this step asynchronously

v_task = asyncio.create_task(verify_step(step, result)) verification_tasks.append((i, v_task))

Check if any prior verification has completed with a signal

for idx, task in verification_tasks: if task.done() and not task.result().ok: await handle_verification_failure(idx, task.result()) return # halt pipeline at failure

Await all remaining verifications after last step

await asyncio.gather(*[t for _, t in verification_tasks])

Verification tier speed vs coverage diagram

Verification design comparison

DesignLatencyAutonomy impactError detection
No verification0msNone0%
Synchronous blocking reviewMinutesKills autonomyHigh (human judgment)
Same-model self-check500ms-2sModerate slowdownLow (correlated errors)
Tiered deterministic + async escalation5-50ms (sync), parallel asyncMinimalHigh (for rule-covered classes)

The Pattern Intelligence Layer specifies which verification tier applies to each action class in a pattern. Low-consequence, high-frequency actions get Tier 1 checks only. High-consequence, low-frequency actions get all three tiers. Routine 90% of actions: autonomy at speed. The 10% that require it: precise, fast intervention. Both, from the same architecture. Autonomy and verification are complementary when the design is right.

Frequently asked questions


Share this post

Join the discussion

Have a take, a war story, or a question? Sign in with GitHub to comment and react. Comments are powered by GitHub Discussions, ad-free and yours to moderate.

Continue Reading

Find where your agent breaks, before you build it

Faultmap maps where your agent will fail from the goal and your data, then hands you the first test suite it has to pass.