在过去的一年里,语言模型驱动的 Agent 和状态机已经成为一种有前景的设计模式,可用于创建灵活有效的人工智能产品。
Agent 的核心是使用 LLMs 作为通用问题解决器,将它们与外部资源连接起来以回答问题或完成任务。
LLM Agent 通常有以下主要步骤:
ReAct Agent 是上面步骤一个很好的原型设计,因为它使用重复的思想、行为、观察循环来提示语言模型:
# 典型的 ReAct 风格的 Agent
Thought: I should call Search() to see the current score of the game.
Act: Search("What is the current score of game X?")
Observation: The current score is 24-21
... (repeat N times)
这利用了思想链 Prompt,让每一步做出单一的操作选择。虽然这对于简单的任务可能有效,但它有几个主要缺点:
克服这两个缺点的一种方法是通过明确的规划步骤。
核心思路是基于关于规划和解决提示(Plan-and-Solve Prompting)的论文,BabyAGI 项目是该论文实现架构的产品。该架构主要由两个基本组件组成:
一旦执行完成,代理会再次被调用,并发出重新计划提示,让它决定是否完成响应或是否生成后续计划(如果第一个计划没有达到预期效果)。
这种 Agent 设计让我们不必为每个工具调用调用大型规划器 LLM。它仍然受到串行工具调用的限制,并为每个任务使用 LLM,因为它不支持变量赋值。
为了解决上述问题,ReWOO: Decoupling Reasoning from Observations for Efficient Augmented Language Models 论文中提出了一个 Agent,它消除了每个任务始终使用 LLM 的需要,同时仍然允许任务依赖于先前的任务结果。他们通过允许在规划器的输出中进行变量分配来实现这一点。下图是代理设计的示意图。
规划器生成一个由交错的“Plan”(推理)和“E#”行组成的计划列表。例如,假设用户查询“What are the stats for the quarterbacks of the super bowl contenders this year”,规划器可以生成以下计划:
Plan: I need to know the teams playing in the superbowl this year
E1: Search[Who is competing in the superbowl?]
Plan: I need to know the quarterbacks for each team
E2: LLM[Quarterback for the first team of #E1]
Plan: I need to know the quarterbacks for each team
E3: LLM[Quarter back for the second team of #E1]
Plan: I need to look up stats for the first quarterback
E4: Search[Stats for #E2]
Plan: I need to look up stats for the second quarterback
E5: Search[Stats for #E3]
请注意 planner 如何使用 #E2 等语法引用以前的输出。这意味着它可以执行任务列表,而不必每次都重新计划。
worker 循环遍历每个任务,并将任务输出分配给相应的变量。当调用后续调用时,它还会用变量的结果替换变量。
最后, Solver 将所有这些输出整合为最终答案。
这种代理设计比简单的计划和执行代理更有效,因为每个任务只能具有所需的上下文(其输入和变量值)。然而,它仍然依赖于顺序任务执行,这可能会产生更长的运行时间。
An LLM Compiler for Parallel Function Calling 论文,旨在进一步提高任务执行速度,超越上述计划和执行代理和 ReWOO Agent,甚至超越 OpenAI 的并行工具调用。
LLMCompiler 有以下主要组件:
这里关键的运行时间提升想法是:
search("${1}") 来搜索任务 1 的输出生成的查询。这使得代理的工作速度比 OpenAI 中调用的“令人尴尬的并行”工具更快。通过将任务格式化为 DAG,代理可以在调用工具时节省宝贵的时间,从而带来更好的整体用户体验。
这些智能体有望比传统的推理和行动 (ReAct) 风格的智能体进行许多改进。
首先,他们可以更快地执行多步骤工作流程,因为每次操作后不需要咨询更大的代理。每个子任务都可以在没有额外的 LLM 调用(或调用轻量级 LLM)的情况下执行。
其次,与 ReAct 代理相比,它们可以节省成本。如果LLM调用用于子任务,它们通常可以针对较小的、特定于域的模型进行。然后,较大的模型仅需要(重新)规划步骤并生成最终响应。
第三,通过迫使规划者明确“思考”完成整个任务所需的所有步骤,他们可以整体表现得更好(在任务完成率和质量方面)。生成完整的推理步骤是一种经过验证的改进结果的提示技术。细分问题还可以更集中地执行任务。
这三种代理架构是“计划和执行”设计模式的原型,它将 LLM 驱动的“计划器”与工具执行运行时分开。如果应用程序需要多个工具调用或 API 调用,这些类型的方法可以减少返回最终结果所需的时间,并通过减少调用更强大的 LLMs 的频率来帮助您节省成本。
参考资料:
ReAct: Synergizing Reasoning and Acting in Language Models (https://arxiv.org/abs/2210.03629)
Chain-of-Thought Prompting Elicits Reasoning in Large Language Models(https://arxiv.org/abs/2201.11903)
Plan-and-Solve Prompting: Improving Zero-Shot Chain-of-Thought Reasoning by Large Language Models(https://arxiv.org/abs/2305.04091)
ReWOO: Decoupling Reasoning from Observations for Efficient Augmented Language Models(https://arxiv.org/abs/2305.18323)
An LLM Compiler for Parallel Function Calling(https://arxiv.org/abs/2312.04511)
Plan-and-Execute Agents(https://blog.langchain.dev/planning-agents/)
原文作者:HelloTech技术派;如有侵权,请联系管理员删除。