构造 RAG 评估数据集¶
学习目标¶
- 掌握RAG性能评估的指标
- 实现RAG评估数据集的构造
1 引言¶
优化 RAG 不是“炼丹”,需要系统的方法。当涉及到如何优化 RAG(Retrieval-Augmented Generation)性能时,许多人往往采取“试错”的方法:“我尝试了一个新模块,问了几个问题,答案看起来还行…”。这样的定性评估方式虽然直观,但很难得出可靠的改进结论。
优化 RAG 性能需要采用科学实验的方式。这意味着我们必须设计量化的评估指标,并准备高质量的评估数据集。通过结构化的实验和评估方法,我们才能明确什么样的调整会真正提升性能。
2 结构化评估 RAG 的性能¶
RAG 系统的性能评估可以从以下两个主要方面进行:
- 检索评估(Retrieval Evaluation): 检索的段落是否相关?
- 生成评估(Generation Evaluation): 模型生成的答案是否恰当?
对于端到端的评估,我们通常关注以下四类指标:
- Groundedness(可靠性): 检索评估中的关键指标,评估检索的段落是否为生成的答案提供了可靠支持,避免幻觉(hallucinations)或无关信息。这是生成评估的基础。
- Completeness(完整性): 生成评估的核心指标,用于评估模型的回答是否全面覆盖了用户问题的所有方面,同时间接反映了检索阶段的信息充分性。
- Utilization(利用率): 连接检索和生成的桥梁指标,用来评估检索到的信息是否被有效利用。如果利用率低,可能意味着检索到的段落与问题无关,或者模型未充分使用这些段落。
- Relevance(相关性): 检索评估的直接反映,衡量检索到的段落与用户问题之间的相关性,同时也会影响生成评估的整体表现。
这些指标需要基于高质量的测试样本和严格的评估流程。
3 使用 Agents 完成 RAG 性能基准测试¶
在开始具体流程前,我们需要了解三个代理(Agents)的协作关系:
- 测试样本代理(Test Sample Agent): 用于生成和准备测试数据,这些数据构成了评估系统的基础。
- 样本质量评价代理(Critique Agent): 对测试样本进行质量审核,确保最终用于评估的数据具备高准确性和清晰性。
- 评估代理(Evaluation Agent): 负责根据设计的指标对系统性能进行量化评估。这些评估指标覆盖了检索和生成的多个层面。
通过这三种代理的协作,可以建立一个系统化的性能基准测试流程,帮助开发者深入理解和优化 RAG 系统。
3.1 生成测试样本¶
为了评估 RAG 系统的性能,首先需要使用测试样本代理(Test Sample Agent) 生成测试样本。这些代理可以自动生成一组高质量的 QA 样本(问题与答案对)。例如,可以先生成 10 个样本用于快速测试,然后从公共资源库加载更多样本,或者生成更大规模的数据集以供全面评估。
但如果针对特定的知识库,建议生成至少 200 个样本,因为后续通过评价代理过滤掉低质量问题后,最终能保留的有效样本约为一半。
以下是生成QA样本的提示词:
QA_generation_prompt = """
你的任务是:根据给定的上下文,编写一个事实型问题及其答案。
你提出的事实型问题应能通过上下文中的具体、简明的事实信息来回答。
你的问题风格应与用户在搜索引擎中提出的问题类似。
这意味着你提出的问题**不能**包含“根据段落”或“根据上下文”等措辞。
请按以下格式给出你的输出:
输出:::
事实型问题:(你的问题)
答案:(你对该问题的回答)
以下是上下文内容:
上下文:{context}\n
输出:::"""
3.2 检查样本质量¶
自动生成的样本可能存在质量问题,因此需要引入样本质量评价代理(Critique Agents) 来对问题进行质量审查。这些代理会根据多种标准对每个问题评分,比如:
- 问题是否清晰、无二义性?
- 问题是否适合特定知识领域?
我们通过这些代理对问题进行系统评分。当任意一个代理的评分过低时,直接剔除该问题。
提示: 当让代理生成分数时,先要求其输出理由,再给出最终评分。这种方式不仅能帮助我们验证评分结果,还能促使代理在回答过程中进行更深入的思考,从而提高评分的准确性。
以下是评估样本质量的提示词:
question_groundedness_critique_prompt = """
你将获得一个上下文和一个问题。
你的任务是给出一个“总评分”,评估该问题是否能够通过给定的上下文明确无歧义地回答。
请在1到5分之间进行评分,其中1表示完全无法根据上下文回答该问题,5表示能够清晰且无歧义地根据上下文回答该问题。
请按以下格式给出你的回答:
回答:::
评价:(你对评分的理由,文本形式)
总评分:(你给出的评分,范围为1到5的数字)
你的回答**必须包含**“评价”和“总评分”的内容。
现在是问题和上下文内容:
问题:{question}\n
上下文:{context}\n
回答::: """
question_relevance_critique_prompt = """
你将获得一个问题。
你的任务是给出一个“总评分”,表示该问题对于正在使用 Hugging Face 生态构建自然语言处理应用的机器学习开发者来说有多有用。
请在1到5分之间进行评分,其中1表示完全没有用,5表示非常有用。
请按以下格式给出你的回答:
回答:::
评价:(你对评分的理由,文本形式)
总评分:(你给出的评分,范围为1到5的数字)
你的回答**必须包含**“评价”和“总评分”的内容。
现在是该问题:
问题:{question}\n
回答::: """
question_standalone_critique_prompt = """
你将获得一个问题。
你的任务是给出一个“总评分”,评估该问题在多大程度上是独立于上下文的。
请在1到5分之间进行评分,其中1表示该问题需要额外信息才能理解,5表示该问题本身就可以被理解。
例如,如果问题提到了“在该文档中”或“在该上下文中”等字样,那么评分必须为1。
即使问题包含专业术语或缩写(如 Gradio、Hub、Hugging Face 或 Space),只要操作人员可以通过文档理解其含义,评分也可以是5。
例如,“ViT 模型是从哪个检查点导入的?” 应该得分为 1,因为它隐含了上下文的依赖,因此不具有独立性。
请按以下格式给出你的回答:
回答:::
评价:(你对评分的理由,文本形式)
总评分:(你给出的评分,范围为1到5的数字)
你的回答**必须包含**“评价”和“总评分”的内容。
现在是该问题:
问题:{question}\n
回答::: """
3.3 设置评估代理¶
最后,我们需要评估 RAG 系统在测试数据集上的表现。可以通过以下步骤完成:
-
选择评估指标:
- 我们重点关注faithfulness(可靠性) 作为主要指标,因为它能全面反映系统的端到端性能。
- 选择评估模型: 使用 GPT-4 作为评估代理,或者尝试其他性能良好的模型,如 kaist-ai/prometheus-13b-v1.0 或 BAAI/JudgeLM-33B-v1.0。
-
设计评估提示词: 提示词需要详细描述每个指标的评分标准(例如 1-5 分),并要求模型在评分前先输出评分依据。
提示: 提供详细的评分标准有助于评估代理保持一致性,避免因模糊标准导致评分结果的波动。
以下是 RAG 评估模型的提示词:
EVALUATION_PROMPT = """### 任务描述:
提供了一条指令(可能包含输入)、待评估的回答、得分为 5 的参考答案,以及表示评估标准的评分细则。
1. 根据给定的评分细则,严格评估回答的质量,撰写详细的反馈,不进行一般性评价。
2. 在撰写反馈后,给出一个 1 到 5 的整数分数,需参考评分细则。
3. 输出格式应如下:“Feedback: {{针对标准的反馈}} [RESULT] {{1 到 5 的整数}}”
4. 请勿生成其他开场、结尾或解释内容。确保输出包含 [RESULT]。
### 待评估的指令:
{instruction}
### 待评估的回答:
{response}
### 参考答案(得分 5):
{reference_answer}
### 评分细则:
[回答是否基于参考答案正确、准确且符合事实?]
得分 1:回答完全不正确、不准确和/或不符合事实。
得分 2:回答大部分不正确、不准确和/或不符合事实。
得分 3:回答部分正确、准确和/或符合事实。
得分 4:回答大部分正确、准确且符合事实。
得分 5:回答完全正确、准确且符合事实。
### 反馈:"""
from langchain.prompts.chat import (
ChatPromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.schema import SystemMessage
evaluation_prompt_template = ChatPromptTemplate.from_messages(
[
SystemMessage(content="You are a fair evaluator language model."),
HumanMessagePromptTemplate.from_template(EVALUATION_PROMPT),
]
)
4 本节小结¶
准备高质量的评估数据集是优化 RAG 性能的基础。通过引入生成代理和评价代理,我们可以建立一个系统化的评估流程,确保每个调整都有量化依据。这种基于数据驱动的方法不仅能帮助开发者快速迭代 RAG 系统,还能避免无效尝试导致的时间浪费。