📘 **TELUS Agriculture & Consumer Goods** 如何通过 **Haystack Agents** 转变促销交易

Haystack 中引入 Agent:让 LLM 解决复杂任务

LLM 现在可以利用合适的工具来解决复杂的查询和任务

如果你能输入一个查询,然后 LLM 能即时决定需要哪些资源来解决这个查询,那不是很酷吗?例如,它需要搜索网络并检索相关资源。或者它需要先搜索你的公司文件。现在,使用 Agent 就可以实现!

随着 Haystack 1.15 的发布,我们正式将 Agent 引入 Haystack 生态系统。Agent 的实现受到两篇论文的启发:MRKL Systems 论文(发音为“miracle” 😉)和 ReAct 论文。如果你喜欢阅读论文,我强烈推荐这两篇。在这里,我将解释我们如何将此功能引入 Haystack。

首先,我们来谈谈 Agent 是什么,然后看看你如何在 Haystack 中开始使用 Agent。首先,我们需要简要谈谈什么是“Prompt”。

什么是 Prompt?

简而言之,Prompt 就是一个指令。在自然语言处理领域,这些指令通常可以是“回答给定查询”或“总结以下文本”之类的内容。近几个月,出现了新的大型语言模型(LLM),例如 OpenAI 不断改进的 GPT 模型(text-davinci-003gpt-3.5-turbo 和 GPT-4)。这些模型在处理和执行越来越复杂的 Prompt 方面表现出了强大的能力。

Haystack 用户可能已经遇到过 PromptNode,它与 LLM 一起工作,处理指令。你可以选择在 PromptTemplate 中定义自己的 Prompt,或使用我们的默认 Prompt。

例如,这是我在 Hugging Face 上的 ‘Should I follow?’演示 中为 PromptTemplate 定义的一个 Prompt。如果你有兴趣了解如何在 Haystack 中使用自定义 Prompt,可以看看!

在这种情况下,我想要一个能够告诉我 Twitter 用户最近在发布哪些类型内容的系统。Prompt 以此开头:

你将收到一个属于特定用户名的推文流。用总结回答他们最近在发布关于什么内容,以及使用了什么语言。你可以详细说明他们倾向于发布哪些话题。请同时提及他们的整体语气,例如:积极、消极、政治化、讽刺或其他。

理解 Agent 为什么这很重要?让我们看看 👇

什么是 Agent?

Agent 是利用 LLM 理解和响应 Prompt 能力的一种方式。本质上,Agent 是一个被赋予了一个非常巧妙的初始 Prompt 的 LLM。这个 Prompt 指示 LLM 将解决复杂查询的过程分解为一系列按顺序一步步解决的步骤。

当我们结合 MRKL 论文中介绍的“专家”时,Agent 就变得非常酷了。简单示例:Agent 本身可能不具备可靠执行数学计算的能力。但是,我们可以引入一个专家——在这种情况下是计算器,一个数学计算方面的专家。现在,当我们进行计算时,Agent 可以调用专家,而不是试图自己预测结果。

例如,一个被问到“十年前的今天,谁是美国总统?”的 Agent。Agent 在分解这个问题时的思考过程简化视图可能如下所示:

  • “我需要回答这个问题:今天的日期是什么?”
  • “现在我知道今天的日期是 2023 年 3 月 29 日,我需要回答:2023 年 3 月 29 日减去 10 年是多少?”
  • “现在我需要回答这个问题:2013 年 3 月 29 日,谁是美国总统?”

在每一步,Agent 都可能决定利用一个专家来达成解决方案。注意它如何能够弄清楚它首先需要问一个问题,然后用答案进行计算,最后再问另一个问题。它能否做到其中任何一项,取决于它拥有哪些专家。在 Haystack 中,这些专家被称为 Tools

什么是 Tools?

在 Agent 的世界里,Tool 就是 Agent 可以随时查询的专家。例如,Agent 可能会得到一个可以搜索网络的 Tool(我们称之为“Websearch”)。如果 Agent 发现有需要搜索网络的需求,并且它的工具集中有 Websearch,它就会使用它。

随着 Haystack 1.15 的发布,我们能够将 Haystack 组件(Nodes、Pipelines 等)作为 Tool 提供给 Agent。例如,一个 Tool 可能只是一个 ExtractiveQAPipeline。这是一个可以访问包含你自己的数据的 DocumentStore 的 Pipeline,给定一个查询,它使用一个抽取式问答模型来从你自己的数据中查找答案。有了这个 Tool,你的 Agent 就可以在认为合适的时候使用该 Pipeline 来查询你自己的数据。

我们 Agent 的第一个版本将允许你使用一些现成的 Haystack Pipeline 和 Node 作为 Tools:ExtractiveQAPipelineDocumentSearchPipelinePromptNode、新的 WebQAPipeline 等等。有关可用 Tools 的完整列表,请查看我们的 Agent 文档。我们很快将扩展开箱即用的 Tools 列表,并且你也将能够创建自己的自定义 Tools。

Agent 如何选择 Tool?每个 Tool 都带有一个 description。这可以说是 Tool 最重要的属性之一,因为 Agent 会使用它来做出 Tool 的选择。例如,一个用于在有关美国总统的文档上进行抽取式问答的 Tool 的描述可以是:“当你需要回答有关美国总统的问题时非常有用”。

让我们设想一下,我们确实有一个包含美国总统信息的自有数据存储。我们为该数据创建一个 ExtractiveQAPipeline,并将其作为名为“ExtractiveQATool”的 Tool 提供给我们的 Agent。当我们向 Agent 提出问题时,输出可能如下所示:

问题:美国第一任总统出生于哪一年?

思考:让我们一步一步来,我首先需要找出谁是美国第一任总统。

Tool:ExtractiveQATool

Tool Input:谁是美国第一任总统?

Observation:乔治·华盛顿

思考:现在我知道了美国第一任总统是谁,我可以使用同一个 Tool 来找出他的出生日期。

Tool:ExtractiveQATool

Tool Input:乔治·华盛顿出生于何时?

Observation:1732 年 2 月 22 日

思考:这就是问题的答案。

Final Answer:1732

请注意输出的突出显示部分。注意 Agent 是如何一步一步地制定行动计划的。根据下一步是什么,它能够选择一个 Tool(在这种情况下是我们的“ExtractiveQATool”)来执行所需的操作。

这些 Tools 的选择几乎是无限的。由用户来定义自己的 Tools,并决定将哪些 Tools 提供给 Agent 访问。

Agent 和 Pipeline 有什么区别?

现在让我们看看这与 Haystack Pipeline 有何不同。Pipeline 是 Haystack 中的一个强大结构。一个简单的 Pipeline 可能由以下部分组成:

  • 一个 Retriever:为查询找到最相关的文档。
  • 一个 Reader:查看一段文本并从中提取问题的答案。

当我们用查询运行 Pipeline 时,数据将从一个节点流向下一个节点(在我们上面的例子中:首先检索文档,然后从中提取答案),直到到达预定义的 Pipeline 流的末尾并输出结果。就是这样。我们与你的时间到此结束,落幕,皆大欢喜。正如你所见,Pipeline 本质上是一个单向系统。而这正是 Agent 与 Pipeline 不同(非常不同)的地方。

Pipeline 有一个明确的开始和结束、输入和结果,而 Agent 没有(尽管你可以定义允许它的最大迭代次数)。这两个结构的核心区别在于,Pipeline 被设计成一个单次迭代系统,而 Agent 是一个多次迭代系统。迭代次数由 Agent 定义,它在每次迭代后决定是否已得出最终答案。(当然,也有一个系统可以防止无限循环!)

Agent 之所以拥有这种能力,归功于三点:

  • 强大的 LLM,能够处理日益复杂的指令;
  • 一个定义了 Agent 生命周期并且使其持续运行直到找到解决方案的明确定义的 Prompt;以及
  • 一套 Tools,每套 Tool 都擅长做某事非常出色

自定义 Agent

你可能已经注意到并开始使用 Haystack 中的 PromptNode。这个节点是与 LLM 的接口,例如 OpenAI 的 text-davinci-003;Google 的 Flan T5 模型等。

核心上,Agent 是一个被赋予了特定 Prompt 的 PromptNode。默认情况下,你在 Haystack 中找到的 Agent 将使用名为 “zero-shot-react”PromptTemplate。然而,你可以自由创建自己的 PromptTemplate 并将其用作 Agent 的基础。

Tools 也是如此。在 Haystack 中,你现在可以将几乎任何 Haystack 组件变成 Agent 可以使用的 Tool。这意味着你可以自由设计和创建包含你自己的 Pipelines 和 Nodes 的 Tools,包括 PromptNode。这使得 Tools 具有极大的灵活性,并将允许你为你的 Agents 添加各种各样的功能。

创建和添加 Tools 的示例

有关创建 Agent 和为其添加 Tools 的演练,请访问我们的第一个教程 “使用 Agents 回答多跳问题”。但这里有一个简单的思路:

首先,创建一个 Tool。假设有以下 Pipeline:

my_pipeline = ExtractiveQAPipeline(retriever=some_retriever, reader=some_reader)

这可以变成一个 Tool,如下所示:

from haystack.agents import Tool
my_qa_tool = Tool(name="ExtractiveQATool", pipeline_or_node=my_pipeline, 
                  description="Useful for when you need to answer questions related to Yoda", 
                  output_variable="answers")

请注意,你为 Tool 提供的 description 属性非常重要。你的 Agent 将使用这些描述来决定为当前任务使用哪个 Tool。

然后,你只需将此 Tool 添加到 Agent 可以访问的 Tools 集中。或者,正如我喜欢想象的那样,你作为掌控着渺小 Agent 的全知神,赋予它(根据描述)使用“ExtractiveQATool”来“回答与 Yoda 相关的问题”的能力 😊

from haystack.agents import Agent
from haystack.nodes import PromptNode

prompt_node = PromptNode(model_name_or_path="text-davinci-003", api_key='OPENAI_API_KEY', stop_words=["Observation:"])

agent = Agent(prompt_node=prompt_node)

agent.add_tool(my_qa_tool)

我们非常期待看到你在 Haystack 中如何使用 Agents 和 Tools,并且我们迫不及待地想开始添加更多功能和可用性改进。加入我们的 Discord 或关注 Haystack repo 中的活动,了解 Haystack 和 Agent 的未来发展。