Reflexion: Language Agents with Verbal Reinforcement Learning
# 反射:言语强化学习的语言代理
原论文:Reflexion: Language Agents with Verbal Reinforcement Learning
# 摘要
大型语言模型 (Large Language Models,LLMs) 作为目标驱动的智能体被越来越多地用于与外部环境 (例如,游戏、编译器、API 等) 进行交互。然而,由于传统的强化学习方法需要大量的训练样本和昂贵的模型微调,这些语言智能体快速有效地从试错中学习仍然具有挑战性。我们提出了一种新的框架 Reflex,它不是通过更新权重来加强语言代理,而是通过语言反馈来加强语言代理。具体来说,反应主体会对任务反馈信号进行言语反思,然后在情景记忆缓冲器中保持自己的反射性文本,以便在随后的试次中诱发更好的决策。反射足够灵活,可以包括各种类型 (标量值或自由形式的语言)
# 1. 引言
最近的工作如 ReAct [30]、SayCan [ 1 ]、Toolformer [ 22 ]、HuggingGPT [ 23 ]、生成式 Agent [ 19 ]、WebGPT [ 17 ] 等已经证明了构建在大型语言模型 (large language model,LLM) 内核之上的自主决策 Agent 的可行性。这些方法使用 LLM 生成可用于 API 调用并在环境中执行的文本和 "动作"。由于它们依赖于具有大量参数的大规模模型,因此这些方法迄今为止仅限于使用语境样本作为教授代理的方式,因为更多的传统优化方案,如梯度下降的强化学习需要大量的计算和时间。
在这篇文章中,我们提出了一种替代方法,称为 "反射" (Reflex),它使用语言强化来帮助代理人从先前的失败中学习。回应将来自环境的二元或标量反馈以文本摘要的形式转换为言语反馈,并在下一集作为 LLM 施动者的附加语境添加。这种自我反思反馈作为一种 "语义" 梯度信号,通过为智能体提供一个具体的改进方向,帮助其从先前的错误中学习,从而更好地完成任务。这就类似于人类如何迭代地学习以少数次的方式完成复杂的任务 -- 通过反思他们之前的失败,以便为下一次尝试形成改进的攻击计划。例如,在图 1 中,反射代理通过尝试、错误和自我反思来学习优化自己的行为,以解决决策、编程和推理任务。
生成有用的反思性反馈是具有挑战性的,因为它需要很好地理解模型在哪里犯了错误 (即信用分配问题),以及生成包含可操作的改进见解的摘要的能力。我们探索了三种方法 -- 简单的二进制环境反馈,针对常见失败案例的预定义启发式,以及自我评估,如使用 LLMs (决策) 或自我编写的单元测试 (编程) 进行二分类。在所有的实现中,评价信号被放大为自然语言经验总结,这些经验总结可以存储在长时记忆中。
与更传统的 RL 方法 (如策略或基于值的学习) 相比,Reflex 有几个优点:1) 它是轻量级的,不需要对 LLM 进行微调;2) 它允许更细微的反馈形式 (例如,有针对性地改变行动),而不是那些难以执行准确的信用分配的标量或向量奖励;3) 它允许在过去的经验中使用更明确和可解释的情景记忆形式;4) 它为未来的情节提供更明确的行动暗示。同时,它也存在依赖 LLM 的自我评价能力 (或启发式) 的力量和不具备成功的正式保证的缺点。然而,随着 LLM 能力的提高,我们只预期这种范式会随着时间的推移而变得更好。
我们在 (1) 决策任务上测试长轨迹上的顺序动作选择,(2) 推理任务上测试知识密集型的单步生成改进,(3) 编程任务上教会智能体有效地使用外部工具,如编译器和解释器。在所有三类任务中,我们都观察到 Reflex Agent 是更好的决策者、推理者和程序员。具体而言,在 12 个迭代学习步骤中,Reflex Agent 在决策 AlfWorld [ 24 ] 任务上比强基线方法提高了 22%,在 HotPot QA [ 28 ] 中的推理问题上提高了 20%,在 HumanEval [ 6 ] 上的 Python 编程任务上提高了 11%。
综上所述,我们的贡献有以下几点:
・我们提出了一种新的 "言语" 强化范式 Reflex,将政策参数化为代理人的记忆编码和 LLM 参数的选择。
・ 我们在 LLMs 中探索了自我反思的这种涌现特性,并通过实验证明了自我反思对于学习复杂任务是非常有用的。
・ 我们介绍了 LeetcodeHardGym,一个由 19 种编程语言中的 40 个具有挑战性的 Leetcode 问题 ("硬水平") 组成的代码生成 RL 训练环境。
・ 我们展示了 Reflex 在多个任务上实现了对强基线的改进,并在各种代码生成基准上取得了最先进的结果。
# 2. 相关工作
图 1:反思任务包括决策 4.1、编程 4.3 和推理 4.2。
推理和决策 Self-Refine [15] 使用迭代的框架进行自我修正,通过自我评估来自主地改进生成。这些自我评价和自我完善的步骤是以给定的任务限制为条件的,例如 "这一代人如何以更积极的方式写作"。自求精是有效的,但仅限于单代推理任务。Pryzant 等人 [ 21 ] 进行了类似的语义提示书写优化,但也仅限于单代任务。Paul 等人 [ 20 ] 微调评价模型,在轨迹中提供中间反馈,以提高推理反应。Xie 等人 [ 27 ] 使用随机束搜索来执行一个更有效的决策搜索策略,该策略允许智能体由于其自我评价成分而使用预见优势。Yoran 等人 [ 31 ] 和 Nair 等人 [ 16 ] 使用判定模型在几代人中进行推理。Kim 等人 [ 10 ] 使用固定步数的重试模式,没有评估步。Goodman [ 9 ] 执行了对上一代提出优化的定性评估步骤。在本文中,我们证明了这些概念中的一些可以通过自我反思来增强,以建立对自我反思经验的持久记忆,这使得代理可以识别自己的错误,并自我暗示随着时间的推移从错误中吸取教训。
编程 过去和最近的一些工作采用了测试驱动开发或代码调试实践的变体。AlphaCode [14] 在评估了一组在隐藏测试用例上的生成。CodeT [ 5 ] 使用自生成的单元测试,用于对生成的函数实现进行打分。自调试 [ 7 ] 使用了一个调试组件,该组件用于在给定代码执行环境反馈的情况下改进现有的实现。CodeRL [ 12 ] 将问题设置在 RL 框架中,使用行动者评论家设置来调试程序,并给出执行环境的反馈。AlphaCode、Self-Debugging 和 CodeRL 在修复复杂度较低的程序错误时是有效的,但它们依赖于无效的通过 @1 合格性的真实测试用例,并且没有使用自我反思来弥合错误识别和实现改进之间的鸿沟。CodeT 不访问隐藏的测试用例,但没有实现自学习步骤来改进代码编写。
# 3. 反射性:通过言语反射进行强化
我们开发了一个 Reflex 的模块化公式,使用了三个不同的模型:一个 Actor,记为,它生成文本和动作;以 Me 为代表的 Evaluator 模型对 产生的输出进行打分;以及一个自我反思模型,记为,它产生言语强化线索来辅助 Actor 进行自我提升。我们对每个模型进行了详细的描述,并随后在 Reflex 框架内阐明了它们的协同作用。
图 2:(a) Reflex 图。( b ) 反射增强算法
Actor Actor 是建立在一个大语言模型 (LLM) 的基础上的,该模型专门提示生成以状态观测为条件的必要文本和动作。类似于传统的基于策略的 RL 设置,我们在 t 时刻从当前策略 π θ 中采样一个动作或生成,从环境中接收一个观测。我们探索了各种行动者模型,包括思想链 (Chain of Thought)[ 26 ] 和 ReAct [ 30 ]。这些不同的生成模型允许我们在 Reflex 框架内探索文本和动作生成的不同方面,为它们的性能和有效性提供了有价值的见解。此外,我们还添加了一个记忆组件 mem,为这个 agent 提供了额外的上下文。这种适应性是受 Brooks 等人 [ 3 ] 的启发,他们提出了一个策略迭代算法 ap
Evaluator Reflex 框架中的 Evaluator 组件在评估 Actor 产生的输出的质量中起着至关重要的作用。它将生成的轨迹作为输入,并计算在给定任务环境下反映其性能的奖励分数。定义适用于语义空间的有效值和奖励函数是困难的,因此我们考察了 Evaluator 模型的几种变体。对于推理任务,我们探索了基于精确匹配 (EM) 评分的奖励函数,以确保生成的输出与期望解紧密对齐。在决策任务中,我们使用预先定义的启发式函数,这些函数是根据特定的评价标准定制的。此外,我们还尝试使用 LLM 本身的不同实例化作为评估器,为决策和编程任务生成奖励。这种对评价者设计的多方位方法允许我们检查不同的策略来对生成的输出进行评分,以了解它们在一系列任务中的有效性和适用性。
自反射 自我反思模型作为 LLM 的一个实例,通过产生言语上的自我反思,为未来的试验提供有价值的反馈,在反思框架中起着至关重要的作用。给定一个稀疏的奖励信号,例如一个二进制的成功状态 (成功 / 失败),当前的轨迹和它的持久记忆,自反射模型会产生细致入微和特定的反馈。然后,这种比标量奖励更有信息的反馈存储在智能体的记忆 (mem) 中。例如,在多步决策任务中,当智能体接收到故障信号时,它可以推断一个特定的动作 导致了随后的不正确动作 和。然后,代理可以口头陈述,它应该采取不同的行动,,这将导致 和, 并将这种经验存储在其记忆中。在随后的试次中,代理可以利用过去的经验,通过选择行动 来调整自己在 时刻的决策方式。这种尝试、错误、自我反思和持久记忆的迭代过程使智能体能够利用信息性的反馈信号迅速提高其在各种环境中的决策能力。
记忆 Reflex 过程的核心成分是短期和长期记忆的概念。在推理时,行动者将其决策条件限定在短时记忆和长时记忆上,类似于人类记忆细粒度近期细节的方式,同时也会回忆从长时记忆中提炼出来的重要经验。在强化学习装置中,轨迹历史作为短时记忆,自反射模型的输出存储在长时记忆中。这两个记忆成分共同提供了特定的情境,但同时也受到了几个试次的经验教训的影响,这也是 Reflex Agent 相对于其他 LLM 动作选择作品的一个关键优势。
Reflexion 过程
在过过程 1 中,反射被形式化为一个迭代优化过程。在第一个试次中,Actor 通过与环境交互产生一个轨迹。然后,Evaluator 产生一个得分, 计算为。 只是对试验 的一个标量奖励,它随着特定任务性能的增加而增加。在第一次试次后,为了将 放大为 LLM 可以改进的反馈形式,自我反思模型对 {,} 集合进行分析,产生摘要,存储在记忆记忆中, 为试次 的言语经验反馈。Actor、Evaluator 和自反思模型通过循环往复的试验共同工作,直到 Evaluator 认为 是正确的。如 3 所述,Reflexion 的记忆成分对其有效性至关重要。在每次试验后,,,被加入到记忆中。在实际应用中,我们通过最大数量的存储经验, (通常设置为 1 ~ 3) 来约束 mem,以遵守最大上下文 LLM 限制。
# 4. 实验
我们在决策、推理和代码生成任务上评估了各种自然语言 RL 设置。具体来说,我们在 HotPotQA [28],AlfWorld [ 24 ] 中常见的家庭环境中的多步任务,以及 HumanEval [ 6 ],MBPP [ 2 ] 中的解释器和编译器,以及一个新的基准测试程序 LeetcodeHard 上挑战一个代理执行基于搜索的问答任务。最值得注意的是,在 AlfWorld 上,Reflex 在强基线上的性能提升了 22 %,在 HotPotQA 上提升了 20 %,在 HumanEval 上提升了 11 %。
# 4.1 序列决策:ALFWorld
AlfWorld 是一套基于文本的环境,它基于 TextWorld [8],在各种交互环境中挑战 Agent 解决多步骤任务。遵循 Yao 等 [ 30 ] 的方法,我们在 134 个 AlfWorld 环境中跨 6 个不同的任务运行该代理,包括寻找隐藏对象 (例如,在抽屉里找到一个铲刀)、移动对象 (例如,将一把小刀移到切割板上) 和用其他对象操作对象 (例如,在冰箱里冷却一个番茄)。我们使用 ReAct [ 30 ] 作为动作生成器,因为 Yao 等人 [ 30 ] 在使用显式中间思想的长轨迹决策中显示出了成功。AlfWorld 任务自然需要一个自我评价步骤,因为只有当任务完成时,环境才能发出信号。为了实现完全自主的行为,我们实现了两种自我评估技术:使用 LLM 的自然语言分类和手写启发式。启发式是简单的:如果智能体执行相同的动作并收到相同的响应超过 3 个周期,或者如果当前环境中采取的动作数量超过 30 (低效的规划),我们进行自我反思。在基线运行中,如果建议进行自我反思,则跳过自我反思过程,重新设置环境,开始新的试次。在 Reflex 运行中,代理使用自我反思来发现其错误,更新其记忆,重置环境,并开始新的尝试。为了避免可能超过最大限制的很长的提示窗口,我们将代理的记忆截断到最后 3 次自我反射 (经验)。
为了避免句法错误,我们为 agent 提供了两个特定领域的小样本轨迹。对于 LLM,我们使用与 Yao 等 [30] 相同的小样本轨道例子和 GPT-3。附录中包括 AlfWorld 任务、ReAct 小样本提示和 Reflex 示例。
结果 ReAct+Reflexion 在 134 个任务中完成了 130 个任务,使用简单的启发式方法来检测幻觉和低效的计划,明显优于 ReAct。进一步,ReAct+Reflexion 通过连续 12 个试次的学习来解决额外任务。在 ReAct-only 方法中,我们发现在进行到 6 至 7 尝试时,性能增加就停止了。
图 3:(a) AlfWorld 在 134 个任务中的表现,显示了使用启发式 ( Heuristic ) 和二分类 ( GPT ) 的自我评估技术解决任务的累积比例。( b ) 按故障原因对 AlfWorld 轨迹进行分类。
分析 在基线失败的 AlfWorld 轨迹中,一个常见的错误是当代理认为自己拥有一个物品,但实际上并不拥有该物品。代理在一个较长的轨迹中执行若干动作,并且不能回溯其动作以发现错误。Reflexion 通过自我反思将长期的、失败的轨迹提炼为相关经验,并在未来作为 "自我暗示",几乎可以消除所有这些情况。在 AlfWorld 中,长时记忆帮助施动者的情况主要有两种:1) 长轨迹中的早期错误很容易被识别。代理人可以提出新的行动选择,甚至是新的长期计划。2) 检查物品的表面 / 容器太多。代理可以利用其在多个试验中的经验记忆来彻底搜索一个房间。在 3 中,学习曲线表明学习过程发生在多个经验上,这意味着代理人成功地平衡了案例 1 和 2,表现在前两个试验之间的改进的立即尖峰,然后在接下来的 11 个试验中稳步增加,以达到近乎完美的性能。另一方面,3 显示了一个 ReAct-only agent 收敛于 22% 的幻觉率,并且没有长期恢复的迹象。
# 4.2 推理:HotpotQa
HotPotQA [28] 是一个基于维基百科的数据集,包含 113k 个问答对,这些问答对要求代理人解析多个支持文档的内容和推理。为了测试推理能力的提高,我们实现了 Reflexion+Chain-of-Thought (CoT) [ 26 ],用于逐步 和 Q, 的实现,其中 是问题, 是来自数据集的背景真值, 是最终答案。由于 CoT 不是一种多步决策技术,因此我们给 Agent 赋予,以便我们可以在提供的文本的大段上隔离推理行为。为了测试需要推理和行动选择的整体问答能力,我们实现了一个 Reflexion+ReAct [30] 代理,该代理可以使用维基百科 API 检索相关上下文,并使用逐步显式思维推断答案。对于 CoT 的实现,我们使用 6-shot 提示;对于 ReAct,我们使用 2-shot 提示,而对于 Self-Reflexion,我们使用 2-shot 提示。所有的例子都可以在附录中找到。
鲁棒地评估自然语言答案是 NLP 中一个长期存在的问题。因此,在试验之间,我们使用精确匹配答案评分使用环境给代理一个二进制成功信号。每次试次结束后,采用自反射循环放大二进制信号,类似于 AlfWorld 中的决策设置 4.1,内存大小为 3 次经验。
结果 在几个学习步骤中,Reflexion 优于所有基线方法,具有显著的优势。此外,ReAct-only,CoT-only 和 CoT (GT)-only 的实现在任何任务上都不能概率性地改进,这意味着从任何基线方法的第一个试验中没有失败的任务能够在随后的试验中使用 0.7 的温度来解决。在 RReflexion 运行中,我们允许代理收集经验并重新尝试失败的任务,直到它在特定任务上产生连续 3 次失败的尝试。自然地,由于 CoT (GT) 能够接触到问题的基本真值背景,因此获得了更高的正确率分数。尽管如此,CoT (GT) 智能体仍有 39 % 的问题无法正确推理出正确答案,但 Reflex 帮助智能体在没有获得真实答案的情况下改正其错误,使其准确率提高了 14%。
图 4:思想链 (COT) 与 ReAct。在 100 个 HotPotQA 问题上,Reflexion 提高了搜索、信息检索和推理能力。(a) Reflexion ReAct vs Reflexion CoT (b) 只进行推理的 Reflexion CoT (GT) (c) Reflexion vs 情景记忆消融。
# 4.3 编程
我们在 MBPP [2],HumanEval [ 6 ] 和我们的新数据集 LeetcodeHardGym 上评估了在 Python 和 Rust 代码上编写的基线和 Reflex 方法。MBPP 和 HumanEval 度量函数给出了人体生成精度的自然语言描述。我们使用基准语言编译器,MultiPL-E [ 4 ] 将 Human Eval 和 MBPP 的子集翻译成 Rust 语言。MultiPL-E 是一个小型编译器的集合,可用于将 Python 基准题翻译成 18 种其他语言。我们包括 Rust 代码生成的实验,以证明 Reflexion 代码生成的实现是语言无关的,可以用于解释和编译语言。最后,我们介绍了一个新的基准测试程序 LeetcodeHardGym,它是一个交互式编程训练器,包含 40 个 Leetcode 硬评分问题,这些问题在 2022 年 10 月 8 日之后发布,这也是 GPT-4 的预训练截止日期 [ 18 ]。
编程的任务提供了一个独特的机会,可以使用更接地气的自我评估实践,如自我生成的单元测试套件。因此,我们基于 Reflexion 的编程任务实现可以满足 pass@1 的准确性报告。为了生成测试集,我们使用思维链提示 [26] 来产生多样化的、广泛的测试以及相应的自然语言描述。然后,我们通过尝试为每个测试构造一个有效的抽象语法树 (AST) 来过滤语法上有效的测试语句。最后,从生成的单元测试集合中采样 n 个测试,生成一个测试集 T,记为 { t0,t1,..,tn }。我们将 n 设置为最多 6 个单元测试。除了单元测试套件组件外,Reflexion 编程代理的学习循环设置与最大内存限制为 1 经验的推理和决策代理完全相同。
表 1:各种模型 - 策略 - 语言组合的 Pass@1 准确率。基本策略是单个代码生成样本。所有基于指令的模型都遵循零样本代码生成。
表 2:HumanEval 和 MBPP 的总体精度和测试生成性能。对于 Rust 问题,从 HumanEval Python 翻译成 Rust 问题的 MultiPL-E [4] 中,HumanEval 是最难的 50 个问题。TP:单元测试合格,解决方案合格;FN:单元测试失败,解决方案通过;FP:单元测试通过,解决方案失败;TN:单元测试失败,解决方案失败。
结果 除了 MBPP Python 1 外,Reflex 在 Python 和 Rust 的所有基准上都超过了所有基线精度,并制定了新的最先进的标准。我们进一步研究了 Reflexion 在 MBPP Python 上的性能劣势。
分析 我们承认,自我反思的代码生成代理势必会影响他们编写多样化、综合测试的能力。因此,在模型生成片状测试集的情况下,有可能所有的测试都传递了错误的解决方案,并导致代码补全上的假阳性标签 [11]。另一方面,如果模型产生了错误编写的测试套件,则有可能导致部分测试在正确的解决方案上失败,从而导致以假阴性代码补全为条件的自我反思的产生。考虑到 Reflexion 的实现,假阴性比假阳性更受欢迎,因为代理可以使用自我反思来识别错误的测试,并提示自己保持原始代码的完整性。另一方面,如果一个无效的测试集返回一个假阳性完成 (内部测试用例全部通过,但执行不正确),则代理将过早地报告一个无效的提交。在 2 中,测量了各种条件,以分析超过 pass@1 精度的性能。之前,我们在 MBPP Python 上展示了 Reflexion 相对于基准 GPT-4 的劣势。在 2 中,我们观察到由内部测试执行产生的假阳性标签之间的显著差异,P (未通过 @1 次生成正确 | 通过)。它表示一个提交通过了所有的单元测试之后失败的概率。对于 HumanEval 和 MBPP Python,基线 pass@1 准确率比较接近,分别为 82% 和 80%。然而,MBPP Python 的假阳性测试执行率为 16.3%,而 HumanEval Python 的假阳性测试执行率仅为 1.4%,总体准确率为 91% (1)。
表 3:以 GPT-4 为基准模型的 Reflexion 方法在 Human Eval Rust - 50 最难问题上各种折衷方法的 Pass@1 精度
消融研究 我们在 50 个最难的 Human Eval Rust 问题的子集上测试了测试生成的 Reflexion 和自反思合作的复合方法。我们的 Rust 编译环境提供了冗长的错误日志和有用的调试提示,因此为妥协方法提供了一个很好的场地。首先,我们省略了内部测试的生成和执行步骤,即在没有当前实现的指导下测试代理进行自我反思。3 的准确率低于 52% vs 60% (基线),这表明在没有单元测试的情况下,代理无法确定当前的实现是否正确。因此,代理必须参与运行的所有迭代,而没有提前返回的选项,对实现进行有害的编辑。
接下来,我们通过省略单元测试集评估失败后的自然语言解释步骤来检验自我反思的贡献。直观地说,这挑战了代理在所有失败的单元测试中结合错误识别和实现改进的任务。有趣的是,被妥协的代理并没有在基线运行时提高性能。我们观察到,测试生成和代码编译步骤能够捕捉到语法和逻辑错误,但实现修复并不能反映这些迹象。这些实证结果表明,最近提出的一些没有自我反思的盲目试错调试技术的工作,对于诸如在 Rust 中编写复杂程序等更难的任务是无效的。
# 5. 局限性
Reflexion 是一种使用自然语言进行策略优化的优化技术。策略优化是一种通过经验来改进行动选择的有力方法,但它仍然可能屈从于非最优的局部极小值解。在这项研究中,我们将长期记忆限制在具有最大容量的滑动窗口中,但我们鼓励未来的工作用更高级的结构来扩展 Reflexion 的记忆组件,例如向量嵌入数据库或传统的 SQL 数据库。具体到代码生成,测试驱动开发在指定精确的输入输出映射方面存在许多实际限制,例如非确定性的生成器函数、与 API 交互的不纯函数、根据硬件规格改变输出的函数,或者调用可能难以预测的并行或并发行为的函数。
# 6. 更广泛的影响
大型语言模型越来越多地被用来与外界环境 (例如互联网、软件、机器人等。) 和人类进行交互。我们的工作具有加强和增强这些代理的潜力,以提高自动化程度和工作效率,但同时也放大了这些代理被误用时的风险。我们相信,这一方向的研究将需要在安全和伦理方面付出更多的努力。
另一方面,强化学习受到其黑盒策略和优化设置的影响,其中可解释性和对齐一直是具有挑战性的。我们提出的 "口头" 强化学习可能会解决一些问题,并使自主代理更具可解释性和可诊断性。例如,在人类难以理解的工具使用情况下,可以在使用工具之前监测自我反思,以确保正确的意图。
# 7. 结论
在这项工作中,我们提出了一种利用言语强化的方法 --Reflexion,它可以教代理从过去的错误中学习。我们的经验表明,通过利用自我反思,Reflexion 代理显著优于目前广泛使用的决策方法。在未来的工作中,Reflexion 可以用来使用在传统 RL 环境中被深入研究的更先进的技术,例如自然语言中的值学习或非策略探索技术。
# 8. 重复性
我们强烈建议其他人在运行自主代码编写实验时使用孤立的执行环境,因为生成的代码在执行之前没有经过验证。