The Reflection Pattern: Agents That Check Their Own Work
The ai agent reflection pattern turns a single guess into a draft-critique-revise cycle. Here's a weak version, why it fails, and the improved version you can copy.
draft = model.chat([{"role": "user", "content": question}]).content
checked = model.chat([
{"role": "user", "content": f"Here's an answer: {draft}. Double-check it and fix any mistakes."},
]).contentPicture this: you're a data engineer at a mid-size retailer, and your new agent writes SQL from plain-English questions. It works in the demo. Then finance runs it, and the agent confidently returns last quarter's revenue off by a factor of a thousand because it summed cents as dollars. Nobody caught it until the board deck was already printed.
The fix isn't a smarter model. It's the ai agent reflection pattern — a loop where the agent reviews its own answer before anyone else has to. Done right, it's the single highest-return change most teams can make. Done wrong, it adds latency and cost while catching nothing. Let's tear down both versions.
Before: The Weak Prompt
Here's the version almost everyone writes first. The agent produces an answer, then you bolt on a vague "double-check your work" instruction and hope.
draft = model.chat([{,[object Object],: ,[object Object],, ,[object Object],: question}]).content
checked = model.chat([
{,[object Object],: ,[object Object],, ,[object Object],: ,[object Object],},
]).contentWhat this does: it asks the model to re-read its own answer with no criteria and no way to say "this is fine" — so it either rubber-stamps the draft or rewrites it for no reason.
On the surface this looks like reflection. It runs a second pass. It uses the word "check." And in a quick test it might even catch an obvious error, which is exactly what makes it dangerous — it produces just enough success to earn your trust.
Why It Fails
The weak version fails for three concrete reasons, and each one shows up in production.
First, there are no criteria. "Double-check it" gives the model nothing to check against. A vague instruction produces a vague review, so the second pass tends to agree with the first. Models are agreeable by default; without explicit standards, reflection collapses into confirmation.
Second, there's no stop condition. The prompt always asks for a fix, so the model always changes something — even a correct answer. A support team at a subscription company shipped a version like this and watched their agent "improve" correct refund amounts into wrong ones roughly one time in twenty, because the revise step had no way to say "leave it alone."
Third, it critiques and rewrites in the same breath. When one call both finds problems and fixes them, you can't see what it found. If the output is wrong, you have no idea whether the critique missed the bug or the rewrite reintroduced it. The two jobs need to be separate so each is inspectable.
There's a subtler fourth problem too: the weak version has no memory of what it already tried. If the first revision doesn't fix things, a naive loop runs the same critique again and often gets the same vague result — or worse, oscillates, where fixing problem A quietly reintroduces problem B, which the next pass fixes by breaking A again. Without tracking what's been attempted, reflection chases its own tail while the token meter keeps running.
You see this most clearly on writing tasks. A content agent asked to "make it more concise" and then "make it more complete" on alternating passes will ping-pong forever, because the two goals pull in opposite directions and nothing in the loop notices the conflict. Reflection needs not just criteria but a sense of when it's done — and when it's stuck and should escalate to a human instead of looping again.
⚠️ Common mistake: Assuming any second pass is reflection. A second call that shares the same blind spot as the first isn't a check — it's the same guess, twice, at double the cost.
After: The Improved AI Agent Reflection Pattern
The strong version separates the two jobs, hands the critique real criteria, and gives it an explicit way to approve.
[object Object], ,[object Object],(,[object Object],):
critique = model.chat([
{,[object Object],: ,[object Object],, ,[object Object],:
,[object Object],
,[object Object],
,[object Object],},
{,[object Object],: ,[object Object],, ,[object Object],:
,[object Object],},
]).content
,[object Object], critique.strip().startswith(,[object Object],):
,[object Object], draft, ,[object Object],
revised = model.chat([
{,[object Object],: ,[object Object],, ,[object Object],:
,[object Object],
,[object Object],},
]).content
,[object Object], revised, critiqueWhat this does: it runs a criteria-bound critique that can approve untouched, and only revises when specific problems were named — so correct answers pass through unchanged and wrong ones get a targeted fix, not a random rewrite.
Breaking Down Each Element of the AI Agent Reflection Pattern
Four things make this version work, and each maps directly to a failure of the weak one.
The criteria are explicit and passed in. For the SQL agent, that might be: units are consistent, the query matches the question's time range, and no column is silently dropped. Named criteria turn a mood ("looks fine") into a test.
The critique can approve. The exact-match "APPROVED" token is the stop condition the weak version lacked. It lets a correct answer survive, which is the whole point — reflection should improve bad answers without touching good ones.
The critique and revision are separate calls. Now you can log the critique on its own. When something slips through, you can see immediately whether the reviewer missed it or the reviser broke it.
The revision is scoped. "Fix ONLY the listed problems" stops the model from wandering off and rewriting things that were already correct.
One more element is easy to miss: the reviewer's tone is set on purpose. Calling it a "strict reviewer" and telling it to assume nothing passes until proven isn't decoration — it measurably changes behavior. A reviewer prompted neutrally tends to be generous with itself; a reviewer prompted to be skeptical catches more. For a support team at a SaaS company, simply rewording the reviewer from "check this answer" to "find every reason a customer might be misled by this answer" roughly doubled the number of real issues surfaced, with no change to the underlying model. The critique prompt is a lever, and most teams leave it in the lazy position.
⚡ Pro tip: Make the critique output a structured verdict, not prose. Have it return JSON like {"pass": false, "failures": ["units", "time range"]}. Then you can route on the fields, count which criteria fail most across runs, and tighten your prompts where they actually break.
⚡ Pro tip: Cap the loop at one or two reflection rounds. A third pass almost never helps and roughly triples your latency and cost. If two rounds can't fix it, the problem is usually the original prompt or a missing tool, not more reflection.
Variations for Different Contexts
The pattern flexes across roles. A marketing copywriter's agent can reflect against brand voice and a banned-phrase list, catching off-tone lines before a human ever reads them. A healthcare intake agent can reflect against a checklist of required fields, refusing to finish until every one is present. A backend developer's code agent can run the critique as an actual test suite — the "criteria" become passing tests, and the revision loop keeps going until they're green.
For high-stakes work, swap the self-critique for a different model or a stricter system prompt on the reviewer. A reviewer that shares the writer's exact biases catches less; a reviewer told to assume the answer is wrong until proven otherwise catches more.
⚡ Pro tip: When cost matters, gate reflection behind a cheap confidence check. Only run the full critique-revise loop when the draft trips a simple rule — a number outside an expected range, a missing field, an unusually short answer. Most answers skip reflection entirely, and you spend the extra calls only where they pay off.
A financial analyst's agent shows the pattern at its sharpest. It drafts a quarterly summary, then reflects against a fixed checklist: every figure traces to a source, percentages add up, and no metric appears without its time period attached. Because those criteria are objective, the critique pass is nearly deterministic — it either finds a broken figure or it doesn't, with little room for the model to hand-wave. Objective criteria make reflection dramatically more reliable than subjective ones like "is this good?"
That's the general principle worth carrying to every project: the more you can turn "is this good?" into a list of checkable facts, the better reflection works. Vague quality judgments invite the model to agree with itself. Concrete, falsifiable checks force it to actually look at the thing.
⚡ Pro tip: Keep a running tally of which criteria fail most often across all your reflection runs. If "units are consistent" fails 30% of the time, that's not a problem to keep catching forever — it's a signal to fix the original prompt or add a unit-handling tool so the error stops happening upstream. Done well, reflection should shrink over time as it teaches you what to fix at the source.
Save and Reuse This
The reflection loop, its criteria, and the reviewer's system prompt are assets, not one-offs. The exact wording that made your reviewer strict without making it paranoid took real tuning to find, and it'll be just as useful on the next agent you build.
It helps to treat your criteria sets as versioned artifacts in their own right. The checklist a healthcare intake agent reflects against will grow as you discover new edge cases — a new required field here, a new format rule there — and you want that history captured in one place, not scattered across a dozen slightly different copies of the prompt. When the criteria live somewhere central, improving them improves every agent that shares them at once, instead of leaving three older versions quietly running yesterday's standards.
Keep the working versions somewhere searchable. Teams that save their critique prompts and criteria sets in a tool like PromptABCD can drop a proven reflection loop into a new project in minutes instead of rediscovering the same wording from scratch. The reflection pattern is only expensive to build once — after that, it should be something you reach for, not rebuild.
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.
