PromptisePromptise
Why PromptiseUse casesRoadmapDocs
GitHubGet started
Promptise - AI Framework LogoPromptise

The foundation layer for agentic intelligence. Build, secure and operate autonomous AI systems with Promptise Foundry.

pip install promptise

[01] Foundry

  • MCPcast
  • The Promptise Agent
  • Reasoning Engine
  • MCP
  • Agent Runtime
  • Prompt Engineering
  • Execution Engine
  • Agent Identity

[02] Resources

  • Documentation
  • GitHub
  • Guides
  • Learning Paths
  • Questions

[03] Company

  • About
  • Terms of Service
  • Privacy Policy
  • Cookie Policy
  • Subprocessors

© 2026 Promptise by Manser Ventures. All rights reserved.

Open source · Python

← Guides> Testing and evals

LLM Self-Correction: Self-Refine, Reflexion and CRITIC

LLM self-correction without fine-tuning: how Self-Refine, Reflexion and CRITIC work, why external feedback matters, and a real self-review vs test example.

Level
Advanced
Reading time
7 min
Published
Sep 7, 2025
Last updated
Oct 18, 2026
By
Promptise Team
  • Self-Correction and Reflection
  • Evals and Testing
Contents · 9 sections↓
  1. 01Can an LLM correct its own mistakes?
  2. 02How the main self-correction methods work
  3. 03Worked example: self-review vs test feedback
  4. 04When to use self-correction (and when not to)
  5. 05A reusable revise loop
  6. 06Reflexion: keep the lessons
  7. 07Common mistakes
  8. 08Frequently asked questions
  9. 09Next steps

LLM self-correction means having a model review and revise its own output at inference time, with no fine-tuning: draft, get feedback, rewrite. Self-Refine, Reflexion and CRITIC are the best-known versions. They work well when the feedback carries real information, such as a failing test, a search result or a checklist the model can verify, and much less when the model just rereads its own answer. This guide explains each method, shows a real case where self-review missed a bug that a test caught, and gives a loop you can reuse.

[01]

Can an LLM correct its own mistakes?

Sometimes. A model can improve its output when the feedback adds information it didn't use the first time: test failures, tool results, a rubric with checkable items. Without external feedback, self-correction on reasoning tasks is unreliable. Large Language Models Cannot Self-Correct Reasoning Yet (Huang et al., ICLR 2024) found models struggled to fix reasoning without external feedback and sometimes got worse. The practical rule: give the critic something to check against.

Key takeaways:

  • External feedback beats self-review. Tests, validators, search results and code checks give the model facts, not opinions.

  • Self-Refine works best for quality and style, where "better" is visible in the text.

  • Reflexion stores lessons across attempts, which helps when a task is retried.

  • Cap the loop. One or two revisions capture most of the benefit; stop when checks pass.

  • Each round costs a full call. Use it where errors are expensive.


[02]

How the main self-correction methods work

Method

Paper

Feedback comes from

Loop

Self-Refine

Madaan et al., 2023, arXiv:2303.17651

The same model, critiquing its own output

Generate, feedback, refine, repeat

CRITIC

Gou et al., 2023, ICLR 2024, arXiv:2305.11738

Tools: search, a code interpreter, a toxicity API

Generate, verify with tools, revise

Reflexion

Shinn et al., 2023, arXiv:2303.11366

Task signals (tests, environment), turned into written reflections

Attempt, reflect, store reflection in memory, retry

Constitutional AI (critique step)

Bai et al., 2022, arXiv:2212.08073

A list of written principles

Critique against a principle, revise

Self-Refine uses one model as generator, critic and reviser, and reports around 20% absolute improvement on average across seven tasks, from dialog responses to math, with GPT-3.5 and GPT-4. CRITIC's paper concludes by highlighting "the crucial importance of external feedback". Reflexion reported 91% pass@1 on HumanEval by reflecting on failed unit tests. The common thread in the strongest results is a signal from outside the model.

Constitutional AI's critique-and-revise step was used to generate training data, but the prompting pattern (critique this against principle X, then revise) works at inference time too.


[03]

Worked example: self-review vs test feedback

The task, at minimal reasoning effort:

Text
Write a Python function parse_duration(s: str) -> int that returns a duration in seconds.
Accept strings like "1h30m", "45s", "2h", "1h 5m 10s" and "90m".
Raise ValueError for anything else. Return only the code.

The draft was reasonable: it stripped whitespace, matched number-unit pairs with a regex and rejected garbage between them. Thirteen test cases found two failures:

Output
parse_duration('1h1h') returned 7200, expected ValueError
parse_duration('30m1h') returned 5400, expected ValueError

The draft accepts repeated units and units out of order. "Raise ValueError for anything else" arguably covers both, but the model didn't read it that way.

Round 1: ask the model to review its own code

Text
1
2
3
4
5
6
7
<task>

Here is a draft:
<draft>

Review the draft for bugs and unhandled edge cases. List what you find in at most 5 short bullets,
then give the corrected code in one Python code block.
Output
- The code rejects strings with leading whitespace (e.g. " 1h") because the first token start != pos and the matched_any check prevents treating leading whitespace as OK.
- The matched_any check in the gap validation is unnecessary; you should allow whitespace between tokens (including before the first token).
- The trailing-character check is correct but the error messages can be simplified; keep consistent ValueError usage.
- Otherwise the token parsing (digits + optional internal spaces + unit h/m/s) is fine; keep re.IGNORECASE to accept upper/lowercase units.

The first bullet is wrong: the draft calls s.strip() before parsing, so leading whitespace never reaches that check. The real problems, repeated and out-of-order units, aren't mentioned. Run against the tests, the "corrected" code fails the same two cases. In an earlier self-review with a different prompt, the model did notice that "5s1h" and "1h30m15m" were accepted, then called them acceptable "depending on spec" and "probably acceptable". Either way, self-review didn't change the outcome.

Round 2: give the model the failing tests

Text
1
2
3
4
5
6
7
8
9
10
<task>

Here is a draft:
<draft>

The draft fails these tests:
parse_duration('1h1h') returned 7200, expected ValueError
parse_duration('30m1h') returned 5400, expected ValueError

Fix the code so these pass without breaking the valid formats. Return only the code.

The revision added a set of seen units and an order check (trimmed):

Output
    seen_units = set()
    for m in token_re.finditer(s):
        …
        if unit in seen_units:
            # duplicate unit (e.g. "1h1h" or "30m1m") is invalid
            raise ValueError(f"duplicate unit: {unit}")
        seen_units.add(unit)
    …
    # enforce ordering: hours, then minutes, then seconds if multiple units provided

All 13 tests pass. The test output told the model exactly what "anything else" meant, which no amount of rereading could. That's the CRITIC and Reflexion insight in one example. Results vary by model and task; a stronger reasoning setting might have caught these cases in the draft.

The parse_duration draft failed 2 of 13 tests. Asked to review its own code, the model flagged the wrong problem and the same two tests still failed; given the failing tests as feedback, it added a check for repeated and out-of-order units and all 13 tests passed.
FigureSelf-review and test feedback on the same parse_duration draft

[04]

When to use self-correction (and when not to)

Use a revise loop when:

  • You have a checker: unit tests, a schema validator, a linter, a SQL EXPLAIN, a fact lookup.

  • The output must meet a checklist: required facts, length, forbidden words, format. Check what you can in code and give the model the result.

  • Style and clarity matter and a second pass is cheap compared to a human edit.

Skip it when:

  • You'd only ask "are you sure?" on a reasoning answer. That tends to produce changes, not improvements.

  • Latency matters more than the last bit of quality. Each round is a full model call.

  • The first output already passes all checks. Stop, don't polish.


[05]

A reusable revise loop

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def generate_with_feedback(task: str, check, max_rounds: int = 2) -> str:
    """check(output) returns a list of problems; empty means done."""
    output = llm(task)
    for _ in range(max_rounds):
        problems = check(output)
        if not problems:
            return output
        output = llm(
            f"{task}\n\nHere is a draft:\n{output}\n\n"
            "It has these problems:\n" + "\n".join(f"- {p}" for p in problems) +
            "\n\nFix every problem without changing anything that already works. "
            "Return only the corrected output."
        )
    return output  # still failing: log it and escalate

check is where the value comes from. For code, run the tests. For structured output, validate against the schema. For writing, count words and search for banned phrases in code, and use a model only for the checks code can't do, such as "does this contradict the source?".

If you build prompts with Promptise Foundry, a self_critique strategy adds a critique-and-revise pass to a prompt function. It's the self-review half of this loop; pair it with a guard or validator for the external half.


[06]

Reflexion: keep the lessons

Reflexion adds memory. After a failed attempt, the model writes a short reflection ("I accepted repeated units; the tests require each unit at most once") and that text is added to the prompt for the next attempt. It helps when the same kind of task is retried many times, as in coding agents or game environments. Keep the reflections short, specific and tied to the signal that produced them; vague lessons ("be more careful") add tokens and nothing else. For agents that store lessons from failed tool calls across runs, see self-improving AI agents.


[07]

Common mistakes

Mistake

Why it fails

Fix

"Review your answer" with no new information

The model rereads its own reasoning and keeps its blind spots, or changes correct parts

Add tests, tool results or a checklist

Unlimited revise rounds

Cost grows, output drifts, correct parts get rewritten

Stop when checks pass; cap at 1-2 rounds

Feedback as vague opinion ("make it better")

The revision changes style at random

List specific, checkable problems

Conflicting instructions in the critique prompt

The model spends the round deciding which to follow

Restate the task without contradictory rules

Trusting the critique

Critiques can be wrong, as above

Verify the revised output with the same checks

LLM-judging what code can check

Slower, costlier, less reliable

Word counts, schemas, tests in code


[08]

Frequently asked questions

What is Self-Refine?

A method from Madaan et al. (2023) where one model generates an output, writes feedback on it, and revises using that feedback, repeating until a stop condition. It needs no training data or fine-tuning and works best on tasks where quality is visible in the text, like dialog, code readability or rewriting.

What's the difference between Reflexion and Self-Refine?

Self-Refine improves one output within a single task. Reflexion runs repeated attempts at a task, turns each failure signal (such as failed tests) into a written reflection and keeps those reflections in memory for later attempts.

Why doesn't asking the model to double-check always work?

Without new information the model reviews its answer with the same knowledge and blind spots that produced it. Huang et al. (2023) found intrinsic self-correction often didn't help on reasoning and sometimes hurt. Feedback from tests, tools or retrieved facts gives it something new to act on.

How many revision rounds should I run?

Usually one or two. Stop as soon as the checks pass. If the output still fails after two rounds, the model may lack the knowledge or the task may be ambiguous; escalate instead of looping.

Is self-correction the same as fine-tuning?

No. Nothing about the model changes. Improvement happens in the prompt: feedback, critiques and stored reflections. Remove them and the model behaves as before.


[09]

Next steps

  • Model-based fact checking: verification loops: CoVe and SelfCheckGPT.

  • Check outputs in code first: LLM output validation.

  • Improve the prompt instead of each output: automatic prompt optimization.

  • Agents that learn from failed tool calls: self-improving AI agents.

  • Use a model as a grader: LLM as a jury, not a judge.

Contents

  1. 01Can an LLM correct its own mistakes?
  2. 02How the main self-correction methods work
  3. 03Worked example: self-review vs test feedback
  4. 04When to use self-correction (and when not to)
  5. 05A reusable revise loop
  6. 06Reflexion: keep the lessons
  7. 07Common mistakes
  8. 08Frequently asked questions
  9. 09Next steps

Learning paths

Want more structure? Paths put guides in order, like a short course.

See the paths →

> Testing and evals

Related guides

All guides in this topic →
  • // 01Intermediate · 20 minHow to Evaluate AI Agents: Evals, LLM Judges and pass^kHow to evaluate AI agents: write golden and refusal tasks, grade tool calls in code, calibrate an LLM judge, measure pass^k and gate CI on the results.
  • // 02Intermediate · 24 minHow to Test LLM Prompts and AI Agents in PythonUnit test LLM prompts with pytest, catch prompt regressions in CI, grade outputs with an LLM judge and check which tools an AI agent calls, in Python.
  • // 03Intermediate · 16 minTesting MCP Servers in Python: pytest Without a Live ServerTest an MCP server in Python without running it: auth, guards, middleware, resources, prompts, error envelopes and job queues in 35 pytest tests, plus CI.
  • // 04Intermediate · 18 minAI Agent Evals in CI: Run Them on Every Pull RequestRun AI agent evals in CI on every pull request: test tool choice, arguments, answers and safety, keep cost and flakiness down, with GitHub Actions.
  • // 05Intermediate · 16 minWho Decides When an AI Agent Is Done? Checks and JudgesWho decides when an AI agent is done? Stop conditions, self-checks, success criteria in code, a separate LLM judge and budgets as a backstop, with code.
  • // 06Intermediate · 18 minHow to Review AI-Generated Code: A Practical ChecklistHow to review AI-generated code: a checklist for intent, tests, invented APIs and packages, security and dead code, plus a script for the first pass.

Keep going.

Browse every guide by topic and level, or follow a learning path that puts them in order.

All guidesLearning paths