Reflection: checking and revising the model's work
A producer-critic loop on the running example, why a critic needs evidence, and what Self-Refine, Reflexion and CRITIC show.
On this page
The systems of articles 13 and 14 take a model's first answer as final. They check its form: the chain checked that every sentence cites a real source, and the agent's gate checked that percentages appear on trusted pages. Neither asks the question that matters most: is the answer right? Gulli calls the remedy reflection [1]: a step whose only job is to evaluate an output and feed the evaluation back so that the output can be revised. This article builds a reflection loop on the running example and shows that the critic's value depends on what the critic can see. A critic that reads only the draft approves a draft with a real error. A critic given the cited sources finds the error and gets it fixed. We then place three well-known methods, Self-Refine, Reflexion and CRITIC, on this distinction, look at what their experiments do and do not show, and end with the ways reflection fails.
1. First drafts that look right
Here is a first draft of the Larkford report, written from the same notes as in article 13:
Larkford's bike share reduced city-centre car trips by 6% between 2022 and 2024 [2]. Tram Line 2 also opened in September 2023 [3].
It passes the citation gate of article 13: both sentences cite a source, and both sources exist. It reads fluently. It is also wrong in a way that matters. Source 2, the city's review, reports a 6% fall in car trips but says explicitly that it "does not estimate how much of this fall is due to the bike share". The draft turns a fall into an effect of the bike share. The university study, which does separate the causes, and the parking charge rise are both missing.
This is a typical first-draft error. The facts are each roughly right, and the relation between them is wrong. Rules in code cannot catch it, because checking whether a sentence says the same thing as its source requires reading both. That is a job for a model.
2. The reflection pattern
Reflection is a loop in which an output is evaluated, by the same model, a second model or a program, and the evaluation is fed back to produce a revised output [1]. It has four steps:
- Produce. Generate a first output, such as a draft, code or a plan.
- Critique. Evaluate the output against explicit criteria: factual accuracy, completeness, tests, style or the task's requirements.
- Revise. Generate a new output that addresses the critique.
- Repeat or stop. Loop until the critique finds no problems, or until a round limit is reached.
The two roles are usually called producer and critic. They can be the same model with different system prompts, or different models. Anthropic's guide calls the same structure the evaluator–optimizer workflow [5]. On the axis of article 13, reflection usually sits in between: code fixes the loop and the stopping rule, and the model's verdict decides how many rounds run.
The producer and the critic are wired together in a few lines:
def reflect(question, critic, max_rounds=3):
draft = write(question, NOTES)
for round in range(1, max_rounds + 1):
verdict = critic(draft)
print(f"round {round} draft: {draft}\nround {round} verdict: {verdict}")
if verdict.startswith("APPROVED"):
return draft
draft = write(question, NOTES, feedback=verdict)
return draft # not approved: the caller should flag it, not publish it
write is the producer. When it gets feedback, it appends it to its prompt with an instruction to rewrite. critic is a function, so the same loop can be run with different critics. The round limit matters as much as the critic: without it, a critic that is never satisfied would keep the loop running indefinitely. And when the limit is reached without approval, the result is a draft that failed review, not a finished report.
3. A critic that sees only the draft
The simplest critic is the model reviewing its own work, with a prompt to look for errors:
def review_alone(draft):
return llm("You are a reviewer. Check the report for errors. Reply APPROVED "
"or list the problems.", draft)
On the flawed draft:
== A. The producer reviews its own report ==
round 1 draft: Larkford's bike share reduced city-centre car trips by 6% between 2022 and 2024 [2]. Tram Line 2 also opened in September 2023 [3].
round 1 verdict: APPROVED. The report is clear and every sentence has a citation.
2 model calls, 181 tokens in, 49 tokens out
The reply is scripted, but the behaviour is the documented one. The reviewer has only the draft, and the draft is fluent, consistent and cited. Nothing in the critic's input contradicts it. A critic in this position can judge form, style and internal consistency. It cannot judge whether a claim matches a source it has not seen.
The research agrees:
- Self-Refine [2] found almost no gain on math word problems (GPT-4: 92.9% to 93.1% solved). When the authors looked at the feedback, ChatGPT judged "everything looks good" in 94% of cases, because a reasoning chain that looks consistent persuades the model reviewing it.
- Huang and colleagues [6] tested self-correction on reasoning benchmarks with no external feedback, asking models only to review and revise their own answers. Accuracy often went down: without new information, the models changed correct answers to wrong ones as readily as they fixed wrong ones.
4. A critic that checks the evidence
The fix is to give the critic information the producer did not use. Here the program fetches the full text of each cited source. This is code, not a model call. The critic is then asked to check every sentence against its source:
def review_with_sources(draft):
cited = sorted({int(n) for n in re.findall(r"\[(\d+)\]", draft)})
sources = "\n\n".join(f"[{n}] {fetch(URLS[n - 1])}" for n in cited) # code, not model
return llm("You are a fact-checker. Check every sentence against the text of the "
"source it cites. Reply APPROVED or list the problems.",
f"Report:\n{draft}\n\nCited sources:\n{sources}")
== B. A fact-checker reads the cited sources ==
round 1 draft: Larkford's bike share reduced city-centre car trips by 6% between 2022 and 2024 [2]. Tram Line 2 also opened in September 2023 [3].
round 1 verdict: 1. Sentence 1 says the bike share reduced car trips by 6%, citing [2]. Source [2] reports the 6% fall but says it does not estimate how much is due to the bike share. Do not attribute the fall to the bike share.
2. Source [1] estimates the bike share's own effect (2.5%); the report omits it.
3. Sentence 2 omits the parking charge rise reported in [3].
round 2 draft: City-centre car trips fell by 6% between 2022 and 2024 [2], but tram Line 2 opened and parking charges rose by 40% over the same period [3]. A comparison with similar districts attributes about 2.5% of the fall to the bike share (95% CI 0.8% to 4.2%) [1].
round 2 verdict: APPROVED. Every sentence matches its cited source.
4 model calls, 1,160 tokens in, 199 tokens out
The critique is specific. It names each sentence, quotes what the source says and states the problem. That is what the producer needs to revise well. Self-Refine measured the same thing: replacing specific feedback with generic feedback ("improve the output") lowered scores. On one task, sentiment reversal with ChatGPT, the score fell from 43.2 to 31.2, and with no feedback step at all to 0 [2]. The revised draft separates the 6% fall from the 2.5% attributed to the bike share. The second check approves it.
The price is visible on the last line. Run B used 4 calls and 1,160 input tokens against run A's 2 calls and 181 tokens, because the critic reads the sources. Each round of reflection costs at least two more calls, and it adds latency the user waits through. Figure 15.1 sets the two critics side by side.
Figure 15.1 Two kinds of critic. a) A critic that sees only the draft can catch problems of form and style, but has no basis for judging whether claims are true. b) A critic given evidence from outside the producer's context, such as the cited sources, test results or a search, can check claims against it. In both, the loop ends on approval or at a round limit, and an output that was never approved should be flagged, not used.
5. Variants: Self-Refine, Reflexion and CRITIC
Three methods are cited for this pattern. Each changes one thing in the loop of section 2.
Self-Refine [2] uses one model for all three roles: produce, give feedback, refine. There is no external signal. It was tested on seven tasks with GPT-3.5, ChatGPT and GPT-4, against the same model's single first attempt. Gains averaged about 20 percentage points, but were very uneven:
- on dialogue responses rated by human preference, GPT-4's outputs were preferred 74.6% of the time after refinement, against 25.4% before;
- on code optimization, the share of programs sped up rose from 27.3% to 36.0%;
- on math, the gain was almost nothing (section 3).
The pattern in these numbers: self-feedback helps most where quality is a matter of judgement and the first draft is visibly improvable, and least where errors are hard to see.
Reflexion [3] keeps the lessons across attempts. An agent tries a task. An evaluator, often the environment itself (a test suite or a game's reward), says whether the attempt succeeded. The model then writes a short reflection on what went wrong. The reflection is stored in memory and included in the prompt of the next attempt (figure 15.2). The results:
- HumanEval, a set of Python programming problems: Reflexion with GPT-4 reached 91.0% pass@1, against 80.1% for GPT-4 alone. Here the model wrote its own unit tests and used them as the evaluator.
- ALFWorld, with ReAct as the base agent: Reflexion completed 130 of 134 household tasks.
- MBPP, another Python benchmark: Reflexion did worse than GPT-4 alone, 77.1% against 80.1%. The authors traced this to the self-written tests. On MBPP, 16.3% of solutions that passed the model's own tests were actually wrong, against 1.4% on HumanEval. When the evaluator is wrong, reflection confidently improves towards the wrong target.
Section C of this article's example shows the memory step: the fact-checker's critique becomes one general lesson that later tasks receive in their prompt.
== C. Keeping a lesson for later tasks (Reflexion) ==
saved to memory; later write() calls get it via lessons=:
- Before attributing a change to one cause, check whether the sources report other changes at the same time, and prefer a source that separates them.
Figure 15.2 Reflexion. After each attempt, an evaluator such as a test suite, a reward or the environment reports success or failure. The model writes a reflection on what went wrong, and the reflection is kept in memory and added to the prompt of the next attempt. Nothing is trained: the model's weights stay fixed, and only its prompt changes. The method is only as good as the evaluator. Self-written tests that pass wrong code mislead it.
CRITIC [4] grounds the critique in tools. To check a factual answer, the model generates search queries and reads the results. To check a math answer written as a program, it runs the program. It then revises in light of what the tools returned. With ChatGPT, on three question-answering datasets, CRITIC raised F1 by 7.7 points on average over the first answer. The ablation is the important result: the same prompts without the search tool, where the model writes its own "evidence", changed F1 by between −0.03 and +2.33 points depending on the model. The authors conclude that the models were unreliable at validating their own outputs, and that the gains came from the tools.
Table 15.1 puts the three side by side with the two critics of this article.
Table 15.1 Where the critique's signal comes from.
| Method | Who critiques | Signal | What persists | Typical cost |
|---|---|---|---|---|
| Self-review (run A) | same model | none beyond the draft | nothing | +1 call per round |
| Self-Refine [2] | same model | none; specific feedback | nothing | +2 calls per round |
| Fact-checker (run B) | model + code | cited sources | nothing | +2 calls per round, sources in the prompt |
| CRITIC [4] | model + tools | search, code execution | nothing | tool calls + 2 calls per round |
| Reflexion [3] | model + evaluator | tests, rewards, environment | lessons across attempts | a whole new attempt per round |
6. Where reflection fits
Reflection fits best where a critic can check something the producer could not, and least where it cannot.
- Code with tests. The signal is objective. The critic runs the tests and reads the failures, and the revision targets them. This is the strongest case, which is why coding agents loop on test results. The caveat from Reflexion: tests written by the same model can be wrong, so prefer tests written independently of the code.
- Factual writing with sources. As in run B, the critic checks claims against retrieved text. It needs the sources in its prompt. A critic told only to "check the facts" has nothing to check them against.
- Style and structure. For tone, clarity or following a template, self-review works reasonably well, because the criteria are visible in the draft itself. Give the critic an explicit rubric and a round limit, or it may keep finding things to polish.
- A poor fit. Skip reflection when the first draft is usually good enough, or when the critic has no criterion and no evidence that the producer lacked. Then each round adds cost and a chance of making a correct answer worse [6].
At a glance: reflection
What: First outputs contain errors that rules in code cannot detect: claims that do not match their sources, code that fails edge cases, plans that ignore a constraint.
Why: A critic evaluates the output against explicit criteria, and the producer revises using the critique. The loop repeats until the critic approves or a round limit is reached.
Rule of thumb: Use reflection when quality matters more than speed and cost, and the critic can check something the producer could not: tests, sources, a search or a rubric. Without such a signal, self-review mostly checks style. Skip it when first drafts are usually acceptable.
7. Failure modes and evaluation
The agreeable critic. A critic with no evidence approves fluent output (run A). Even with evidence, a critic built on the same model may share the producer's blind spots. Give the critic different information, a different prompt, and where possible a different model.
The endless critic. A critic that always finds something keeps the loop running and can make a good draft worse with each change. A round limit is mandatory. Logging how many rounds runs take shows whether the critic's bar is sensible.
Regressions. A revision can fix the named problem and break something else, for example dropping a correct citation while rewriting a sentence. The critic should check the whole revised output each round, not only the sentences it flagged.
Optimizing for the critic. The producer learns to satisfy the critic rather than the task. Reflexion's self-written tests show the extreme case: wrong code that passes wrong tests counts as success [3]. Wherever possible, the critic's signal should come from something the producer cannot influence.
Judge biases. When a model judges outputs, its judgements have known biases. In a study of models judging chatbot answers, they favoured the first of two answers shown, longer answers, and sometimes answers in their own style [7]. These matter most for subjective criteria.
Cost and latency. Each round adds at least two calls, and evidence enlarges the critic's prompt. Run B cost about six times run A in input tokens.
Evaluating a reflection loop means measuring it against the same system without reflection, on the same test set:
-
Final quality, with and without reflection. Only a clear improvement justifies the cost.
-
The critic's own accuracy. Measure two error rates:
- approved but wrong: the critic's false positives, the most dangerous error;
- rejected but right: needless rounds that risk regressions.
These two numbers are the critic's confusion matrix (article 6).
-
Rounds per task and cost per task. Watch for loops that routinely hit the limit.
Key takeaways
- Reflection adds a critic that evaluates an output and a producer that revises it, in a loop with a round limit.
- A critic is only as good as its signal. One that sees only the draft judges form, not truth. Give it evidence the producer did not use: sources, test results or search.
- Self-feedback helps most on tasks judged by preference and style. It barely helps where errors are hard to see. Self-Refine's math gain was 0.2 points, and self-correction without feedback can lower accuracy.
- CRITIC's ablation found that the gains came from the tools, not from the model critiquing itself.
- Reflexion carries lessons across attempts through memory. It is only as reliable as its evaluator: flawed self-written tests made it worse than the baseline on MBPP.
- Measure the critic itself. Its approved-but-wrong rate determines how much the loop can be trusted.
Summary
A reflection loop has a producer generate an output and a critic evaluate it, feeds the critique back for revision, and stops on approval or at a round limit. On the running example, a first draft credited the whole 6% fall in car trips to the bike share. It passed article 13's citation gate, and it passed a self-review that saw only the draft. A fact-checker given the text of the cited sources found the misattribution and the missing evidence, and the revised draft separated the fall from the 2.5% attributed to the bike share, at the cost of two extra calls and about six times the input tokens. The research tells the same story. Self-Refine's gains were largest where quality is judged by preference and smallest on math, where self-feedback mostly said "looks good". CRITIC's gains disappeared without its tools. Reflexion's memory of lessons helped where tests were reliable and hurt where they were not. Reflection is worth its cost when the critic can check something the producer could not.
Notes
Terminology. "Reflection" covers several related ideas in the literature: self-critique within one answer, critique by a second model, and reflection on past attempts stored in memory (Reflexion). Gulli's chapter 4 covers the producer–critic form and its links to goal monitoring and memory [1]. Andrew Ng's series lists reflection first among its four agentic patterns, partly because it is easy to add [8].
Self-correction research. Whether models can improve answers without external feedback has been debated. The careful reading of the evidence [2, 6] is this: self-feedback without new information improves outputs whose quality is visible in the output itself, such as style and constraint coverage, and does little or harm for correctness on reasoning tasks. External feedback, from tools, tests or retrieved sources, is what makes correction reliable [4].
Judges and verifiers. A critic that scores rather than comments is a judge. One trained specifically to check solutions is a verifier. Judges are widely used to evaluate model outputs at scale, with the biases noted in section 7 [7]. Training models with feedback from verifiers is one of the ways current models are taught to reason step by step. That is training, beyond the scope of this inference-time pattern.
Frameworks. In LangGraph, as of 2026, reflection is a cycle in the graph: a producer node and a critic node, with a conditional edge that loops back or exits. Google's ADK offers a loop agent that repeats sub-agents until a condition is met. Gulli gives both versions in code [1].
Problems
Problem 15.1 Draft 1 in section 1 passes article 13's citation gate. Write a rule in code that would catch it. Why is any such rule fragile? (Example: reject sentences in which "bike share" and a percentage appear together unless the cited source contains the same percentage in a sentence with "bike share". It catches this draft, but misses paraphrases, and rejects correct sentences that combine figures from different sentences. Checking meaning needs a reader.)
Problem 15.2 Run A cost 181 input tokens and run B 1,160. Suppose a report needs on average 1.4 rounds with the fact-checker, each round costing about 600 input tokens for the writer and 700 for the checker. Estimate the input tokens per report, and the extra cost compared with writing once without review. (Answer: tokens, against 600 for a single draft, about three times as much.)
Problem 15.3 In Reflexion's MBPP experiment, 16.3% of solutions that passed the model's own tests were wrong. Explain how this can make reflection score below the baseline. (Answer: when self-written tests accept wrong code, the agent stops and submits it as solved; it can also be led by failing wrong tests to "fix" correct code. The loop then converges on the tests, not on the task.)
Problem 15.4 You build a critic for marketing copy with the rubric "clear, friendly, under 80 words, mentions the price". Which criteria can code check, and which need a model? What should stop the loop? (Answer: length and the presence of the price can be checked in code, before any model call. Clarity and friendliness need a model judge. Stop when the checks in code pass and the judge approves, or after two or three rounds, since style can be polished forever.)
Problem 15.5 Design an evaluation that decides whether to keep run B's fact-checker in production. What would you measure on a test set of 50 questions? (Answer: report quality with and without the checker, judged against a checklist of required facts; the checker's approved-but-wrong and rejected-but-right rates against human labels; rounds per report; and input tokens and seconds per report. Keep it only if quality rises clearly and the approved-but-wrong rate is low.)
References
- 1: Antonio Gulli (2025). Agentic Design Patterns: A Hands-On Guide to Building Intelligent Systems. Springer. Chapter 4.
- 2: Aman Madaan, Niket Tandon, Prakhar Gupta and colleagues (2023). Self-Refine: iterative refinement with self-feedback. Advances in Neural Information Processing Systems 36.
- 3: Noah Shinn, Federico Cassano, Edward Berman, Ashwin Gopinath, Karthik Narasimhan and Shunyu Yao (2023). Reflexion: language agents with verbal reinforcement learning. Advances in Neural Information Processing Systems 36.
- 4: Zhibin Gou, Zhihong Shao, Yeyun Gong, Yelong Shen, Yujiu Yang, Nan Duan and Weizhu Chen (2024). CRITIC: large language models can self-correct with tool-interactive critiquing. International Conference on Learning Representations.
- 5: Erik Schluntz and Barry Zhang (2024). Building effective agents. Anthropic.
- 6: Jie Huang, Xinyun Chen, Swaroop Mishra, Huaixiu Steven Zheng, Adams Wei Yu, Xinying Song and Denny Zhou (2024). Large language models cannot self-correct reasoning yet. International Conference on Learning Representations.
- 7: Lianmin Zheng, Wei-Lin Chiang, Ying Sheng and colleagues (2023). Judging LLM-as-a-judge with MT-Bench and Chatbot Arena. Advances in Neural Information Processing Systems 36, Datasets and Benchmarks.
- 8: Andrew Ng (2024). Agentic design patterns part 2: reflection. The Batch, DeepLearning.AI.