The Verifier in the Loop: Designing an Oracle Your Agent Can Iterate Against
Coding agents work as well as they do because compilers exist. In other domains the oracle is something you build — and most tasks have one hiding in them if you spend ten minutes looking.
The most reliable agent pattern is also the least glamorous: let the agent attempt something, run a check that returns an objective verdict, and let it try again. Coding agents work as well as they do largely because compilers and test suites exist — an unambiguous signal, available on demand, that the model cannot argue with.
The generalizable insight is that this signal is a design artifact. Most domains don't come with one, and building it is usually a better investment than improving the prompt.
What makes a usable oracle
Objective. Same input, same verdict, every time. A model judging output is not an oracle; it's a second opinion with the same blind spots.
Fast. It runs on every iteration, so seconds matter. An oracle taking minutes limits you to two or three attempts before the budget is gone.
Specific. "Failed" tells the agent nothing. "Field currency missing from record 12" tells it exactly what to change, and the difference in iteration efficiency is large.
Cheap. Ideally free — ordinary code, no model call. If checking costs as much as generating, you've doubled the price of every attempt.
What counts as an oracle in non-code domains
The pattern is underused because people look for a compiler and don't find one. There are usually several available:
- Schema validation. Any structured output. Free, instant, and specific.
- Arithmetic reconciliation. Totals that must match, balances that must net to zero, counts that must line up between input and output. Excellent for anything financial or data-related.
- Cross-source consistency. The extracted value must equal what's in the system of record. Catches hallucinated fields precisely.
- Quoted-span verification. Every claim must include a verbatim quote from a source, checked as a literal substring. This is the strongest available oracle for summarization and research, and it's just string matching.
- Constraint satisfaction. A schedule with no overlaps, an allocation that doesn't exceed a budget, a plan whose steps respect declared dependencies.
- Round-trip identity. Transform, invert, compare to the original. Catches lossy transformations in translation, format conversion, and normalization.
- Idempotence. Apply twice, expect the same result. Catches a surprising number of over-eager transformations.
Most tasks that look unverifiable have one of these hiding in them. → It's worth ten minutes of deliberate searching before concluding a domain has no oracle.
Wiring it in
Two placements, and the second is much better:
As a tool the agent calls. validate_output(draft) returns pass or a list of violations. The agent chooses when to check. Simple, and the agent sometimes skips it.
As a gate in the loop. The loop runs the verifier on every candidate output and only accepts a passing one:
for attempt in range(MAX_ATTEMPTS):
draft = agent.produce()
result = verify(draft) # ordinary code
if result.ok:
return draft
agent.observe(result.violations) # specific, actionable
return escalate(draft, result.violations) # never ship an unverified result
The loop version is stronger because passing is no longer optional. ✅ Note the final line: exhausting attempts must escalate, not return the last draft. An unverified result presented as finished is exactly what the oracle existed to prevent.
The failure modes
Over-fitting to the oracle. The agent learns to satisfy the check rather than the intent — output that validates and is useless, tests that pass because they assert nothing. ⚠️ The oracle must check properties you actually care about, not proxies. If it's cheap to satisfy trivially, it will be.
Slow convergence. If violations aren't specific enough, each attempt is a guess. Watch attempts-to-pass; anything consistently above two or three means the feedback needs to be more precise, not that the model needs to be bigger.
False confidence. Passing the oracle means passing the oracle. A schema-valid record can hold wrong values. Be explicit about what the check covers, and don't let a green verdict substitute for the evaluation you'd otherwise do.
🔍 Where to build one first
Look for the step where you most distrust the output and where wrongness is discoverable in principle. That's where an oracle pays.
If the untrusted step's correctness genuinely can't be established by any mechanical means, that's important information about the task — it likely needs a human in the loop rather than a better prompt, and knowing that early is worth a lot.
The takeaway
An agent iterating against an objective check is the most reliable pattern available, and the check is something you build rather than something you find. Schema validation, arithmetic reconciliation, quoted-span verification, round-trip identity — most domains have one hiding in them. Make the verifier fast, specific, and free; gate the loop on it; escalate rather than shipping when attempts run out. That investment returns more than any equivalent time spent on prompts.