在 LLMs Agent 领域中,给 LLMs 的提示词已被证明对 LLMs 生成的结果有很大影响,从而影响 Agent 性能。因此,自动提示工程已成为研究者研究的重要方向。本文提出 RePrompt,它基于与 LLMs Agent 交互获得的聊天历史,通过“梯度下降”来优化 LLMs Agent 提示中的一步步指令。 通过优化提示,LLMs 将学会如何在特定领域进行规划。
介绍大型语言模型(LLMs)自 ChatGPT 发布以来取得了显著的成功。除了传统的自然语言任务,如总结和情感分析外,LLMs 在许多更接近应用的领域,如代码生成、人机交互和数学问题解决中也显示出有效性。尽管纯 LLMs 在推理能力上有限,研究人员已经将工具使用引入 LLMs 并构建了集成系统,即 LLM Agent,以实现在更通用领域如机器人控制和自动驾驶中使用 LLM 的可能性。
在所有这些成功背后,提示词扮演着重要角色。研究表明,不同的提示可能导致完全不同的成功率,因此通常需要针对每个特定任务进行提示工程。由于提示工程既困难又耗时,自动提示工程(APE)作为一种策略出现了。在有限的尝试次数内,APE 可以有效地收敛到一个健壮的提示,该提示在传统自然语言处理任务上的表现优于简单提示。
然而,大多数用户仍然在其 LLM 中使用原始提示或精心手工制作的提示。除了 APE 收敛到良好提示所需的时间和计算外,当前应用 APE 框架的过程存在一些限制,这使得它们难以超越精心手写的提示。 首先,LLM 并不清楚什么提示对他们更有效。虽然 LLM 可以写出清晰的指令句子作为提示,但与人类相比,它们并不更能理解不同提示将如何在它们自己身上起作用。此外,由于 LLM 是固定的,它们无法学习人们发现的新范式,并且当许多人正在尝试流行的 LLM 如 GPT-4 或 LLAMA-2 时,他们得到了更多关于如何编写良好提示的想法。然而,LLM 只能使用它们关于如何提示早期模型的知识,而不是如何提示它们自己。此外,LLM 通常无法为潜在的失败识别正确的解决方案,并且只会改变到略有不同的提示而没有改进。针对本文在复杂推理任务中的目标,也称为 LLM Agent,许多 APE 方法主要针对简单的问答(QA)任务如 HotPotQA 设计,并无法推广到更难的推理任务。
本文关注这样一个场景:有一个特定的推理任务需要使用 LLMs,例如人们已经选择使用 ChatGPT 中的特定 OpenAI GPTs 工具来规划他们的旅行或帮助编写代码。在这些领域,LLMs 通常使用 Chain-of-Thought(CoT)提示与 ReAct 和 Reflexion 等交互式过程来提高其性能。本文提出了一个新颖的自动提示工程方法,名为 RePrompt,该方法考虑了使用 CoT 和 ReAct 的常见实践,并使用这些结果的对话历史作为每次提示更新的信息。 通过总结对话历史,然后分析如何逐句改进提示,可以在不过度拟合到角落案例的情况下,基于过去的历史成功优化提示。本文进一步展示了提议的方法如何被视为机器学习中的一个标准微调过程,其中可变参数(或输入)是初始提示。图 1 展示了本文提出的框架的概览。
本文通过 Planning Domain Definition Language(PDDL)生成和旅行规划的实验,证明了本文方法可以实现更高的首次尝试成功率。这些场景证明了当反馈要么昂贵但准确,要么便宜但不太准确且信息量少时,本文方法的有效性。
总之,本文的贡献如下:
提出在 LLM Agent 中使用"基于梯度"的提示优化。提出了一种基于总结的方法,具体指导当前提示如何进一步改进,并提出了新颖的指南,以逐步格式优化提示。使用更新的提示,在多个 LLM Agent 基准上提高结果,而无需在这些基准上微调 LLM 模型。相关工作本文的工作位于提示优化和用于推理的大语言模型(LLM)的交叉领域。 在提示优化方面,许多研究提出了使用可微分调优软提示来优化提示,训练辅助模型作为优化器,或者直接训练提示器本身。这一系列工作需要访问语言模型的模型权重,并且在使用像 GPT-4 和 Claude-3 等 LLM 通过 API 的当前时代并不普遍适用。另一系列工作选择使用机器学习模型来提供关于更好提示的近似指导,无论是通过使用强化学习还是进行带有 LLM 反馈的离散操作。提示优化中还有一些其他工作提出了相对通用的解决方案,例如使用束搜索作为“梯度下降”优化器。本文的工作与第二组工作非常接近,可以看作是从当前方法推广到更侧重于推理领域的领域。
在用于推理的 LLM 中,研究人员确定的一个关键挑战是如何正确使用提示来引导 LLM 生成有用的辅助输出,从而得到一个好的最终解决方案。Chain-of-Thought(CoT)是最常用的提示,可以提高 LLM 的性能,它仅包括添加一个固定的句子“让我们一步步思考。”后来,Tree-of-thought 和 Graph of Thoughts 也被提出,作为从辅助输出的简单基于行的架构扩展到树和图结构输出。研究人员还发现利用 LLM 的交互能力也可以提高其性能。ReAct 可以让 LLM 在提出实际行动之前列举一些想法。Reflexion 提示 LLM Agent 对行动进行反思,并将反思保存在记忆中以提高效率。有许多大量工作,如 self-refine,RCI 和 self-debugging,使用类似的提供反馈作为推理相关任务指导的想法,并战略性地调整想法以适应特定领域的需求。本文考虑了这种在最终确定答案之前迭代反馈的流行且有用的工作流程,并根据提供的交互历史优化提示。
▶▶LLM agents 预备知识本文专注于用于推理任务的 LLM 智能体。由于 LLM 可能无法一次就给出正确答案,在某些仍然可能获得反馈的场景中,先前的方法已经提出在 LLM 给出最终答案之前允许进行几次交互。在这些情况下,用户向 LLM 提供一些错误信息,并让 LLM 在附加信息的基础上再次尝试。这些信息不一定能提供关于最终解决方案的任何线索,而是关于当前解决方案为何不正确的错误信息。例如,在代码生成任务中,此信息可能是典型的 Python 运行时错误消息。如何使用带有错误信息的特定提示主要取决于不同的任务。例如,在广泛使用的 ReAct 中,要求 LLM 在执行下一轮之前对当前结果提供思考,而这些思考通常不是一个具体的错误,但可能还包括一个简短的分析,得出当前行动是正确的结论。
对于专注于推理的 LLM 智能体,Chain-of-Thoughts(CoT)是 LLM 中最受欢迎的方法之一。通过添加一句简单的“让我们一步步来”,LLM 将自动考虑在生成最终答案之前输出辅助步骤。类似于写下计算过程帮助高中生解决数学问题的方式,这些辅助步骤被证明能有效帮助 LLM 在解决推理问题时获得更高的成功率。从一项任务到另一项任务,辅助步骤可能差异很大,LLM 智能体中需要的确切步骤被称为规划。一个常见的做法是让 LLM 先生成这些步骤,然后再进一步决定是否应该由另一个 LLM 或外部工具执行每个步骤。
▶▶RePrompt在本文中,我们专注于使用提示优化来解决 LLM Agent 的规划部分。在这项工作中,我们关注的是任务已知的 LLM Agent 的问题。这种情景的一个典型例子是 OpenAI 中的不同 GPTs。
如图 1 所示,本文提出的方法 RePrompt 是一种基于交互式动作生成过程的提示优化器。本文的方法与典型的机器学习训练循环非常相似,但在这里,我们训练的是要输入模型的提示,而不是 LLM 的参数。给定一个用于训练的具体小型推理任务数据集,我们首先让 LLM 使用当前提示生成它们的响应。这个过程需要包括与 ReAct 或 Reflexion 等某种反馈提供者的交互方案,但我们不对这部分应该如何完成以及反馈的准确性施加任何限制。我们称这个过程为 act 循环。
然后,我们等待收集到整批此类聊天历史,然后将整批聊天历史放入 LLM 模型中以总结最重要的关注点。关注点可能是一个经常出现并导致长时间迭代的问题,或者是显示有助于生成良好响应的具体建议(在 ReAct 中的想法)。通常,这些信息已经包含在聊天历史中,不需要进一步的分析或总结。我们要求我们的总结团队总结不同的情景,以删除情景的具体信息和建议,但也不总结过多,那将需要进一步的推理能力,并且如果 LLM 在当前任务上不够好,可能会引入过程中的幻觉。与之前的自动提示工程工作相比,包括 APE 和 ProTeGi,我们对一批进行了总结,并防止提示优化在单个异常数据点上过拟合。
接着,利用这个总结的典型错误,我们使用另一个 LLM 来更新实际的提示。我们要求这个优化器 LLM 在提供可能的解决方案时遵循以下规则:
改进应关注于常见的提示部分,而不是从数据点到数据点变化的情景特定提示。例如,在为 PDDL 生成公式化的任务中,最常见的建议之一是提供更多关于 LLM 试图生成特定领域的具体信息以及关于该领域背景的更详细知识。但是,因为我们要获得一个足够通用的提示来解决所有的 PDDL 公式化生成问题,这样的更新不应该发生。改进应优先确定在给定的情景中是否确实存在特定问题。例如,假设有一个预算限制,希望 LLM 提供的解决方案能够满足,并且之前的的历史显示这个预算约束可能是导致解决方案失败的主要问题之一。在这种情况下,它应该尝试使用工具来计算典型计划的花费。如果它违反了约束,它可以在获得解决方案时优先考虑预算约束;否则,应忽略这个问题。基于以上规则,我们要求 LLM 执行以下步骤:
对问题提出一些可能的解决方案。逐个分析这些解决方案,看哪个更好地符合规则。选择最佳的单一解决方案。与 APE 和后续的一些工作不同,我们不要求 LLM 给出一个具体的数字作为句子的值。分析原始提示中的原始步骤,检查是否应将所选解决方案插入当前步骤之前,或者解决方案是对步骤的更具体细节,当前步骤的提示应被解决方案替换。如果是步骤,就在这里添加提示。输出最终的提示,这是原始提示和更新提示的组合。在这些步骤之后,我们将_得到一个更新的提示,并且可以继续进行更多的迭代_,这也可以被视为更多类似于训练 ML 模型的 epoch,直到提示收敛。这个收敛的提示将帮助改善第一轮的生成结果。在测试时,我们只需要使用收敛的更新提示并在新的测试集上进行测试。在测试期间,我们不需要完全相同的过程来生成响应,例如,如果反馈生成器相当昂贵,可以从 Act 过程中完全移除。
为了帮助优化器解决一些常见问题,我们目前已经在优化器的提示中手动编码了一些常见解决方案。
注意,在优化过程中,RePrompt 只改变逐步指导阶段,而不改变任何其他问题描述或格式要求。这为我们带来了算法最终可能出现的两种提示格式:
如果当前提示是类似 ReAct 的,它已经包括了一个逐步指导,给出了一个具体的步骤,比如 ReAct 中的 Thought,以包括所有可能的分析,我们的提示将始终更新这个思考步骤,通过添加越来越多的关于接下来要做什么的提示。与其他引入动态提示的提示工程工作相比,本文方法变成了一个给出更具体提示的算法,指出分析应该关注的部分。如果提示是逐步的,比如解决一个数学或逻辑问题,那么本文的算法很可能会为计划生成的过程添加越来越多的步骤。这将导致规划过程中有更具体的方向去尝试和关注,将指导 LLM 获得正确的最终答案,并将作为分解高级任务的规划器。虽然我们了解到上下文学习对于推理非常重要,但我们发现始终如一地按照我们的指示逐步更新示例非常具有挑战性。因此,我们选择根本不更改示例。在大多数情况下,示例作为 LLM 对输出格式和相关能力的提示,而不是如何逐步遵循指导的具体指南,
实验分析为了全面测试本文算法在不同场景下的能力,选择了两个环境:PDDL 生成和旅行规划器。PDDL 生成任务提供了准确但昂贵的反馈,挑战了 LLMs 的精确翻译能力,这对于 LLMs 进一步能够编写正确代码是必要的。另一方面,旅行规划器环境通过 Reflexion 提供了便宜但不准确的反馈,而无需知道真实信息。旅行规划器还提供了工具,用于查询数据库中的成本信息,并通过请求直接生成解决方案来挑战推理能力。此外,在旅行规划器中,本文还测试了与 Reflexion 一起使用的 RePrompt,这进一步包括了思考-行动-观察步骤,而不是 PDDL 中的标准逐步指令,其中每一步都是可能有助于指导生成最终结果的中间步骤。鉴于不同类型的反馈,本文的 RePrompt 的目的也有所改变:在 PDDL 中,RePrompt 旨在提高零样本生成性能,以降低生成反馈的成本;而在旅行规划器中,RePrompt 用于帮助指导 LLM 关注所有场景中的重要步骤,并减少因思考不完整而导致的潜在失败。
▶▶PDDL Generation给定一个 PDDL 实例的自然语言描述,任务是为 PDDL 中的动作定义先决条件和效果。具体而言,本文考虑了构建模型的最初步骤,并未进一步考虑后续的修正阶段和 PDDL 翻译阶段。
在提交本文时,官方 Github 仓库中缺少评估阶段,因此本文无法以公平的方式比较那些阶段中的成功率。在生成动作的先决条件和效果后,引入人类领域专家来检查生成的正确性。在本文中,不仅有人类领域专家,还使用了另一个大型语言模型(LLM)作为独立的检查器,以验证原始论文中给出的提示结果中出现的错误是否也出现在本文的结果中,该提示结果与其代码一同发布。
在这个实验中,本文使用了“Tyreworld”领域的生成结果和人类专家的注释作为 RePrompt 训练集中的聊天历史,并更新了一个周期以获得更新的提示。这里,由于反馈是由领域专家提供的,因此它是准确的但也是昂贵的,所以多轮迭代是不可行的,因此选择只对 RePrompt 进行一个周期的训练,大大减少了对额外注释的需求。
如表 1 所示,本文从 RePrompt 获得的提示不仅在训练集上表现更佳,即 Tyreworld 领域,而且还能推广到其他相关领域并提高那里的成功率。有趣的是,本文发现改变提示后,提示并未引入任何新的错误,即新提示犯的错误是原始论文中提示错误的子集。有了这个错误子集,需要的领域专家注释会减少,使得整个 PDDL 翻译过程大大加快。
在剩余的错误中,有些是由描述中缺失的常识引起的。例如,在动作“清空真空吸尘器”中,动作描述中有一句话:“如果垃圾桶可以打开,应该打开它。”这是常识,没有额外信息。然而,在当前语境中,这句话表明了一个先决条件。然而,LLM 生成的 PDDL 先决条件已被省略,这导致了一个错误。类似的问题也发生了几次,并导致了一类可以归在一起的重要错误数量。
▶▶Travel Planner接下来,本文在 TravelPlanner 基准测试中测试了单一规划设置。 本文对部分代码进行了微调,以在自动检查过程中识别某些特定格式。在这个基准测试中,LLMs 需要提供一个具体的日计划,包括他们应该在哪里住宿、吃饭以及如何旅行,并且要满足诸如合理城市路线和预算约束之类的常识约束。尽管有关于计划不满足的具体约束类型的一些分解,但用于比较不同方法的主要指标是最终的通过率。需要指出的是,在这个基准测试中,评估是在 act 循环完成后单独与一个地面真实检查器进行的,而不是直接进入 Reflexion 中的反馈循环,因此,RePrompt 使用的聊天历史中的反馈实际上并不涉及任何人为干预或对正确答案和约束列表的预言。这使得本文可以在测试集的一个子集上训练,而不必担心向模型泄露任何额外的预言信息。因此,为了节省模型的 API 成本,本文选择报告验证集上 180 个数据点的结果,而不是更大测试集上的结果。
使用 Reflexion 策略在单一规划上测试了 180 个验证数据点,完成一次生成的成本为 300-800 美元,具体取决于提供给模型的确切反思。完整的测试集包括 1000 个数据点,成本将随着测试的数据点的数量线性增长。 由于 RePrompt 是基于进一步收集数据,本文选择验证集中 10 个数据点的子集作为训练数据集。
如上表所示,经过 5 个周期的训练后,RePrompt 生成的提示比纯 Reflexion 结果的最终通过率更好。在优化过程中,与 PDDL 环境不同,一个周期后的优化提示并没有显示出任何优势。这是因为,如前所述,第一个周期后的提示只包括一个额外的建议,在这种情况下是关于预算约束的。不管这一轮更新是什么,这都是从 ReAct 方案提供的思路中总结出来的,并且在生成最终计划的迭代循环中通常已经注意到并处理了。5 个周期后的优化提示帮助 LLMs 在本文用于训练的数据集以及其他未包括在优化过程中的数据上表现得更好。这显示了本文通过该过程获得的提示的泛化能力。
进一步分析本文在最终通过率上的改进之处,发现本文的方法有助于提高宏常识通过率,这是目前使用 LLM 进行旅行规划的主要瓶颈。进一步分解发现,提示显著提高了所谓的“合理城市路线”的通过率(表 2 中未显示,但它是 TravelPlanner 测试的约束之一)。这种常识是要确保“旅行中城市间的变动必须是合理的”。这是第一轮没有交互的结果大多可以满足但容易在与反馈提供者交互后忘记的常识约束。因此,这是 LLMs 在过程中可以自己发现的常识约束之一,而且有时但不经常包含在反馈循环中提供的思路里。本文的 RePrompt 捕捉到了这个约束并将其包含在提示中,所以大多数迭代都涵盖了它。本文相信这是本文算法解决了 Travelplanner 论文中提到的“智能体难以将其行动与推理对齐”挑战的一个例子。
令本文惊讶的是,发现本文的方法并没有帮助停止“由于信息混淆智能体产生幻觉答案”的问题,本文的智能体仍然输出错误的航班号,用于错误的航段,并输出相同的航班号作为出发和到达航班。虽然理论上这可以通过反馈提供者来解决,但似乎这样的反馈从未在循环中提供并解决,本文的 RePrompt 训练循环也无法捕捉到这样的错误。本文期待进一步研究 RePrompt 框架如何作为一个更高级别的检查器来处理简单的幻觉错误。 其中,一种可能性是在尝试计算“损失”时,将场景特定信息与聊天历史结合起来。
错误分析实验中发现自动提示优化过程并不能保证成功生成更好的提示。在本节中,本文简要列举了一些常见的错误,并描述了应对这些错误的方法。本文认为,这些额外的方法既不是必需的,也不普遍适用于所有领域,因此选择将它们作为一种特设解决方案留在此处。本文相信,当大型语言模型(LLMs)的指令跟随能力进一步改进时,所有这些特设解决方案都可以被自动移除。
很多时候,提示优化器无法生成完整的提示。 如附录中完整的提示所示,本文已经添加了关于生成完整提示而不是不完整提示的广泛指令。如上图所示,LLMs 有时会输出一个提示模板,它需要用户进行复制粘贴以使提示完整。本文发现这通常发生在初始提示相对较长的情况下,并相信 LLMs 被训练成可能生成更短的响应,但它们未能遵循生成完整提示的指令。为了解决这个问题,本文添加了额外的 LLM 来帮助填充模板。本文也在附录中提供了这个 LLM 的提示。这个额外的 LLM 帮助本文在 TravelPlanner 领域中生成完整的提示。本文不使用基于规则的修复器,因为生成的提示模板可能包含多个符号,包括但不限于<>或{}。为了减轻本文的工作量,选择让 LLM 自动识别并替换它们。
在某些领域,输出格式可能与更常用的领域相似,导致大型语言模型(LLMs)在特定部分误导性地修正提示。 例如,在本文的 PDDL 领域,本文要求 LLM 生成动作的前提条件,而不是实际的 PDDL 文件。在实验中,本文发现即使提示已经明确要求 LLM 不要更改任何其他部分,尤其是输出格式部分,更新的提示有时仍会错误地更改输出格式,具体来说,将“Preconditions”一词的大写形式改为小写的“precondition”。为解决此问题,本文利用语法检查器的反馈。虽然生成结果可能存在一些错误,但结果应始终保持完整,并具有所需的语法。如果从 LLM 输出中提取答案的语法解析器找不到“Precondition”一词,则本文知道所使用的提示不正确,随后在相同步骤上重新运行 RePrompt 以生成正确的提示。由于当前代码的失败率经验上小于 10%,这种临时解决方案是足够的。
RePromp 局限性讨论本文提出的 RePrompt 方法的局限性是很重要的。首先,由于提示的优化方式类似于微调,本文生成的提示也受限于训练数据,并在一定程度上损害了 LLM 的泛化能力,即_如果训练数据对 LLM 展示了仅在这些训练场景中出现而非普遍情况下的独特挑战,本文优化的提示可能甚至不如原始提示有效。_
接下来,本文的提示依赖于 LLM Agent 可用的全面工具。由于优化方法是直接从 LLM 提供,而不是通过基于搜索的方法处理的,RePrompt 可能会提出使用一些在实际给定设置中不可用的统计工具。本文留下了一个可能性,即让 LLM 在未来的工作中自行编码额外的、不可用但常用的工具。
此外,有时,我们没有控制和反馈生成器,可能会生成无用甚至错误和误导性的结果。虽然 RePrompt 基于总结,但如果经常出现这样的错误,RePrompt 将会将这样的反馈纳入提示中。由于本文不考虑在提示中删除无用的步骤,这样的错误只会增加使用的总标记数,而不会带来更好的结果。未来工作可能会添加一个基于搜索的机制来识别这样的错误并可能修复它,但这可能需要更多来自环境的真实反馈,并可能导致适用领域的更多限制。
最后但同样重要的是,本文提出的方法在提示阶段进行规划,因此,如果 LLM Agent 被提议用于非常通用的领域,需要在不同场景中完全不同的程序,例如,解决数学问题的 LLM Agent,本文提出的方法将完全不起作用。然而,如果 LLM Agent 被提议用于特定任务,比如使用 LLM Agent 解决高中几何问题,本文提出的方法可以非常有效地帮助学习规划,正如上述实验所示。
总结本文专注于优化 LLM Agent 中使用的提示,提出了一个新的自动提示优化器 RePrompt,该优化器基于 LLM Agent 与反馈提供者之间的交互总结。实验表明,LLM Agent 在 1 周期设置和 5 周期设置中都能从更新后的提示中受益。此外,本文还讨论了目前工作的局限性以及未来的工作如何调整这些局限性。