In plain English
When you write an email, you usually do two things: you write a first draft, then you read it back and fix the parts that are wrong, unclear, or rude. Self-critique and self-refine prompting asks a language model to do the same two-step move — first answer, then turn around and inspect its own answer for mistakes, and rewrite it.

The whole idea is a loop of three roles played by the same model: a generator produces a draft, a critic points out specific flaws, and a refiner rewrites the draft using that feedback. You can repeat the critic-and-refine pass a few times until the answer stops changing or passes a check.
Think of a writer and an editor who happen to be the same person at different moments. The writer is in 'produce' mode — get words on the page, don't stop to judge. The editor is in 'find problems' mode — read coldly, mark what's broken. Splitting these into separate steps works better than trying to write perfectly on the first pass, because generating and judging pull in opposite directions.
Why it matters
A model's first answer is rarely its best answer. The first pass is fast, fluent, and often almost right — but it may skip an edge case, miscount, contradict a constraint you gave, or leave the tone wrong. Asking for a fresh, critical second look is one of the cheapest ways to catch those misses without a smarter model or more training.
- It separates two skills the model is bad at doing at once. Producing text and evaluating text compete for attention in a single pass. Two passes — write, then judge — let the model spend its full effort on each.
- It catches concrete, checkable errors. Code that doesn't run, JSON that doesn't parse, a math step that doesn't add up, a requirement you listed that the draft ignored. These are exactly the flaws a critique pass is good at flagging.
- It needs no fine-tuning. Self-refine is pure prompting. You wire up two or three prompts and a loop. Any capable model can do it today, and you can add it to an existing system without retraining anything.
- It produces a feedback trail. The critique step writes down why the answer changed. That trail is useful for debugging, for logging, and for letting a human review the reasoning.
Who should care? Anyone whose output has a clear quality bar: code generation (does it compile and pass tests?), structured extraction (does it match the schema?), drafting with hard constraints (did it stay under the word limit, use the required tone, include every section?). The more checkable the task, the more self-critique helps. This is closely related to other reasoning techniques that trade extra tokens for better answers.
How it works
The core is a three-step cycle. Crucially, each step is a separate prompt (often a separate API call), not one giant instruction. Keeping the critic's prompt distinct from the generator's is what makes the critique sharp instead of self-congratulatory.
Step 1 — Generate
Get a first answer the normal way. Nothing special here — a plain prompt, maybe with chain-of-thought if the task needs reasoning. This draft is allowed to be imperfect; that's the point.
Step 2 — Critique
Now start a new prompt that hands the model the original task plus its own draft, and asks it to act as a strict reviewer. The wording matters a lot. A vague 'Are you sure?' tends to make the model cave and apologize regardless of whether it was right. A specific critique prompt that names the criteria pulls out real, actionable feedback.
You are a strict reviewer. Below is a task and a candidate answer.
List every concrete problem with the answer. Be specific:
- Does it satisfy each requirement listed in the task?
- Are there factual, logical, or arithmetic errors?
- Is anything missing, ambiguous, or contradictory?
If the answer is already correct and complete, reply exactly: NO ISSUES.
Task:
{task}
Candidate answer:
{draft}Step 3 — Refine
Feed the task, the draft, and the critique back in, and ask for a revised answer that fixes each listed issue. Then check: if the critique said 'NO ISSUES', or you've hit a max iteration count, or the answer stopped changing, stop. Otherwise loop the critique-and-refine pass again. The loop and its stop condition are the difference between a useful technique and an infinite back-and-forth.
from anthropic import Anthropic
client = Anthropic()
MODEL = "claude-sonnet-4-6"
def ask(prompt):
msg = client.messages.create(
model=MODEL, max_tokens=1024,
messages=[{"role": "user", "content": prompt}],
)
return msg.content[0].text
def self_refine(task, max_iters=3):
draft = ask(task) # 1) GENERATE
for _ in range(max_iters):
critique = ask( # 2) CRITIQUE (fresh prompt)
f"You are a strict reviewer. List concrete problems with the\n"
f"answer, or reply exactly NO ISSUES.\n\n"
f"Task:\n{task}\n\nAnswer:\n{draft}"
)
if "NO ISSUES" in critique: # CHECK -> stop condition
break
draft = ask( # 3) REFINE
f"Revise the answer to fix every issue.\n\n"
f"Task:\n{task}\n\nAnswer:\n{draft}\n\nIssues:\n{critique}"
)
return draft
print(self_refine("Write a Python function to check if a string is a palindrome, ignoring case and spaces. Include 3 test cases."))A worked example
Watch the loop catch a real mistake. The task: 'Write a function that returns the second-largest number in a list.' A typical first draft sorts the list and returns the element at index -2.
def second_largest(nums):
return sorted(nums)[-2]
# second_largest([5, 5, 3]) -> 5 (wrong: 5 isn't the *second* largest)
# second_largest([7]) -> crashes (index out of range)The critique prompt, given the task and this draft, returns specific, checkable feedback — not vague praise:
- Duplicates aren't handled. For
[5, 5, 3]it returns5, but the second-largest distinct value is3. - Lists with fewer than two distinct values crash with an
IndexErrorinstead of failing gracefully. - No examples or tests are provided to demonstrate the edge cases.
The refine step takes that critique and rewrites the function to deduplicate first and guard the short-list case:
def second_largest(nums):
distinct = sorted(set(nums))
if len(distinct) < 2:
return None # no well-defined second largest
return distinct[-2]
assert second_largest([5, 5, 3]) == 3
assert second_largest([7]) is NoneWhen it helps vs when it hurts
This is the part most tutorials skip. Self-correction is not a universal upgrade. Research has shown that on some reasoning tasks, prompting a model to revise without any external feedback makes accuracy go down — the model second-guesses correct answers. Whether it helps hinges on one thing: is there a reliable signal telling the critic what 'wrong' looks like?
- Output is checkable (runs / parses / compiles)
- Hard constraints to verify against
- An external signal exists: tests, a linter, a schema, search results
- Tasks with clear right/wrong: format, syntax, arithmetic
- Open-ended reasoning with no ground truth
- The model is already right and gets talked out of it
- Critique is vague ('are you sure?')
- No external feedback — model grades its own homework
The practical rule: the more your critic can lean on something outside the model, the more reliable the loop. A critique that runs the code and reads the error message, validates JSON against a schema, or checks an answer against retrieved documents is grounded in reality. A critique that only re-reads the text and feels whether it's good is the case that often backfires.
| Feedback source | Reliability | Example |
|---|---|---|
| Run the code / tests | High | Use the actual error or failing assertion as the critique |
| Validator / schema / parser | High | Reject output that doesn't match the JSON schema, then refine |
| Retrieved documents | Medium | Critic checks claims against fetched sources |
| Model's own judgment alone | Low–Medium | Useful for style/format, risky for factual correctness |
Common pitfalls
- Infinite agreement loops. Without a clear stop condition, the model can ping-pong between two versions, 'fixing' issues that aren't there. Always set a max iteration count and an explicit 'NO ISSUES' exit the critic can trigger.
- Sycophancy. If you phrase the critique as 'Are you sure? I think it's wrong,' the model tends to apologize and change a correct answer. Use neutral, criteria-based wording and never imply the answer is wrong before the model has looked.
- Critiquing in the same conversation. Leaving the draft in the chat history biases the model toward defending it. Send the critique as a fresh prompt where the draft is just text to review, not 'my answer'.
- Cost and latency explosion. Each loop is 2–3 extra model calls. Three iterations can mean 7+ calls for one answer. Cap iterations and only loop when the task quality justifies the spend.
- Refining drift. With each rewrite, the answer can wander away from a constraint it originally satisfied. Re-state the full task and all constraints in the refine prompt so nothing silently gets dropped.
- Fake problems. A critic with no escape hatch will always find something to complain about, degrading a good answer. The 'reply NO ISSUES if correct' instruction is not optional.
Going deeper
The basic loop — generate, critique, refine, check — is the foundation. Here are the directions worth knowing once it clicks.
Reflexion-style memory. Instead of just rewriting the answer, the model writes a short reflection ('my last attempt failed because I forgot to handle the empty-list case') and carries that note into the next attempt. The reflection acts as a lesson, which is especially useful in agent loops where the model retries a task many times. This pairs naturally with context engineering — the reflection becomes part of the context for the next try.
Self-critique vs self-consistency. They're easy to confuse but different. Self-consistency samples many independent answers and takes a majority vote — no critique, just aggregation. Self-refine produces one answer and iteratively improves it. They can be combined: generate several drafts, critique each, then vote. Tree-of-thought goes further, exploring and pruning a branching set of partial solutions.
Reasoning models change the picture. Newer reasoning models already do a kind of internal self-critique during their hidden 'thinking' phase — they question and revise before you ever see the output. That overlaps with what an external self-refine loop gives you, so on a strong reasoning model, an explicit critique pass may add less. The technique still earns its place when you can wire in a real external check (tests, a validator, retrieved facts) that the model can't perform on its own.
The honest takeaway. Self-critique is a real, useful tool, not a magic 'make it correct' button. It reliably improves checkable outputs and grounded tasks; it can quietly degrade open-ended reasoning with no external signal. The durable lesson from the research is the same one that runs through all of prompt engineering: a model is a weak judge of its own work in a vacuum, so the value of self-correction comes mostly from the feedback you can give the critic, not from asking the model to try harder.
FAQ
Does self-critique actually improve LLM output?
It depends on the task. On checkable outputs — code, structured data, math, constraint-following — asking the model to critique and revise reliably catches mistakes and improves quality. On open-ended reasoning with no way to verify the answer, self-correction can backfire and turn correct answers into wrong ones. The deciding factor is whether the critic has an external signal (tests, a schema, retrieved facts) to check against.
What is the difference between self-critique and self-refine?
They describe the same idea at different scopes. Self-critique is the single act of asking a model to find flaws in its own answer. Self-Refine is the full loop: generate a draft, get critique feedback, rewrite, and repeat until the answer is good enough. In practice people use the terms interchangeably for the generate-critique-revise cycle.
Why does a fresh critique prompt work better than asking 'are you sure?'
'Are you sure?' reads as social pressure, so the model tends to apologize and change even correct answers. A separate critique prompt that lists specific criteria reframes the task as neutral inspection rather than defending a position, and it pulls out concrete, actionable problems instead of a reflexive 'you're right, sorry.'
How do I stop a self-refine loop from running forever?
Use two stop conditions together: a maximum iteration count (often 2–3), and an explicit exit signal the critic can emit, like replying 'NO ISSUES' when the answer is already correct. You can also stop when the refined answer stops changing between iterations. Without these guards the model can ping-pong endlessly, inventing problems that aren't there.
Can self-correction make an answer worse?
Yes. Research has shown that prompting a model to revise without external feedback can lower accuracy on some reasoning tasks, because the model second-guesses answers that were already right. It also risks sycophancy (caving under pressure) and drift (dropping a constraint during a rewrite). Ground the critique in a real check to avoid this.
Is self-critique still useful with modern reasoning models?
Somewhat less, because reasoning models already self-critique internally during their hidden thinking phase. An explicit external loop adds the most value when you can give the critic a real check the model can't do alone — run tests, validate a schema, or compare against retrieved documents — rather than just asking it to re-read its own text.