16. ReAct 循环失败时怎么办?Reflexion 和 Self-Refine 的核心思路是什么?

整理 Agent 自我纠错的常见模式与工程取舍。

简单回答

ReAct 循环失败时单靠继续 ReAct 很难自救——错误会沿着同一条思路被强化。Reflexion 和 Self-Refine 是两种"让 Agent 自我纠错"的代表方案。Self-Refine 是单轮内的自我修订——生成 → 自评 → 修改,直到满足某个停止条件。Reflexion 是跨轮次的反思——任务失败后让 LLM 用语言总结"为什么失败、下次怎么改",把这条反思加进下一轮的上下文,作为一种文本形式的"经验记忆"。两者的共同前提是:LLM 自己评估自己的输出比生成新输出更容易,所以可以用评估能力来弥补生成能力的不足。

详细解释

为什么 ReAct 自己纠不了自己的错

ReAct 的循环是 Thought → Action → Observation → Thought → ...,每一步的 Thought 都基于之前的全部上下文。问题在于错误会"自我合理化"——一旦某一步走偏,后续的 Thought 倾向于在这条错误路径上继续推理,而不是回头质疑前面的判断。

这是因为 LLM 在生成下一段 Thought 时看到的上下文是"我已经决定这样做",模型很难凭空跳出这个框架去推翻自己。表现出来就是本专题第 08 篇文章里讲过的死循环、错误累积、过早终止等。

要打破这个惯性,需要显式地引入一个"反思"步骤——明确把模型从"生成"切换到"评估"模式。Self-Refine 和 Reflexion 是这两种模式的代表,区别在于反思发生的粒度。

Self-Refine:单轮内的自我修订

Self-Refine 的思路是把一次任务拆成 Generate → Feedback → Refine 三步,并且这三步都用同一个 LLM 来完成,只是 Prompt 不同。

第一步 Generate 是常规生成,得到一个初版输出。第二步 Feedback 用一个专门的 Prompt 让 LLM 评价自己刚才的输出——"这段代码有什么问题?这段回答漏了什么?",输出一段自然语言反馈。第三步 Refine 把原始输出和反馈一起喂回去,让 LLM 基于反馈生成修改后的版本。

这个过程可以迭代多次,直到反馈认为"没问题了"或达到最大轮数。

直觉上这看起来像是"左手打右手",但实证效果还行。原因是 LLM 的判别能力(看一段输出有没有问题)通常比生成能力(一次写出完美输出)强。给定一段已有的代码或文本,挑刺比从零写出来容易。Self-Refine 利用的就是这个判别-生成的不对称性。

适用场景比较具体:写代码、写长文、写数学题解这类有明确质量标准的任务。对开放式对话或创意类任务效果不明显,因为没有清晰的"正确"标准供反馈引用。

Reflexion:跨轮次的经验积累

Reflexion 解决的是另一个问题——Agent 在一个 episode(任务尝试)失败后,怎么避免下次重复同样的错误。

它的做法是引入一个外部的"反思缓冲区"。每次 episode 结束(无论成功还是失败),让 LLM 总结"这次的整体表现如何、哪一步是关键失误、下次应该怎么改进",把这段反思以自然语言形式存进缓冲区。下一次开始这个任务时,把缓冲区里的反思拼进 Prompt 作为额外的上下文。

这样 Agent 在重试时不是从零开始,而是带着"上次的教训"重新尝试。多轮迭代下来,反思缓冲区像一个越来越厚的"经验册"。

Reflexion 在 HotpotQA、AlfWorld、HumanEval 等需要多步推理或多轮交互的 benchmark 上都有明显提升。直觉上它把强化学习的"试错"换成了"用语言写下教训"——不更新参数,而是更新上下文。

它的局限也很明显。反思的质量取决于 LLM 自己的诊断能力,如果模型自己也没意识到错在哪,反思就是空话。反思缓冲区也可能膨胀到很长,反而稀释了关键信息。而且这个机制要求任务可重试——对于客服对话这类一次性的、不可重来的任务用不上。

Self-Refine vs Reflexion vs Critic Model

这三种方案值得放在一起对比。Self-Refine 是单轮自我修订,反思和生成是同一个模型。Reflexion 是跨轮次反思,依然是同一个模型,但反思的粒度从"输出级"变成"任务级"。Critic Model(评判模型)则是用一个独立的、专门训练的模型做评估,常见于 RLHF 中的 Reward Model,或者一些 Agent 系统里的"Verifier"。

工程上的取舍是:Self-Refine 实现最简单,单次任务内多调用几次 LLM 就行。Reflexion 需要维护一个跨任务的反思状态,工程上稍重,但对可重试的任务收益明显。独立 Critic Model 准确度上限最高,但需要额外训练或维护一个模型,复杂度最高。

实际项目里怎么落地

最常见的混合形态是:在 Agent 主循环里加一个轻量的 Self-Refine 节点,比如生成完最终答案后用一个独立的 Prompt 检查"答案是否回答了用户问题、是否有事实性错误、是否引用了正确来源",如果发现问题就让模型修订一次。这是本专题第 12 篇文章里讲的 Agent Guardrails 的一种自动化形式。

更激进的做法是在每一步 Tool Calling 之后做一次微型反思——"刚才这次工具调用拿到了想要的信息吗?没有的话是工具选错了、参数不对、还是该换种问法?"这种"细粒度反思"能减少一些循环和死路问题,代价是 token 成本和延迟会显著上升,需要根据场景权衡。

面试时可以这样答

ReAct 循环最大的问题是错误会自我合理化——模型基于之前的上下文继续推理,很难跳出来质疑自己。要纠错就必须显式引入一个"反思"步骤,把模型从生成模式切到评估模式。

Self-Refine 是单轮内的自我修订,三步走——先生成一个初版输出,再用同一个 LLM 评价这版输出有什么问题,最后基于反馈生成修改版。原理是 LLM 的判别能力通常比生成能力强,挑刺比从零写容易。适合写代码、写长文这种有明确质量标准的任务。

Reflexion 是跨轮次的经验积累。任务失败后让 LLM 用自然语言总结"哪步错了、下次怎么改",存进一个反思缓冲区。下次重试时把这段反思拼进上下文。本质是用语言形式做"试错学习",不更新参数只更新上下文。在多步推理任务上效果不错。

实际项目里我常用的是轻量版 Self-Refine——Agent 输出最终答案前加一个自检步骤,比如"答案是否回答了问题、有没有引用错的来源",发现问题就让模型再修订一次。完整 Reflexion 工程上稍重一些,但对可重试任务很有用。

常见追问

  1. Self-Refine 的迭代什么时候停?停止判断本身怎么避免被 LLM"敷衍"?
  2. Reflexion 的反思缓冲区会越来越长,怎么管理?
  3. 如果 LLM 自己诊断不出问题,自我反思机制就失效了,怎么补救?