Press "Enter" to skip to content

利用实体提取、SQL查询和具有Amazon Bedrock的代理来提升基于RAG的智能文档助手的能力

近年来,由于生成式人工智能(AI)的快速发展,特别是通过指令微调和强化学习等训练技术引入的大型语言模型(LLMs)的性能改进,对话式AI已经取得了长足的进步。当正确提示时,这些模型可以进行连贯的对话,而无需任何特定任务的训练数据。然而,它们对于企业特定问题的泛化能力不强,因为为了生成答案,它们依赖于预训练期间所接触到的公共数据。这些数据通常缺乏现代企业中可用的内部文件中包含的专业知识,这通常是在药物研究、金融调查和客户支持等领域获取准确答案所必需的。

要创建能够以专业企业知识为基础进行讨论的AI助手,我们需要将这些强大但通用的LLM连接到内部文件的知识库中。将LLM生成上下文与从您的内部数据源中检索的信息相结合的这种方法称为检索增强生成(RAG),并且生成的助手是特定领域的,并且更可靠,正如“检索增强的生成用于知识密集型NLP任务。”(Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks)中所示。RAG流行的另一个推动因素是其易于实施和成熟的矢量搜索解决方案的存在,例如亚马逊肯德拉(Amazon Kendra)(参见“为亚马逊肯德拉索引您爬取的内容”)和亚马逊OpenSearch Service(参见“在亚马逊OpenSearch Service中使用k最近邻(k-NN)搜索”)等。

然而,具有语义搜索的流行RAG设计模式不能回答所有可能的文档类型问题,尤其是那些需要跨多个文档进行分析推理的问题。例如,想象一下,您正在规划一家投资公司明年的战略。其中一个关键步骤是分析和比较候选公司的财务结果和潜在风险。这个任务涉及回答分析推理问题。例如,查询“给我最近2年内收入最高的前5家公司,并确定它们的主要风险”需要进行多步推理,其中一些可以使用语义搜索检索,而其他的则需要具备分析能力。

本文中,我们展示了如何设计一个智能文档助手,能够回答分析和多步推理问题,并分为三个部分。在第一部分中,我们回顾了RAG设计模式并讨论了其在分析问题上的局限性。然后,我们向您介绍了一个更通用的架构,以克服这些限制。在第二部分中,我们将帮助您深入了解用于准备结构化数据的实体提取流程,这是分析问题回答的关键因素。第三部分将指导您如何使用Amazon Bedrock LLM来查询数据并建立具备分析能力的LLM代理,从而使您能够构建能够回答跨多个文档的复杂领域特定问题的智能文档助手。

第一部分:RAG的局限性和解决方案概述

在本节中,我们回顾了RAG设计模式并讨论了其在分析问题上的局限性。我们还介绍了一个更通用的架构,以克服这些局限性。

RAG概述

RAG解决方案受到表示学习和语义搜索思想的启发,这些思想从2010年开始逐渐被采用在排名问题(例如推荐和搜索)和自然语言处理(NLP)任务中。

今天流行的方法由以下三个步骤组成:

  1. 离线的批处理作业从输入知识库中提取文档,将其分成块,为每个块创建一个嵌入以表示其语义,使用预训练的嵌入模型,例如Amazon Titan嵌入模型,然后使用这些嵌入作为输入创建语义搜索索引。 利用实体提取、SQL查询和具有Amazon Bedrock的代理来提升基于RAG的智能文档助手的能力 四海 第1张
  2. 当实时回答新问题时,将输入问题转换为嵌入,然后使用相似度度量方法(例如余弦相似度)和近似最近邻算法搜索和提取最相似的文档块。使用元数据过滤也可以提高搜索精度。 利用实体提取、SQL查询和具有Amazon Bedrock的代理来提升基于RAG的智能文档助手的能力 四海 第2张
  3. 从系统消息和上述步骤中提取的相关文档块以及输入问题本身的组合构建一个提示,然后将该提示提供给LLM模型,从上下文生成最终的答案。 利用实体提取、SQL查询和具有Amazon Bedrock的代理来提升基于RAG的智能文档助手的能力 四海 第3张

通过正确的底层嵌入模型,能够产生准确的语义表示输入文档块和输入问题的能力,以及高效的语义搜索模块,这个解决方案能够回答需要从文档数据库中检索现有信息的问题。例如,如果你有一个服务或产品,你可以先建立其常见问题解答部分或文档的索引,然后定制一个最初的对话式人工智能,以适应你的特定产品。

尽管RAG是现代领域特定人工智能助手的重要组成部分,也是构建以专业知识库为基础的对话式人工智能的明智起点,但它无法回答那些需要同时扫描、比较和推理你的知识库中所有文档的问题,特别是当增强仅基于语义搜索时。

为了理解这些局限性,让我们再次考虑一下基于财务报告做投资决策的例子。如果我们使用RAG与这些报告进行对话,我们可以问诸如“公司X在2022年面临的风险有哪些”或“公司Y在2022年的净收入是多少”的问题。对于每个问题,与该问题的语义含义编码相关的嵌入向量都用于检索搜索索引中提供的与其语义上最相似的文档块。这通常通过使用近似最近邻解决方案(如FAISS、NMSLIB、pgvector等)来实现,它们在检索速度和召回率之间寻求平衡,以实现实时性能同时保持满意的准确性。

然而,前面的方法无法准确回答关于所有文档的分析性问题,例如“2022年净收入最高的前5家公司是哪些?”

这是因为语义搜索检索试图找到与输入问题最相似的前K个文档块。但是,由于没有任何文档包含收入的详细摘要,它会返回仅包含“净收入”和可能的“2022年”提及的文档块,而没有满足关注具有最高收入的公司这个重要条件。如果我们将这些检索结果作为上下文呈现给一个LLM来回答输入问题,它可能会给出一个误导性答案或拒绝回答,因为所需的正确信息缺失。

这些局限性是有意设计的,因为语义搜索没有对所有嵌入向量进行全面扫描来找到相关文档。相反,它使用近似最近邻方法在索引期间将嵌入空间分成组,以快速识别在检索期间可能包含相关嵌入向量的组,而无需进行成对比较。此外,即使是传统的最近邻技术如KNN也只计算基本距离度量,不适合分析推理所需的复杂比较。因此,基于语义搜索的RAG并不适用于回答涉及跨所有文档的分析性推理问题。

为了克服这些局限性,我们提出了一种将RAG与元数据和实体提取、SQL查询和LLM代理相结合的解决方案,如下所述。

通过元数据、SQL和LLM代理克服RAG的局限性

让我们更深入地研究RAG失败的问题,以便能够追溯回答它所需的推理过程。这个分析应该将我们指向正确的方法,可以在整体解决方案中补充RAG。

考虑以下问题:“2022年净收入最高的前5家公司是哪些?”

为了回答这个问题,我们需要:

  1. 识别每个公司的收入。
  2. 过滤并保留它们各自2022年的收入。
  3. 按降序对收入进行排序。
  4. 选取前5个收入以及公司名称。

通常,这些分析操作是在结构化数据上完成的,使用诸如pandas或SQL引擎的工具。如果我们可以访问一个包含companyrevenueyear列的SQL表,我们可以通过运行类似以下示例的SQL查询来轻松回答这个问题:

SELECT company, revenue FROM table_name WHERE year = 2022 ORDER BY revenue DESC LIMIT 5;

将结构化元数据存储在一个包含有关相关实体信息的SQL表中,可以通过编写正确的SQL查询来回答许多类型的分析性问题。这就是为什么我们在解决方案中用离线过程中提取的元数据填充的SQL表对RAG进行补充的原因。

但是我们如何将这种方法应用于基于LLM的对话型AI并进行整合?

要能够添加SQL分析推理,需要三个步骤:

  • 元数据提取 – 从非结构化文档中提取元数据到SQL表中
  • 文本到SQL – 使用LLM准确地从输入问题中制定SQL查询
  • 工具选择 – 确定是否必须使用RAG或SQL查询来回答问题

为了实施这些步骤,首先我们认识到从非结构化文档中提取信息是一项传统的自然语言处理任务,LLM通过零 shot或few-shot学习有望实现高准确性。其次,这些模型生成自然语言的SQL查询的能力已经在2020年的发布中得到证明,并在Amazon QuickSight Q中得到应用。最后,自动选择特定问题的正确工具可以增强用户体验并通过多步推理回答复杂问题。为了实现这一特性,我们在后面的章节中探索LLM代理。

总结起来,我们提出的解决方案由以下核心组件组成:

  • 语义搜索检索以增强生成上下文
  • 使用SQL进行结构化元数据提取和查询
  • 一个能够使用正确工具回答问题的代理

解决方案概述

下图描述了解决方案的简化体系结构。它可以帮助您识别和了解核心组件的角色以及它们如何相互交互以实现完整的LLM助理行为。编号与实施此解决方案时的操作顺序相对应。

利用实体提取、SQL查询和具有Amazon Bedrock的代理来提升基于RAG的智能文档助手的能力 四海 第4张

实际上,我们按照下面的详细架构来实施这个解决方案。

利用实体提取、SQL查询和具有Amazon Bedrock的代理来提升基于RAG的智能文档助手的能力 四海 第5张

对于这个架构,我们建议在GitHub上进行实施,其中后端(5),数据管道(1, 2, 3)和前端(4)可以分别演进。这样可以简化在为生产环境定制和改进解决方案时跨能力进行协作。

部署解决方案

要在您的AWS账户中安装此解决方案,请完成以下步骤:

  1. 克隆GitHub上的存储库
  2. 安装后端AWS Cloud Development Kit (AWS CDK) 应用
    1. 打开backend文件夹。
    2. 运行npm install以安装依赖。
    3. 如果您以前没有在当前账户和区域中使用AWS CDK,请使用npx cdk bootstrap运行引导
    4. 运行npx cdk deploy以部署堆栈。
  3. 可选地,按如下方式运行streamlit-ui
    1. 我们建议将此存储库克隆到Amazon SageMaker Studio环境中。有关更多信息,请参阅使用Quick setup入门Amazon SageMaker域
    2. frontend/streamlit-ui文件夹内运行bash run-streamlit-ui.sh
    3. 选择以下格式的链接打开演示:https://{domain_id}.studio.{region}.sagemaker.aws/jupyter/default/proxy/{port_number}/
  4. 最后,您可以运行在data-pipelines/04-sagemaker-pipeline-for-documents-processing.ipynb笔记本中定义的Amazon SageMaker管道,以处理输入的PDF文档并准备LLM助理使用的SQL表和语义搜索索引。

在本文的其余部分,我们专注于解释最重要的组件和设计选择,希望能在您设计自己的AI助手时给您灵感。我们假设组件1和4很容易理解,并着重介绍核心组件2、3和5。

第2部分:实体提取流程

在本节中,我们将深入介绍用于准备结构化数据的实体提取流程,这是分析性问题回答的关键组成部分。

文本提取

文档通常以PDF格式或扫描图像的形式存储。它们可能由简单的段落布局或复杂的表格组成,并包含数字或手写文本。为了正确提取信息,我们需要将这些原始文档转换为纯文本,同时保留它们的原始结构。为此,您可以使用Amazon Textract,这是一个机器学习(ML)服务,提供用于从数字和手写输入中提取文本、表格和表单的成熟API。

在组件2中,我们按以下方式提取文本和表格:

  1. 对于每个文档,我们调用Amazon Textract来提取文本和表格。
  2. 我们使用以下Python脚本将表格重新创建为pandas DataFrames。
  3. 我们将结果合并到单个文档中,并将表格插入为Markdown格式。

此过程在以下流程图中进行了概述,并在notebooks/03-pdf-document-processing.ipynb中得到了具体示例。

利用实体提取、SQL查询和具有Amazon Bedrock的代理来提升基于RAG的智能文档助手的能力 四海 第6张

使用LLMs进行实体提取和查询

为了有效回答分析性问题,您需要从文档的知识库中提取相关的元数据和实体到一个可访问的结构化数据格式。我们建议使用SQL来存储这些信息并检索答案,因为SQL具有广泛的应用、易于使用和可扩展性。这个选择还受益于经过验证的语言模型能够从自然语言生成SQL查询。

在本节中,我们将深入介绍以下支持分析性问题的组件:

  • 使用LLMs从非结构化数据中提取结构化数据的批处理过程
  • 实时模块将自然语言问题转换为SQL查询,并从SQL数据库中检索结果

您可以按以下方式提取相关的元数据以支持分析性问题:

  1. 为您需要提取的信息定义一个JSON模式,其中包含每个字段的描述和数据类型,并包含预期值的示例。
  2. 对于每个文档,提示一个LLM使用JSON模式并要求其准确地提取相关数据。
  3. 当文档长度超过上下文长度,并且为了减少与LLM的提取成本,您可以使用语义搜索来检索和呈现与LLM在提取过程中相关的文档部分。
  4. 解析JSON输出并验证LLM的提取。
  5. 可选择将结果作为CSV文件备份到Amazon S3。
  6. 加载到SQL数据库中以供以后查询。

此过程由以下架构管理,其中以文本格式加载的文档由一个运行在Amazon SageMaker Processing作业中运行的Python脚本来执行提取。

利用实体提取、SQL查询和具有Amazon Bedrock的代理来提升基于RAG的智能文档助手的能力 四海 第7张

对于每组实体,我们动态构建一个提示,包括信息提取任务的清晰描述,并包含定义预期输出并包含相关文档部分作为上下文的JSON模式。我们还添加了一些输入和正确输出的示例,以改善少样本学习的提取性能。这在notebooks/05-entities-extraction-to-structured-metadata.ipynb中得到了演示。

第三部分:使用Amazon Bedrock构建自主文档助手

在本节中,我们将演示如何使用Amazon Bedrock LLMs查询数据并构建一个具有分析能力的LLM代理,从而使您能够构建智能文档助手,能够跨多个文档回答复杂的领域特定问题。您可以参考GitHub上的Lambda函数,了解本部分中所描述的代理和工具的具体实现。

制定SQL查询并回答分析问题

现在,我们有一个包含相关实体的结构化元数据存储,并已将其加载到可以查询的SQL数据库中,剩下的问题是如何从输入的自然语言问题生成正确的SQL查询?

现代LLMs擅长生成SQL。例如,如果您通过Amazon Bedrock向Anthropic Claude LLM请求生成SQL查询,您将看到合理的答案。然而,在编写提示时,我们需要遵守一些规则,以便生成更准确的SQL查询,特别是对于复杂查询来减少错误:

  • 准确描述提示中的任务
  • 在提示中包含SQL表的模式,并描述每个列的列名并指定其数据类型
  • 明确告诉LLM仅使用现有的列名和数据类型
  • 添加一些SQL表的行数据

您还可以使用linter(例如sqlfluff)对生成的SQL查询进行后处理,以纠正格式,或者使用解析器(例如sqlglot)来检测语法错误和优化查询。此外,当性能不能满足要求时,您可以在提示中提供一些示例,以引导模型进行少次学习,以生成更准确的SQL查询。

从实现的角度来看,我们使用一个AWS Lambda函数来进行以下的流程:

  1. 使用输入的问题调用Amazon Bedrock中的Anthropic Claude模型,获取相应的SQL查询。在这里,我们使用LangChain的SQLDatabase类添加相关SQL表的模式描述,并使用自定义提示。
  2. 解析、验证并对Amazon Aurora PostgreSQL-Compatible Edition数据库运行SQL查询。

本解决方案的架构在以下图表中突出显示。

利用实体提取、SQL查询和具有Amazon Bedrock的代理来提升基于RAG的智能文档助手的能力 四海 第8张

防止SQL注入攻击的安全考虑

当我们让AI助手查询SQL数据库时,我们必须确保这不会引入安全漏洞。为此,我们提出以下安全措施来防止SQL注入攻击:

  • 应用最低权限IAM权限 – 使用符合最低权限原则AWS身份和访问管理(IAM)策略和角色来限制运行SQL查询的Lambda函数的权限。在这种情况下,我们授予只读访问权限。
  • 限制数据访问 – 仅提供对最低限度的表和列的访问权限,以防止信息泄露攻击。
  • 增加审查层 – 引入一个能够及早检测到提示注入尝试并阻止其传播到系统其他部分的审查层。它可以采用基于规则的过滤器、与已知提示注入示例数据库的相似度匹配,或者是一个ML分类器。

语义搜索检索增强生成上下文

我们提出的解决方案在组件3中使用带有语义搜索的RAG。您可以使用Amazon Bedrock的知识库来实现此模块。此外,还有各种其他实现RAG的选项,例如Amazon Kendra检索APIAmazon OpenSearch向量数据库Amazon Aurora PostgreSQL与pgvector等。开源软件包aws-genai-llm-chatbot演示了如何使用许多这些向量搜索选项来实现LLM驱动的聊天机器人。

在这个解决方案中,由于我们既需要SQL查询又需要向量搜索,所以我们决定使用支持这两个功能的Amazon Aurora PostgreSQL和pgvector扩展。因此,我们使用以下架构实现语义搜索RAG组件。

利用实体提取、SQL查询和具有Amazon Bedrock的代理来提升基于RAG的智能文档助手的能力 四海 第9张

使用上述架构回答问题的过程分为两个主要阶段。

首先,离线批处理过程作为SageMaker处理作业来运行,创建语义搜索索引,具体步骤如下:

  1. 定期或接收到新文档时,运行SageMaker作业。
  2. 从Amazon S3加载文本文档,并将其拆分为重叠的块。
  3. 对于每个块,使用Amazon Titan嵌入模型生成嵌入向量。
  4. 使用LangChain的PGVector类将嵌入向量及其文档块和元数据导入Amazon Aurora PostgreSQL,并在所有嵌入向量上创建语义搜索索引。

其次,针对每个新问题实时构造答案的步骤如下:

  1. 接收到问题后,由在Lambda函数上运行的协调器接收。
  2. 协调器使用相同的嵌入模型对问题进行嵌入。
  3. 它从PostgreSQL语义搜索索引中检索与最相关的文档块。可以使用元数据过滤来提高准确性。
  4. 这些块与输入问题一起动态插入到LLM提示中。
  5. 将提示展示给Amazon Bedrock上的Anthropic Claude,指示其根据当前上下文回答输入问题。
  6. 最后,将生成的答案发送回协调器。

一个能够使用工具进行推理和行动的代理

迄今为止,在这篇文章中我们讨论了需要RAG或分析推理的问题的处理方法。然而,许多现实世界的问题需要这两种能力,有时需要经过多次推理才能得出最终答案。为了支持这些更复杂的问题,我们需要引入代理的概念。

最近出现的LLM代理,如Amazon Bedrock的代理,已经成为一种有希望的解决方案,能够使用LLMs根据当前上下文进行推理和调整,并从一组选项中选择合适的行动,从而提供了一个通用的问题解决框架。正如在LLM Powered Autonomous Agents中讨论的那样,LLM代理支持复杂推理的提示策略和设计模式有多种。

其中一种设计模式是Reason and Act(ReAct),在ReAct: Synergizing Reasoning and Acting in Language Models中介绍。在ReAct中,代理接收一个目标作为输入,这个目标可以是一个问题,它确定回答问题所需的缺失信息,并根据可用工具的描述迭代地提出正确的工具来收集信息。在收到给定工具的答案后,LLM重新评估是否已经获得了完全回答问题所需的所有信息。如果还没有,它会进行另一步推理,并使用相同的或另一个工具收集更多信息,直到得出最终结论或达到限制。

下面的时序图解释了ReAct代理如何工作,以回答问题“给我最近两年内收入最高的前5家公司,并确定排名第一的风险。”

利用实体提取、SQL查询和具有Amazon Bedrock的代理来提升基于RAG的智能文档助手的能力 四海 第10张

实现这种方法的Python细节在Custom LLM Agent中有描述。在我们的解决方案中,代理和工具以以下突出的部分架构实现。

利用实体提取、SQL查询和具有Amazon Bedrock的代理来提升基于RAG的智能文档助手的能力 四海 第11张

为了回答一个输入的问题,我们使用AWS服务如下:

  1. 用户通过用户界面输入他们的问题,该界面调用Amazon API Gateway上的API。
  2. API Gateway将问题发送到实现代理执行者的Lambda函数。
  3. 代理调用LLM,其中包含可用工具的描述,ReAct指令格式和输入问题,并解析下一个要完成的动作。
  4. 动作包含要调用的工具和动作输入。
  5. 如果要使用的工具是SQL,代理执行者调用SQLQA将问题转换为SQL并运行它。然后将结果添加到提示中,再次调用LLM,看它是否能回答原始问题或是否需要更多的操作。
  6. 类似地,如果要使用的工具是语义搜索,则解析出动作输入,并用于从PostgreSQL语义搜索索引中检索。将结果添加到提示中,并检查LLM是否能回答或是否需要另一个动作。
  7. 在获取回答问题的所有信息后,LLM代理构建最终回答并发送给用户。

您可以使用更多的工具扩展代理。在GitHub上可用的实现中,我们演示了如何将搜索引擎和计算器作为额外工具添加到前述的SQL引擎和语义搜索工具中。为了存储进行中的对话历史记录,我们使用了一个Amazon DynamoDB表。

根据我们迄今的经验,一个成功的代理需要以下关键要素:

  • 具备用ReAct格式推理的基础LLM
  • 清楚描述可用工具及其使用时机,以及它们的输入参数的描述,可能还包括输入和预期输出的示例
  • 明确规定LLM必须遵循的ReAct格式
  • 为LLM代理提供解决业务问题所需的合适工具
  • 正确解析LLM代理响应中的输出,因为它进行推理

为了优化成本,我们建议缓存常见问题及其答案,并定期更新此缓存以减少对基础LLM的调用。例如,您可以创建一个语义搜索索引,其中包含最常见的问题,如前面解释过的,并在调用LLM之前首先将新用户的问题与该索引进行匹配。要了解其他缓存选项,请参考LLM缓存集成

支持视频、图像、音频和3D文件等其他格式

您可以将相同的解决方案应用于各种类型的信息,如图像、视频、音频和3D设计文件,如CAD或网格文件。这涉及使用已建立的机器学习技术将文件内容描述为文本,然后将其纳入我们之前探讨的解决方案中。这种方法使您能够对这些多样化的数据类型进行问答对话。例如,您可以通过创建图像、视频或音频内容的文本描述来扩展您的文档数据库。您还可以通过对这些格式中的元素进行分类或对象检测来识别属性,从而增强元数据表。在将此提取的数据索引到元数据存储或语义搜索索引后,所提议系统的总体架构基本保持一致。

结论

在本文中,我们展示了使用LLMs和RAG设计模式来构建特定领域的人工智能助手的必要性,但这对于达到所需的可靠性水平以生成商业价值是不足够的。因此,我们建议将流行的RAG设计模式与代理和工具的概念相结合,工具的灵活性使我们能够同时使用传统的NLP技术和现代LLM能力,以便让AI助手在获取信息和有效解决业务问题时有更多选择。

这个解决方案展示了设计过程,以构建一款LLM助手,能够回答各种类型的检索、分析推理和多步推理问题,涵盖了所有的知识库。我们还强调了从您的LLM助手预期帮助用户的问题和任务类型开始反向思考的重要性。在这种情况下,设计过程引导我们形成了具有以下三个组件的体系结构:语义搜索、元数据提取和SQL查询,以及LLM代理和工具,我们认为这种设计具有通用性和灵活性,适用于多种用例。我们还相信,通过从这个解决方案中获取启示并深入了解您的用户需求,您将能够进一步扩展这个解决方案,以达到最佳效果。

Leave a Reply

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