Press "Enter" to skip to content

“研究代理:应对基于大型文本语料库回答问题的挑战”

我制作了一个具有深度多跳推理能力的自主AI研究代理,可以回答困难问题

作者提供的图片(使用Photoshop生成填充生成)

问题简介

在2021年,我开始研究基于大量文本语料库回答问题的挑战。在预训练的transformers出现之前,这个问题是一个难题。

令我沮丧的是,我开始用最复杂、最复杂的故事之一,即《马哈巴拉塔》进行实验。对于不熟悉这部作品的人来说,《马哈巴拉塔》是一部包含18卷、约180万字的作品。它是有史以来最长的诗歌作品,大约有9万行。它的长度不仅如此,而且其广度也令人震惊。它的因果关系高度非线性和复杂,涉及七代人物,其中没有一个人物完全善良或邪恶。它对义务(业)(Karma)、选择和人类存在有深刻的哲学评论,特别是对义务冲突和多重错误之间的选择的评论。《博伽罗歌》(印度教的关键哲学)也是《马哈巴拉塔》第六卷的一部分。

我从多个在线来源编译了《马哈巴拉塔》的文本数据,并整理成一个干净的数据集。然而,我找不到一种方法来实现有意义的文本问答。

不到两年的时间,一切都改变了。

人工智能和大型预训练transformers的快速进步正在深刻和根本地改变技术世界。我对此着迷,就像现在的大多数技术人员一样。

因此,几个月前,我以对“提示工程”的新生艺术的天真知识重新回到了这个问题上。但这次我有一个整体的想法,即制作一个能够处理任何复杂知识库的自主研究代理

《马哈巴拉塔》是最复杂的用例之一。然而,在任何知识领域中,无论是法律、科学研究、教育、医学等,每个项目都始于对先前工作的深入研究。所以这个问题是值得解决的。

研究代理

在这里,我将讨论一个具有深度推理能力的自主AI研究代理的设计和实现,该代理可以解决多跳KBQA问题。我将在Python笔记本中分享研究代理的初始实现,并附上git存储库。如果您只对这部分感兴趣,请随时跳到本文后面的实现部分。

如果您对AI代理、基于知识的问答(KBQA)以及AI研究代理的“为什么”、“什么”和设计演变更感兴趣,请继续阅读。

为什么?

首先,人们可能会问的第一个问题是为什么不直接使用ChatGPT界面提问。它已经在2021年之前生成的互联网数据的庞大量上进行了训练,因此对于《马哈巴拉塔》这样的文本语料库是知晓的。

那是我的第一个尝试。我向ChatGPT提了关于《马哈巴拉塔》的几个问题。对于一些问题,我得到了不错的答案。然而,它们大多数缺乏严谨性。这是可以预料的。GPT是根据一般数据集进行训练的。它可以很好地理解和解释自然语言。它也可以进行合理的推理。然而,它不是任何特定领域的专家。因此,虽然它可能对《马哈巴拉塔》有一些了解,但它可能无法给出经过深入研究的答案。有时,GPT可能根本没有答案。在这种情况下,它要么谦虚地拒绝回答问题,要么自信地虚构答案(幻觉)。

实现KBQA的第二种最明显的方法是使用检索式QA提示。这就是LangChain变得非常有用的地方。

检索问答

对于那些不熟悉LangChain库的人来说,它是在你的代码中使用类似GPT的LLM的最佳方式之一。这是使用LangChain实现KBQA的一个示例。

使用检索器的问答 | 🦜️🔗 Langchain

这个示例展示了对索引进行问答。

python.langchain.com

总结一下,在任何文档集上实现KBQA的步骤如下:

  • 将知识库拆分为文本块。
  • 为每个块创建一个数值表示(嵌入),并将它们保存到向量数据库中。如果你的数据是静态的,步骤1和2只需进行一次。
  • 在这个数据库上使用用户的查询进行语义搜索,并获取相关的文本块。
  • 将这些文本块与用户的问题一起发送给LLM,并要求它们回答。

这是这个过程的图形表示。

作者使用draw.io创建的图片

那么为什么要进一步研究呢?这个问题似乎已经解决了!

并不完全 🙁

这种方法对于简单的问题和简单事实的知识库效果很好。然而,对于更复杂的知识库和需要更深入、多跳推理的更复杂的问题,它并不适用。多跳推理是指采取多个逻辑或上下文推理步骤来得出结论或回答问题的过程。

此外,LLM在一次提示中能够处理的文本长度是有限的。当然,你可以一次发送一个文档,然后在每次调用时“细化”或“减少”答案。然而,这种方法不允许进行复杂的“多跳”推理。在某些情况下,使用“细化”或“减少”方法得到的结果比将所有文档都放在一个提示中要好,但差距并不大。

对于一个复杂的知识库来说,仅凭用户的问题可能不足以找到所有能够帮助LLM得出准确答案的相关文档。

例如:

阿周那是谁?

这是一个简单的问题,可以通过有限的上下文回答。然而,下面这个问题:

为什么发生了《摩诃婆罗多》中的战争?

是一个问题,其上下文遍布整个文本语料库。问题本身对其上下文的信息有限。找到相关的文本块,然后根据它进行推理可能行不通。

那么接下来呢?

AI代理

这是在人工智能问世后出现的最酷的概念之一。如果你不知道AI代理的概念,我迫不及待地想向你解释,但我可能还是无法传达它的精彩之处。让我先用ChatGPT来解释一下。

AI代理,也简称为“代理”,是指能够自主感知环境、做出决策并采取行动以实现特定目标的软件程序或系统。AI代理旨在模仿人类在解决问题和做决策任务中的行为。它们在一个定义好的环境中运行,并与该环境进行交互以实现期望的结果。

简而言之,代理是一个程序,它接受一个问题,决定如何解决它,然后解决它。代理被提供了一组工具,如函数、方法、API调用等。如果选择使用其中任何一个工具,可以按任意顺序使用。与传统软件相比,传统软件中解决问题所需的步骤顺序是预先编程的。这当然是一个非常模糊的定义。但是你现在可能已经掌握了要领。

这是我为我们的KBQA用例尝试的两种不同的代理。

React这个代理使用了一种“ReAct”(Reason and Action)的推理方式,以决定使用哪个工具来解决给定的问题。

这是ReAct Agent的langChain实现:

ReAct | 🦜️🔗 Langchain

这个演示展示了使用一个Agent来实现ReAct逻辑。

python.langchain.com

我为Agent提供了以下工具供其选择:

  • 带有文档存储的检索QA链。
  • 字符词汇表搜索(我使用预训练模型创建了一个具有命名实体识别的词汇表)。
  • 维基百科搜索。

ReAct Agent大部分时间都没有给我提供好的结果,也没有收敛到任何答案。它在与GPT 3.5一起工作时效果不好。也许在GPT 4上可能会更好,但GPT 4的价格比GPT 3.5高出20-30倍,所以目前可能还不是一个选择。

即使在收敛时,我也无法得到好的结果。那些在创建’react’提示方面更有知识的人可能会做得更好。

自问代理该代理根据原始问题提出后续问题,然后尝试找到中间答案。使用这些中间答案,最终得出最终答案。这里有一篇文章解释了自问代理

自问提示

自问提示是从思维链提示的发展。以下是一些实际示例和…

cobusgreyling.medium.com

这种方法给我带来了一些不错的结果。它对于单跳推理很有效。但是对于需要多跳推理的问题,甚至这种方法也失败了。

例如,以下问题:

谁杀了卡尔纳,为什么?

使用这种方法相对容易回答

但是以下问题

为什么阿朱那杀了他的同父异母的兄弟卡尔纳?

回答起来更加困难。它需要LLM知道阿朱那不知道卡尔纳是他的同父异母的兄弟这个事实。LLM也无法知道它需要知道这个事实,无论是通过理解问题还是根据原始问题提出进一步问题。

人类研究过程

再次引用GPT

AI代理的设计目的是模仿人类在解决问题和做决策任务时的行为

所以,我的下一个想法是研究人类如何进行研究,即元研究。我想象自己坐在图书馆里(大学的怀旧感),可以轻松获取与我的研究课题相关的所有书籍。我拿起笔记本和笔,开始记录我研究一个课题时遵循的过程。

以下是我得出的结果。

研究方法:

在一页上记录下原始查询。

  1. 我尝试通过阅读一些书籍来回答当前的问题。在这个过程中,我做了一些笔记,并书签了一些我认为与当前问题最相关的摘录。
  2. 在这些摘录中,我发现了很多未知的内容。我记录下这些未知,并写下一些更多的问题,可以帮助我了解这些未知。
  3. 从这些问题中,我选择一个与原始问题最相关的问题。
  4. 我回到第1步。

经过几次迭代后,我问自己是否有足够的信息来回答原始问题。

如果有,那么工作做得很好!如果没有,那就继续努力。

大功告成!

最后,我知道该如何编码了。我希望通过一些提示工程,这个过程可以给我提供比我之前尝试过的任何其他方法更深入的答案。

剧透……确实做到了!:)

在开始编码之前,我在互联网上搜索了类似的想法。然后我发现了BabyAGI。多么美妙的世界啊!

这里有一个描述BabyAGI的存储库

我意识到BabyAGI和上述研究过程之间有许多相似之处。因此,我从BabyAGI实现中使用的提示中汲取了一些灵感。

研究代理 — 实现

这里是使用令人惊叹的 draw.io 将相同的过程转换为流程图的结果

作者生成的图像(使用draw.io生成)

这张图表中的每个蓝色框都是对 LLM 的调用。

组件

  1. QA 代理 — 搜索答案和进一步的上下文这是一个简单的“物品”检索 QA 链,它使用向量存储。将来,这可以是一个使用向量存储、搜索 API 或维基百科 API、审查 API 和以前的研究数据等工具的 AI 代理。这里的提示被调整为基于 1. 上下文(文档)和 2. 与原始问题相关性生成简洁的答案。除了第一个循环外,当前问题始终是在步骤 2 生成并在步骤 3 中选择的中间问题。代理将中间答案附加到注释中,并将最新的摘录(用于回答当前问题的文档)添加到书签中。这些文档中最近的文档在步骤 2 中被利用。
  2. 问题生成器 — 基于最新注释提出更多问题在这里,代理使用与当前问题匹配的最近的向量搜索结果,并用它们生成与原始问题相关的更多问题。它将这些问题追加到未回答问题的列表中。这里的提示被调整得新生成的问题不会与现有的问题列表重叠。
  3. 最相关问题选择器 — 选择与原始问题最相关的一个问题这个提示从未回答问题的列表中选择一个与原始问题最相关的问题。这个问题被用作下一个循环的当前问题。在下一个循环中,在生成一组新问题之后,代理会从未回答问题的列表中删除这个问题。
  4. 分析器 — 我是否了解足够?我正在使用一个 max_iterations 参数来退出循环。目前这个方法效果很好。但是,根据不断变化的上下文,根据迭代次数或退出策略来动态决定可能更好。将来我会研究一种可以自主完成这个任务的“分析器”。
  5. 研究编译器 — 编译研究这是最终的提示。它使用在研究过程中做的注释来得出对原始问题的详细回答。

结果

研究代理是我尝试过的所有先前方法的重大改进。它比任何其他方法都能提供更详细和准确的答案。我已经使用它玩了几个星期,对所得到的答案的丰富性感到惊讶。

代理相对于先前的方法更加避免出现幻觉的问题。它在最初的几次迭代中会自动纠正产生的幻觉和事实错误。它越深入问题,结果就越准确。

这是一个示例运行。

问题:为什么潘达瓦必须在森林中生活12年?

输出 —

“研究代理:应对基于大型文本语料库回答问题的挑战” 四海 第4张

如果你感兴趣,这是最终答案

最终答案:潘达瓦决定在森林中生活12年主要是由于在他们的生活中发生的情况和事件。在与卡瓦拉王子们赌博输掉后,潘达瓦被迫流亡13年,最后一年要隐姓埋名。在流亡期间,他们面临了许多挑战和困难,包括生活在森林中。比马曾考虑过杀死所有库鲁人,但他的兄弟尤迪斯提尔总是安抚他,称现在不是实现他们愿望的时机。因此,生活在森林中使他们能够避免冲突并保持和平。在森林中的这段时间里,潘达瓦面临了几个困难。其中一个主要的挑战是比马如何忍受苦行生活。比马曾考虑过杀死所有库鲁人,但他的兄弟尤迪斯提尔总是安抚他并劝阻他这样做。此外,潘达瓦必须生活在森林中,并依靠讨饭维持生计,因为他们的王国在赌博中被掠夺。他们对自己的王国的丧失和对他们的王后德拉乌帕蒂的侮辱感到痛苦。森林本身也充满了危险,增加了他们的困难。此外,潘达瓦觉得自己无法满足与他们一起在森林中居住的某些虔诚的婆罗门的需求,因为他们一无所有,生存依赖乞讨。尽管面临这些挑战,潘达瓦在森林中度过了宝贵的时光。他们从圣人和圣洁的人那里得到了知识,帮助他们获得智慧和精神上的洞察力。伟大的圣人比亚萨告诉他们许多将军已经同意支持他们的堂兄杜里奥达,包括卡尔纳、沙库尼、布里什拉瓦斯、萨拉、德罗纳和毕沙摩。比亚萨还告诉阿周那,如果他将来参加战争,他需要获得主因陀罗和湿婆神的神圣武器。基于这些信息,尤迪斯提尔命令阿周那前往喜马拉雅山脉进行苦行,以取悦湿婆神。这对于阿周那获得在即将到来的战争中至关重要的神圣武器是必要的。潘达瓦了解到为了对抗对手的实力,准备和获取必要的资源的重要性。因此,尤迪斯提尔决定派阿周那执行这个任务,寻求湿婆神的祝福并获得神圣武器。总的来说,潘达瓦在森林中流亡十二年是输掉赌博后对他们施加的条件的结果。他们在森林中的时间面临各种困难,但也获得了宝贵的知识,并为未来的挑战做好了准备。

这个答案非常详细。但是,这个Agent的美妙之处不仅在于它准确地回答了原始问题,还在于它进一步找到了围绕问题的故事。

在大多数情况下,我得到的答案都充满了这样的细节。每一个这样的答案都激发了我对进一步调查的好奇心。

在研究过程中,Agent还提供了一系列已回答的问题和未回答的问题。因此,每次运行后,它都引导我提出许多其他问题。在过去的几周里,我对《摩诃婆罗多》的了解比之前的许多年都要多。

** 未回答的问题 ** '4. 在森林中的时间里,帕童达兄弟是如何从圣人和圣洁人物那里得到知识的?''5. 阿朱纳在喜马拉雅山上进行了哪些特定的苦行,以取悦湿婆神?''6. 帕童达兄弟是如何在整整第十三年的流放期间几乎一直躲避杜里奥达纳的间谍的?''8. 比玛在森林中作为一个苦行者的挑战是如何应对的?在他们的流放期间,他是否遇到了特殊的困难或挣扎?''9. 您能提供关于支持杜里奥达纳事业的将军们的更多信息吗?他们在库鲁克什特拉战争中的角色和贡献是什么?''10. 帕童达兄弟是如何在面对各种挑战时保持平静的森林生活的?''11. 帕童达兄弟在森林中从圣人和圣洁人物那里学到了哪些特定的教诲和知识?''12. 您能提供有关帕童达兄弟在进入森林之前在一个完整的一年中居住的宫殿的更多信息吗?''13. 在流放期间,湿婆神在森林中的存在如何影响帕童达兄弟的经历?''14. 您能提供有关帕童达兄弟在森林中面临的危险的更多信息吗?''15. 作为森林居民,尤迪斯提拉和他的兄弟们在日常生活中面临了哪些特定的挑战和困难?''

想象一下对其他领域的知识采用同样的过程,这是一个令人振奋的想法!

代码

下面是使用研究Agent实现的Python笔记本。

GitHub – rahulnyk/research_agent

通过在GitHub上创建一个账户,参与到rahulnyk/research_agent的开发中。

github.com

《摩诃婆罗多》数据集的Git存储库

GitHub – rahulnyk/mahabharata: 从多个来源编制的摩诃婆罗多文本,分割成块…

摩诃婆罗多文本是从多个来源编制的,分割成块,并带有元数据的CSV文件。命名实体…

github.com

接下来做什么?

当前的实现是一个自主AI研究Agent的简化版本。在实现Agent的过程中,我多次调整了研究过程。这是一段令人兴奋的旅程,但乐趣并未结束。以下是我目前正在努力改进的一些方面。

  • 将该Agent部署在公共链接上,并观察更多的使用模式。
  • 将Agent用于除《摩诃婆罗多》以外的不同源文档。
  • 目前,该过程的第一步是一个简单的“stuff” QA链,它使用一个带有源文本语料库的向量存储。我正在努力用“ReAct” Agent替换它,以便在研究过程中可以使用其他工具,如搜索API、维基百科、审查API等。
  • 我将保存每次运行期间生成的数据和元数据到一个`runs`向量存储中。我还将原始问题的嵌入保存到同一个存储中。这帮助我跟踪Agent的推理路径,并观察到其中产生的几个逻辑模式。这可以帮助调整QA Agent以遵循更紧密的推理路径。
  • 目前,研究Agent在固定的一组迭代后退出。对于大多数问题,这工作得很好。但是,根据不断演变的上下文情况,动态决定迭代次数或退出策略可能更好。我将研究一个能够自主完成此任务的“分析器”。
  • 该Agent对大多数类型的问题都能很好地工作,但对于元问题则不然。例如,如果我问“描述第5章第3节中发生的事情”,Agent很难回答。在未来的版本中,我将在“ReAct” Agent中加入一个自查询检索器,以处理这种情况。
  • 到目前为止,我只尝试过使用OpenAI GPT3.5模型的Agent。每次运行大约需要花费我0.02美元。我很快会尝试使用像Llama这样的较小模型来运行研究Agent,以便可以在本地托管。

在下一篇文章中,我打算写一些我在实施这些更新后的发现。更大的想法是创建一个一流的自主AI研究代理,它可以在找到深入研究的答案上做得很出色。因此,请随时提出建议,并在可能的情况下与我合作,以进一步完善这个项目。

我希望您会发现这篇文章和共享的代码有用。

谢谢您的阅读。

我希望您会觉得这个AI研究代理很令人兴奋和有用。

我分享的笔记本只是创建一个自主AI研究代理这个更大想法的简单实现。还有很多工作可以做,使这个代理成为一名一流的研究员。

因此,请随时提出建议,并在可能的情况下与我合作,以进一步完善这个项目。

谢谢您的阅读。

以上文章中使用的数据集的来源和许可信息如下:

  1. K. M. Ganguli的完整翻译:公共领域可用。
  2. Laura Gibbs Tiny Tales:这是使用两百个每个100字的情节重新讲述的Mahabharata。我在这里使用她的作品并获得了她的许可。
  3. Tilak的Kaggle数据仓库:Mahabharata的所有18个Parvas的文本格式用于自然语言处理。由Tilak以公共领域许可分享。
Leave a Reply

Your email address will not be published. Required fields are marked *