Plan-and-Execute Agents

计划与执行代理

4 分钟阅读

概要:我们正在引入一种新型的代理执行器,我们称之为“计划与执行”。这与我们之前支持的代理类型形成对比,我们称之为“行动”代理。“计划与执行”代理的灵感主要来自 BabyAGI 和最近的 计划与解决 论文。我们认为“计划与执行”非常适合更复杂的长期规划,但代价是需要更多次调用语言模型。我们将此初始版本放在 experimental 模块中,因为我们预计会有快速的更改。

链接

到目前为止,LangChain 中的所有代理都遵循 ReAct 论文开创的框架。我们称这些为“行动代理”。这些代理的算法大致可以用以下伪代码表示

  • 接收到一些用户输入
  • 代理决定使用哪个工具(如果有),以及该工具的输入应该是什么
  • 然后使用该工具输入调用该工具,并记录观察结果(这只是使用该工具输入调用该工具的输出)
  • 工具、工具输入和观察的历史记录被传递回代理,然后代理决定下一步要采取什么步骤
  • 重复此过程,直到代理决定不再需要使用工具,然后它直接响应用户。

这种风格到目前为止运作良好,但一些变化正在发生,这些变化在这个算法中出现了一些裂缝

  • 用户目标变得更加复杂
  • 开发人员和组织开始在生产中依赖代理

这些具有双重影响,既希望代理系统能够处理更复杂的需求,又希望它们更可靠。这两个因素结合在一起,迅速导致提示大小增加

  • 由于目标更加复杂,因此包含越来越多的历史记录,以使代理专注于最终目标,同时允许它记住和推理以前的步骤
  • 当开发人员尝试提高可靠性时,他们会包含更多关于如何使用工具的说明

当使用大多数语言模型时,对日益复杂的能力和提高可靠性的需求正在引起问题。

计划与执行的实现

从这个角度来看,我们已经看到一种新型的代理框架涌现出来。这些代理框架尝试将高层次的规划与短期执行分开。具体来说,它们首先计划要采取的步骤,然后迭代地执行这些步骤。当然,这种核心算法有一些有趣的变体(我们稍后可以讨论)。这些代理(我们称之为“计划与执行”代理)的伪代码如下所示

  • 计划要采取的步骤
  • 对于步骤中的每个步骤:确定完成该步骤的适当工具或其他最佳行动方案

这是在 Python 和 TypeScript 中实现的核心代理框架。此代理框架依赖于两件事:规划器和执行器。

让我们先谈谈规划器。这几乎总是应该是一个语言模型。这将利用语言模型的推理能力来规划要做什么,并处理歧义/边缘情况。我们可以在最后添加一个输出解析器,将原始 LLM 输出解析为字符串列表(每个字符串都是一个步骤)。

现在让我们谈谈执行器。在我们的初始实现中,我们将其设为一个行动代理。这允许执行器代理接收一个高层次的目标(一个步骤),并找出要使用哪些工具来完成该目标(可以在一个步骤或两个步骤中完成)。

这种方法有几个好处。它将规划与执行分开 - 这允许一个 LLM 专门专注于规划,另一个专注于执行。这使得两个方面都更加可靠。这也使得将来更容易将这些组件替换为更小的微调模型。这种方法的主要缺点是它需要更多次调用。但是,由于关注点分离,我们希望这些调用可以是对更小(因此更快更便宜)的模型的调用。

未来方向

我们认为这仅仅是计划与执行代理的开始。未来的方向包括

  • 更好地支持长步骤序列。目前,之前的步骤作为列表传递 - 随着规划步骤越来越长,我们希望将其存储在向量存储中并检索中间步骤
  • 重新审视计划。目前,在开始时只有一个规划步骤,但之后从未重新审视过。我们可能希望有一些机制来重新审视和调整计划,无论是每一步还是根据需要。
  • 评估。目前,许多这些改进在很大程度上是理论上的,或者至少没有经过基准测试。我们希望有更严格的方法来评估代理框架。
  • 执行链的选择。目前,只有一个执行链。很容易出现您想要多个执行链的情况,并且规划器可以指定要使用哪个执行链。例如,如果您有一个针对网络研究优化的执行链,一个用于分析等等。

应该注意的是,对于许多这些未来方向,我们可以从现有工作中汲取灵感。例如,BabyAGI 已经使用向量存储来存储中间步骤,并且还在每次迭代中重新审视规划。“计划与解决”论文对带有基准的输出进行了更严格的评估。

结论

我们非常高兴看到这种新的代理范式在 BabyAGI 中出现(我们在几周前的帖子中强调这是最大的区别之一)。我们同样高兴地看到“计划与解决”论文的出现,作为对类似想法的严格评估。我们期待看到“计划与执行”方法如何发展 - 在这里试用 (Python) 或在这里试用 (JS)