跳转到内容

Self-Refine — 让同一个模型自己改自己写的东西

是什么

Self-Refine 是一套让 LLM 自评自改的最小流程:同一个模型先写一稿,然后自己挑刺、自己改,反复直到自己满意为止。

日常类比:像一个写作者交稿前自检——先写初稿,然后通读”这里啰嗦、那里逻辑不顺”,自己改完再读一遍,直到读不出问题。Self-Refine 把这个动作搬给了 LLM。

整个流程只用一个模型,不调外部工具、不开多智能体、不需要额外训练数据/微调/RL。三件 prompt 串起来就能跑:

  1. 生成 prompt:让模型给出初稿
  2. 反馈 prompt:让同一个模型读自己的初稿,指出问题
  3. 改写 prompt:让同一个模型根据反馈出新稿

新稿再丢回反馈步,直到模型说”没问题了”或达到迭代上限。

为什么重要

不理解 Self-Refine,下面这些事都解释不清:

  • 为什么 2023 年开始有了”agent loop”这个词——Self-Refine 是其中最小可行版
  • 为什么”让 GPT-4 多想一步”经常真的能提分——同一个模型也存在”生成 vs 判别”的不对称
  • 为什么 ReAct / Reflexion / Tree-of-Thoughts 都把”自反馈”作为标配组件
  • 为什么 prompt engineering 的工作有时候 = 把单次生成切成多步——切的就是 Self-Refine 的影子

论文给出的数字也很直接:在 GPT-4 上,7 个任务平均绝对提升约 20 个百分点,包括对话生成、代码可读性、代码优化、数学推理、情感反转、缩略语生成、约束生成——任务跨度很大但都吃这套。

核心要点

Self-Refine 的循环可以拆成 三个角色 + 一个判停

  1. Generator(生成器):拿到任务后写初稿 y₀。和普通 prompt 调用没区别。

  2. Feedback(反馈者):读 y₀,按某种维度给出具体可执行的批评——不是 “不太好”,而是 “第 3 行 for 循环可以换成 list comprehension,第 7 行变量名 a 含义不清”。这一步是核心,反馈越具体,下一步改写越有方向。

  3. Refiner(改写者):看着 y₀ + 反馈,写出 y₁。

  4. 判停:要么模型自己在反馈里说”没什么可改的了”,要么达到预设迭代上限(论文里通常 3-5 轮)。

三个角色用的是同一个 LLM,只是 prompt 不同。这是论文最反直觉的设计——很多人会以为需要一个更强的”评审”模型,作者证明不需要

实践案例

案例 1:代码优化任务

# Generator 初稿
def is_prime(n):
for i in range(2, n):
if n % i == 0:
return False
return True

Feedback 给出:

这段代码可以优化。循环只需要到 sqrt(n);n=1 应单独返回 False;n=2 是边界。

Refiner 改写:

def is_prime(n):
if n < 2:
return False
if n == 2:
return True
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False
return True

关键:Generator 和 Feedback 是同一个 GPT-4。它写完一稿后,换一个 prompt,自己就能挑出”循环到 sqrt(n) 就够”。这种”生成时想不到,但被问一句就能想到”的不对称,是整个方法成立的前提。

案例 2:情感反转(把负面句改成正面)

输入:“这家餐厅服务慢得离谱,菜还凉了。”

Generator 初稿:“这家餐厅服务有点慢,菜温度可以更好。” Feedback:“只是变中性了,没真正变正面。建议突出值得肯定的点。” Refiner:“这家餐厅菜品丰富,下次希望上菜更快、温度更理想。”

可以看到 Feedback 起到了目标对齐的作用——一次生成模型容易”打折”,反馈一刀下去把它推回正面区间。

案例 3:判停信号

论文里反馈 prompt 通常长这样:

读下面这份代码,给出具体的可改进点。
如果你认为已经足够好,回答 'No suggestions, the code is good as is.'

模型一旦给出”No suggestions”就停。这个自己说停的设计简单粗暴但有效——配合迭代上限做兜底。

踩过的坑

  1. 模型判别能力不够时反而越改越糟:GPT-3.5 在某些任务上 Self-Refine 不稳定甚至倒退——它”挑刺”挑得不准,Refiner 跟着错的方向改。论文的结论:生成器至少要比判别任务的下限强,否则 loop 会放大噪声而不是收敛。

  2. 反馈太笼统等于没反馈:“写得不够好,请改进”这种反馈完全无效。必须要求 Feedback prompt 给出位置 + 问题 + 建议三要素,否则 Refiner 不知道动哪里。

  3. 迭代次数不是越多越好:论文实验显示 2-3 轮后收益快速递减,很多任务到 4-5 轮反而轻微下降(开始过度修改)。固定上限 + 自停才是更安全的组合。

  4. 不同任务需要不同反馈维度:代码优化要看效率/可读性,对话要看一致性/有用性,数学推理要看每一步推理是否有效。不能用一套通用 feedback prompt 打天下——这是落地时最容易栽的地方。

适用 vs 不适用场景

适用

  • 任务有明确质量维度(代码效率、文本通顺、推理对错)
  • 模型本身判别能力 > 单次生成能力——能挑出自己写的问题
  • 没有可靠外部 verifier(编译器/测试/检索)但模型自己懂规则
  • 想用最小工程量提质量——三个 prompt + 一个 loop

不适用

  • 模型对该任务完全没判别能力(如冷门领域事实校验)→ 用 RAG / 工具调用
  • 任务有明确客观判据(数学正确性、代码能跑)→ 用 verifier-in-the-loop(Reflexion 这一类)更稳
  • 实时延迟敏感场景(客服 / IM)→ 多轮迭代延迟翻倍
  • 单次生成已经接近上限(短答案问答)→ 没空间提升

历史小故事(可跳过)

  • 2022 年:ReAct(Reasoning + Acting)让 LLM 把”想”和”做”交替出现,但需要外部工具
  • 2023 年 3 月:Self-Refine 论文挂上 arXiv——只用一个 LLM、不调工具、不微调,把”自反馈”压到最简
  • 2023 年 5 月:Tree-of-Thoughts 把单线迭代扩成搜索树
  • 2023 年 6 月:Reflexion 加了长期记忆——把过往失败的反馈存下来给下次用

回头看,Self-Refine 是 2023 年 LLM agent 风潮里架构最简、影响最深的一篇之一。后来所有”loop 类” agent 都能在它身上找到原型。

学到什么

  1. LLM 的生成和判别能力不对称——这是 Self-Refine 能成立的根因。一次写不出最好,不代表它认不出最好。
  2. agent loop 不一定要复杂:三个 prompt + 一个判停就是最小可行版,工程量极低,上限也明确
  3. 反馈必须具体:写 feedback prompt 时要求”位置 + 问题 + 建议”,是落地的关键控制点
  4. 不要无限迭代:固定上限 + 自停信号双保险,避免越改越烂

延伸阅读

  • 论文 PDF:Self-Refine arXiv 2303.17651(28 页,正文核心 10 页内)
  • 官方代码与 prompt:github.com/madaan/self-refine(看 prompt 怎么写比看模型怎么调更重要)
  • 后续工作:reflexion-2023 —— 给 Self-Refine 加长期记忆
  • 上一代思路:tree-of-thoughts-2023 —— 把单线迭代扩成搜索树
  • 实战框架:dspy —— 把 prompt 模板化、自动调参的工程化方案

关联

  • tree-of-thoughts-2023 —— 搜索维度的扩展,Self-Refine 是其退化为”线性单路”的特例
  • react-2022 —— 引入外部工具的 agent loop,Self-Refine 是去掉工具的纯内省版
  • chain-of-thought —— 单次推理的”想清楚再回答”,Self-Refine 把它扩成多轮
  • dspy —— 把这种 loop 写成可优化的 program 而不是手写 prompt

反向链接

  • dspy —— DSPy — 把 prompt 写成签名,让编译器替你调