使用 Amazon Bedrock 知识库对表格数据进行元数据筛选 机器学习博客

使用 Amazon Bedrock 知识库对表格数据进行元数据过滤

重点摘要

在本篇文章中,我们介绍了如何使用 Amazon Bedrock 的新功能元数据过滤,来提高从知识库检索表格数据的准确性。通过配置元数据字段,组织使得检索过程更加精准,从而优化信息获取和召回效果,降低无关结果带来的成本。

Amazon Bedrock 是一项完全托管的服务,提供了来自领先人工智能公司的高性能基础模型FMs,包括 AI21 Labs、Anthropic、Cohere、Meta、Mistral AI、Stability AI 以及 Amazon。为了为 FMs 提供最新的专有信息,组织使用增强生成RAG技术,通过从公司数据来源获取数据来丰富提示,从而提供更相关和准确的响应。Amazon Bedrock 知识库是一个全面的能力,帮助用户实现从数据摄取到检索和提示增强的完整 RAG 工作流。然而,一个数据集的信息可能包含在另一个数据集中,这称为元数据。如果不使用元数据,检索过程可能导致无关结果的出现,从而降低 FMs 的准确性并增加成本。

在 2024 年 3 月 27 日,Amazon Bedrock 宣布了一项重要的新功能元数据过滤,并改变了默认引擎。这项更改使您能够在检索过程中使用元数据字段,但需要在知识库数据摄取过程中配置这些字段。您可能会有一些表格数据,其中一个字段的详细信息可以在另一个字段中找到。此外,您可能需要引用确切的文本文档或文本字段以防止虚构现象。本文将展示如何在 Amazon Bedrock 知识库中使用新的元数据过滤功能来处理这类表格数据。

解决方案概述

解决方案包含以下高层步骤:

准备元数据过滤的数据。创建并将数据和元数据摄取到知识库中。使用元数据过滤从知识库中检索数据。

准备元数据过滤的数据

截至目前,Amazon Bedrock 知识库支持以下底层向量存储提供商:Amazon OpenSearch Serverless、Amazon Aurora、Pinecone、Redis 企业版、和 MongoDB Atlas。在本帖中,我们将使用 Amazon Bedrock Boto3 SDK 创建和访问 OpenSearch Serverless 向量存储。更多详情请见 为您的知识库设置向量索引。

在本文中,我们将使用公共数据集 Foodcom 食谱和评论 来创建知识库。如下图所示:

TotalTime 使用 ISO 8601 格式。您可以使用以下逻辑将其转换为分钟:

python

将 ISO 8601 持续时间转换为分钟的函数

def converttominutes(duration) hours = 0 minutes = 0

# 使用正则表达式查找小时和分钟match = rematch(rPT((d)H)((d)M) duration)if match    if matchgroup(1)        hours = int(matchgroup(1))    if matchgroup(2)        minutes = int(matchgroup(2))# 将总时间转换为分钟totalminutes = hours  60  minutesreturn totalminutes

df[TotalTimeInMinutes] = df[TotalTime]apply(converttominutes)

在转换了 CholesterolContent、SugarContent 和 RecipeInstructions 等特征后,数据框如下图所示:

为了让 FMs 指向特定菜单引用文档,我们将每一行表格数据拆分到一个单独的文本文件,每个文件中包含 RecipeInstructions 作为数据字段,同时将 TotalTimeInMinutes、CholesterolContent 和 SugarContent 作为元数据。元数据应保存在与数据文件名称相同且后缀名为 metadatajson 的单独 JSON 文件中。例如,如果数据文件名为 100txt,则元数据文件名应为 100txtmetadatajson。更多详情见 将元数据添加到您的文件以便进行过滤。此外,元数据文件的内容应采用以下格式:

json{ metadataAttributes { {attribute1} {value1} {attribute2} {value2} }}

为了简化处理,我们仅处理前 2000 行以创建知识库。

在导入所需库后,使用以下 Python 代码创建本地目录

pythonimport pandas as pdimport os json tqdm boto3

metafolder = multifilerecipedataosmkdir(metafolder)

遍历前 2000 行,创建数据和元数据文件存储到本地文件夹中:

pythonfor i in tqdmtrange(2000) desc = str(df[RecipeInstructions][i]) meta = { metadataAttributes { Name str(df[Name][i]) TotalTimeInMinutes str(df[TotalTimeInMinutes][i]) CholesterolContent str(df[CholesterolContent][i]) SugarContent str(df[SugarContent][i]) } } filename = metafolder / str(i 1) txt with open(filename w) as f fwrite(desc)

metafilename = filename  metadatajsonwith open(metafilename w) as f    jsondump(meta f)

创建一个名为 foodkb 的 Amazon Simple Storage Service (Amazon S3) 存储桶,并上传文件:

python

将数据上传到 S3

s3client = boto3client(s3)bucketname = recipekbdataroot = metafolder /def uploadDirectory(path bucketname) for root dirs files in oswalk(path) for file in tqdmtqdm(files) s3clientuploadfile(ospathjoin(root file) bucketname file)

uploadDirectory(dataroot bucketname)

使用 Amazon Bedrock 知识库对表格数据进行元数据筛选 机器学习博客

创建并摄取数据和元数据到知识库

一旦 S3 文件夹准备好,您可以根据该示例笔记本使用 SDK 在 Amazon Bedrock 控制台上创建知识库。

使用元数据过滤从知识库中检索数据

现在让我们从知识库中检索一些数据。本文使用 Anthropic Claude Sonnet 作为我们的 FM,但您也可以从多种 Amazon Bedrock 模型 中选择。首先,您需要设置以下变量,其中 kbid 是您的知识库 ID。知识库 ID 可以通过编程方式获取,如 示例笔记本 所示,或者通过在 Amazon Bedrock 控制台中导航至单个知识库来查找,如下图所示:

使用以下代码设置所需的 Amazon Bedrock 参数:

pythonimport boto3import pprintfrom botocoreclient import Configimport json

pp = pprintPrettyPrinter(indent=2)session = boto3sessionSession()region = sessionregionnamebedrockconfig = Config(connecttimeout=120 readtimeout=120 retries={maxattempts 0})bedrockclient = boto3client(bedrockruntime regionname=region)bedrockagentclient = boto3client(bedrockagentruntime config=bedrockconfig regionname=region)kbid = EIBBXVFDQPmodelid = anthropicclaude3sonnet20240229v10

检索 API,仅获取相关上下文

query = 告诉我一个可以在 30 分钟内制作并且胆固醇低于 10 的食谱

relevantdocuments = bedrockagentclientretrieve( retrievalQuery={ text query } knowledgeBaseId=kbid retrievalConfiguration={ vectorSearchConfiguration { numberOfResults 2 } })pppprint(relevantdocuments[retrievalResults])

以下代码展示了针对“告诉我一个可以在 30 分钟内制作并且胆固醇低于 10 的食谱”这个查询从知识库中检索数据的结果,而没有进行元数据过滤。如我们所见,在两个食谱中,准备时间分别为 30 和 480 分钟,胆固醇含量分别为 86 和 1124。因此,检索结果并没有精准响应查询。

接下来,以下代码展示如何使用检索 API,并设置元数据过滤以实现胆固醇含量低于 10 和准备时间低于 30 的过滤:

pythondef retrieve(query kbId numberOfResults=5) return bedrockagentclientretrieve( retrievalQuery={ text query } knowledgeBaseId=kbId retrievalConfiguration={ vectorSearchConfiguration { numberOfResults numberOfResults filter { andAll [ { lessThan { key CholesterolContent value 10 } } { lessThan { key TotalTimeInMinutes value 30 } } ] } } } )

query = 告诉我一个可以在 30 分钟内制作并且胆固醇低于 10 的食谱response = retrieve(query kbid 2)retrievalResults = response[retrievalResults]pppprint(retrievalResults)

如下结果显示出使用元数据过滤后,两个菜谱的准备时间分别为 27 和 20,胆固醇含量均为 0。借助元数据过滤,我们得到了更准确的结果。

以下代码展示了如何使用相同的元数据过滤与 retrieveandgenerate API 来获得准确输出。首先,我们设置提示,然后配置带有元数据过滤的 API:

熊猫加速器安卓版下载

pythonprompt = f人类 你对食物有很好的知识,请根据事实回答问题。如果你不知道答案,只需说你不知道,不要尝试编造答案。

助手

def retrieveandgenerate(query kbid modelId numberOfResults=10) return bedrockagentclientretrieveandgenerate( input={ text query } retrieveAndGenerateConfiguration={ knowledgeBaseConfiguration { generationConfiguration { promptTemplate { textPromptTemplate f{prompt} searchresults } } knowledgeBaseId kbid modelArn modelId retrievalConfiguration { vectorSearchConfiguration { numberOfResults numberOfResults overrideSearchType HYBRID filter { andAll [ { lessThan { key CholesterolContent value 10 } } { lessThan { key TotalTimeInMinutes value 30 } } ] } } } } type KNOWLEDGEBASE } )

query = 告诉我一个可以在 30 分钟内制作并且胆固醇低于 10 的食谱response = retrieveandgenerate(query kbid modelid numberOfResults=10)pppprint(response[output][text])

如我们所见,模型返回了一个详细的食谱,遵循了准备时间低于 30 分钟和胆固醇含量低于 10 的元数据过滤指令。

清理

如果您打算使用您为构建 RAG 应用而创建的知识库,请确保注释以下部分。如果您只想尝试使用 SDK 创建知识库,请确保删除所有已创建的资源,因为您将会产生存储文档在 OpenSearch Serverless 索引中的费用。请参见以下代码:

pythonbedrockagentclientdeletedatasource(dataSourceId=ds[dataSourceId] knowledgeBaseId=kb[knowledgeBaseId])bedrockagentclientdeleteknowledgebase(knowledgeBaseId=kb[knowledgeBaseId])ossclientindicesdelete(index=indexname)aossclientdeletecollection(id=collectionid)aossclientdeleteaccesspolicy(type=data name=accesspolicy[accessPolicyDetail][name])aossclientdeletesecuritypolicy(type=network name=networkpolicy[securityPolicyDetail][name])aossclientdeletesecuritypolicy(type=encryption name=encryptionpolicy[securityPolicyDetail][name])

删除角色和策略

iamclientdeleterole(RoleName=bedrockkbexecutionrole)iamclientdeletepolicy(PolicyArn=policyarn)

结论

在本篇文章中,我们讲解了如何将大型表格数据集拆分为行,以便为每条记录设置知识库的元数据,并展示了如何使用元数据过滤检索输出。我们也表明,使用元数据检索的结果比没有元数据过滤的结果更准确。最后,我们展示了如何借助 FM 来获取准确结果。

如需进一步探索 Amazon Bedrock 知识库的功能,请参考以下资源:

Amazon Bedrock 知识库Amazon Bedrock 知识库 构建 RAG 工作流的示例

关于作者

Tanay Chowdhury 是亚马逊网络服务的生成 AI 创新中心的数据科学家。他帮助客户使用生成 AI 和机器学习解决业务问题。

成本高效的非持久性虚拟桌面Amazon WorkSpaces Pools主要重点Amazon WorkSpaces 现在支持非持久性虚拟桌面的 Pools 功能,方便用户共享。管理员可以通过 GUI、...

用全新 Amazon EventBridge 集成自动化部署 Amazon QuickSight 资产作者 Mayank Agarwal 和 Arun Santhosh,2023年11月17日,发表于...