生成用于评估 RAG 系统的合成数据 机器学习博客
使用 Amazon Bedrock 生成合成数据以评估 RAG 系统
关键要点
在将检索增强生成RAG系统投入生产之前,必须验证其能否满足业务需求。生成高质量的合成数据集可以帮助有效评估 RAG 系统的表现,特别是在开发初期。本文提供了使用 Amazon Bedrock 中的 Anthropic Claude 模型生成合成数据的步骤和实例。评估检索增强生成RAG系统的能力,以确保其能够满足实际业务需求,是在将其投入生产环境之前不可或缺的一步。然而,这通常需要获取高质量的现实问题与答案对数据集,这在开发早期阶段尤其困难。此时,合成数据的生成显得尤为重要。使用 Amazon Bedrock,您可以生成模拟实际用户查询的合成数据集,从而有效且大规模地评估 RAG 系统的性能。借助合成数据,您可以简化评估流程,并在将其投入到实际应用之前,增强对系统能力的信心。
本文将解释如何在 Amazon Bedrock 上使用 Anthropic Claude 生成合成数据,以评估您的 RAG 系统。Amazon Bedrock 是一项完全托管的服务,提供来自 AI21 Labs、Anthropic、Cohere、Meta、Stability AI 和 Amazon 等领先 AI 公司高性能基础模型FMs的选择,通过单一 API 访问,同时提供构建安全、隐私和负责任 AI 生成应用程序的广泛能力。
RAG 评估基础
在深入了解如何评估 RAG 应用程序之前,让我们回顾一下简单的 RAG 工作流程的基本构成,如下图所示。
工作流程包括以下步骤:
在异步的摄取步骤中,数据被切分成多个独立的块,并使用嵌入模型生成每个块的嵌入,存储在向量存储中。当用户向系统提出问题时,从问题中生成嵌入,并从向量存储中检索出 k 个最相关的块。RAG 模型通过在上下文中添加相关的检索数据来增强用户输入。这一步使用提示工程技术有效与大型语言模型LLM沟通,增强的提示使 LLM 能够生成准确的用户查询答案。一个 LLM 被提示根据用户的问题和检索到的块来形成有用的答案。Amazon Bedrock 知识库 提供了一种简化的方式来在 AWS 上实现 RAG,为将 FMs 连接到自定义数据源提供了一种完全托管的解决方案。要使用 Amazon Bedrock 知识库实施 RAG,首先需要指定数据的位置,通常在 Amazon 简单存储服务Amazon S3中,并选择嵌入模型将数据转换为向量嵌入。Amazon Bedrock 然后在您的账户中创建和管理一个向量存储,通常使用 Amazon OpenSearch 无服务器,处理整个 RAG 工作流程,包括嵌入创建、存储、管理和更新。可以使用 RetrieveAndGenerate API 进行简单实现,该 API 会自动从您的知识库检索相关信息并使用指定的 FM 生成响应。为了更精细的控制,可以使用 Retrieve API,允许您通过处理检索到的文本块和开发自己的文本生成编排,构建自定义工作流程。此外,Amazon Bedrock 知识库还提供了定制选项,例如定义 分块策略 和选择 自定义向量存储,如 Pinecone 或 Redis 企业云。
RAG 应用程序有许多变化的部分,而在驶向生产的过程中,您需要对系统的各个组件进行调整。没有良好的自动化评估工作流程,就无法有效测量这些变化的效果,您将无法对应用程序的整体性能有清晰的了解。
为了准确评估这样的系统,您需要收集一个包含典型用户问题和答案的评估数据集。
此外,您需要确保不仅评估过程的生成部分,还要评估检索部分。如果 LLM 没有相关的检索上下文,无法回答用户的问题,因为信息未在训练数据中出现。即使它具有卓越的生成能力,这一点也同样适用。
因此,典型的 RAG 评估数据集至少应包含以下组成部分:
用户将向 RAG 系统提出的问题列表用于评估生成步骤的相应答案列表每个问题的上下文或答案列表,以评估检索在理想情况下,您会以真实用户问题为基础进行评估。虽然这种方法是最优的,因为它直接反映了最终用户的行为,但这并不总是可行,特别是在构建 RAG 系统的早期阶段。随着进展的加深,您应努力将真实用户问题纳入评估集。
要了解更多关于如何评估 RAG 应用的信息,请参见 使用 Amazon Bedrock 评估检索增强生成应用的可靠性。
解决方案概述
我们使用示例用例来说明构建 Amazon 股东信 chatbot 的过程,这可以让业务分析师获取有关公司战略和过去几年的绩效的洞察。
在这个用例中,我们使用亚马逊股东信的 PDF 文件作为知识库。这些信件包含有关公司运营、项目和未来计划的重要信息。在实施 RAG 时,知识检索器可能使用支持向量搜索的数据库动态查找相关文档。
下图说明了生成合成数据集的工作流程。
工作流程包括以下步骤:
从数据源加载数据。像处理 RAG 应用程序一样对数据进行分块。从每个文档生成相关问题。通过提示 LLM 生成答案。提取回答问题的相关文本。根据特定风格演变问题。使用领域专家或 LLM 的批评代理对问题进行过滤并改进数据集。我们使用 Anthropic 的 Claude 3 模型家族中的模型来从我们的知识源中提取问题和答案,但您也可以尝试其他 LLM。使用 Amazon Bedrock,使这一过程变得轻而易举,允许对多个 FM 进行标准化的 API 访问。
对于该过程中的编排和自动化步骤,我们使用 LangChain。LangChain 是一个开源的 Python 库,旨在构建利用 LLM 的应用程序。它提供了一个模块化和灵活的框架,结合 LLM 与其他组件,例如知识库、检索系统和其他 AI 工具,以创建强大且可定制的应用。
接下来的几部分将逐步介绍该过程中的重要部分。如需深入了解并亲自尝试,请参阅 GitHub。
西游加速器安卓app加载和准备数据
首先,使用 LangChain 的 PyPDFDirectoryLoader 加载股东信,并使用 RecursiveCharacterTextSplitter 将 PDF 文档拆分为块。此 RecursiveCharacterTextSplitter 会将文本拆分为指定大小的块,同时尽量保留上下文和内容的意义。当处理基于文本的文档时,这是一个良好的开始。如果您的 LLM 支持足够大的上下文窗口,您不必拆分文档创建评估数据集,但这可能会导致生成的问题质量较低,因为任务的大小增加。在这种情况下,您希望 LLM 为每个文档生成多个问题。
pythonfrom langchaintextsplitter import CharacterTextSplitter RecursiveCharacterTextSplitterfrom langchaindocumentloaderspdf import PyPDFLoader PyPDFDirectoryLoader
从目录加载 PDF 文档
loader = PyPDFDirectoryLoader(/syntheticdatasetgeneration/)documents = loaderload()
使用递归子文本拆分器,更适合该 PDF 数据集
textsplitter = RecursiveCharacterTextSplitter( # 将文档拆分为小块 chunksize = 1500 # 重叠块以减少句子断裂 chunkoverlap = 100 separators=[nn n ])
将加载的文档拆分为块
docs = textsplittersplitdocuments(documents)

为了演示生成相应的问题和答案以及对其进行逐步改进的过程,我们使用从加载的股东信中提取的示例块:
python“pagecontent=我们的 AWS 和消费业务在疫情期间的需求轨迹各不相同。在疫情的第一年,AWS 收入继续以快速速度增长2020 年同比增长 30“YoY”,而2019 年的年收入基数为 350 亿美元,但增速低于2019年的37。[]许多公司的这种转变加上经济复苏帮助 AWS 的收入增长在 2021 年恢复至同比增长37。相反,我们的消费收入在2020年急剧增长。2020年,亚马逊北美和国际消费收入同比增长39,而2019 年的收入基数巨大,为2450亿美元;这一非凡的增长延续到2021年,2021年第一季度收入同比增长43。这些数字令人震惊。我们在大约15个月内实现了三年预测增长的相当于。随着世界在2021年第二季度末再次开放,更多人走出去吃饭、购物和旅行,”
生成初始问题
为便于使用 Amazon Bedrock 和 LangChain 提示 LLM,您首先要配置推断参数。为了准确提取更广泛的上下文,将 maxtokens 参数设置为 4096,这对应于 LLM 在输出中将生成的最大令牌数。此外,将温度参数设置为 02,因为目标是生成符合指定规则的回答,同时仍允许一定程度的创造性。这个值对于不同的使用案例是不同的,可以通过实验确定。
pythonimport boto3
from langchaincommunitychatmodels import BedrockChat
设置 Bedrockruntime 客户端用于推断大型语言模型
boto3bedrock = boto3client(bedrockruntime)
由于成本和性能效率选择 Claude 3 Haiku
claude3haiku = anthropicclaude3haiku20240307v10
设置 langchain LLM 用于实现合成数据集生成逻辑
每个模型提供者在进行模型推断时都有不同的参数需要定义
inferencemodifier = { maxtokens 4096 temperature 02}
llm = BedrockChat(modelid = claude3haiku client = boto3bedrock modelkwargs = inferencemodifier )
使用每个生成的块创建合成问题,模拟真实用户可能提出的问题。通过提示 LLM 分析股东信数据的一部分,生成基于上下文呈现信息的相关问题。我们使用以下示例提示为特定上下文生成单个问题。为了简单起见,提示被硬编码为生成单个问题,但您也可以指示 LLM 使用单个提示生成多个问题。
这些规则可以调整以更好地引导 LLM 生成反映用户可能提出的查询类型的问题,从而将方法量身定制为特定用例。
python
创建一个提示模板,以生成最终用户可能对给定上下文提出的问题
initialquestionprompttemplate = PromptTemplate( inputvariables=[context] template= 这里是一些上下文 {context}
您的任务是生成 1 个可以使用提供的上下文回答的问题,并遵循以下规则:ltrulesgt1 该问题应对人类有意义,即使在没有给定上下文的情况下阅读也应成立。2 从给定的上下文中可以完整回答该问题。3 该问题应从包含重要信息的上下文部分构建,也可以是表格、代码等部分。4 问题的答案不应包含任何链接。5 问题应具有适度的难度。6 问题必须合理,必须能让人理解并得到回复。7 不要在问题中使用“给定上下文”等短语。8 避免使用“和”字构建可以拆分为多个问题的问题。9 问题不得超过 10 个字,尽量使用缩写。lt/rulesgt生成问题时,请首先确定上下文中最重要或最相关的部分。然后围绕该部分框架提出一个符合上述所有规则的问题。只输出生成的问题,并在末尾加上“”,不附加其他文本或字符。lt/Instructionsgt)
以下是从示例块中生成的问题:
问题 AWS Graviton2 芯片相较于 x86 处理器的价格性能改善是多少?
生成答案
要使用问题进行评估,您需要为每个问题生成参考答案,以供测试。使用以下提示模板,您可以生成根据问题和原始源块生成的参考答案:
python
创建一个提示模板,该模板考虑问题并生成答案
answerprompttemplate = PromptTemplate( inputvariables=[context question] template= 您是一个经验丰富的 QA 工程师,专注于构建大型语言模型应用。 您的任务是仅根据 {context} 生成以下问题 {question} 的答案。 输出应为根据上下文生成的答案。
ltrulesgt1 仅使用给定的上下文作为生成答案的源。2 尽可能准确地回答该问题。3 答案应简洁,仅限于直接回答问题,而不是添加额外信息。lt/rulesgt仅输出生成的答案为一条句子。没有额外字符。lt/Taskgtlt/InstructionsgtAssistant)
基于示例块生成的答案为:“AWS 收入在 2021 年同比增长 37。”
提取相关上下文
为了使数据集可验证,我们使用以下提示从给定上下文中提取回答生成的问题的相关句子。了解相关句子可以检查问题和答案是否正确。
python
为了检查大型语言模型生成的答案是否正确,您需要获取来自用于回答问题的文档的相关文本段落。
sourceprompttemplate = PromptTemplate( inputvariables=[context question] template=人类: 这里是上下文: {context}
您的任务是从给定上下文中提取可能帮助回答以下问题的相关句子。您不得对上下文中的句子进行任何更改。ltquestiongt{question}lt/questiongt仅输出您找到的相关句子,每行一个句子,不添加额外字符或解释。lt/InstructionsgtAssistant)使用上述提示提取的相关源句子为:“许多公司的这种转变加上经济复苏帮助 AWS 的收入增长在 2021 年恢复至同比增长 37。”
改进问题
从同一提示生成问题和答案对时,可能会发现问题在形式上重复且相似,因此不模拟真实的最终用户行为。为防止这种情况,采用先前创建的问题并提示 LLM 修改,遵循指定的规则和指导。通过这样做,可以产生更多样化的合成数据集。针对特定用例生成的问题的提示很大程度上依赖于特定用例。因此,您的提示必须准确反映最终用户的需求,设定适当的规则或者提供相关的示例。问题的改进过程可以根据需要重复多次。
python
为了生成更灵活的测试数据集,您可以交替修改问题,以查看 RAG 系统在不同表述的问题上的表现
questioncompressprompt
发表评论