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
- Round 0 (generator). Run the base architecture (default ReAct) to produce an initial output.
- 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.
- Critic. Review the current output. Output a critique. If the
critique is
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}).