ReAct + Reflexion - Reasoning Acting and Verbal Reinforcement Learning
[!联读黑称 / 术语速查]
ReAct 协议:
- thought: 模型自言自语写出的 reasoning trace, 不出现在环境里
- action: 模型对外发出的工具调用 / 环境指令, 会被执行
- observation: 工具或环境返回给模型的下一段输入
- trajectory: thought action observation thought … 的整条交替序列
- act-only: 没有 thought, 只对外发 action 的 baseline (WebGPT, SayCan 那一派)
- CoT-only: 全程在脑子里推, 不调外部工具的 baseline (Wei et al. 2022)
Reflexion 协议:
- Actor: 真正生成 action 的 policy LM, 在 Reflexion 实验里基本就是套了一层 ReAct 协议的 GPT
- Evaluator: 产生 reward signal 的判官, 可以是 ground-truth, heuristic, 或者另一个 LM
- Self-Reflection: 把 trajectory + reward 翻译成自然语言 critique 的 LM
- short-term memory: 当前 episode 的 trajectory 本身 (thought / action / observation 序列)
- long-term memory: 跨 episode 累积的 reflection 文本, 拼到下一次 prompt 头部
- verbal RL: 用自然语言 critique 代替梯度更新, 把 reward 从标量空间搬进语言空间
- trial: 一个完整的 episode (尝试一次任务), 失败后做 reflection, 再开下一个 trial
为什么 ReAct + Reflexion 要放一起读
这两篇是 LLM agent 这条研究线 2023 年的协议奠基 + 学习闭环;
- ReAct 定义了 agent runtime 的 “骨架协议” — 一个 trajectory 里 thought / action / observation 怎么交替;
- Reflexion 在这个骨架上外挂了一个跨 trial 的学习 loop — 失败 trajectory 写成自然语言反思, 拼回下一次 prompt;
后续几乎所有 agent paper (Self-Refine, CRITIC, LATS, Voyager, AutoGen, SWE-agent, 甚至 OpenAI o1 / DeepSeek-R1 的训练范式) 都可以拆解成 “在 ReAct 骨架的哪个组件上加了什么” 或 “把 Reflexion 的 verbal RL 内化到了哪一层”; 所以这两篇必须作为一个配对的整体理解, 而不是孤立地读;
前置基础 A: Chain-of-Thought 的局限
CoT 把 prompt 改成
形式上让模型先写一段推理再给答案, 在 GSM8K 这种纯算术 / 纯符号任务上有巨大提升; 但 CoT 有两个根本痛点:
- hallucination: 模型没有外部知识源, 只能凭参数里记得的事实"假装查到", 一旦记错就是错; 在 HotpotQA, FEVER 这种 knowledge-intensive QA 上经常会非常自信地编造一个看起来合理的实体或日期;
- error propagation: CoT 是一次性 sampling, 中间任何一步出错都不可逆, 后续步骤会继续在错误前提上推理;
CoT-SC (self-consistency) 用 sample 多条 rationale 再投票的方式部分缓解了第二个问题, 但仍然解决不了第一个问题, 因为所有 sample 共享同一份过时的内部知识;
前置基础 B: act-only agent 的局限
另一边, 一个纯 action-only 的 agent 拿到 observation 之后只能输出下一个 action, 比如:
1 | Action 1: search[Apple Remote] |
这种交互的问题在于:
- 模型对为什么要发这个 action 没有显式表示, 调试者只能从 action 序列倒推意图;
- 当 observation 很长或者跑题, 模型没有"我要做的事是 X, 当前还差 Y"这种 working memory 形式的痕迹, 很容易陷入循环 (反复 search 同一个词) 或者忘记原始问题;
- 任务一旦需要多跳推理 (multi-hop QA, compositional question), act-only 完全没有办法在 observation 之间做组合;
前置基础 C: Actor-Critic 是 Reflexion 的母架构
要理解 Reflexion 为什么自然地分出 Actor / Evaluator / Reflector 三组件, 必须回到 RL 的经典 Actor-Critic 框架 (Barto, Sutton, Anderson, 1983);
经典 Actor-Critic 定义:
- Actor 是 policy, 决定在状态 下选什么 action ;
- Critic 是 value function, 估计当前状态下未来累计 reward 的期望, 给 Actor 提供 gradient 反馈;
现代所有 policy gradient 算法 (A2C, PPO, SAC, DDPG, 以及 DeepSeek-R1 的 GRPO) 本质都是 Actor-Critic 的变种; LLM 时代的 RLHF, RLAIF, 以及现在的 reasoning model 训练流水线, 骨架仍然是这一套;
Reflexion 把这套搬进 LLM agent, 改了三件事:
- Critic 不再是参数化的 value function, 改成外部信号 (ground truth / heuristic / LM judge) , 拿到的是稀疏 outcome reward 而非密集 value;
- 不做 gradient update on Actor weights, 改成改 prompt;
- 在 Critic 和 Actor 之间多插一个 Self-Reflection 模块, 把 reward 翻译成自然语言反思;
第三件事是 Reflexion 的灵魂, 也是它跟经典 Actor-Critic 真正分家的地方;
Part I — ReAct: 把 reasoning 和 acting 放进同一条 trajectory
ReAct 论文定位
ReAct 不是一个新模型, 也不需要额外训练 (主要实验是 prompt-only, few-shot in-context), 它是一种输出协议: 让 LLM 在解决任务时生成一种交替结构的 trajectory, 把"想"和"做"显式地交叉起来; 通过这个协议, 同一个 frozen LLM 既能利用外部工具拿到 grounding, 又能保留 CoT 那种透明的 reasoning trace;
ReAct 解决的核心问题
现有方案的不足:
- CoT-only: 没有外部 grounding, 容易 hallucinate, 错了不可逆;
- act-only: 没有 working memory, 没有计划性, 调试不可读;
- CoT + retrieval (一次性 RAG): retrieval 只发生在 forward 之前, 中途无法根据 reasoning 改变检索意图;
ReAct 试图回答:
- 能不能让 reasoning trace 和 tool action 共享同一个生成过程, 让 thought 来规划下一个 action, 让 observation 来修正后续 thought?
- 在只改 prompt, 不改模型的前提下, 这种交替结构能不能在 knowledge-intensive QA 和 sequential decision-making 两类任务上同时拿到收益?
- 写出来的 thought 本身能不能作为 interpretability 和 human-in-the-loop 修正的入口?
ReAct 核心机制: thought action observation 的交替

原论文 Figure 1: (1a) HotpotQA 上 Standard / CoT-only / Act-only / ReAct 四种 prompting 的对比, (1b) AlfWorld 上 Act-only vs ReAct 的 trajectory 对比; 红框是错误信息, 绿框是正确证据, 这张图把 ReAct 协议的 thought / action / observation 交替结构和它相对 baseline 的优势一次说清楚, 后文公式都是在解释这张图;
ReAct 把 trajectory 定义为如下序列:
- : 第 步的 thought, 是模型自己生成的自然语言, 不发给环境, 只是写进 context 给后续 token 看;
- : 第 步的 action, 在固定的 action space 里取值, 会被 parser 抽出来发给环境;
- : 环境对 的返回, append 回 context;
形式上, ReAct 等价于把"reasoning trace"也写进了 action 历史, 但只标记一类不可观测的 action, 这类 action 不改变环境状态, 只改变 LLM 自己的 context; 这是它和经典 RL agent 最大的差异: action space 被人为扩张到了 , 其中 是自然语言"内心独白"空间;
一个 HotpotQA 上的具体 trajectory 大概长这样:
1 | Question: Aside from the Apple Remote, what other device can control the program Apple Remote was originally designed to interact with? |
这个例子里至少有两件事是 CoT 和 act-only 各自做不到的: thought 2 把 observation 1 的关键事实抽取出来并形成下一步 query (这是 act-only 缺的); thought 3 在 observation 2 失败时主动改写 query (这是 CoT-only 缺的, 因为它根本不会发请求);
Action Space 的两种设计
ReAct 在两类任务上跑实验, 对应两套 设计:
| 任务类 | action space | 备注 |
|---|---|---|
| Knowledge QA (HotpotQA, FEVER) | Search[entity], Lookup[string], Finish[answer] — 三个动作, 后端是 Wikipedia API |
action 空间极小, 关键是让 thought 决定 search 什么 |
| Decision-making (ALFWorld, WebShop) | 沿用环境本身的 action set (goto, take, open, put, click[button] 等) | action 空间是环境给的, ReAct 的贡献是注入 thought |
注意 Knowledge QA 这一组的 action 设计是有讲究的:
Search[entity]返回的是 Wikipedia 上实体页的前几句, 不是 search engine ranking 的 snippet — 这避免了 reasoning 被 search engine 的 ad 或者 SEO 干扰;Lookup[string]是在当前已经 search 过的页面内做 ctrl-F, 模拟人类"先看页面顶部, 再针对性查关键词"的两段式访问;Finish[answer]是一个 terminal action, 触发后 trajectory 终止并把 answer 提交给打分器;
这个 action 设计本身就是 ReAct 工作的一部分: 它把"信息获取"拆成 search (定位) + lookup (定点) 两步, 给 thought 留出干预的空间;
ReAct 的 Prompt 是怎么搭的
ReAct 全程 prompt-only, 不微调; few-shot 示例由人工写好, 每个示例就是一条完整的 thought / action / observation 交替轨迹; LLM 在 inference 时被给到:
模型逐 token 解码, 解码到 Action N: 这一行时, 外部 parser 停止解码, 把方括号里的 action 抽出来送给环境, 环境返回 observation 后 append 到 context 后面继续解码; 这是一个非常工程化的 loop, 整体跟现在所有 ReAct-style agent runtime (LangChain, LlamaIndex agent, 我们自己手撕 60 行 ReAct loop) 的实现是一致的;
关键点是: 停止解码的 trigger 不是模型的特殊 token, 而是 parser 检测到 “Observation N:” 这一行尚未填入, 这样旧 LLM (没有 function calling 训练) 也能跑;
ReAct 实验对比: 4 种策略
论文在 HotpotQA / FEVER 上比较了:
| 方法 | reasoning trace | tool call | 何时 stop | 备注 |
|---|---|---|---|---|
| Standard | 否 | 否 | 直接给答案 | 纯 in-context 回答 |
| CoT | 是 | 否 | 一次性输出 rationale + answer | 没有 grounding |
| CoT-SC | 是 × N | 否 | sample N 条后投票 | 缓解 error propagation, 没解决 hallucination |
| Act-only | 否 | 是 | 输出 Finish | 没有 thought, 容易循环 |
| ReAct | 是 (交替) | 是 | 输出 Finish | 同时拿到 grounding 和规划性 |
| ReAct→CoT-SC | 是 (优先 ReAct) | 是 | ReAct 失败时 fallback CoT-SC | 拿不到 evidence 时退回内部知识 |
| CoT-SC→ReAct | 是 (优先 CoT-SC) | 是 | CoT 自信度低时切 ReAct | 信号不够强时再去查证 |
主要结论:
- 在 HotpotQA 上, ReAct 单独跑略低于 CoT-SC (因为 search engine 偶尔检索失败会拖累整个 trajectory), 但 ReAct + CoT-SC 的组合显著超过任一单一方法;
- 在 FEVER (事实核查) 上, ReAct 单独就明显赢, 因为这类任务严重依赖外部证据;
- 在 ALFWorld (text-based household) 上, ReAct vs 模仿学习训练的 BUTLER, 在 prompt-only 设定下绝对成功率从 act-only 的 25% 飙升到 ReAct 的 71%; 关键是 thought 让模型能记住"我目前 sub-goal 是把刀放到 sink 里";
- 在 WebShop 上, ReAct 也明显赢 act-only, 帮模型在多个商品候选间做对比和取舍;
一句话总结: thought 在 sequential decision-making 上的收益比在 QA 上还要大, 因为 sub-goal 跟踪比 grounding 还更难离开自然语言;
ReAct 留下的三个失败模式 (← 这一节直接 bridge 到 Reflexion)
ReAct 协议本身解决了"思考 + 行动"的交替结构, 但 trajectory 一旦跑挂就跑挂了, 没有任何修复机制; 论文里坦诚列出了三种典型挂法:
- search failure: Wikipedia 拿不到精确实体, 模型陷入
Search[X] $\rightarrow$ not found $\rightarrow$ Search[X 改写] $\rightarrow$ not found的循环; - hallucinated thought after empty obs: observation 为空或没有有效信息时, 模型有概率在下一个 thought 里直接编造事实, 然后基于这个假事实输出 Finish;
- reasoning error propagation: thought 把 observation 关键事实抽错了, 之后所有 action 都建立在错误前提上;
ReAct 没有跨 trajectory 的记忆, 跑挂之后下一次 attempt 还是从零开始, 同样的错误大概率再犯一次; 这三个失败模式直接催生了 Reflexion 的存在动机;
Part II — Reflexion: 在 ReAct 之上加 verbal RL loop
Reflexion 论文定位
Reflexion 不是新模型, 也不需要 fine-tune; 它是一个框架: 在任何已有的 LLM agent (ReAct 是默认 Actor) 外面套一层 reflection loop, 让 agent 在每次 episode 失败后写一段自然语言反思, 把反思塞进下一次的 prompt 当 episodic memory;
它把这套机制起名叫 verbal reinforcement learning, 主张自然语言可以充当 reward signal 在不更新权重的前提下让 LLM 学习;
Reflexion 解决的核心问题
现有方案的不足:
- ReAct 单 trial: 失败后无累积, 下次 attempt 同样错;
- RL fine-tune (RLHF): 改权重才能"记住"经验, 训练贵且不可解释;
- Self-Refine (Madaan et al. 2023): 同一轮 output 内部的"生成 自检 重写", 只解决 within-output 修正, 没法跨 episode 累积;
Reflexion 试图回答:
- 能不能让 LLM agent 在 prompt-level 而非 weight-level 完成"从失败中学习"?
- 能不能用自然语言 critique 作为唯一的学习信号, 不依赖参数化 reward model?
- 同一个机制能不能在 decision-making, knowledge QA, code 三类截然不同的任务上都拿到一致提升?
Reflexion 核心机制: Actor / Evaluator / Self-Reflection 三组件分离
Reflexion 把一次完整的"学习闭环"拆成三个独立 LM-callable 组件:
1 | ┌─────────────┐ |
形式化一点, 第 个 trial 的 prompt 是:
注意这里两种 memory 的角色截然不同:
| 记忆类型 | 实际内容 | 跨 trial 累积 | 类比 |
|---|---|---|---|
| short-term memory | 当前 trial 的 thought / action / observation 序列 | ❌ trial 结束就清 | 工作内存 |
| long-term memory | 历次 trial 失败后的 reflection 文本 | ✅ 跨 trial 累积 | 教训本 |
很多人误以为 short-term memory 是用来"中途修正"trajectory 的, 不是; Reflexion 的 reflection 只在 trial 结束后才发生, 不存在 within-trial 修正; 那是 Self-Refine 的活;
Evaluator 的三种实现, 启发式可以打过 LM-as-judge
Reflexion 把 Evaluator 这一层故意做得通用, 论文里给了三种实现:
| Evaluator 类型 | 实现 | 适用场景 |
|---|---|---|
| Ground truth (binary) | 任务有标准答案, 直接比对 | HotpotQA (答案对/错), HumanEval (单测过/不过) |
| Heuristic | 程序化检查 (步数超限, 重复 action, 物体不存在) | ALFWorld (有限状态文字世界) |
| LM self-evaluation | 拿 GPT 当裁判, 读 trajectory 后输出二分类 | 没有 GT 的开放任务 |
这一节最反直觉的实验发现是 ALFWorld 上 Heuristic Evaluator 略胜 LM-as-judge (Figure 3a):
| Evaluator | trial 10 success rate |
|---|---|
| ReAct only (无 Reflexion) | ~0.75 (饱和) |
| ReAct + Reflexion (Heuristic) | ~0.97 |
| ReAct + Reflexion (GPT) | ~0.94 |
为什么启发式赢了 LM? 三层原因:
- 任务结构友好: ALFWorld 的失败模式 (循环 action, 物体不存在, 卡同一房间) 程序化检测准确率近 100%, GPT 读 100+ 步 trajectory 反而抓不住信号;
- self-preference bias: Actor 和 Evaluator 是同一家模型时, 模型倾向给自己输出打高分, 会系统性低估失败信号; 这是后来 Zheng et al. 2023 “Judging LLM-as-a-Judge” 系统量化的偏差;
- Reward 噪声会被 reflection loop 放大: Evaluator 错一次 reflection 学错 下次 prompt 注入错误经验 更可能继续错; 启发式的 deterministic 错误率 vs LM 的随机错误率, 在这个 loop 里被指数放大;
这条 ablation 直接催生了后续 process reward model (PRM) 这一支研究: Lightman et al. 2023 “Let’s Verify Step by Step” 训练专用 verifier; OpenAI o1 / DeepSeek-R1 用 rule-based reward (启发式) + verifier 模型混合, 故意避开 GPT-as-judge; AlphaProof 用 Lean formal verifier; 整条 reasoning model frontier 都在贯彻同一个原则: 奖励信号要尽量来自不可被 actor 操纵的源;
Evaluator design is the bottleneck, not policy design — 这条规则是这张图能教给你的最重要 takeaway;
Self-Reflection: 把 reward 翻译成自然语言
Reflector 这个组件的 prompt 大致长这样:
1 | You are an assistant tasked with reviewing the trajectory below. |
输出会被原样拼接到 long-term memory, 不做 embedding 也不做 summarization; 一个典型的 reflection 例子 (来自 ALFWorld):
“I failed to find the knife because I kept searching the bedroom; next time I should check the kitchen first since cooking utensils are usually stored there. I also wasted several steps opening cabinets I had already checked, so I should track which cabinets I’ve opened.”
这段文本就是 Reflexion 全部的"学习"; 没有 gradient, 没有 fine-tune, 只是一段会出现在下一次 prompt 里的 text;
这种设计有两个非显然的好处:
- 可解释: 你能直接读 reflection 知道 agent 学到了什么, 比看一组 LoRA 权重 diff 直观一万倍;
- 可干预: human-in-the-loop 时人可以手动改 reflection, 把先验知识塞进去, 这是 RL fine-tune 做不到的;
Reflection 的本质是把数值 reward 信号压缩并增维, 从标量空间搬进自然语言空间;
Verbal RL 这个 framing 才是 Reflexion 真正的贡献
看到这里你应该意识到, 从算法层面 Reflexion 真的就是一个 trick — end-of-episode reflection 拼回 prompt, 一图能讲完, 200 行代码能写完;
但让这篇论文被疯狂引用的不是算法, 而是它给整个领域命名了一件事:
自然语言 critique 可以充当 reward signal, 不需要 gradient, 不需要 reward model 参数化
这个 framing 直接喂出了 RLAIF (Bai et al. 2022 Constitutional AI), 喂出了 LLM-as-judge 整条评估管线, 喂出了 DeepSeek-R1 的 verbal self-correction (long CoT 里那些 “Wait, let me reconsider…”), 喂出了 process reward model 的概念准备;
类比 Transformer: 算法上"只有一个新东西" (self-attention 取代 RNN), 但它的真正贡献是 “sequence modeling 不需要 recurrence” 这个 conceptual liberation; Reflexion 处在同一个 pattern — mechanic 简单, framing 深远;
这件事对 PhD 阅读是关键 lesson: distill paper 到最小 pseudo-code 之后, 别立刻下"创新点太少"的判断, 还要问 “这篇给领域命名了什么 conceptual primitive”; 算法薄但 framing 厚的论文不止 Reflexion, SWE-agent, Voyager, o1, R1 都属于这一类;
ALFWorld 实验细节 (Figure 3)
ALFWorld 是文字版 ALFRED, 部分可观测的家庭机器人任务 (“把刀放到 sink 里”); 这是 ReAct 的主场 — long horizon, partial observability, sparse reward, irreversible action 全凑齐;
| 方法 | trial 0 | trial 10 |
|---|---|---|
| ReAct only (饱和) | 0.63 | 0.75 |
| ReAct + Reflexion (Heuristic) | 0.63 | 0.97 |
| ReAct + Reflexion (GPT) | 0.63 | 0.94 |
关键观察:
- trial 0 三者重合: 因为还没失败过, long-term memory 是空的, Reflexion 和 ReAct 没区别;
- trial 5-10 是 Reflexion 真正发力的区间: 累积的 reflection 让模型把过去十次失败的教训都写进了 prompt;
- Figure 3b 把失败原因拆成 “hallucination” 和 “inefficient planning”, 两者都随 trial 数下降, 说明 reflection 真的在学习这两类失败的修复策略, 不是噪声;
HotpotQA 实验细节 (Figure 4) — 和 ReAct 直接对照
HotpotQA 是 multi-hop QA, 但只有 2-3 跳, 是个推理多但 action horizon 短的任务; 这导致一个反直觉的现象: trial 0 时 ReAct-only ≈ CoT-only ≈ 0.34;
为什么 ReAct 没赢 CoT? 四个原因:
- HotpotQA 的事实大部分在 GPT 预训练时见过的 Wikipedia 里, parametric knowledge 已经覆盖;
- 2-hop horizon 太短, thought 作 working memory 没有用武之地;
- ReAct 引入了 search 失败模式 (找不到实体, 拿到错段落), 是 CoT 没有的新风险;
- ReAct 用的 Wikipedia API 只返回主页前几句, 答案藏在文章深处时根本拿不到;
Reflexion 的贡献在这张图里体现得很巧妙 — 加 Reflexion 后两条曲线显著拉开:
| 方法 | trial 0 | trial 6 |
|---|---|---|
| CoT only | 0.34 | 0.34 (无变化) |
| ReAct only | 0.34 | 0.34 (无变化) |
| CoT + Reflexion | 0.34 | 0.40 (小幅) |
| ReAct + Reflexion | 0.34 | 0.55 (大幅) |
Reflection 给 ReAct 的提升远大于给 CoT 的提升; 这是一条跨论文的通用判断:
Self-improvement 的天花板由 action space 决定; action space 越大, reflection 的回报越高;
CoT 能 reflect 的只有 reasoning 的措辞和顺序, 底层 prompt 没法显著换; ReAct 能改 search query, 改 lookup 策略, 改 search 顺序, 可塑性大得多; 这条规律后续在 Voyager (把 action 扩展到任意 Python skill) 上被进一步放大, 在那里 Reflexion 风格的累积学习收益比 HotpotQA 大一个数量级;
CoT (GT) 这个 oracle 上限测试
Figure 4(b) 引入了一个特殊变种 CoT (GT) — 把 HotpotQA dataset 标注好的 supporting paragraphs 直接塞进 prompt, 跳过 retrieval, 只测纯 reasoning 能力:
| 设定 | trial 0 |
|---|---|
| CoT only (纯 parametric) | 0.34 |
| ReAct only (自己 search) | 0.34 |
| CoT (GT) (gold passages 直接给) | 0.61 |
这个 0.27 个百分点的 gap 告诉你: HotpotQA 上 retrieval quality 才是真正的瓶颈, 不是 reasoning quality; ReAct 协议是对的, 它的 search API 不行;
这个观察直接催生了 agentic RAG 这条研究线 — Self-RAG, FLARE, Adaptive-RAG 这些后续工作的 motivation 都是 “ReAct 协议保留, retriever 大幅升级”;
HumanEval 实验细节
HumanEval 是函数级 code generation, Evaluator 用单测;
| 方法 | pass@1 |
|---|---|
| GPT-4 baseline | 80.1% |
| GPT-4 + Reflexion | 91.0% |
这是 Reflexion 数字最漂亮的一组, 也是它在工业界最被广泛复制的 setting — 因为 单测就是天然的 ground truth Evaluator, 不需要任何额外设计;
Self-Debug (Chen et al., ICLR 2024), AlphaCodium, Aider 的 “test-driven repair” loop 全是 Reflexion-in-code 的变种;
Reflexion vs Self-Refine — 极易混淆的两篇
两篇同期 (2023 春) 出来的工作经常被一起讲, 但 scope 完全不一样:
| 维度 | Reflexion | Self-Refine (Madaan et al. 2023) |
|---|---|---|
| 修正的尺度 | between-episode (跨 trial) | within-output (同一轮内) |
| 状态间隔 | trial 失败后才反思 | 生成后立刻自检 |
| 适用任务 | sequential decision-making, multi-step QA | single-turn generation (写作, 数学, 代码 polish) |
| 长期记忆 | ✅ 跨 trial 累积 | ❌ 没有 |
| Action space | 真实环境 action | 文字生成本身 |
两者解决的是不同尺度的 self-correction, 不互斥, 现实部署常常组合用 — Self-Refine 处理同一轮的措辞 / 逻辑修正, Reflexion 处理跨任务的策略级学习;
Reflexion 的失败模式与限制
Reflexion 在实验中已经暴露的限制:
- reflection 长度爆炸: 每个 trial 累积一段, 跑十几轮后 long-term memory 占掉一大半 context window; 生产系统必须加 summarization 或 retrieval 选 top-k reflection, 但论文里没解决;
- reflection 质量不可控: Reflector 偶尔写出空话 (“I should try harder next time”), 这种 reflection 注回 prompt 等于浪费 token;
- 依赖 Evaluator 准确性: 如前所述, Evaluator 错一次会通过 reflection loop 放大;
- 只学失败, 不学成功: 论文设计里 Reflector 只在失败时触发, 成功的 trajectory 不写反思, 这意味着模型不会主动归纳"什么策略是 work 的", 后续 Voyager 通过把成功 trajectory 编译成 skill 解决了这件事;
Part III — 两篇合起来看
协议层 学习层的演化
把两篇拼起来看, LLM agent 的一次完整 iteration 长这样:
1 | ┌──────────── outer Reflexion loop ────────────┐ |
ReAct 定义了内层循环 (一次 trajectory 内的 thought / action / obs 交替), Reflexion 定义了外层循环 (跨 trajectory 的反思累积); 这两层结构成了 2023 年后 LLM agent 的事实标准, 后续工作几乎都是在这两层上各自加东西;
ReAct vs Reflexion 一表对照
| 维度 | ReAct | Reflexion |
|---|---|---|
| 解决的尺度 | 单次 trajectory 内推理 + 行动的统一 | 跨 trajectory 的失败累积学习 |
| 是否改模型权重 | ❌ prompt-only | ❌ prompt-only |
| 核心数据结构 | trajectory (thought / action / obs 序列) | long-term memory (reflection 文本累积) |
| 组件数 | 1 个 (单一 LM) | 3 个 (Actor / Evaluator / Reflector) |
| 算法层面新意 | 中等 (协议设计) | 低 (一个 reflection trick) |
| Framing 层面新意 | 高 (推理 + 行动统一) | 极高 (verbal RL 作为新 reward 范式) |
| 主要失败模式 | search failure, hallucinated thought, error propagation | reflection 长度爆炸, evaluator 噪声, 只学失败 |
| 后续工作的协议来源 | LangChain / LlamaIndex / AutoGen 的 agent loop | RLAIF / PRM / R1 long CoT 的训练范式 |
后续工作系谱表 (合并)
后续 agent / reasoning model 工作都可以拆解成"在 ReAct 骨架的哪个组件上加, 或者把 Reflexion 的 verbal RL 内化到哪一层":
| 后续工作 | 加在哪 | 加了什么 |
|---|---|---|
| Self-Refine (Madaan 2023) | Reflexion 同期 | 把 reflection 缩到 within-output 尺度 |
| CRITIC (Gou 2023, ICLR 2024) | Reflexion 的 Reflector | 强制调外部工具校验事实, 不只 verbal |
| Self-Debug (Chen 2023, ICLR 2024) | Reflexion 的 Evaluator | 专门用 code execution, 在 HumanEval / MBPP 落地 |
| Tree of Thoughts (ToT) | ReAct 的 thought | 把 thought 从单链改成树, 在节点做 BFS / DFS |
| LATS (Zhou 2024) | ToT + Reflexion | thought 树 + MCTS + verbal value model |
| Voyager (Wang 2023) | Reflexion 的 long-term memory | 把成功 trajectory 编译成 reusable skill code, 解决"只学失败"的局限 |
| Toolformer (Schick 2023) | ReAct 的 action 协议 | 把 action 协议编进模型权重, 不再需要 few-shot |
| MemGPT (Packer 2023) | ReAct 的 context 管理 | 给 trajectory 加 OS-style memory hierarchy |
| SWE-agent (Yang 2024) | ReAct 的 action space | 换成 file edit / shell, 在 SWE-bench 上跑 |
| AgentTuning / FireAct | Reflexion 的 long-term memory | 把 trajectory 蒸馏成 SFT 数据, 从 prompt-level 搬到 weight-level |
| STaR / ReST (Zelikman 2022, Singh 2024) | Reflexion 的精神 | filter 过的成功 trajectory SFT, bootstrapped self-improvement |
| DeepSeek-R1 / o1 (2024-2025) | Reflexion + ReAct 都内化 | long CoT 里 “Wait, let me reconsider…” 就是 in-trajectory 版本的 verbal RL |
| AlphaEvolve / Absolute Zero (2024-2025) | Reflexion 的 self-play 推广 | 自己出题自己解, 反思进一步去人化 |
整条 reasoning model frontier 的训练范式, 本质上是 Reflexion 的 conceptual primitive (verbal critique as reward) 的工业化和 scale-up; 同时, runtime 层面的 agent framework (LangChain / AutoGen / OpenAI Assistants API / Claude Code) 全部是 ReAct 协议的工程封装;
复杂度 / 成本侧
ReAct trajectory 的 token 数远高于 CoT, 因为每步都要写一段 thought + 一段 action + 把 observation append 回去; 单次 trajectory 期望长度大致是
其中 是 step 数, 分别是 thought / action / observation 的平均 token 数, 而 通常远大于 (Wikipedia 一段就上百 token); Reflexion 在 ReAct 之上再叠一个 long-term memory, 总成本是
也就是 trial 的 prompt 长度随 线性增长, 这是 Reflexion 在生产环境部署最大的痛点; 实践中要么 truncate observation, 要么再加一层 summarizer (这就过渡到 MemGPT 那一套了);
我对这两篇的几个判断
- ReAct 真正的贡献不在性能数字, 而在协议: thought / action / observation 这套交替结构是后续所有 agent runtime 的事实标准;
- “prompt-only, 不训练” 这件事是 ReAct 能扩散得这么快的关键, 任何团队拿一个 frozen LLM 就能跑;
- ReAct 协议的根本短板是 trajectory 不可分支 — 单链推理, 一旦 thought 错了, 后续步骤继承错误前提; 这是 ToT, LATS 这些后续工作的存在动机;
- Reflexion 算法层面薄, framing 层面厚: 这是 PhD 阅读时最容易踩的坑 — 看完算法觉得"就这?", 错过了它的 conceptual contribution; 真正的护城河在 “verbal RL” 这个命名;
- 三组件分离 (Actor / Evaluator / Reflector) 是 Reflexion 最被低估的贡献: 后续所有 agent framework 都沿用这个 abstraction, 看 SWE-agent, Voyager, AutoGen 时都能用这把尺子拆;
- Evaluator 设计是 agent 研究的真正瓶颈: 不是 policy, 不是 reasoning; 谁能定义出可信且不可作弊的 reward signal, 谁就握住了 self-improvement 的方向盘; ALFWorld 上 Heuristic > GPT 这条 ablation 是这条规律最早的实证;
- Reflexion 不可能 scale 到生产: long-term memory 增长无界, 必然要被 summarization / retrieval 替代; 真正 production-level 的 self-improving 路线最终会回到 weight-level (R1 那条线), Reflexion 是过渡形态, 但作为概念证据它永远是基石;
[!ReAct + Reflexion 联读主流观点总结]
如果把这两篇当一个整体浓缩, 它们的主流观点是:
- CoT 提供 reasoning, 但没 grounding, 容易 hallucinate; act-only agent 有 grounding, 但没 working memory, 容易循环; ReAct 把 thought / action / observation 三类 token 放进同一个生成序列, 让 LLM 自己决定每一步是想还是做, 是最朴素的统一办法;
- ReAct 是 prompt-only 协议, 任何 frozen LLM 都能跑; 它的真正贡献是定义了 agent runtime 的事实标准 trajectory 结构, 后续所有 agent framework 都是它的工程封装;
- ReAct 协议在单 trial 内是对的, 但跨 trial 不会学习; Reflexion 在外面套一层 reflection loop, 让 agent 在 trial 失败后写自然语言反思并拼回下一次 prompt;
- Reflexion 把 RL 经典 Actor-Critic 拆成三件套 — Actor (ReAct policy), Evaluator (GT / heuristic / LM-as-judge), Reflector (LM, 把 reward 翻译成自然语言); 这套三组件是后续 agent / RLAIF 研究的事实抽象;
- Reflexion 的真正 conceptual contribution 是 verbal reinforcement learning 这个 framing — 自然语言 critique 可以充当 reward signal 在不更新权重下让模型学习, 这个想法后来被吸收进了 RLAIF / Constitutional AI / PRM / o1 / R1 的训练范式;
- 两篇都暴露了同一个深层问题: agent 研究的真正瓶颈在 Evaluator 设计 (奖励信号是否可信, 是否可作弊), 而不是 policy 或 reasoning; ALFWorld 上 Heuristic > GPT 这条 ablation 是这条规律的最早实证, 后续整条 process reward model 路线都在贯彻这件事;
- ReAct 定义了 agent runtime 的内层循环 (trajectory), Reflexion 定义了外层循环 (反思累积); 后续工作几乎都可以拆解成"在 ReAct 协议的哪个组件上加 / 把 Reflexion 的 verbal RL 内化到哪一层"; 把这两篇当作"双坐标系", 整个 LLM agent 文献都能装进去;
