使用 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)

创建并摄取数据和元数据到知识库
一旦 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 和机器学习解决业务问题。
亚马逊 WorkSpaces 池:高性价比的非持久虚拟桌面 新闻博客
成本高效的非持久性虚拟桌面Amazon WorkSpaces Pools主要重点Amazon WorkSpaces 现在支持非持久性虚拟桌面的 Pools 功能,方便用户共享。管理员可以通过 GUI、...
使用新的 Amazon EventBridge 集成功能自动化您的 Amazon QuickSigh
用全新 Amazon EventBridge 集成自动化部署 Amazon QuickSight 资产作者 Mayank Agarwal 和 Arun Santhosh,2023年11月17日,发表于...