Sub-agent verification loops
Learn the Implement-Review-Resolve pattern where fresh-context reviewer agents catch errors that implementing agents miss, producing 2-3x quality improvement.
TL;DR
- A sub-agent verification loop spawns a fresh reviewer agent (zero prior context) to audit the output of an implementing agent, then spawns a resolver agent to fix any issues found. The chain is Implement, Review, Resolve.
- Fresh context is the key mechanism. The reviewer never saw the 200K tokens of reasoning, dead ends, and design decisions that the implementer accumulated. It evaluates the output objectively, without sunk-cost bias.
- One verification round with Sonnet 4.6 costs $0.10-$0.20 and catches 2-3x more issues than self-reflection. With Opus 4.6, $0.50-$1.00 for stronger analytical coverage.
- The reviewer produces a structured verdict (PASS, ISSUES_FOUND, or CRITICAL) with severity-tagged issues. The resolver fixes critical and major issues, can decline suggestions that don't apply, and outputs the corrected artifact.
- For high-stakes code (auth, payments, migrations), run a second review on the resolver's output. Max two loops. If the code isn't clean after two cycles, the problem is architectural.
- Limitation: doubles latency and token cost for every reviewed artifact. Skip this pattern for trivial changes (config tweaks, log additions, typo fixes).
The Problem It Solves
Your coding agent just spent 200,000 tokens building a payment processing module. It explored three different approaches, hit dead ends with two of them, debugged a tricky race condition, and finally produced working code. You ask it: "Can you review this for issues?" It responds: "The implementation looks clean and handles all edge cases correctly."
It's wrong. There's a SQL injection vulnerability in the merchant lookup, a missing null check on the refund path, and two helper functions that duplicate logic already in the codebase. But the agent can't see these problems because the same attention patterns that produced the code are now evaluating it.
This is the sunk-cost bias problem in agentic systems. When an agent invests significant compute in an approach, it becomes blind to its own mistakes. Asking it to self-review is like asking a developer who spent 8 hours on a feature to objectively review their own pull request. They'll defend their decisions unconsciously. The code "looks right" because they remember why they wrote it that way. I've watched this happen dozens of times: the implementing agent confidently declares its output is correct, and a fresh reviewer finds 15+ issues in under 30 seconds.
Self-reflection (same agent, different prompt) catches superficial problems: formatting, naming, obvious logic errors. It misses structural issues, subtle security holes, and unnecessary complexity because the model's internal representations still carry the original reasoning. The fix is simple: give the review to someone who wasn't in the room when the code was written.
What Is It?
Sub-agent verification loops separate implementation from evaluation by spawning a fresh reviewer agent (different context, often a different model) that audits the output the implementer produced. If the reviewer finds issues, a resolver agent receives both the original code and the review feedback, then produces a corrected version.
Think of it as the relationship between an author, an editor, and a copy editor. The author writes the manuscript (implementation). The editor reads only the manuscript, not the author's notebooks or drafts, and flags structural problems, factual errors, and sections that don't work (review). A copy editor then takes both the manuscript and the editor's notes, applying fixes while preserving the author's voice (resolution). The editor catches things the author can't because they approach the text without the baggage of having written it.
The critical detail: the reviewer sees only the output and the original requirements. No tool call logs, no reasoning traces, no explored-and-abandoned approaches. This constraint is the entire mechanism. A reviewer loaded with the implementer's context would inherit its biases.
How It Works
The three-agent chain
The pattern uses three distinct agent roles, each with a specific context window and purpose.
The Implementer builds the artifact. It has full context: the original requirements, access to tools (file system, web search, code execution), and accumulates a long reasoning trace as it works. By the time it produces output, it has 100K-200K tokens of context including dead ends, debugging sessions, and design tradeoffs. This context is valuable for building but toxic for reviewing.
The Reviewer spawns with a clean slate. It receives exactly two inputs: the output artifact and the original requirements. Nothing else. No tool call history, no chain-of-thought reasoning, no information about what approaches the implementer tried and rejected. This forces a genuinely independent evaluation. The reviewer checks five dimensions: correctness, edge cases, simplification, security, and codebase consistency.
The Resolver bridges both perspectives. It receives the original artifact plus the reviewer's full feedback, including severity ratings and suggested fixes. Its job is to produce a corrected version that addresses the review while preserving the implementer's intent. The resolver can also decline suggestions. If the reviewer flagged something that isn't actually a problem (false positive), the resolver provides reasoning for why the suggestion doesn't apply.
I find that the resolver role is what makes this pattern production-viable. Without it, you'd need a human to manually reconcile review feedback with the original code, which defeats the purpose of automation.
The review checklist
The reviewer evaluates across five dimensions, each targeting a different class of error:
| Dimension | What It Catches | Example |
|---|---|---|
| Correctness | Logic errors, wrong behavior relative to requirements | Function returns user count but requirements asked for active user count |
| Edge cases | Inputs and states that break the code | Empty arrays, null values, concurrent access, network timeouts |
| Simplification | Over-engineering, dead code, unnecessary abstractions | A factory pattern wrapping a single class that will never have siblings |
| Security | Injection vectors, auth bypasses, secrets in code | SQL concatenation instead of parameterized queries, API keys in source |
| Consistency | Deviation from surrounding codebase patterns | Using camelCase in a codebase that uses snake_case throughout |
The reviewer produces a structured report, not free-form prose. Each issue gets a severity tag (critical, major, minor, nit), a location, a description of the problem, and a concrete fix showing corrected code.
Verdict classification
The reviewer's output falls into one of three categories, each triggering a different workflow:
PASS: The reviewer found no issues. The artifact ships as-is. This happens roughly 30-40% of the time for well-tuned implementing agents. No resolver step needed.
ISSUES_FOUND: The reviewer found non-critical problems. The resolver receives both the original code and the review feedback, fixes what it can, and outputs a corrected version. This is the most common outcome (50-60% of reviews).
CRITICAL: The reviewer found a security vulnerability, data loss risk, or fundamentally incorrect logic. The system flags this to the user immediately before attempting resolution. The user may want to change the entire approach rather than patch a broken design.
The resolution protocol
The resolver follows a strict protocol for handling each issue in the review:
- Critical and major issues: Fix them. These are non-negotiable. The resolver applies the reviewer's suggested fix or implements its own.
- Minor issues: Fix unless the fix adds complexity disproportionate to the benefit. A missing edge case check in a throwaway script? Probably skip it. A missing edge case check in a payment handler? Fix it.
- Nit-level issues: Ignore unless trivially fixable (a rename, a whitespace adjustment). Nits shouldn't trigger a full revision.
- False positives: The resolver can decline any suggestion with an explanation. "The reviewer flagged this as unused code, but it's called dynamically via reflection. Declining."
For each issue, the resolver outputs either "FIXED: [corrected code]" or "DECLINED: [reasoning]." Then it outputs the complete corrected artifact, not a diff. The orchestrator replaces the original with the corrected version.
Continue Reading with Premium
Unlock this article and every other in-depth system design guide on the platform with NotesFromSDE Premium.