Skip to Content
ArchitecturesSelf-Refine

Self-Refine

Self-Refine has one model write a draft, critique it, and rewrite it until the critique finds nothing left to fix. Use it to polish output quality (writing, code, answers) when one model is good enough to judge its own work; for a reviewer with different blind spots, use ActorCritic. From Madaan et al. 2023, Self-Refine: Iterative Refinement with Self-Feedback.

Pattern

  1. Round 0 (generator). Run the base architecture (default ReAct) to produce an initial output.
  2. Rounds 1..max_rounds:
    • Critic. Review the current output. Output a critique. If the critique is stop_phrase (default "no issues"), either the whole reply or its first line, ignoring case, markdown and punctuation, terminate: the model considers the output good enough. A critique that merely mentions the phrase (“Grammar: no issues. Fact: wrong date.”) doesn’t stop the loop.
    • Refiner. Produce a revised output addressing the critique, seeing every earlier output and critique (Madaan et al., Eq. 4). The new output replaces the old.

Usage

from loomflow import Agent from loomflow.architecture import SelfRefine agent = Agent( "Write a tight 3-paragraph product brief.", model="claude-opus-4-7", architecture=SelfRefine(max_rounds=3), ) result = await agent.run("Brief about Acme Corp.")

Or by string:

agent = Agent("...", model="...", architecture="self-refine")

When same-model self-critique pays off

  • Clearly-defined output rubrics (style, length, structure).
  • Tasks where the first draft has predictable failure modes the same model can recognise on a second pass (filler, hedging, repetition, missing sections).
  • Cost is roughly 2–3× ReAct. You pay for the critic + refiner calls.

When to use ActorCritic instead

When the same model has the same blind spots as critic and generator, gains plateau quickly. For asymmetric blind-spot coverage (different prompts, ideally different models), use ActorCritic. Actor and critic are distinct Agent instances, possibly on different model providers.

Threshold via stop phrase, not score. Self-Refine’s critic outputs free-form text; termination is keyword-based. For numeric-score gating (score ≥ threshold), use ActorCritic which returns structured JSON ({score, issues, summary}).

Last updated on