首页 > 云计算 > 公有云实践 > 生成式人工智能数据指南:从业者实用手册
在本次课程中,您将获得部署端到端生成式AI应用所需的技能,这些应用将利用您最有价值的数据。虽然本课程重点关注检索增强生成(RAG)过程,但这些概念同样适用于定制生成式AI应用的其他方法。探索使用亚马逊云科技数据库服务(如Amazon Aurora、Amazon OpenSearch Service或Amazon MemoryDB)以及数据处理服务(如Amazon Glue)和流数据服务(如Amazon Kinesis)的最佳实践架构。学习数据湖、治理和数据质量概念,以及Amazon Bedrock Knowledge Bases、Amazon Bedrock Agents和其他功能如何将解决方案组件连接在一起。
以下是小编为您整理的本次演讲的精华。
好的,下午好,欢迎大家。首先,在我们开始之前,请注意展览大厅已经开放,所以我们正站在你们和展览大厅的派对之间,因此我们会尽量控制在时间范围内。欢迎来到“面向生成式人工智能的数据实践指南”。我是Jonathan Katz。这位是Siva Ragapathi,他从2009年就加入了亚马逊云科技,因此他见证了多年来数据的重大演变,他将在演讲的最后发表意见,将我们所讨论的内容联系起来。
谢谢你暂时和我一起上台,Siva。
“不客气,”Siva回答道。
本次演讲的背景围绕着数据流展开。你们可能听说过很多关于向量数据库、向量搜索和生成式人工智能的内容,但生成式人工智能真正的魔力在于利用你们多年来积累的所有私有数据源,并将它们整合到这些基础模型中,以生成异常丰富和个性化的响应。
这是一个300级的演讲,这意味着我们将尽可能深入探讨尽可能多的技术细节,但这是一个范围极广的主题,我们的目标是为你们提供尽可能多的策略,以便在开发这些生成式人工智能应用程序时做出明智的决策。而要实现这一目标,有什么比通过一个生动的例子更好的方式呢?
让我们直接深入讨论Pat。Pat需要购买汽车保险。这可能是你们都或多或少熟悉的一种情况。我的意思是,我们当中有谁以前买过汽车保险呢?这可能是我们可以构建一个虚拟人工智能助手来协助的事情。然而,购买汽车保险的过程可能相当复杂,因为它涉及诸如驾驶历史、事故记录、付款历史、之前支付了多少以及使用过哪些汽车保险提供商等因素。
为了实现这一点,我们需要能够从多种不同的数据源中获取信息,以提供个性化的体验,但我们也需要理解细微的语言,因为Pat可能会说“我有兴趣购买汽车保险”。这种措辞至关重要,因为“有兴趣”可能表达不同的含义。Pat只是在研究汽车保险吗?还是Pat已经准备好购买汽车保险了?这最终可能决定了工作流程。
因此,在我们着手提供响应时,我们需要了解如何利用我们拥有的所有数据来提供丰富的体验或个性化的体验?实现这一目标的技术被称为“检索增强生成”。谁听说过RAG?好吧,你们将会有一个惊喜,因为这基本上就是整个演讲的内容 - 讨论RAG。
到目前为止,RAG发生了什么变化?它是如何演变的?好吧,首先让我们来看看RAG中的工作流程,以充分理解正在发生的事情。
假设我们试图构建语义数据,我们可能有一些PDF文档。我们需要将这些PDF文档转换为可用于嵌入模型的大块,因为嵌入模型可能无法读取整个嵌入文档。嵌入模型对其进行处理,将其转换为向量,然后你就可以开始使用某种向量数据库了。
所以这是为你的应用程序添加语义上下文的第一部分 - 这是摄取管道。下一部分,也是客户将看到的部分,是代理工作流程,客户进来并提出问题,“不,我对汽车保险感兴趣。”它在提出问题,做出陈述,你知道,这是一个隐含的问题。它进入生成式人工智能应用程序,然后该应用程序也会将该问题转换为嵌入,在向量数据库中执行相似性搜索,返回答案并允许你完成,增强提示并向用户提供答案。所以这就是代理工作流程,这两个工作流程相互配合,因为你需要保持数据的新鲜和更新,以便能够搜索语义上下文,你也需要能够很好地查询它。这就是最终目标。
那么我们可以使用RAG的方法有哪些呢?首先是朴素的RAG,这有点名不副实,因为与我们将要看到的相比,它的工作流程确实很朴素,但它实际上是基础方法。它有效地是我们刚才看到的工作流程,问题进来,我们对数据库执行查询,我们给出响应。就这样。在很多情况下,这可能都不错,但正如我们刚才看到的Pat的保险示例,我们并没有为该特定应用程序获得最佳响应,这就是高级RAG的用武之地,我们可以使用不同的搜索技术来访问数据并提供更多上下文。例如,也许我们有关于Pat驾驶历史的信息,可以帮助我们缩小实际报价范围。
最后是模块化RAG。好吧,在高级RAG中,你通常会从多个数据源获取信息,并设置了多个知识库,你需要一种方式来选择不同的知识库,以便能够在当时提供最准确的响应。此外,你可能有一个多步骤的工作流程,你需要在给定时间查询多个资源,以便生成响应,进一步自动化这一过程最终可以为你节省大量时间。
那么什么是朴素的RAG呢?我们真的应该称之为基础RAG,这是基本的工作流程。这是你将做出初始设计和技术决策的地方,比如你将如何准备数据,以及不同的检索技术是什么。但真正的重点是技术选择 - 你将使用哪些构建框架?你将使用哪些基础模型和嵌入模型?以及你需要引入哪些数据存储,你将使用哪些数据库,你将添加哪些其他技术到技术栈中。但正如我一再强调的,这是关于奠定基础的,尽管它是一个朴素和简单的工作流程。最终,它是一个迭代的过程,当你添加高级RAG技术时,你就能够引入额外的数据和上下文。
让我们看一个简短的例子,再次强调,我们不会构建一个完整的代码示例,但我们将查看开源框架LangChain,它提供了许多基元,可以实现RAG工作流程。再次强调,这应该看起来就像编程任何其他类型的应用程序一样 - 你只是为生成式人工智能构建这个应用程序。
我想特别强调一下这种情境上下文。如果你注意到,我们在那里有一个LangChain调用,但也有一些看起来像是对于熟悉Postgres的人来说,调用Python Postgres库。这很好 - 我认为这是建立情境上下文的一部分,你可能会从一直在使用的数据源中提取信息,并在这种情况下执行SQL查询以获取情境信息。这就是那个突出显示的地方。
但有一件有趣的事情是要在语义上下文中发挥作用。只要记住,为了让用户可以使用语义上下文,构建语义上下文的一部分就是摄取工作流程,这将是魔力字管道。
现在,当我是一名应用程序开发人员时,我回想起构建我的第一个管道。我有一个电子邮件管理应用程序,作为一个当时很天真的应用程序开发人员,我试图全部以事务方式完成,就像有东西进来,发送电子邮件出去,就完成了。这是网络请求的一部分。但是当我们一次发送100封电子邮件或1000封电子邮件时,这些网络请求就会变得非常缓慢,我就想,“嗯,这没有道理啊。”所以我构建了一个管道 - 基本上当需要发送电子邮件时,我发出一个请求,它将某些内容放入队列,然后异步处理,我觉得这真的很酷。但后来我意识到,“哦,等等,我必须管理这个异步电子邮件管道,必须为此构建所有的监控和其他东西。”这是很久以前的事了 - 现在做这件事要容易得多。但重点是管道管理可能是一个挑战。
因此,让我们看一个例子,我们有一堆文档被上传。那么我们需要做什么呢?我们将文档分成块,转换为向量,然后我们必须存储它们。我们需要将它们存储在这种情况下的OpenSearch数据库中,最终我们就能够对其执行相似性搜索。但前两个步骤可能是异步发生的,所以我需要确保将代码放在一个可以持续管理的地方。
这就是亚马逊Bedrock知识库的用武之地。这个Knowledge Basis自动化了这一部分,基本上为您处理了管道摄取。因此,您不必编写代码来管理自己的管道,而是可以使用Bedrock知识库,并说“好吧,我在亚马逊S3存储桶中有这些文档。有时会添加,有时会删除,但Knowledge Basis会检测到这一点,并自动更新您的向量数据库,以便添加或删除行或保持所有数据的新鲜度。”实际上您所要做的就是替换用于管理的库,代码实际上会变得更加简洁,因为您不必编写所有管道管理代码,而是有效地拥有管理控制台,可以说“这是我的块大小,这是我的数据目的地,这是存储在此数据库中的数据源。我不想担心这些,我只想专注于相似性搜索方面。”
因此,在建立数据基础时需要考虑的一件事是,您可以在哪里自动化诸如管道管理之类的事情?您的管道并不是您的差异化因素,您的应用程序才是您的差异化因素,因此能够专注于准备好数据源并将其拉入应用程序将有助于节省整体管理时间。
那么,naive RAG的权衡是什么呢?因为即使我一直说它是基础RAG,我也一直在使用这个术语“naive”。它非常简单,简单就是好的 - 简单有助于您入门,并且可能适用于您的许多不同工作流程。但它可能无法捕捉您的语义数据的细微差别。因此,再次回到汽车保险的例子,如果我说“嘿,你的汽车保险可能在20美元到5000美元之间”,这并不是一个很好的回应。此外,您可能无法完全获得所需的防护措施。我知道,我们稍后将探讨这一点,但重点是,如果我们想获得更个性化的响应,我们可能需要结合多种搜索方法,这就是高级RAG的用武之地。
所以让我们回到这个例子 - 您可能还记得我说Pat有三辆车。事实证明,其中一辆车发生了事故,但Pat当时并不拥有那辆车。但是,如果我们只使用这种naive RAG技术,我们可能无法理解这一点,因为代理人看到它,它会说“哦,你的第二辆车出了事故。很抱歉,我无法给你超级优惠的折扣率。”Pat可能会回来说“等等,你在说什么?我几年前就卖掉那辆车了。”但代理人可能没有足够的信息来满足这一要求,因为我们只使用了基本的相似性搜索。
因此,我们需要能够引入更多信息来提供量身定制的响应,因为此时Pat对代理人感到沮丧。就像“你知道吗,我不会从你这里买汽车保险。你不了解我的驾驶记录。”
让我们看看高级RAG中的一些技术,这些技术将帮助我们引入更多上下文。首先,要理解高级RAG的工作流程,您有预检索任务。因此,当问题进来时,您可以做一些额外的工作来量身定制问题。例如,您可以添加防护措施,比如“嘿,不要在代理工作流程中完成交易,您必须重定向到其他地方或由人工代理接手。”但也有其他技术可以预处理数据,您将探索这些技术。
然后是上下文检索,我们将看到多种技术来执行更高级的搜索。最后,还有后检索任务,您可能需要一些额外的防护措施来过滤数据,或者您可能需要重新排序或总结数据,我们将在接下来的几张幻灯片中看到这一点。
因此,第一种技术是混合搜索。混合搜索是一种根据问题的上下文解锁更多语义含义的方式。我之前谈到的例子是单词“interested”。“interested”是什么意思?它是说“我只是在探索是否想买汽车保险”,还是说“不,我准备好买了,让我们开始吧”?我们能够使用混合搜索来更好地理解全文搜索技术、向量搜索的组合以及最终的重新排序。这就是我们能够结合我们建立的语义关系的含义、嵌入模型和我们建立的一般文本语料库的地方。
我们看到混合搜索在各种不同的方面都有应用,可能是围绕内容生成、总结、情感分析,但从某种程度上讲,它为您的数据提供了另一个检查,以确保您真正获得了最佳质量。
因此,让我们看这个例子:“我有兴趣购买汽车保险。”这是我们可以添加防护措施的一个地方,即确保“嘿,我要确保Pat建议的内容不是非法的、令人反感的等等。”但我们也可以提出额外的要求,可能是“嘿,你能查看一下这个上下文中’interested’一词的含义吗?它是否有这种’我打算购买’的语义?”
因此,由于这一点,如果我们重写并说“purchase”,现在让我们做一个不同的搜索。
"让我们对所有我们拥有的文档进行这种向量搜索,看看这个词的真正含义,让我们进行一次基于文本的搜索,我们已经这样做了很长时间,我们将看到所有文档及其含义。将它们全部放在一起并获得结果,目的是提高结果的相关性。
如果您将向量搜索视为召回率的度量,即返回预期结果的度量,这是一种可以提高召回率的技术。现在,就像所有好东西一样,也存在权衡。权衡是您的搜索速度可能会稍微慢一些,因为您现在正在执行两次搜索,每次搜索的延迟时间不同,最终您必须重新排序,而重新排序通常是很快的。
权衡是,如果您获得了更好的结果质量,就可以为购买汽车保险的Pat提供更个性化的体验。这将是我们在考虑这些技术时面临的很大张力,您将不得不在某个地方付出代价,但理想情况下,您希望能够支付足够的成本,使用户体验或用户的最终目标超过可能略慢的数据库响应时间的成本。
接下来是GraphRAG。GraphRAG是另一种能够增强RAG工作流程中信息的RAG技术,因为您能够找到数据之间的更多关系。
因此,让我们看这个“我有兴趣购买汽车保险”的例子。在这种情况下,我们不太关心单词的含义,在GraphRAG中。我们试图理解Pat的车辆所有权历史,因为请记住,如果您曾在一辆车中发生过事故,您的汽车保险费率就会上升,我们知道Pat的第二辆车发生过车祸,但Pat当时并不拥有那辆车,如果我们能够拥有数据的图形或数据的映射,我们就可以看到系谱,并说“哦,Pat拥有这辆车。另一个人拥有这辆车。他们在那个时候撞了车”,这很好,因为我们可以说“哦,Pat是我们可以依赖的低风险驾驶员,我们可以为Pat报价最超值的费率。”
因此,GraphRAG的权衡是,您能够获得数据背后更多的含义,特别是如果您创建了系谱。这将带来成本,可能需要更多时间来生成查询。您可以使用诸如Amazon Neptune Analytics或Amazon Neptune之类的工具,它是专门为图形搜索而构建的,并能够在那里执行搜索,从而增强响应。但最终,您希望使用最适合搜索该类型数据的技术。
我们还可以将其他内容引入高级RAG,包括上下文总结。naive RAG的一个挑战是,或者说RAG总体上的一个挑战是,输入令牌是有成本的。如果您有大量输入令牌,您实际上是按令牌付费的,并且并非所有这些令牌都可能有意义。例如,如果您正在查看内华达州汽车保险法规,我个人没有阅读过,但我相信它们非常详细,其中包含大量信息,而基础模型存在一个称为“中间丢失问题”的挑战,当有太多信息时,它可能无法有效地将其总结为适当的响应。
但是,有一种解决这个问题的技术,叫做总结,您可以将保险法规等内容交给一个较小的大型语言模型,较小的大型语言模型可能会快速返回响应,但
然而,有一种技术可以解决这个问题,那就是总结技术。在将大型基础模型应用于保险条例之前,你可以先使用一个较小的大型语言模型,这个较小的大型语言模型可能会返回一个快速响应,但它可以将保险条例总结为关键要点。你将这些关键要点输入到大型基础模型中,然后将总结的响应作为提示输入到大型基础模型中,这是一种有效的技术,可以节省成本,并提供更好的响应,特别是当源信息过多时,无法获得有意义的最终响应来提供给客户。
还有一些其他高级RAG技术吗?我最喜欢的自然语言查询技术。我之所以这么说,是因为我非常喜欢编写SQL。这可能让我有点难过,因为自然语言查询变得如此强大,但至少我知道SQL不会消失。但重点是,并非所有通过生成式AI应用程序提出的问题都需要转换为向量。例如,如果Pat想了解去年的汽车保险情况,那听起来就像是’SELECT * FROM payment_history WHERE user = Pat’这样的SQL查询。在这种情况下,当问题出现时,如果你在Amazon Redshift集群中有所有这些信息,你可以获取该模式,将该模式输入到增强的提示中,以了解数据之间的所有关系,最终输出一个SQL查询,而SQL查询就是你的自然语言查询,然后你可以选择对数据库执行该查询并返回响应。这非常强大,因为如果你不必转换数据,那就太好了。如果你只需要将问题转换为查询,然后对现有数据执行查询并获得答案,那就非常有效。因为假设你在数据仓库中有所有这些数据,你最终可以将其转换为向量。可能会发生两件事情之一:一是你可能会使数据膨胀,因为向量表示可能比源数据大;另一个是你不得不管理另一个管道,还记得在演示文稿的早些部分吗?每次我们不得不管理管道时,这就意味着更多工作,这可能最终会使你正在构建的应用程序无法区分。因此,如果你可以直接查询数据,那就一定要这样做,你甚至可以以生成式AI的方式来做这件事。
好了,我们已经讨论了很多关于朴素RAG和高级RAG的内容,那么什么时候使用每一种呢?嗯,你猜对了,你总是在使用朴素RAG,因为那是基础RAG,这是一个陷阱问题。但是什么时候继续使用朴素RAG呢?基本上,如果不涉及任何逻辑,等等,我们在处理计算机,你什么意思?如果你有一个非常简单的问答,比如“天空是什么颜色的?”我应该准备一个更好的例子。但基本上,如果你不需要思考问题,它只是数据库中的一个事实,带有语义信息,你可以返回这个事实。但一旦你开始想要更多个性化,特别是围绕着我想为Pat提供的有关汽车保险费率的所有语义含义,你可能需要高级RAG。同样,这是好事。在这些情况下,个性化是好事,但要理解成本和成本权衡。你想在数据库查询部分支付更多费用,还是想在基础模型上支付更多费用?最终,随着你的应用程序不断成熟,你可能会偏向于高级RAG,或者说不是偏向,而是迭代向高级RAG发展,这将有助于提供更好的响应。
现在是有趣的部分。你已经建立了所有这些知识库,其中包含了各种不同的信息。你如何知道何时使用特定的知识库呢?你可以将其编码到应用程序中,但这将是困难的,因为突然间你就像需要一个代理来管理你的代理一样,因为你有这些不同的分散数据源,你不知道何时使用它们。这有点像你现在在思考时一样,比如我在思考一个例子,好吧,我选择哪个例子?这个概念有点类似。这就是模块化RAG的用武之地,因为我们希望确保在正确的时间选择正确的数据源。
因此,这种技术是一种不断发展的技术,但它正迅速变得非常流行,那就是预检索查询路由。它可以帮助你根据输入的问题在不同的知识库和不同的搜索技术之间进行选择。这里有一个使用LlamaIndex代码查询多个存储系统的示例,你可以看到这变得非常复杂。再次,这几乎感觉就像你正在构建一个AI模型来决定该做什么,这就是Amazon Bedrock Agents这样的功能发挥作用的地方,因为Bedrock Agents将有助于协调这些多步骤工作流,在这些工作流中,你可能需要访问多个来源来整理答案,或者你可能需要调用多个不同的服务来获取信息并添加到答案中。同样,只要我们可以自动化协调,就可以消除无差别的繁重工作。这已经成为我在整个演示过程中最喜欢的术语,因为我们可以自动化的越多,就越容易添加你需要的特定于应用程序的逻辑。
这里有一个关于Pat的汽车保险困境的示例,问题来了,“我对汽车保险感兴趣。”工作流程的第一部分可能是提取不同的上下文,假设大部分上下文都在数据库中,但也许我们需要直接查询DMV记录,因为我们还没有更新它们。或者我们需要获取Pat的理赔历史或信用报告,以便我们可以使用代理,代理将知道根据你提供的上下文自动创建该数据。然后,一旦我们理解了上下文,我们可能需要采取一些额外的步骤。比如说,Pat将被预先批准购买汽车保险,我们可以通过执行各种任务,如获取保险报价、更新数据库以说明我们在某个日期为Pat提供了保险报价等等。这非常酷,因为最终通过在你这边执行这个多步骤的代理工作流,在你设置好代理工作流后,这只是一个API调用。你发出一个API调用来启动这个工作流,代理会完成所有这些不同步骤的艰苦工作,最终为Pat提供汽车保险理赔的答复。
最后,如果不提及语义缓存,我就有疏忽了,因为我一直在提及你可能希望或不希望调用基础模型的程度。语义缓存是一种技术,如果你向基础模型发送类似的问题或提示,你就可以绕过而不调用基础模型。缓存可以在多个层面上发生,可以是问题本身,也可以是问题和增强的上下文,或者是问题、上下文和答案的全部内容。
现在,语义缓存的挑战就像缓存的一切一样,那就是范围。如果你有一个简单的公共问答聊天机器人,你可能可以缓存一切,但如果是面向租户或用户的,语义缓存可能就没有意义了,这取决于特定模型的使用程度。因此,对于像汽车保险这样的东西,它可能是高度面向用户的,可能是一种个人互动,在这种情况下使用缓存技术可能没有太大意义。但如果你有一个通用的聊天机器人,只是讨论美国各地的汽车保险规则,那可能就是你可以利用语义缓存的情况。
那它是如何工作的呢?这是我们看到的典型代理工作流程,但当问题出现时,或者是问题、答案和上下文(无论你选择哪种方法),你首先要检查它是否存在于Amazon MemoryDB之类的地方,在那里你可以对其执行向量搜索。如果不存在,你就去基础模型获取答案,然后将其带回来并存储在Amazon MemoryDB实例中。但如果语义缓存命中,你就可以绕过整个下半部分工作流程,这样一来,你不仅可以更快地获得答案,这很棒,因为谁不喜欢速度呢?而且你也不必调用基础模型,因此可以节省成本。
那么到目前为止我们做了什么?我们研究了如何准备我们的数据,如何…抱歉,我们还没有研究如何准备我们的数据。我们研究了不同的RAG工作流程,以及如何开始将我们的数据引入其中,但准备我们的数据可能是一个重要的步骤,特别是对于这一步骤。嗯,不是这一步骤。我们可能需要为结构化数据准备这一步骤。
结构化数据有明确的模式,有其含义和模式,根据你所做的事情,你可能不需要准备它,因为你可以对其进行自然语言查询,但我们知道它的结构。这可能是情境上下文所在的地方。
然后是半结构化数据,在我看来这仍然是一种结构化数据,但结构定义较少。例如JSON,JSON确实有结构,但可能会随时间而演变,或者存在于数据湖中的数据,其模式会随时间而演变。这些数据可能最终成为你的情境上下文。它可能最终成为语义上下文,因此你可能需要做一些准备工作。
然后是非结构化数据,我们不知道其含义,这就是嵌入模型发挥作用的地方,因为这些嵌入模型将有助于赋予数据意义。在这种情况下,我们肯定需要对其进行某种转换。
因此,让我们从非结构化数据开始。我们如何为RAG应用程序准备它?好吧,我们之前简单讨论过,即我们有源信息,在这种情况下是一个文档,我们需要首先将其分块。分块是将文档分成适合放入嵌入模型的小块的一种方式,在嵌入模型中,这些小块将转换为向量。我们必须将其分块的原因是,在某种程度上,嵌入模型可能无法处理完整文档,但即使上下文窗口足够大,这也可能是一种成本。这样做可能没有必要,而且你可能无法捕获其适当的含义。
因此,我们需要了解不同的分块策略是什么,以及哪种策略最合理。那么你如何选择一种呢?快速入门是所谓的固定分块,你可以说嘿,一次只分块多少个标记,比如分块256个标记,因为256是个很酷的数字。这种方式很容易构建,但可能无法完全捕获你试图解决的特定问题所需的所有上下文。
例如,注意到了吗?我试图为所有这些内容着色编码。希望颜色编码有意义,但假设我们正在查看内华达州保险法规文件。如果我们只是按块查看,我们可能会错过特定法规的含义,尤其是法规意味着法律,如果我们错过了这种上下文就可能很糟糕。
因此,如果有定义的模式,我们可以使用结构化分块或模式分块。再次,这很好,因为它有点像一个伪结构化文档或半结构化文档,特别是如果我们正在解析诸如HTML之类的内容。而且,如果你有一个定义的模式,这很棒,但如果没有,你仍在做一些猜测,而且再次,假设我们按段落分块,可能会丢失含义。如果你像我一样写作,我会努力确保每个段落都是一个自包含的意义,但这并不总是可能的。
因此,如果你想要一种相对平衡的方法,就有层次分块,通过层次分块,你可以说你基本上可以定义组或层次结构,在此基础上你可以对所有内容进行分块。现在,它有点类似于结构化分块,但你不一定知道结构,所以你必须为它设置规则。很好的是,如果你能够定义这些规则,你将获得具有很多意义的块,因为你基本上定义了围绕特定点的所有上下文,比如说,内华达州保险法规中的每个法规部分,但它也要求你对领域有深入了解,如果大量文档来自各个领域,那么这种分块策略可能行不通。
因此,最后是语义分块,这将是最强大的策略,因为它实际上就像使用嵌入模型一样,你能够找到所有不同块之间的意义,分析整个文档,然后确定,好吧,将其分解为这些块。这将为你最终执行语义搜索提供最佳相关性,但需要更多时间和资源,随着方法的发展,它可能会产生额外的成本。对于成熟的应用程序,你最终将使用层次分块或语义分块,但所有这些分块方法都有其权衡。你想快速构建一个概念验证,只是为了展示某些东西正在运行?固定分块就是这样,但你最终将不得不选择一种能够为你提供更多意义的方法。
那么结构化和半结构化数据呢?好吧,我们已经介绍了可以使用自然语言查询来查询数据的事实,但也许你需要通过转换来解锁语义含义。这很好。实际上,我看到我们的客户在生产环境中这样做,他们从关系数据库或数据仓库中获取数据块,放入某种文档中。它可能只是像我看到的那样,就是文本数据库中的文本块,但你也可以使用JSON文档或其他内容,并将其转换为向量,然后最终你可以将其用作语义搜索的一部分。再次,如果这对于你的应用程序有意义,你需要一种不同的方式来解锁语义含义,那么这种方法就可以,但请记住这是一个管道管理问题,因此这将是你必须持续管理以保持最新的问题。
那么,除了使用语义分块(希望已经为你解决了这个问题),你如何确定使用什么大小的块呢?通常会有一个平衡,较小的块适用于意义不太重要的应用程序,比如简单的问答,而如果你需要获得非常具体的内容,或者有大量代码、文本或内华达州的保险法规,你可能需要更大的块来捕获这些内容。部分原因是你将不得不尝试什么对你的应用程序最有意义,但关键是你现在有一些技术和策略可以查看,而且,如果你最终使用了一些层次分块,其中一些问题将会为你解决,你可能最终需要根据嵌入模型或你希望在数据库中存储的成本来设置块大小上限。
现在让我们讨论向量搜索,向量搜索是我最喜欢的话题之一。今天早些时候我在423分会场做了深入探讨,我们深入探讨了Postgres方面的内容,但在本讲座进行了三分之二的时间,这是我第一次谈到选择向量搜索,这就是重点,因为在TRIVA增强生成中,向量只是一个组成部分,但大量意义来自于你的应用程序,来自于你的传统企业交易、运营、分析存储,以及你现在已经转换为向量的非结构化数据。
那么,你如何选择这些向量搜索解决方案之一呢?首先从熟悉程度入手。你会发现,归根结底,根据你在做什么,很多性能特征将非常相似,因此选择你最熟悉的解决方案,因为这将有助于实施。我们回顾一下,在交付个性化方面,将取决于你选择的RAG技术。你将从朴素RAG开始,但最终将演变为高级RAG,你要确保能够选择一种你觉得可以在整个堆栈中集成的向量搜索解决方案。
构建性能可能很重要,但这取决于你的数据集的大小,这很有趣。每个人对你正在处理的向量数量的定义都不同。对我来说,我觉得现在是数十亿的范围,但再次,我已经盯着这些问题看了太久,有两年了,但我会听到有人说,哦,我有很多向量。大约有几十万个,但所有这些解决方案都可以快速处理这些向量,所以这就是熟悉度和实施的回归,因为实际上,你可能正在迭代交付个性化响应给你的生成式AI应用程序。
但我们确实提供了许多集成了向量搜索的不同数据库,你可以看到,总的来说,它们提供了许多非常相似的功能,包括性能、速度、规模和不同的查询技术,如果你需要特别选择一种,除了熟悉度之外,可能是解决特定领域问题的解决方案。例如,让我们看看图RAG,如果你需要利用图RAG并在图上搜索,那么你可能需要选择一个支持图搜索的解决方案。
这里是续篇:
但是我们确实提供了一系列不同的数据库,这些数据库包含了向量搜索功能,总体来说它们提供了许多非常相似的特性,如性能、速度、规模和不同的查询技术等。如果您需要选择一个特定的数据库,除了熟悉度之外,可能会选择一个能解决特定领域问题的数据库。例如,让我们以图RAG为例。如果您需要利用图RAG并在信息图上进行搜索,您很可能会使用Amazon Neptune Analytics,因为它就是为这种确切用例而构建的。如果您要做涉及全文搜索的事情,那么您将使用Amazon OpenSearch Service,因为它是为这种用例而构建的。因此,最终您要选择一个您最熟悉的解决方案来开始,随着您探索和架构更深入的用例,您将能够为自己找到合适的解决方案。
最后是索引选择,我可能会花上1到2个小时来讨论这个主题,所以我会尽量将其浓缩到一张幻灯片中。在索引向量时需要记住的一点是,您正在进行近似最近邻搜索,近似最近邻意味着您可能无法返回所有最佳结果,因此您需要通过召回率来衡量搜索相关性。如果您需要100%的召回率,基本上您需要确保始终能看到您搜索的最佳候选结果。在这种情况下,您不会使用索引或向量索引。我应该说,您可能会使用不同的索引。如果您知道具有高选择性,您可以在关系数据库中使用B树,这将为您提供非常快速的搜索,但如果您想保证始终获得最佳质量结果,您就不会使用近似最近邻技术。
现在有各种不同的向量搜索,抱歉,向量索引可用,但受欢迎的是HNSW。它代表Hierarchical Navigable Small Worlds,简而言之,HNSW适用于许多用例。首先,它对开发人员来说非常容易使用,因为它的行为很像其他传统索引,您可以从中添加和删除数据,只要索引允许自动更新和删除,它就会自动更新。实际上,在HNSW中做到这一点有点困难,但是可能,但一般来说,从您的角度来看,您不需要关心我刚才提到的这个注解,因为它很容易使用,而且效果不错。它提供了高质量的结果和相当不错的性能。
现在您可能会发现您的HNSW索引变得非常庞大,它确实是一种笨重的索引,量化是一种最终通过缩小向量大小来减少存储的技术,但它确实会影响您的召回率。因此,接下来就是权衡利弊,我可以减少数据库的存储空间,也许可以获得更快的数据库响应,但也许我无法获得所需的相关性,最终我需要为基础模型付费,因为那是我花费最多成本的地方。因此,量化对于某些应用程序可能没有意义。
您必须与数据科学团队合作,看看他们最终希望在哪里花费时间。最后,如果具有高选择性,其他索引类型可能会更好。高选择性是一种相反的属性。如果您说某物具有高度选择性,意味着返回的结果很少,如果您返回的结果很少,您可能不想使用向量索引来搜索它。有许多其他索引方法可以帮助您。
现在我们已经讨论了所有这些不同的RAG技术来个性化数据。我们已经讨论了如何准备数据,那么我们如何最终让这些数据流动起来呢?我很高兴将话题转交给Siva。
谢谢,谢谢Jonathan。我还在这里,所以我们进入最后阶段。那么上下文从哪里来呢?在RAG应用程序中,正如您可能已经看到的,在我看来,一切都围绕着上下文展开,所以您要做的是接收上下文并将其提供给您的应用程序。
那么让我们回到这个上下文从何而来的问题。它实际上来自您的所有运营数据库、数据仓库、数据湖,甚至流数据存储。让我们以保险示例为例。在这种情况下,我们一直在讨论的Raisin God示例。可能有大量关于客户的信息。客户资料可能保存在关系数据库中。您的所有历史记录,无论是代码历史、保单历史还是理赔历史,可能都保存在数据仓库或数据湖中。
此外,Jonathan提到的规则,如果您在内华达州,有一些规则。它们可能是PDF文档,存储在您的文件存储或数据湖中,例如S3,或者在某些情况下,一些公司提供基于使用的保险。换句话说,他们在您的汽车上安装了一个设备或在您的应用程序中安装了一个应用程序,因此它会传输您驾驶汽车时的所有数据,基于您的驾驶特征,他们可能会给您很大的折扣。所以这就是流入的流数据。
所有这些数据实际上都流入了您的数据系统,如果您愿意的话。您的机动车辆管理部门拥有您的驾驶执照信息以及您的车辆记录。例如,我们讨论了一种情况,第二辆车可能发生了事故。这是因为实际上汽车销售的数据并没有显示在系统中。出现了问题。
所以所有这些基本上都进入了公司的数据系统。这带来了许多挑战。这些数据存在于各种数据孤岛中,您需要能够跟踪数据线索,换句话说,这些数据来自何处,以及数据质量问题。例如,如果您从两个来源获取数据,您需要能够实际更新并保持同步。我们需要了解和评估流入的数据质量。
此外,还有PII数据。例如,您可能会获取客户的信用记录。与之相关的是社会安全号码。如果您从驾驶部门获取驾驶信息,那里也有驾驶执照ID,通常是保密的,包括您的姓名和地址详细信息,所以您的管道都需要能够处理这些,在某些情况下对其进行标记化等。对吗?
此外,还有身份解析。例如,机动车辆管理部门通过驾驶执照ID来识别您。例如,信用局可能通过您的社会安全号码来识别您,而您在组织中有一个您分配给客户的客户ID。这三个都是同一个人,因此您需要能够将这些匹配在一起,然后返回并说这些都与同一客户有关。
访问控制显然很重要,如果您正在编写一个聊天机器人应用程序,它需要以相关权限访问相关数据。因此,您需要一种解决所有这些问题的架构。
在亚马逊云科技,我为客户构建了许多大数据管道。我总结了5条规则,这些规则在我看来经受住了时间的考验。我将与您分享这些规则,尽管亚马逊云科技推出了新的产品和其他变化。
因此,首先是,每当我构建大数据应用程序和架构时,它都感觉像是一个管道。数据从一端进入,答案从另一端出来,中间是您要处理的数据。通常,当您想要构建一个解耦系统时,您会以这种方式构建它:有一个处理阶段,然后在两端都有处理系统。您使用存储子系统将它们解耦。
例如,如果您正在进行流处理,您可能会将数据流(当您将此设备放入汽车时,所有进入的信息)放入Kinesis或Kafka中,然后您可能会使用Spark Streaming或Flink来处理它。这就是处理阶段。然后,如果您想在此基础上进行图RAG,您就需要将该数据存储在图数据库中。
因此,您将数据存储在何处实际上取决于第二点,在管道的每个阶段,您使用的技术或工具取决于您要处理的数据结构、您要加载数据的位置以及您的延迟要求。换句话说,您需要了解访问模式,以便将数据存储在正确的位置。
第三点同样重要,当您构建整个应用程序时,最佳实践是如果有一种托管服务可以处理整个集群管理问题,您可能应该使用托管服务或者甚至无服务器服务,这样您就不必花时间管理集群,而是专注于实际增强您的应用程序。
即使对于流式数据,最佳实践也是将数据副本存储在S3中。我称之为日志中心设计模式,即使我从事数据业务已有很长时间。实际上,数据库也首先写入事务日志,然后在各种系统中实体化数据,对吗?无论是支持行的页面等。因此,真正采用类似的范例,在S3中保留数据副本,有时应用程序出现错误。回到原始数据并重新处理是个好主意。
创建视图和物化视图将非常重要。最后但并非最不重要的是,大数据不应等同于高成本。每次为客户进行设计评审后20或30分钟,我都会暂停设计评审,说让我们找出端到端解决方案的成本。通常有点失衡。可能我使用了错误的工具,或者我必须更改设计以满足客户需求。因此,当我们在亚马逊云科技构建数据服务时,我们以低成本构建它们来执行其功能。通常,当您使用高成本服务时,您会发现可能没有使用正确的服务。
有了这些,RAG管道如何相关?为RAG选择正确的数据架构总是需要创建服务层。对我来说,这感觉像是反向ETL。您构建一个服务层。例如,如果要在图形数据库中实体化数据,本质上您必须将其存储在图形数据库中。
因此,在某些RAG系统中,您可能需要执行数十或数百次请求来实体化您要查找的语义含义,如果是这种情况,您可能需要毫秒级响应速率。对吗?比如,如果调用100次,100毫秒可能客户可以等待,但如果您调用的系统需要几秒钟才能回答该问题,您就根本没有时间回答。您的管道的延迟要求决定了您存储数据的位置。
例如,通常数据库、运营数据库需要毫秒级响应,如果您正在寻求数据湖架构,可能将其存储在数据湖中会需要一秒或更长的响应时间。对吧?这是一个决定。
第二个决定是后端管道,我称之为数据新鲜度。如果您构建后端管道,希望数据在几毫秒内显示,可能需要直接将数据流式传输到数据库。
第二种选择是,如果您希望在一秒内完成,实际上是将数据流式传输到Redshift等数据仓库。我们有连接器可以将Kinesis或Kafka中的流式数据实体化到Redshift中。我会为此使用该模式。
开放表格式越来越流行,如果您考虑将此数据存储为表格数据访问,请将其存储在Iceberg等开放表格式中。如果您希望在一分钟左右访问,将流式数据存储到开放表格式并访问它是正确的模式。
或者,对客户非常有效的是,如果您有5分钟或更长时间,可能运行批处理作业将数据实体化到开放表格式中。
现在使用这些东西,我认为Chenata谈了很多关于前端模式。
我想总结一下,就应用程序而言,它将保留对话历史记录。许多客户使用DynamoDB存储对话历史记录,如果您知道DynamoDB的细节,它有哈希键或分区键或范围键来建立父子关系,您可以将客户ID放在哈希键中,将时间戳放在范围键中。它可以为您保留所有对话,然后将有效载荷作为指向对象的指针存储在S3中,或者直接存储在那里并进行压缩。
同样,您的情境上下文可以来自运营数据库。您知道SQL、NoSQL、图形,任何适合您使用模式的数据库,然后您的分析也可以来自分析系统。通常需要一秒左右才能获取,因此可以通过Athena或Redshift等访问开放表格式中的数据,您的语义上下文是Jonathan介绍的新向量数据存储。
那么这真正来自哪里?更新上下文的后端架构是什么呢?您知道,这是中间的服务层,对吗?然后在中间是情境上下文。如果您通过分析数据存储派生,真正将数据保存在S3中,我将其视为3层。底层是S3,您在其中保存可能为Parquet文件格式的文件,并以开放表格式存储数据,然后在其上是数据目录,Athena可以非常好地检索这些数据集。它还允许您保留所有metadata,您知道目录中的metadata,Glue数据目录保留了所有适用的metadata。在某些情况下,就像Jonathan指出的文本到SQL场景,您正在聚合所有数据。您首先推导出模式,然后实体化SQL查询。如果将其放入技术数据目录中,就可以实现这一点。同样,如果您有流式数据源,您可以执行标准流处理,将数据存储在Kinesis、Kafka中,并运行Spark Streaming或Glue Streaming或Flink来管理数据并将其放入开放表格式。或者这也是Jonathan谈到的分块部分。对吧?您知道,这个反向ETL从您的数据湖中获取所有数据,可能还有Kinesis或Kafka,并将其存储在前端服务层中,所有这些对您来说应该很熟悉。与我们迄今为止在流处理或批处理中所做的没有什么不同。唯一的区别是,我们真正将这种上下文表面化为RAG应用程序的服务层。
我想谈谈数据治理。您知道数据共享的概念。有些人称之为各种类型的架构。例如,可以称为数据共享架构、数据市场等。例如,如果您考虑我们在保险公司案例中讨论的示例,可能销售部门有自己的数据湖。一种方法是,聊天机器人构建器可以构建整个数据湖并获取所有数据。更好的模式是,如果销售部门有自己的数据湖,理赔部门也有自己的数据湖,您可以创建数据产品,数据产品通常包括多个构件。构件可以是S3文件或各种表。然后,如果您可以将其注册到数据区域,实际上有一个订阅数据流,聊天机器人构建团队可以订阅各团队构建的各种数据产品。发生的情况是,当您作为聊天机器人团队请求共享特定数据产品的权限时,产品创建者批准时会带来所有所需权限等。这是最佳实践。将其视为构建数据共享架构,您可以将整个内容视为数据产品。与相关团队共享数据产品是最佳实践。
就像我们讨论的数据质量和血统一样。例如,确保数据质量的一项业务规则可能是,理赔日期应在保单开始日期和结束日期之间。如果您在内华达州签发保单,可能需要最低责任保险。所有这些都是业务规则。您的管道应该能够满足这些要求,还可能有格式要求,如电话号码格式或保单ID应该是唯一的。您需要一个系统来跟踪数据质量。例如,如果您使用Amazon Glue并运行Amazon Glue管道,我们发明了一种称为数据质量定义语言的语言。它包含各种规则,您可以声明性地指定这些规则,然后当您运行作业时,它实际上会验证这些规则是否满足,您还可以得出数据质量分数。因此,我们在这里有10
就像我们讨论过的数据质量和数据血缘。例如,确保数据质量的一个业务规则可能是,理赔日期应该在保单生效日期和终止日期之间。如果你在内华达州签发保单,那里可能需要最低责任保险。所有这些都是业务规则。你的数据管道应该能够满足这些要求,还可能有格式要求,比如电话号码格式或保单ID应该是唯一的。你需要一个系统来跟踪数据质量。例如,如果你使用Amazon Glue,并且你正在进行Amazon Glue管道,你实际上可以使用一种叫做数据质量定义语言的语言,这是我们发明的一种语言。它包含了各种规则,你可以声明性地指定这些规则,然后当你运行作业时,它会验证这些规则是否满足,你也可以得到一个数据质量分数。比如我们有10条规则,当你运行这个作业时,只有9条规则被满足,那么你就有9/10,也就是90%的数据质量。构建这个数据产品的团队可以确保他们公开的特定工件满足特定的数据质量。了解数据质量并制定相应的措施非常重要,数据血缘也很重要。比如在这个保险设置中,有一个承保团队作为数据生产者。当销售部门给出一个代码时,它会说这是客户的代码ID,这是保费金额,然后承保团队会根据这个代码为客户签发不同的保单,每个保单都有一个保单ID,通常他们会将保费金额存储在那个表中。当你在应用场景中创建一个嵌入时,比如你从承保部门获取一个PDF保单文档,将其分块存储在向量存储中,你可能会有一个包含向量嵌入和保费金额的表。如果发现保费金额有误,你需要能够追溯这个血缘。如果你使用数据区来存储所有这些资产,开放血缘是一个开放标准,用于保存血缘,任何开放血缘兼容的技术,如Spark或dbt,都可以保存这个血缘,对于构建聊天机器人的团队来说,了解数据血缘非常重要。
例如,我想将这一切整合到RAG的架构中。前端是关键,需要构建一个服务层,能够将数据以可被生成式应用程序服务的形式实现。我将把话题转交给Jonathan来总结这次讨论。我知道我们进行得很快,但我试图在这个时间窗口内完成,这样你们就可以按时离开了。所以我是这里的总结模型。
Jonathan提供了以下总结:
今天我们学到了很多东西,对吗?正如我们所说,这是一个L300级别的讨论,我们必须深入技术细节,涵盖许多不同的概念,那么有什么收获呢?我总是喜欢从数据出发,但在这种情况下,你需要从工作流程出发。你如何引入数据?你使用什么RAG技术来支持生成式AI应用程序?这些就是数据源,它们将最终支持生成式AI应用程序,所以数据源的选择实际上就是数据目标的选择,你可以朝着这个方向迭代,并尽可能利用自动化。你也可以使用现有数据。这可能是你听到的一个收获,就是“哦,我必须把所有东西都转换成向量”。事实上,我们今天讨论的大部分内容都不是向量,而是你原有的源数据,你可以将其带入你的生成式AI应用程序中。最后是自动化,请尽可能自动化。这可能是我作为应用程序开发人员犯的最大错误,就是没有足够的自动化,这本可以为我节省大量的操作任务时间。所以,非常感谢大家。请对这次讨论提供反馈,感谢您的加入。
我们正处在 Agentic AI 爆发前夜。 2025 亚马逊云科技中国峰会提出,企业要从 " 成本优化 " 转向 " 创新驱动 " ,通过完善的数据战略和 AI 云服务,把握全球化机遇。亚马逊将投入 1000 亿美元在 AI 算力、云基础设施等领域,通过领先的技术实力和帮助“中国企业出海“和”服务中国客户创新“的丰富经验,助力企业在 AI 时代突破。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70038688/viewspace-3089975/ ,如需转载,请注明出处,否则将追究法律责任。