RAG (Retrieval-Augmented Generation) 评测面
来源:AiGC面试宝典 作者:宁静致远 日期:2024年01月28日
目录
一、为什么需要对 RAG 进行评测?
在探索和优化 RAG(检索增强生成)的过程中,如何有效评估其性能已经成为关键问题。通过评测,我们可以:
- 了解系统效果:判断 RAG 系统在实际应用中的表现
- 指导系统优化:发现薄弱环节,有针对性地改进
- 对比不同方案:为技术选型提供量化依据
- 保障上线质量:确保系统满足业务需求
📝 通俗解释:就像考试需要评分标准一样,RAG系统也需要一套"考卷"来检验它是否合格。没有评测,我们就像盲目摸索,不知道系统到底好不好,哪里需要改进。
二、如何合成 RAG 测试集?
假设你已经成功构建了一个 RAG 系统,并且现在想要评估它的性能。为了这个目的,你需要一个评估数据集,该数据集包含以下列:
| 字段名 | 说明 |
|---|---|
| question(问题) | 想要评估的 RAG 的问题 |
| ground_truths(真实答案) | 问题的标准答案 |
| answer(答案) | RAG 预测的答案 |
| contexts(上下文) | RAG 用于生成答案的相关信息列表 |
📝 通俗解释:这个表格就像一张"考卷"。"question"是考题,"ground_truths"是标准答案,"answer"是学生(RAG)写的答案,"contexts"是学生参考资料。批改时,我们对比标准答案和学生答案来打分。
前两列代表真实数据,最后两列代表 RAG 预测数据。
2.1 生成问题和答案的元组
要生成(问题、答案)元组,我们首先需要准备 RAG 数据,我们将其拆分为块,并将其嵌入向量数据库中。完成这些步骤后,我们会指示 LLM 从指定主题中生成 $num_questions$ 个问题,从而得到问题和答案元组。
为了从给定的上下文中生成问题和答案,我们需要按照以下步骤操作:
- 选择一个随机块 并将其作为根上下文
- 从向量数据库中检索 $k$ 个相似的上下文
- 将根上下文和其 $k$ 个相邻上下文 的文本连接起来以构建一个更大的上下文
- 使用这个大的上下文 和 $num_questions$ 在以下的提示模板中生成问题和答案
英文提示模板:
Your task is to formulate exactly {num_questions} questions from given context and provide the answer
to each one.
End each question with a '?' character and then in a newline write the answer to that question using only
the context provided.
Separate each question/answer pair by "XXX"
Each question must start with "question:".
Each answer must start with "answer:".
The question must satisfy the rules given below:
1. The question should make sense to humans even when read without the given context.
2. The question should be fully answered from the given context.
3. The question should be framed from a part of context that contains important information. It can
also be from tables, code, etc.
4. The answer to the question should not contain any links.
5. The question should be of moderate difficulty.
6. The question must be reasonable and must be understood and responded by humans.
7. Do not use phrases like 'provided context', etc in the question
8. Avoid framing question using word "and" that can be decomposed into more than one question.
9. The question should not contain more than 10 words, make use of abbreviation wherever possible.
context: {context}中文提示模板:
您的任务是根据给定的上下文提出 {num_questions} 个问题,并给出每个问题的答案。
在每个问题的末尾加上"?",并在下一行根据
提供的上下文写出该问题的答案。
每个问题/答案之间用"XXX"隔开。
每个问题必须以"question:"开头。
每个答案必须以"answer:"开头。
问题必须符合以下规则:
1. 即使在没有给定上下文的情况下,问题也应该对人类有意义。
2. 问题应能根据给定的上下文给出完整的答案。
3. 问题应从包含重要信息的上下文中提取。也可以是表格、代码等。
4. 问题答案不应包含任何链接。
5. 问题难度应适中。
6. 问题必须合理,必须为人类所理解和回答。
7. 不要在问题中使用"提供上下文"等短语。
8. 避免在问题中使用"和"字,因为它可以分解成多个问题。
9. 问题不应超过10个单词,尽可能使用缩写。
上下文:{context}- 重复以上步骤 num_count 次,每次改变上下文并生成不同的问题。
📝 通俗解释:这个过程就像老师出题。老师从一个知识点出发(随机块),找到相关的补充材料(相似上下文),然后让AI根据这些材料出几道题。这样生成的题目质量和真实考试差不多。
2.2 生成合成数据集的完整示例
步骤1:加载数据
首先构建一个向量存储,其中包含 RAG 使用的数据。我们从 Wikipedia 加载它:
from langchain.document_loaders import WikipediaLoader
topic = "python programming"
wikipedia_loader = WikipediaLoader(
query=topic,
load_max_docs=1,
doc_content_chars_max=100000,
)
docs = wikipedia_loader.load()
doc = docs[0]步骤2:数据分块
加载数据后,我们将其分成块:
from langchain.text_splitter import RecursiveCharacterTextSplitter
CHUNK_SIZE = 512
CHUNK_OVERLAP = 128
splitter = RecursiveCharacterTextSplitter(
chunk_size=CHUNK_SIZE,
chunk_overlap=CHUNK_OVERLAP,
separators=["\n\n", "\n", " ", ""],
)
splits = splitter.split_documents([doc])📝 通俗解释:把一篇长文章切成一小段一小段,就像把一本小说分成章节。每个章节就是一个"块"(chunk),方便后续检索和使用。
步骤3:创建向量索引
在 Pinecone 中创建一个索引:
import pinecone
import os
pinecone.init(
api_key=os.environ.get("PINECONE_API_KEY"),
environment=os.environ.get("PINECONE_ENV"),
)
index_name = topic.replace(" ", "-")
if index_name in pinecone.list_indexes():
pinecone.delete_index(index_name)
pinecone.create_index(index_name, dimension=768)步骤4:索引文档嵌入
使用 LangChain 包装器来索引其中的分片嵌入:
from langchain.vectorstores import Pinecone
from langchain.embeddings import VertexAIEmbeddings
embedding_model = VertexAIEmbeddings()
docsearch = Pinecone.from_documents(
splits,
embedding_model,
index_name=index_name,
)步骤5:生成合成数据集
我们使用 LLM、文档拆分、嵌入模型和 Pinecone 索引名称从 TestsetGenerator 类初始化一个对象:
from langchain.llms import VertexAI
from testset_generator import TestsetGenerator
generator_llm = VertexAI(
location="europe-west3",
max_output_tokens=256,
max_retries=20,
)
embedding_model = VertexAIEmbeddings()
testset_generator = TestsetGenerator(
generator_llm=generator_llm,
documents=splits,
embedding_model=embedding_model,
index_name=index_name,
key="text",
)通过传递两个参数来调用 generate 方法:
synthetic_dataset = testset_generator.generate(
num_contexts=10,
num_questions_per_context=2,
)生成结果示例:
| # | question | ground_truths |
|---|---|---|
| 8 | What is the difference between lists and tuples in Python? | ['Lists are mutable and cannot be used as dictionary keys, while tuples are immutable and can be used as dictionary keys if all elements are immutable.'] |
| 4 | What is the name of the Python variant optimized for microcontrollers? | ['MicroPython and CircuitPython'] |
| 13 | What is the name of the programming language that Python was designed to replace? | ['ABC programming language'] |
| 17 | How often do bugfix releases occur? | ['Bugfix releases occur about every 3 months.'] |
| 3 | What is the significance of Python's release history? | ['Python 2.0 was released in 2000, while 3.0, a major revision with limited backward compatibility, was released in 2008.'] |
📝 通俗解释:这就是用AI自动生成的"模拟考试题"。从维基百科文章出发,AI自动出题并给出标准答案,形成一个可以用来测试RAG系统的数据集。
2.3 使用 RAG 预测答案
接下来使用 RAG 来预测每个问题的答案,并提供用于支撑响应的上下文列表。
步骤1:初始化 RAG
from rag import RAG
rag = RAG(
index_name,
"text-bison",
embedding_model,
"text",
)步骤2:预测并收集结果
通过对每个问题调用 predict 方法来迭代合成数据集并收集预测:
rag_answers = []
contexts = []
for i, row in synthetic_dataset.iterrows():
question = row["question"]
prediction = rag.predict(question)
rag_answer = prediction["answer"]
rag_answers.append(rag_answer)
source_documents = prediction["source_documents"]
contexts.append([s.page_content for s in source_documents])
synthetic_dataset_rag = synthetic_dataset.copy()
synthetic_dataset_rag["answer"] = rag_answers
synthetic_dataset_rag["contexts"] = contexts步骤3:最终结果示例
| # | question | ground_truths | answer | contexts |
|---|---|---|---|---|
| 7 | What are the two types of classes that Python supported before version 3.0? | ['old-style and new-style'] | Before version 3.0, Python had two kinds of classes (both using the same syntax): old-style and new-style. | [...] |
基于以上步骤,我们已经为评估 RAG 做好了准备,接下来我们讲解如何进行 RAG 评估。
📝 通俗解释:这就是让RAG系统"做题"的过程。把生成的题目逐个输入RAG系统,记录它给出的答案和参考资料,形成完整的"考试成绩单"。
三、RAG 有哪些评估方法?
主要有两种方法来评估 RAG 的有效性:独立评估和端到端评估。
📝 通俗解释:有两种考试方式。一种是"分科考试",只考某一门课(检索或生成);另一种是"综合考试",考整个系统的表现。两种方式各有优缺点,结合使用更全面。
3.1 独立评估
3.1.1 什么是独立评估?
独立评估(Independent Evaluation)是指对检索模块和生成模块分别进行评估,就像把RAG系统拆分成两个独立的"科目"来考试:
- 检索模块评估:评估系统能否准确找到相关文档
- 生成模块评估:评估系统能否基于检索到的内容生成正确答案
📝 通俗解释:就像把语文和数学分开考。检索模块相当于"查找资料"的能力,生成模块相当于"根据资料答题"的能力。分开考可以更清楚地知道哪里薄弱。
3.1.2 独立评估的模块与指标
生成模块指的是将检索到的文档与查询相结合,形成增强或合成的输入。这与最终答案或响应的生成不同,后者通常采用端到端的评估方式。
评估指标:
1. 答案相关性(Answer Relevancy)
此指标的目标是评估生成的答案与提供的问题提示之间的相关性。答案如果缺乏完整性或者包含冗余信息,那么其得分将相对较低。这一指标通过问题和答案的结合来进行计算,评分的范围通常在 $0$ 到 $1$ 之间,其中高分代表更好的相关性。
示例:
问题:健康饮食的主要特点是什么?
- ❌ 低相关性答案:健康饮食对整体健康非常重要。(太笼统,没回答具体特点)
- ✅ 高相关性答案:健康饮食应包括各种水果、蔬菜、全麦食品、瘦肉和乳制品,为优化健康提供必要的营养素。(直接回答了特点)
📝 通俗解释:就像批改作文题,老师要看学生的答案有没有"跑题"。如果问"健康饮食特点",却回答"健康很重要",就是低相关;回答具体包含哪些食物,才是高相关。
2. 忠实度(Faithfulness)
这个评价标准旨在检查生成的答案在给定上下文中的事实准确性。评估的过程涉及到答案内容与其检索到的上下文之间的比对。这一指标也使用一个介于 $0$ 到 $1$ 之间的数值来表示,其中更高的数值意味着答案与上下文的一致性更高。
示例:
问题:居里夫人的主要成就是什么?
背景:玛丽·居里(1867-1934年)是一位开创性的物理学家和化学家,她是第一位获得诺贝尔奖的女性,也是唯一一位在两个不同领域获得诺贝尔奖的女性。
- ✅ 高忠实度答案:玛丽·居里在物理和化学两个领域都获得了诺贝尔奖,使她成为第一位实现这一成就的女性。(完全符合背景信息)
- ❌ 低忠实度答案:玛丽·居里只在物理学领域获得了诺贝尔奖。(与背景信息矛盾)
📝 通俗解释:就像考试时只能翻看指定参考资料答题,不能自己编造。如果参考资料说"她在两个领域都得奖了",你却回答"只在一个领域得奖",就是"不忠实"——相当于作弊。
3. 上下文精确度(Context Precision)
在这个指标中,我们评估所有在给定上下文中与基准信息相关的条目是否被正确地排序。理想情况下,所有相关的内容应该出现在排序的前部。这一评价标准同样使用 $0$ 到 $1$ 之间的得分值来表示,其中较高的得分反映了更高的精确度。
常用指标:
- 命中率 (Hit Rate):相关文档被检索到的比例
- 平均排名倒数 (MRR):第一个相关文档排名的倒数
- 归一化折扣累积增益 (NDCG):综合考虑相关性和排名的指标
- 精确度 (Precision):检索结果中相关文档的比例
📝 通俗解释:就像在图书馆找书,我们希望最相关的书放在最前面。如果前三本书都是你想找的,那就是高精确度;如果翻到第十本才找到想要的,那就是低精确度。
4. 答案正确性(Answer Correctness)
该指标主要用于测量生成的答案与实际基准答案之间的匹配程度。这一评估考虑了基准答案和生成答案的对比,其得分也通常在 $0$ 到 $1$ 之间,较高的得分表明生成答案与实际答案的一致性更高。
示例:
基准答案:埃菲尔铁塔于 1889 年在法国巴黎竣工。
- ✅ 答案正确率高:埃菲尔铁塔于 1889 年在法国巴黎竣工。(完全正确)
- ❌ 答案正确率低:埃菲尔铁塔于 1889 年竣工,矗立在英国伦敦。(时间对,但地点错误)
📝 通俗解释:这就是标准的"批改卷子"。对比标准答案,看学生(RAG)答对了多少。完全一致得满分,部分一致得部分分,完全错误得零分。
3.2 端到端评估
3.2.1 什么是端到端评估?
端到端评估(End-to-End Evaluation)是对 RAG 模型对特定输入生成的最终响应进行评估,涉及模型生成的答案与输入查询的相关性和一致性。
这种评估方式不区分检索和生成模块,而是把整个系统当作一个黑盒,直接评估最终输出的质量。
📝 通俗解释:就像家长只看孩子期末考试的总成绩,不关心他平时听课和作业分别得了多少分。端到端评估只看最终答案好不好,不管中间过程。
3.2.2 端到端评估的模块
1. 无标签的内容评估
不需要人工标注的答案标签,直接评估生成内容的质量:
- 答案的准确性:答案是否正确
- 答案的相关性:答案是否针对问题
- 答案的无害性:答案是否包含有害内容
2. 有标签的内容评估
需要人工标注或预设标准答案:
- 准确率 (Accuracy):正确回答的问题占总问题的比例
- 精确匹配 (EM):答案与标准答案完全匹配的比例
📝 通俗解释:无标签评估就像让老师直接读学生的作文,看写得怎么样(但没有标准答案)。有标签评估就像传统考试,有标准答案可以对照打分。
四、RAG 有哪些关键指标和能力?
评估 RAG 在不同下游任务和不同检索器中的应用可能会得到不同的结果。然而,一些学术和工程实践已经开始关注 RAG 的通用评估指标和有效运用所需的能力。
4.1 关键指标
RAG 评估主要集中于三个核心指标:
| 指标 | 说明 |
|---|---|
| 答案准确性 | 生成答案的正确程度 |
| 答案相关性 | 答案与问题的相关程度 |
| 上下文相关性 | 检索到的内容与问题的相关程度 |
📝 通俗解释:这三个指标就像考试的三个评分维度:答题对不对(准确性)、有没有答非所问(相关性)、有没有翻错资料(上下文相关性)。三个都高分才是好学生。
4.2 关键能力
RGB 的研究分析了不同大语言模型在处理 RAG 所需的四项基本能力方面的表现:
| 能力 | 说明 |
|---|---|
| 抗噪声能力 | 能否从包含干扰信息的上下文中提取正确信息 |
| 拒绝无效回答能力 | 当检索到的内容不足以回答问题时,能否拒绝回答 |
| 信息综合能力 | 能否整合多个检索到的文档内容生成完整答案 |
| 反事实稳健性 | 能否识别并忽略与事实不符的上下文信息 |
这些能力为检索增强型生成设立了标准,帮助我们更全面地评估 RAG 系统的表现。
📝 通俗解释:这就像考察一个学生的四种"超能力":
- 抗噪声:在嘈杂的教室(有很多无关信息)里还能专注听课
- 拒绝无效回答:不会的问题敢说"我不知道"
- 信息综合:能把课本多章的内容整合成完整答案
- 反事实稳健性:发现题目有错误时会质疑,而不是跟着错
五、RAG 有哪些评估框架?
在 RAG 评估框架领域,RAGAS 和 ARES 是较新的方法。
📝 通俗解释:这两个框架就像两套不同的"考试系统",可以自动帮我们评估RAG系统的表现,不需要人工逐个检查答案。
5.1 RAGAS
介绍
RAGAS(Retrieval-Augmented Generation Assessment)是一个基于简单手写提示的评估框架,通过这些提示全自动地衡量答案的准确性、相关性和上下文相关性。
算法原理
答案忠实度评估:
- 利用大语言模型 (LLM) 分解答案为多个陈述
- 检验每个陈述与上下文的一致性
- 最终,根据支持的陈述数量与总陈述数量的比例,计算出一个"忠实度得分"
答案相关性评估:
- 使用大语言模型 (LLM) 基于答案创造可能的问题
- 分析这些问题与原始问题的相似度
- 答案相关性得分是通过计算所有生成问题与原始问题相似度的平均值来得出的
上下文相关性评估:
- 运用大语言模型 (LLM) 筛选出直接与问题相关的句子
- 以这些句子占上下文总句子数量的比例来确定上下文相关性得分
📝 通俗解释:RAGAS就像一个智能阅卷老师。它用三个"绝招":
- 第一招:把学生答案拆成小句子,检查每个是否能在参考资料里找到(忠实度)
- 第二招:根据答案反向出题,看跟原题像不像(相关性)
- 第三招:检查参考资料里有多少是真正有用的(上下文相关性)
5.2 ARES
介绍
ARES(Automated Evaluation of Retrieval-Augmented Generation Systems)的目标是自动化评价 RAG 系统在上下文相关性、答案忠实度和答案相关性三个方面的性能。
ARES 减少了评估成本,通过使用少量的手动标注数据和合成数据,并应用预测驱动推理 (PDR) 提供统计置信区间,提高了评估的准确性。
算法原理
生成合成数据集:ARES 首先使用语言模型从目标语料库中的文档生成合成问题和答案,创建正负两种样本。
训练大语言模型 (LLM) 裁判:然后,ARES 对轻量级语言模型进行微调,利用合成数据集训练它们以评估上下文相关性、答案忠实度和答案相关性。
基于置信区间对 RAG 系统排名:最后,ARES 使用这些裁判模型为 RAG 系统打分,并结合手动标注的验证集,采用 PPI (Prediction Interval) 方法生成置信区间,从而可靠地评估 RAG 系统的性能。
📝 通俗解释:ARES就像一个更"聪明"的考试系统。它有三个步骤:
- 第一步:用AI生成一些"模拟试卷"
- 第二步:训练一个"AI裁判"来打分
- 第三步:用统计方法给出"置信区间",就像说"这个学生成绩在85-90分之间",而不是只有一个笼统的分数
致谢
感谢 AiGC面试宝典 提供的内容支持。
整理日期:2024年