Reflection
📖 3 min readUpdated 2026-04-19
Reflection is the simplest quality boost you can add to an agent. The pattern: after the agent produces an answer, you run a second LLM call that critiques the answer. "Is this correct? Is anything missing? What would you change?" The agent reads the critique, revises, returns. That one extra step routinely buys 5-20% quality on hard tasks, at the cost of roughly doubling the spend. For anything where the answer matters more than the dollar, it's a cheap trade.
The pattern
- Draft: the agent produces whatever it would normally produce.
- Critique: a second LLM call gets the draft and a critique prompt. It lists problems.
- Revise: a third LLM call takes the draft + critique and produces v2.
- Stop (or loop 1-2 more times if the task is high-stakes).
Why this works
The model wrote the draft with one set of constraints in its head. When you ask it to critique, you're putting it in a different mental mode: adversarial, look-for-errors, grade-this. In that mode it catches things it missed the first time. It's the same trick editors use on their own writing: do a draft, take a break, re-read as a stranger.
A worked example: code generation
Draft:
def get_avg(nums):
return sum(nums) / len(nums)
Critique prompt: "Review this function. List edge cases it doesn't handle."
Critique output: "Empty list → ZeroDivisionError. Non-numeric input → TypeError. No type hints or docstring."
Revise:
def get_avg(nums: list[float]) -> float:
"""Return the mean of a list of numbers. Returns 0.0 if the list is empty."""
if not nums:
return 0.0
return sum(nums) / len(nums)
Same model, same problem. First draft is fragile. Second draft ships. The difference is the middle step.
When reflection pays off
Self vs separate critic
Two flavors of reflection:
- Self-reflection: the same model, new prompt, critiques its own output. Cheap, fast. Limited by the model's self-awareness; models have blind spots they keep missing.
- Separate critic: a different model (or at minimum a very different persona prompt) critiques. More expensive but surfaces genuinely different feedback.
For real production code or published writing, pay for the separate critic. For internal tools, self-reflection is usually enough.
The empirical gain
Published benchmarks show reflection adds 5-20% quality depending on the task. The gains concentrate in:
- Tasks with verifiable correctness (code, math) → biggest gains
- Tasks with multi-step reasoning → meaningful gains
- Factual retrieval from context → small gains (model usually gets it right once)
- Simple formatting tasks → essentially zero gain
Stop conditions
Reflection can loop forever if you let it. Always cap:
- Max 2-3 reflection iterations. Diminishing returns after that.
- If the revision is essentially identical to the draft, stop. The model ran out of changes to make.
- If the critique says "no issues," stop.
Pitfalls
- Reflection on everything. You doubled your bill for no quality gain on simple tasks. Apply reflection only where it earns its cost.
- Vague critique prompts. "Review this" produces generic feedback. "Find edge cases. Check types. Check for off-by-one errors" produces specific, actionable feedback.
- Same-blindspot reflection. If the model missed something in the draft because of a systematic blindspot, it'll miss it in the critique too. Switch models or change persona.
- Losing the draft. Debug-tip: save draft, critique, and revision separately in your trace. When reflection breaks, you need to see which step went wrong.
What to do with this
- Add one reflection pass to your highest-stakes agent output. Measure: does the eval set improve?
- Read self-correction, which is reflection with an external verifier.
- Read debate + consensus for the multi-agent version of the same idea.