How to Add a Critic Step to Your Agent Loop
A second model reviewing the first catches errors a single pass never will. Here's how an agent critic loop works, where it pays off, and the trap that makes most critics useless.
def critic_loop(task, generate, criticize, max_rounds=3):
draft = generate(task)
for _ in range(max_rounds):
verdict = criticize(task, draft)
if verdict.approved:
return draft
draft = generate(task, feedback=verdict.objections)
return draft # best effort if critic never fully approvesA model reviewing its own work catches mistakes it can't catch while producing that work. That sounds like a contradiction until you've watched it happen: give an agent a second pass whose only job is to find fault, and it will flag errors the generating pass sailed right past. An agent critic loop is that second pass made structural — a reviewer wired into the loop, not bolted on as an afterthought. And it's one of the highest-return additions you can make to an agent that has to be right, not just plausible.
The idea is simple. After the agent produces a candidate answer, a critic step evaluates it against explicit criteria and either approves it or sends it back with specific objections. The generator revises; the critic reviews again. That back-and-forth catches the confident-but-wrong output that a single pass ships without hesitation.
What Is an Agent Critic Loop?
An agent critic loop separates producing from judging. The generator's job is to make a good attempt; the critic's job is to find everything wrong with it. Splitting these into two roles — even two calls to the same model — works because judging and producing pull in different directions, and a model asked to do both at once tends to do neither sharply.
[object Object], ,[object Object],(,[object Object],):
draft = generate(task)
,[object Object], _ ,[object Object], ,[object Object],(max_rounds):
verdict = criticize(task, draft)
,[object Object], verdict.approved:
,[object Object], draft
draft = generate(task, feedback=verdict.objections)
,[object Object], draft ,[object Object],What this does: generates a draft, runs a dedicated critic that either approves or returns specific objections, and revises against those objections — looping until the critic signs off or the round budget runs out.
The critic isn't a vague "is this good?" check. It's a targeted reviewer with a rubric: does the answer meet each requirement, cite real sources, avoid the known failure modes? Specificity is the whole game.
Why It Matters
Single-pass agents fail silently on exactly the tasks where failure costs most. A model producing a legal summary, a financial calculation, or a code change is generating fluent, confident output whether or not it's correct — and fluency is not accuracy. The critic loop adds an adversarial check precisely where confidence and correctness diverge.
There's a structural reason it works. When a model generates, it commits to a path and its attention is on continuing that path coherently. A fresh critic call starts cold, with no investment in the draft, free to look for what's wrong rather than what's next. That change of stance — from author to adversary — is what surfaces errors the author was blind to.
The asymmetry is the point. An author and a proofreader reading the same page catch different things, and not because one is smarter — because their jobs point their attention in opposite directions. The author's attention flows forward, toward the next sentence; the proofreader's flows sideways, across what's already written, hunting for the seam. A generate-then-critique loop manufactures that second stance on demand, which is why it catches the specific errors a single confident pass never notices about itself.
⚡ Pro tip: Run the critic in a fresh context, not appended to the generator's transcript. If the critic sees all the generator's reasoning, it inherits the generator's blind spots and tends to agree with the path it just watched being built. A cold critic that sees only task and draft judges far more independently.
⚡ Pro tip: Give the critic a different, sharper persona than the generator. "You are a skeptical senior reviewer whose job is to reject anything that isn't airtight" produces far better objections than a neutral "check this." The critic should want to find problems.
Building an Effective Critic
The critic's rubric is where the loop lives or dies. A vague critic rubber-stamps; a specific one catches real faults.
The difference is concreteness. "Is this good?" invites the model to pattern-match on whether the draft looks like a competent answer — and confident, fluent, wrong answers look exactly like competent ones. A rubric that asks "is every number in the summary traceable to a line item?" forces an actual check the fluency can't fake. Every item you can turn from a judgment call into a verifiable check is an item the critic will catch reliably instead of waving through.
CRITIC_PROMPT = (
,[object Object],
,[object Object],
,[object Object],
,[object Object],
,[object Object],
,[object Object],
,[object Object],
)What this does: gives the critic a concrete, itemized rubric and forces it to quote specific problems rather than issue vague impressions — so its objections are actionable and its approvals are earned.
The "default to rejection when unsure" line matters more than it looks. A critic biased toward approval is worse than no critic, because it launders bad output with a stamp of review. You want a critic that errs toward sending work back.
⚡ Pro tip: Have the critic output its objections as a numbered list tied to specific rubric items, then feed that exact list back to the generator. A generator revising against "objection 3: the total doesn't match the line items" fixes precisely that; one revising against "the critic had concerns" flails. Structured objections make revisions surgical.
⚠️ Common mistake: Using the critic to rewrite instead of to review. The moment your critic starts producing the fix instead of describing what's wrong, you've collapsed the two roles back into one and lost the independent-judgment benefit. Keep the critic's output to objections only; let the generator own every revision. A critic that writes is just a second generator wearing a badge.
When a Critic Loop Pays Off (and When It Doesn't)
The critic loop is not free — it at least doubles your model calls per task. It earns that cost on high-stakes, error-prone work: anything where a wrong answer is expensive and errors are the kind a second look catches.
It does not pay off on simple, low-stakes tasks where the generator is already reliable — there, the critic just adds latency and cost to approve work that was fine. And it fails on tasks where the critic can't actually verify correctness: if neither pass can tell whether the answer is right, a second opinion adds confidence without adding accuracy, which is worse than useless.
The roles that benefit most share a shape: high cost of error, and errors a second read can catch. A compliance officer's policy-check agent runs a critic that hunts for unaddressed regulations — a missed clause is expensive and catchable. A backend engineer's code agent runs a critic focused on edge cases and injection risks the generator skipped while making the happy path work. A grant writer's proposal agent runs a critic against the funder's exact criteria, catching the requirement the draft quietly ignored. In each, the critic's cost is trivial next to the cost of shipping the miss.
⚡ Pro tip: Measure the critic's catch rate before trusting it. Feed it drafts you know are flawed and see how many it rejects. A critic that approves known-bad drafts is decorative — fix its rubric until it reliably catches seeded errors, then deploy it.
Common Mistakes
Beyond critics that rewrite and critics that rubber-stamp, two patterns recur. Teams run too many critic rounds, letting the loop bounce a draft five times when two rounds capture nearly all the benefit and further rounds mostly reshuffle wording. And teams use one generic critic for every task when the failure modes differ — a code critic should check for edge cases and injection, a summary critic should check for unsupported claims, and one rubric can't do both well. A generic critic degrades to a generic "looks fine," which is the rubber stamp you were trying to avoid. Specialize the rubric to the failure modes that actually threaten each task, and the critic earns its keep; leave it generic and it becomes theater.
Conclusion
An agent critic loop turns a single confident guess into a reviewed answer by splitting production from judgment. Give the critic a sharp persona, a specific rubric, and a bias toward rejection; keep it reviewing rather than rewriting; and spend it only where a wrong answer actually costs you. Done right, it catches the class of errors that a single pass ships with a straight face. That class is larger than most teams expect until they instrument it — the first week of catch-rate data usually reframes the critic from "nice to have" to "how did we ship without this."
The critic prompt and the rubric checks become reusable across every agent that needs to be right. I keep mine saved and versioned in PromptABCD — the reviewer persona, the itemized rubric, the reject-when-unsure default — so a new agent inherits a critic that already catches seeded errors instead of a rubber stamp that approves whatever it's shown.
Continue Reading
Save the prompts from this post
PromptABCD is a free prompt manager. Paste, organize, and reuse your best AI prompts — no more hunting through chat history.
