Anna:Lewis,传统机器学习模型的评估相对直接。例如,分类器或目标检测系统都有明确的对错标准。但 RAG 系统不一样,如果客户问它的表现到底怎么样,我很难给出一个确定答案。
Lewis:确实如此。RAG 系统的评估方式与传统机器学习模型不同。传统模型评估通常依赖清晰的量化指标,例如分类准确率、目标检测精度、Gini 系数、R-squared、F1 score、confusion matrix 等。相比之下,评估 RAG 系统需要分别评估它的两个核心组件:retriever 和 generator。这不仅涉及检索内容相关性的评估,还涉及生成答案是否满足用户需求。
图 9.1:Lewis 和 Anna 关于 RAG 系统的对话。
retriever 的目标是找到最相关的文档。虽然 retriever 的评估,也称为 retrieval evaluation,带有一定主观因素,但我们仍然可以使用信息检索领域中的一些指标进行衡量,例如 Precision、Recall 和排名准确性。
Anna:这个还比较容易理解。那么 generator 怎么评估呢?
Lewis:generator 的评估,也称为 response evaluation,实际上是对 RAG 系统最终交付结果的整体评估,会更复杂。它不仅要检查生成答案是否有事实依据,也就是是否与上下文相关,还要看它是否有效回答了用户问题,也就是 query relevance;同时还要看答案是否流畅、安全,并且符合人类价值观。为了评估生成质量,我们会结合定量指标,例如 BLEU 或 ROUGE,以及定性指标,例如答案相关性、语义一致性、上下文契合度、鲁棒性和忠实度。此外,由于这些因素非常复杂,在整个评估过程中也需要人工主观评估辅助。
retrieval evaluation 和 response evaluation 结合起来,就构成了 RAG 系统的评估框架。
图 9.2:系统评估流程图。
RAG 系统的评估体系
Anna:既然 RAG 系统评估复杂得多,而且还涉及很多主观因素,那我们在项目落地时应该从哪里开始?
Lewis:如果条件允许,我建议你和客户一起,基于一部分最常用、最熟悉的文档,收集一些典型问题和标准答案。以此作为起点,先建立一个双方都认可的高质量评估数据集。
RAG 的评估数据集
建立评估数据集至关重要。在缺乏统一评估标准的情况下,开发团队和业务团队在讨论问答系统准确率时,可能各说各话。评估数据集的完整性和多样性,直接影响 RAG 系统评估过程的准确性和可靠性。一个高质量数据集应该包含丰富且全面的问题,以及来源可靠、并经业务团队或客户验证过的答案。
图 9.3:一张表格展示评估数据集,其中包含 queries、answers 和 sources 列。
评估数据集包括问题、标准答案,以及标准答案所在源文档和页码信息。基于这些材料,可以建立一系列评估指标,检查系统是否能够准确检索到标准答案。当然,评估数据集的具体格式应根据实际项目需求确定。示例中的数据集之所以包含 page 标签,是因为该项目中的文档主要是 PDF 或 Word / WPS 格式。如果项目文档是 Markdown 或网页格式,那么 page 字段可能并不适用。
Alex:Lewis,从零开始构建数据集非常消耗资源。这个数据集应该多大?
Lewis:从零开始构建数据集确实需要大量资源。用于初步测试时,可以先创建大约 200 条 Q&A 记录。随着项目推进,再逐步积累更多内容。
不同 RAG 系统的评估数据集格式可能不同。有时存在一个精确且唯一的数据源,有时答案可能来自多个页面或多个文档。因此,在项目实施时需要灵活处理这些差异。
Retrieval evaluation 和 response evaluation
Retrieval evaluation 和 response evaluation 是 RAG 系统评估框架的两个核心组成部分。我们来详细看一下:
Retrieval evaluation 关注模型在查询过程中是否能够检索到准确且相关的上下文。它评估系统从知识库或外部资源中找到的内容,是否与用户查询紧密相关,并且能够有效支持后续生成。retrieval evaluation 的关键指标包括 context relevance、retrieval precision 和 recall。retrieval evaluation 通常更强调评估 embedding model,也就是 retriever 的核心组件的质量。
Response evaluation 则关注模型基于检索内容生成答案的质量。它的目标是确保生成内容不仅与用户查询相关,而且忠实于提供的上下文信息。response evaluation 通常会检查生成答案是否准确、是否包含“幻觉”、是否与上下文一致。response evaluation 的关键指标包括 answer relevance 和 faithfulness,这些指标可以帮助团队更好地判断生成答案是否符合预期。response evaluation 通常更强调评估 generative model,也就是 generator 的核心组件水平。
当评估数据集可用时,也就是有些问题已经标注了标准答案和来源,对于 retrieval evaluation,可以使用 precision 和 recall 等更精确的量化指标;而对于 response evaluation,通常很难用具体分数量化答案质量,主观因素所占比例相对更大。
RAG TRIAD:整体评估
目前,有一种评估方法是评估 Retrieval-Augmented Generation,RAG,整个流程的整体效果。该方法被称为 RAG TRIAD 框架。
图 9.4:流程图展示 query、context 和 response 之间的关系。
在 RAG TRIAD 框架中,评估聚焦于三个核心方面:query、context 和 response。这三个方面通过以下三个关键评估指标衡量:
Contextual relevancy:这是 retrieval evaluation 的指标,主要评估 retriever 返回的文本块是否与用户 query 相关,并且是否有助于生成理想答案。这涉及 block size、Top-K 值和 embedding model 等超参数选择。高效的 embedding model 可以确保检索到的文本块与用户 query 在语义上相似,而合适的 block size 和 Top-K 组合,则有助于从知识库中选出最关键的信息。
Faithfulness:这是 response evaluation 中的关键指标,用于衡量生成答案是否基于提供的上下文,也就是答案是否有事实依据,是否不包含“幻觉”。该指标通常与模型选择密切相关。如果当前模型无法基于检索上下文生成准确答案,可能就需要更换模型或对模型进行微调。
Answer relevancy:这同样是 response evaluation 指标,关注生成答案与用户 query 的相关程度。随着模型推理能力提升,该指标越来越依赖检索结果质量,而不是模型本身能力。如果分数较低,可能需要改进检索过程,或者优化 prompts,以增强模型生成更相关答案的能力。
RAG TRIAD 框架提供了一套无参考评估体系。即使没有现成评估数据集,仍然可以从上述三个方面评估 RAG 系统输出。因此,这套评估体系具备一定通用性和灵活性。每个指标都对应 RAG 流程中的特定组件或超参数设置。如果一个 RAG 系统在这三方面得分都很高,就说明其组件或超参数设置较为合适;否则,就需要进一步调整和优化。
这种无参考评估体系省去了创建评估数据集的麻烦,但同时也意味着评估指标本身具有一定不确定性。因此,RAG 系统的最终表现不应只依赖这些评估指标,还需要业务团队和最终用户进行实际确认。
Retrieval evaluation 指标
Retrieval evaluation 对 RAG 系统至关重要,因为它直接影响 generator 所采用上下文的质量,进而间接影响最终生成响应的相关性和准确性。
MTEB 为评估文本 embedding models 提供了一个综合 benchmarking 平台,覆盖文本相似度、文本分类和检索等任务。MTEB 可以有效衡量文本 embedding model 在多种任务上的表现。因此,MTEB 被视为评估检索过程中使用的 embedding models 的一种方式,适合本地任务评估。
不过,在实际 RAG 项目中,retrieval evaluation 并不局限于直接评估 embedding model,而是更广泛地面向整个 retriever 组件,评估它是否能够有效识别并优先返回最相关文档。这个过程不仅依赖 embedding model 的质量,也会受到 chunking strategy 和 indexing strategy 等因素影响。
Retrieval evaluation 主要使用 precision、recall、Mean Reciprocal Rank,MRR,以及 Mean Average Precision,MAP 等指标。在介绍这些指标之前,需要注意,retriever 检索到的文本 chunks 通常不是单个,而是一个或多个,这是一个可配置参数。此外,与某个具体 query 相关的上下文文本 chunks 往往也不止一个,所有相关文本 chunks 都应该列入评估数据集中。
Precision
Precision 衡量检索到的文本块中有多少与 query 相关,也就是所有检索到的文本块中,相关文本块所占比例。Precision 试图回答的问题是:“在所有被检索出来的文本块中,有多少是真正相关的?”
Precision 的计算公式如下:
图 9.5:公式展示 precision 等于找到的相关文本数除以找到的全部文本数。
假设一个科学文献信息检索系统返回 15 个文本块,其中 12 个与 query 直接相关,那么 precision 就是 80%。高 precision 意味着学习者可以更快获得所需信息,而不会被无关文本块干扰。
Lewis 的提示
“在评估数据集中,如果系统能够找到相关的‘text chunks’,就可以认为检索成功。
不过,根据任务不同,我们可能还需要定位到具体页面、段落、句子,甚至原始文档。”
高 precision 也意味着检索内容更加准确,能够有效减少不必要的信息展示。在医学和法律等领域,这一指标尤其重要,因为高 precision 可以有效防止误导性信息传播。
Recall
Recall 衡量系统检索相关文本块的全面程度,也就是系统检索出的相关文本块数量,占数据库中所有相关文本块数量的比例。Recall 试图回答的问题是:在所有相关文本块中,系统成功检索到了多少?
Recall 的计算公式如下:
图 9.6:召回率公式,展示检索到的相关文档与全部相关文档之间的比例。
假设在一个法律文档检索系统中,数据库里有 50 份与 query topic 相关的文档,而系统成功检索出其中 40 份。那么 recall 就是 80%。在科学研究中,高 recall 可以确保研究人员不会遗漏关键参考资料。
高 recall 对避免遗漏关键信息非常重要。如果 recall 较低,模型可能因为缺失关键信息而生成不完整答案,或者产生错误。例如,在法律文档检索中,遗漏相关信息可能影响案件分析的完整性。
F1 score
在 RAG 系统中,提高 precision 往往会导致 recall 下降,反之亦然。因此,为了获得最佳检索表现,通常需要在 precision 和 recall 之间找到平衡。这个平衡通常通过 F1 score 量化,它是 precision 和 recall 的调和平均值,用于找到适合具体应用需求的最佳点。
F1 score 的计算公式如下:
图 9.7:F1 score 公式,展示 precision 和 recall 的调和平均值。
Mean reciprocal rank
Mean Reciprocal Rank,MRR,是检索系统效率的评估指标,特别关注第一个相关文本 chunk 的排名。MRR 帮助我们判断一个 RAG 系统能否快速返回第一个相关文本 chunk,其值会直接影响用户体验。MRR 值越高,系统越能够快速找到第一个合适答案。
MRR 的计算公式如下:
图 9.8:MRR 数学公式,展示对 Q 个 queries 的 inverse rank 求平均。
其中,Q 表示 query 总数。rankq 表示第 q 个 query 的第一个相关文本 chunk 的位置。公式要求取第一个相关文本 chunk 排名的倒数,也就是说,MRR 只考虑每个 query 返回的第一个相关文本 chunk 的位置。在这种计算方式下,文本 chunk 排名越高,rankq 的倒数越大,因此 MRR 越大。
MRR 在问答系统或信息检索系统中特别重要,因为它关注快速获得第一个相关答案的能力。例如,在客服问答系统中,如果用户提出问题后,系统能在前 3 个结果中选出并回复答案,那么 MRR 值就会相对较高,说明系统在响应用户需求方面速度和准确性更强。
Mean average precision
Mean Average Precision,MAP,是跨多个 queries 评估的 precision 指标。它不仅考虑检索结果的 precision,也强调文档排名的重要性。MAP 通过计算每个 query 在各个排名位置上的 precision 来评估检索效果,确保重要相关文档排在更靠前的位置,从而优化用户搜索体验。
MAP 的计算公式如下:
图 9.9:MAP 数学公式,展示它等于 Q 个 queries 的 Average Precision 的平均值。
这里,Q 表示 query 总数。Average Precision 是针对每个 query 计算的平均 precision,它会考虑相关文档的顺序。
MAP 对于排名质量重要的系统非常有用,例如搜索引擎,也常用于电商平台的产品推荐系统。
P@K
P@K 衡量前 K 个检索结果的 precision,确保展示在最前面的几个结果中包含尽可能多的相关信息。
图 9.10:P@K 数学公式,展示 top K 结果中的相关文档数除以 K。
这里,分子表示 Top K 结果中的相关文档数量,分母中的 K 是固定返回数量。
P@K 在用户特别关注前几个结果的场景中非常有用。例如,在新闻搜索系统中,P@K 可以确保检索出的前几条新闻与 query topic 高度相关,从而提升阅读效率。
Document precision、page precision 和 positional document precision
成功检索相关文本块并不是唯一标准。在某些项目中,我们需要一些不同评估视角。例如,有时除了文本块之外,我们还关心课程和页面的定位,以及它们在检索结果中的相对位置。相关评估指标如下:
Document precision:该指标评估系统是否找到了包含答案的整门课程。它主要关注课程级准确性,也就是是否找到正确课程,但不关心课程中特定页面的准确性。
Page precision:该指标关注系统是否找到了课程中包含答案的正确页面。
Positional document precision:该指标根据课程在检索结果中的位置,为课程分配不同权重。课程出现得越早,权重越高。它通过应用惩罚因子,例如 -1.1,降低排名靠后课程的得分,确保更早出现的课程获得更高分。最终分数会被归一化到 [0, 1] 范围内。
注意
前面介绍的指标,例如 precision、MRR 等,都直接作用于具体文本块;而 Document Precision、Page Precision 和 Positional Document Precision 则面向文本块所在的具体课程和页面。这些属于文本块的 metadata。为什么要关注这些 metadata 的准确性?
在某些情况下,只识别出相关课程或页面就足够了,尤其是当大模型能够基于长上下文生成答案时。我们可以通过文本块定位到某门课程或某一页,然后把整门课程或整页传给大模型。
查看系统实际检索出的文本块和页面,在 Top 5 检索结果中,虽然没有文本块匹配预期答案,但有一个相关页面,也就是 page 23,满足要求。所有预期课程都被命中。因此,Document Precision 达到 100%,而 Page Precision 为 33.3%,因为三个预期页面中只找到一个。
图 9.11:流程图展示 expected 和 found 的 documents 与 pages,并计算准确率。
Alex:Lewis,这个例子和检索结果说明了什么?
Lewis:如上所示,系统已经找到了两个包含答案的文档,也就是 100% expected document hit rate,但由于没有识别出所有关键页面,答案准确性可能受到影响。换句话说,如果项目目标是从大量 PDF 文件中检索相关文档,那么系统表现已经相当不错。但如果要求精确定位具体文本内容,系统表现仍然需要明显提升。
从文本生成角度看,如果我们只依赖检索到的文本块来生成答案,信息可能不够准确。不过,如果我们考虑这些文本块所属的页面,甚至整个文档,那么生成文本可能包含部分甚至全部关键信息。还记得我们在第 6.1 节讨论过的父子文本块检索策略吗?从这个角度看,这次检索可以认为是成功的。
Alex:我明白了!
Positional document precision
Positional document precision 进一步细化了评估指标,它会考虑文档在检索结果中的位置,强调越早出现在结果中的文档越有价值。
图 9.12:图示展示文档来源、带分数归一化的文本块,以及准确率计算。
要计算 positional document precision,应首先记录每个文本块的相关信息和分数。在每个位置,如果找到了正确文本块,则加 0.5 分;如果没有找到,则使用一个随时间变化的负值向量作为惩罚因子。这意味着参考答案出现得越晚,对整体分数的惩罚越大。
Response evaluation 指标
Response evaluation 关注 RAG 系统中的 generator 组件。它在评估大模型输出的准确性、连贯性和可靠性方面发挥重要作用。Response evaluation 指标通常可以分为三大类:基于 n-gram overlap 的指标、基于 semantic similarity 的指标,以及基于 faithfulness 或 factuality 的指标。
基于 n-gram overlap 的指标
这类指标包括 BLEU、ROUGE 和 METEOR,它们通过计算生成答案与参考答案之间的相似度来衡量生成响应质量,重点关注词语和短语的重叠。我们来详细看一下:
BLEU:Bilingual Evaluation Understudy,即 BLEU,用于评估生成响应与参考答案之间的 n-gram overlap,强调 precision。它通过精确的 n-gram 匹配计算分数,也就是连续 n 个 tokens 构成的序列,其中 n 可以是 1、2、3、4 等。
BLEU 的公式如下:
图 9.13:BLEU score 数学公式:BLEU 等于 BP 乘以加权 log precision 求和的指数。
这里,BP 是 Brevity Penalty,用于防止生成响应过短。如果生成响应比参考答案短,那么 BP 小于 1;否则,BP 等于 1。Pn 是 n-gram precision。wn 是每个 n-gram 的权重,通常 w1、w2、w3 和 w4 的值相等。
例如,假设参考答案是 “the cat is on mat”,生成响应是 “the cat on mat”。
对于 BLEU-1,也就是 1-gram precision,匹配的 1-gram,也就是词,包括 “the”“cat”“on”和“mat”,共 4 个。生成响应中有 4 个 1-grams。因此,1-gram precision 为 1。
对于 BLEU-2,也就是 2-gram precision,匹配的 2-gram,也就是连续两个词,包括 “the cat” 和 “on mat”,共 2 个。生成响应中有 3 个 2-grams。因此,2-gram precision 是 2/3,约为 0.67。
对于 BP,参考答案包含 5 个词,而生成响应包含 4 个词。因此会应用一个小于 1 的 BP 来降低分数。
在这个例子中,虽然生成响应缺少 “is” 这个词,但由于它包含了参考答案中的大多数词和短语,并且长度相近,因此 BLEU 分数仍会相对较高。
BLEU 简单直观,常用于评估机器翻译等答案清晰明确的任务质量。不过,它的局限在于无法捕捉语义相似性。
ROUGE:Recall-Oriented Understudy for Gisting Evaluation,即 ROUGE,用于计算生成答案与参考答案之间的 n-gram overlap,同时考虑 precision 和 recall,以提供相对平衡的评估。
ROUGE 的公式如下:
图 9.14:ROUGE-N 公式,展示 n-gram overlap 除以总 n-grams。
继续前面的例子,假设参考答案是 “the cat is on mat”,生成答案是 “the cat on mat”。
对于 ROUGE-1,即 1-gram,匹配包括 “the”“cat”“on”和“mat”,共 4 个。参考答案中有 5 个 1-grams。因此,ROUGE-1 是 0.8。
对于 ROUGE-2,即 2-gram,匹配包括 “the cat” 和 “on mat”,共 2 个。参考答案中有 4 个 2-grams。因此,ROUGE-2 是 0.5。
ROUGE 常用于自动摘要生成等任务评估,因为它可以有效衡量生成文本是否保留了原文关键信息。不过,它的局限是过度依赖词汇层面的匹配,缺少对语义相似度的考虑。
METEOR:Metric for Evaluation of Translation with Explicit Ordering,即 METEOR,会通过考虑同义词、词干和词序等因素,更细致地评估生成响应与参考答案之间的相似度。它不仅计算 precision 和 recall 的调和平均值,也就是 F mean,还引入惩罚机制来处理词序错误和其他不匹配问题。相比 BLEU 和 ROUGE,METEOR 能更好捕捉语义特征。
METEOR 的计算公式如下:
METEOR = F mean × (1 - P penalty)
这里,F mean 是 precision 和 recall 的调和平均值,用于综合衡量生成响应与参考答案的匹配程度。P penalty 是惩罚项,用于惩罚词序错误和其他类型错误。
这里我们仍然假设参考答案是 “the cat is on mat”,生成响应是 “the cat on mat”。
对于 precision,生成响应包含 4 个词,全部匹配,因此 precision 是 1。
对于 recall,参考答案包含 5 个词,其中 4 个匹配,因此 recall 是 0.8。
对于调和平均值:
图 9.15:数学公式展示 F mean 等于 2 × 1 × 0.8 / (1 + 0.8) = 0.89。
至于惩罚项,由于生成响应缺少 “is”,METEOR 会应用一个惩罚项 P penalty。该惩罚项的具体值取决于实现细节,但在这个例子中,可以假设为 0.1。
最终,METEOR 是 0.801。
在这个例子中,METEOR 比 BLEU-2 和 ROUGE-2 更宽容,因为它允许生成响应中缺少词。事实上,METEOR 也容忍轻微词序变化,并考虑同义词或词形变化。这使 METEOR 在评估需要更高语义理解的任务时特别有用。尤其是在翻译质量评估中,当生成译文与参考译文词序不同但语义接近时,METEOR 仍可以给出相对较高分数。
Alex:我理解 METEOR 更关注 semantic similarity,但我还是不太清楚 BLEU 和 ROUGE 的关键区别。
Lewis:BLEU 主要关注 precision,也就是评估生成内容中有多少能在参考文本中找到。它通过计算生成文本和参考文本之间的 n-gram 匹配来实现,强调生成输出中正确匹配的比例。BLEU 最初是为评估机器翻译质量设计的,通过比较机器译文和参考译文之间的 n-gram overlap 来衡量翻译质量。
相比之下,ROUGE 更关注 recall,也就是考虑参考文本中的内容有多少被生成文本覆盖。虽然 ROUGE 也涉及 n-gram matching,但它的核心是评估生成文本是否覆盖了参考文本中的关键信息。因此,ROUGE 更常用于摘要或文档抽取等任务。
在机器翻译领域,我们倾向于追求较高 BLEU 分数,因为这表示机器翻译输出与人工翻译之间具有较高相似度。此外,由于 ROUGE 强调 recall,它更适合摘要或文档抽取等文本生成任务。在这些场景中,我们希望生成文本尽可能包含参考文本中的重要信息,而不是严格匹配参考文本的措辞。
基于 semantic similarity 的指标
基于 embeddings 和 semantic similarity 的评估方法不依赖词汇匹配。相反,它们会将生成响应和参考答案转换成向量,并使用 cosine similarity 等方法计算生成内容与参考答案之间的语义相似度。
下面,我们回顾一些熟悉的概念:
Cosine similarity:Cosine similarity 用于衡量生成响应 embedding 与参考答案 embedding 之间的角度相似性,从而评估二者语义接近程度。计算公式如下。
图 9.16:Cosine similarity 数学公式,展示点积除以模长乘积。
虽然单独使用时可能不够准确,但在多个样本上取平均,可以粗略估计生成答案质量。
假设生成响应的 embedding 为 A = [1,0,1],参考答案的 embedding 为 B = [1,1,0],那么 cosine similarity 是:
图 9.17:数学公式展示使用向量计算 cosine similarity,结果等于 0.5。
这表明生成响应与参考答案存在一定相似度。
Euclidean distance:Euclidean distance 用于衡量两个向量之间的直线距离;值越小,二者相似度越高。其计算公式如下。
图 9.18:Euclidean distance 数学公式,展示平方差求和后开方。
再次假设生成答案 embedding A = [1,0,1],参考答案 embedding B = [1,1,0],那么 Euclidean distance 是:
图 9.19:数学公式展示距离公式计算,结果为 √2,约等于 1.41。
这表明生成答案和参考答案之间的相似度相对较低。
在答案生成任务中,cosine similarity 通常被认为是更准确的语义相似度指标,因为它关注向量方向上的相似性,更能反映语义一致性。不过,在推荐系统中,Euclidean distance 可能更适用。
Alex:这些知识我们已经比较熟悉了。这里的要点是,当 RAG 系统生成最终结果后,我们可以使用 semantic similarity score 来评估生成答案。分数越高,表示生成答案和参考答案越相似。
基于 faithfulness 或 groundedness 的指标
在大模型评估中,BLEU、ROUGE、METEOR 和基于 semantic similarity 的指标,经常用于衡量答案相关性。也就是说,大模型生成的响应是否与用户 query 相关,并提供了有用信息。然而,相关性并不等于准确性。即使一个答案在语义上与 query 对齐,也可能包含幻觉错误或理解错误,如下图所示:
图 9.20:对比图展示关于角色称谓的视觉错误和理解错误。
这类幻觉错误对于普通用户尤其危险,因为如果用户不熟悉某个领域,就可能无法识别生成响应中的不准确之处。相比之下,由明显逻辑混乱造成的理解错误,虽然也是一种模型失败,但通常更容易被发现。与准确性相关的指标更难量化,因为它们往往涉及看似合理但实际错误的答案。因此,在设计具体评估规则时,需要更多智慧和考虑。
Alex:确实,即使是 DeepSeek-R1 这样强大的模型,在专业领域也会犯错。尤其是生成响应中的细节看起来合理时,非专家很难发现错误。这可能误导初学者或领域外人士,造成深远后果。
Lewis:为了解决这个问题,我们引入了 faithfulness 或 groundedness 作为新的评估标准。这些标准关注衡量生成响应是否基于检索文档,是否准确且无误,确保提供的信息不仅相关,而且真实可靠。
为了更好地量化 faithfulness,可以使用以下指标进行评估:
Document accuracy 和 page accuracy:这些指标用于衡量大模型引用的文档和具体页面是否准确。这要求大模型在生成答案时明确标注来源,以减少编造信息的发生。
Hallucination detection / consistency check:这些指标旨在判断大模型生成响应是否基于提供的上下文信息,或者不同 query 中给出的事实信息是否一致。在评估过程中,采用二元评估,也就是 0/1。如果生成响应无法从给定文档中推导出来,即便答案本身正确,也仍然被视为幻觉。
Large model scoring scale:使用更强大的大模型为生成响应打分,例如采用 0 到 5 分评分制。具体评分标准可以根据业务要求自定义,以更灵活地适应不同应用场景。
Human evaluation:领域专家人工检查大模型生成响应是否准确,并验证其是否合理引用了检索文档。
Faithfulness 的评估涉及对大模型输出逻辑推理能力的严格检查。例如,即使某个生成响应是正确的,如果它无法从提供文档中推导出来,也应该被视为幻觉。因此,需要设计专门评估流程来处理这些问题,包括要求大模型以可解析格式引用来源,确保生成答案具备明确文献支持,并进行严格上下文一致性检查,以确保大模型不会针对不同 query 给出相互矛盾的答案。
解决幻觉问题的一种方式,是合理控制信息量。虽然提供更多上下文可能有助于提升评估指标,但过多信息可能降低大模型响应质量,并增加幻觉概率。
RAG 系统评估框架
Alex:前面提到的那些指标,不会都要我们手动实现吧?
Lewis:截至目前,仍然没有一种通用且被广泛认可的 RAG 框架,可以实现上面介绍的所有指标。因此,我们需要实验性地尝试不同 RAG 评估框架,例如 Retrieval Augmented Generation Assessment Suite,RAGAS、TruLens 和 DeepEval。这些框架的采用程度和使用场景差异很大。如果某个具体框架无法满足项目需求,你可能需要组合多个框架,确实也可能需要手动添加自己的评估指标。
使用 RAGAS 评估 RAG 系统
在各种评估 RAG 系统的框架中,RAGAS 目前是开发者中比较受欢迎的选择之一。RAGAS 提供一组客观评估指标,专门用于衡量大模型应用表现,适用于多种场景,包括 RAG 和 Agentic workflows,以确保其输出质量、准确性和一致性。
对于 RAG 系统,RAGAS 评估指标主要分为两类:retrieval-related metrics 和 generation-related metrics。
RAGAS 支持的主要 retrieval-related metrics 如下:
Context precision:衡量检索文档与 query 的相关性。
Context recall:评估检索文档是否全面覆盖回答问题所需信息。
Context entity recall:关注检索过程中召回实体的能力,例如人名、地名、技术术语。这对于需要高度准确实体匹配的任务尤其重要,例如医学、法律或金融领域查询。
Noise sensitivity:检测大模型对检索结果中无关信息的抗干扰能力。
RAGAS 支持的主要 generation-related metrics 如下:
Answer relevancy:衡量生成答案是否直接且准确地回应用户 query,避免答非所问。
Faithfulness:衡量生成答案是否基于检索事实,以避免幻觉。高 faithfulness 的大模型能够确保答案基于可验证知识,而不是编造内容。
Multimodal faithfulness:适用于文本-图像或文本-音频等多模态场景,确保不同模态之间的信息一致性。
Multimodal relevancy:衡量模型在多模态任务中输出内容是否满足用户需求。例如,大模型生成的音频是否恰当地传达了文本描述中的情绪。
下面的代码示例演示如何使用 RAGAS 进行评估。注意,该示例使用英文数据,因为实际操作中发现,有些指标还不支持中文。
首先,导入必要库并配置相关设置:
import numpy as np
from datasets import Dataset
from ragas.metrics import Faithfulness, AnswerRelevancy
from ragas.llms import LangchainLLMWrapper
from ragas.embeddings import LangchainEmbeddingsWrapper
from langchain_openai import OpenAIEmbeddings
from ragas.embeddings import HuggingfaceEmbeddings
from langchain_deepseek import ChatDeepSeek
from ragas import evaluate
### 准备用于评估的大模型
llm = LangchainLLMWrapper(ChatDeepSeek(model="deepseek-chat"))
使用 RAGAS 评估时,需要一个详细数据集,包括 questions、contexts 和 reference answers。这种评估方式可以更全面地分析 RAG 系统表现,但准备工作量相对较大:
data = {
"question": [
"Who is the main character in Black Myth: Wukong?",
"What are the special features of the combat system in Black Myth: Wukong?",
"How is the visual quality of Black Myth: Wukong?",
],
"answer": [
"""The main character in Black Myth: Wukong is Sun Wukong, based on the Chinese classic ‘Journey to the West’ but with a new interpretation. This version of Sun Wukong is more mature and brooding, showing a different personality from the traditional character.""",
"""Black Myth: Wukong’s combat system combines Chinese martial arts with Soulslike game features, including light and heavy attack combinations, technique transformations, and magic systems. Notably, Wukong can transform between different weapon forms during combat, such as his iconic staff and nunchucks, and use various mystical abilities.""",
"""Black Myth: Wukong is developed using Unreal Engine 5, showcasing stunning visual quality. The game’s scene modeling, lighting effects, and character details are all top-tier, particularly in its detailed recreation of traditional Chinese architecture and mythological settings.""",
],
"contexts": [
[
"Black Myth: Wukong is an action RPG developed by Game Science, featuring Sun Wukong as the protagonist based on ‘Journey to the West’ but with innovative interpretations. In the game, Wukong has a more composed personality and carries a special mission.",
"The game is set in a mythological world, telling a new story that presents a different take on the source material."
],
[
"Combat in Black Myth: Wukong is notable for its fluid martial arts action inspired by Chinese traditions. In addition to standard attacks, players can unleash magic powers and perform shape-shifting transformations that offer new tactics in battle.",
"Players can wield the protagonist’s iconic staff, use weapons like nunchucks, and access abilities reminiscent of the original legend, creating a rich and varied fighting system."
],
[
"Powered by Unreal Engine 5, Black Myth: Wukong offers extraordinary realism in environments, character models, and animation quality.",
"Lighting, physics, and atmospheric effects enhance the authenticity of ancient Chinese landscapes and fantastical creatures within the game."
]
]
}
游戏战斗系统深受 Soulslike 游戏影响,同时融合了中国传统武术元素。玩家可以使用不同武器形态,包括标志性的长棍和其他可变形武器。
在战斗中,玩家可以释放各种神秘能力,并结合轻重攻击和连招系统,形成流畅且独特的战斗体验。游戏还具备独特的变身系统。
《黑神话:悟空》展现了出色视觉质量,基于 Unreal Engine 5 构建,实现了极高画面保真度。游戏环境和角色模型都经过精细打磨。
光照效果、材质渲染和环境细节均达到 AAA 级标准,完美捕捉了东方神话世界的氛围。
接下来,可以评估生成答案是否忠实于给定上下文,如下面代码片段所示。先将生成答案拆分为简单 statements,然后验证每个 statement 是否可以从上下文中推断出来。faithfulness 指标需要指定用于评估的大语言模型,但不需要指定 embedding model。
完整代码可参考 github.com/PacktPublis…
### 评估 Faithfulness
faithfulness_metric = [Faithfulness(llm=llm)]
print("\nEvaluating faithfulness......")
faithfulness_result = evaluate(dataset, faithfulness_metric)
scores = faithfulness_result['faithfulness']
mean_score = np.mean(scores) if isinstance(scores, (list, np.ndarray)) else scores
print(f"Faithfulness score: {mean_score:.4f}")
预期输出:
Evaluating faithfulness......Evaluating: 100%|███████████████| 3/3 [00:06<00:00, 2.03s/it]
Faithfulness score: 0.6111
接下来,我们评估 answer relevancy。它会使用 embedding models 计算 semantic similarity,并比较开源 embedding models 与 OpenAI embedding models。完整代码可参考 github.com/PacktPublis…
### 设置两种 Embedding Models
opensource_embedding = LangchainEmbeddingsWrapper(
HuggingfaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
)
openai_embedding = LangchainEmbeddingsWrapper(
OpenAIEmbeddings(model="text-embedding-3-small")
)
### 创建 Answer Relevancy 评估指标
opensource_relevancy = [
AnswerRelevancy(llm=llm, embeddings=opensource_embedding)
]
openai_relevancy = [
AnswerRelevancy(llm=llm, embeddings=openai_embedding)
]
print("\nEvaluating answer relevancy......")
print("\nEvaluating with open-source embedding model:")
opensource_result = evaluate(dataset, opensource_relevancy)
scores = opensource_result['answer_relevancy']
opensource_mean = (
np.mean(scores) if isinstance(scores, (list, np.ndarray)) else scores
)
print(f"Relevancy score: {opensource_mean:.4f}")
print("\nEvaluating with OpenAI embedding model:")
openai_result = evaluate(dataset, openai_relevancy)
scores = openai_result['answer_relevancy']
openai_mean = (
np.mean(scores) if isinstance(scores, (list, np.ndarray)) else scores
)
print(f"Relevancy score: {openai_mean:.4f}")
## 比较两种 Embedding Models 的结果
print("\n=== Embedding Model Comparison ===")
diff = openai_mean - opensource_mean
print(f"Open-source embedding model score: {opensource_mean:.4f}")
print(f"OpenAI embedding model score: {openai_mean:.4f}")
print(
f"Difference: {diff:.4f} "
f"({'OpenAI is better' if diff > 0 else 'Open-source embedding model is better' if diff < 0 else 'Comparable'})"
)
预期输出:
Evaluating answer relevance......
Using open-source embedding model for evaluation:
Evaluating: 100%|████████████████████| 3/3 [00:02<00:00, 1.02it/s]
Relevance score: 0.8565
Using OpenAI embedding model for evaluation:
Evaluating: 100%|████████████████████| 3/3 [00:06<00:00, 2.15s/it]
Relevance score: 0.9426
=== Embedding Model Comparison ===
Open-source embedding model score: 0.8565
OpenAI embedding model score: 0.9426
Difference: 0.0861 (OpenAI is better)
这里提供的示例,只展示了 RAGAS 提供的众多评估指标中的两个代表性指标。事实上,还有许多其他指标可用于评估。如果你能找到现有合适指标,就没有必要从零开始创建新的指标体系。
使用 TruLens 进行 RAG TRIAD 评估
TruLens 基于 RAG TRIAD 框架,专注于从三个方面评估 RAG 系统:contextual relevance、faithfulness 和 answer relevance。
TruLens 通过 feedback functions 客观衡量大语言模型应用生成答案的质量和有效性。这些函数支持以编程方式评估输入、输出和中间结果,并支持使用大模型或传统 NLP 模型打分。内置 feedback functions 包括基于 chain-of-thought 的评估、faithfulness、contextual relevance、answer relevance、user sentiment、fairness 和 bias,以及 harmful 或 offensive language 评估。此外,TruLens 允许用户定义自定义 feedback functions,以满足特定项目或应用场景中的评估需求。
TruLens 支持多个框架,例如 LangChain 和 LlamaIndex,并可以通过可视化 dashboard 实时监控评估结果。
下面的代码示例演示如何使用不同 feedback functions 评估一个 RAG 系统的表现。完整代码可参考 github.com/PacktPublis…
import os
import chromadb
from chromadb.utils.embedding_functions import OpenAIEmbeddingFunction
from openai import OpenAI as OpenAIClient # 避免与 TruLens 的 OpenAI 类命名冲突
from trulens.core import TruSession, Feedback, Select
from trulens.apps.app import TruApp, instrument
from trulens.providers.openai import OpenAI as TruLensOpenAI
import numpy as np
### 初始化 Embedding Function
embedding_function = OpenAIEmbeddingFunction(
api_key=os.environ.get("OPENAI_API_KEY"),
model_name="text-embedding-ada-002"
)
chroma_client = chromadb.Client()
vector_store = chroma_client.get_or_create_collection("Info", embedding_function=embedding_function)
### 添加示例数据
vector_store.add("starbucks_info", documents=[
"""
Starbucks Corporation is an American multinational chain of coffeehouses headquartered in Seattle, Washington.
As the world’s largest coffeehouse chain, Starbucks is seen to be the main representation of the United States’ second wave of coffee culture.
"""
])
class RAG:
@instrument # TruLens decorator,用于追踪函数调用
def retrieve(self, query: str):
"""检索相关文档"""
results = vector_store.query(query_texts=[query], n_results=2)
return results["documents"][0] if results["documents"] else []
@instrument
def generate_completion(self, query: str, context: list):
"""生成答案"""
oai_client = OpenAIClient(api_key=os.environ.get("OPENAI_API_KEY"))
context_str = "\n".join(context) if context else "No context available."
completion = oai_client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": f"Context: {context_str}\nQuestion: {query}"}]
).choices[0].message.content
return completion
@instrument
def query(self, query: str):
"""完整 RAG query 流程"""
context = self.retrieve(query)
return self.generate_completion(query, context)
### 初始化 TruLens Session
session = TruSession(database_redact_keys=True)
session.reset_database()
### 初始化 TruLens OpenAI
provider = TruLensOpenAI(model_engine="gpt-4")
### 定义评估指标
f_groundedness = Feedback(provider.groundedness_measure_with_cot_reasons, name="Groundedness") \
.on(Select.RecordCalls.retrieve.rets).on_output()
f_answer_relevance = Feedback(provider.relevance_with_cot_reasons, name="Answer Relevance") \
.on_input().on_output()
f_context_relevance = Feedback(provider.context_relevance_with_cot_reasons, name="Context Relevance") \
.on_input().on(Select.RecordCalls.retrieve.rets[:]).aggregate(np.mean)
### 设置 TruApp
rag = RAG()
tru_rag = TruApp(
rag,
app_name="RAG",
app_version="base",
feedbacks=[f_groundedness, f_answer_relevance, f_context_relevance]
)
### 执行 Query 并记录
with tru_rag as recording:
response = rag.query("What wave of coffee culture is Starbucks seen to represent in the United States?")
print(f"Response: {response}")
### 查看评估结果
print(session.get_leaderboard())
预期输出:
Initialized with db url sqlite:///default.sqlite.
Secret keys will not be included in the database.
In **Groundedness**, input source will be set to __record__.app.retrieve.rets.
In **Groundedness**, input statement will be set to __record__.main_output or `Select.RecordOutput`.
In **Answer Relevance**, input prompt will be set to __record__.main_input or `Select.RecordInput`.
In **Answer Relevance**, input response will be set to __record__.main_output or `Select.RecordOutput`.
In **Context Relevance**, input question will be set to __record__.main_input or `Select.RecordInput`.
In **Context Relevance**, input context will be set to __record__.app.retrieve.rets[:] .
instrumenting <class ‘__main__.RAG’> for base <class ‘__main__.RAG’>
instrumenting retrieve
instrumenting generate_completion
instrumenting query
Response: Starbucks is seen to represent the second wave of coffee culture in the United States.
app_name, app_version, latency, total_cost
RAG base 2.397581 0.000147
在这个例子中,使用 TruLens 创建了一个评估 session,并定义了以下评估指标:
f_groundedness:用于评估答案准确性。
f_answer_relevance:用于评估答案相关性。
f_context_relevance:用于评估检索文档相关性。
结果显示,系统首先初始化一个 SQLite 数据库,用于存储评估数据,并设置三个评估指标的输入来源。评估结果被保存到数据库中,但这里没有展示具体结果。这些结果可以通过 TruLens dashboard 查看,或者从数据库中导出。查询执行时间约为 2.4 秒,API 调用成本为 $0.000147。
DeepEval:强大的开源大模型评估框架
与前面两个评估框架的设计理念不同,DeepEval 将软件工程中的 testing 概念引入大模型评估领域,支持通过 unit tests 验证大模型表现。它是一个专门为大模型设计的开源评估框架,提供简单易用的评估、测试和压力测试工具。DeepEval 类似 Pytest,但它的重点是为大模型输出提供 unit testing 能力,帮助开发者使用各种评估指标,快速测试并优化大模型应用表现,包括基于 RAG 或 fine-tuning 构建的应用。
开发者可以使用声明式语法快速编写 test cases,验证大模型在特定场景中的答案准确性、安全性或响应延迟等关键属性。DeepEval 与 CI/CD,即 Continuous Integration / Continuous Deployment 流程深度集成,支持自动化 regression testing,确保模型迭代过程中核心性能指标不会退化。对于需要频繁更新知识库的行业助手应用,DeepEval 可以有效维护系统稳定性,非常适合敏捷开发团队构建质量防护栏,确保每次迭代后的模型质量和性能。
DeepEval 为 RAG 系统提供专门评估工具,旨在帮助开发者全面评估 retrievers 和 generators 的效果,确保大模型输出的准确性和相关性:
Retrieval evaluation:使用 context precision、context recall 和 context relevance 等指标评估 retriever 效果。这些指标帮助开发者确保检索信息与 query 高度相关、排序合理,并且不过度冗余。
Generation evaluation:通过 answer relevance 和 faithfulness 等指标评估 generator 表现,确保大模型输出信息准确、高度相关,并避免幻觉。
End-to-end RAG evaluation:DeepEval 支持检索和生成的组合评估,使开发者能够全面评估整个 RAG pipeline 表现。
Custom evaluation metrics:开发者可以通过继承 DeepEval 的 base metric classes 创建自定义评估指标,并将其无缝集成进 DeepEval 生态。
DeepEval 非常灵活:你可以在 command line interface 上执行测试文件,也可以直接在本地 Python 脚本中使用 evaluate 函数来使用这些指标。此外,学习者也可以选择在云端运行评估任务,由 Confident AI 提供基础设施,免费执行大规模评估。
下面的 RAG 评估示例展示如何使用类似 Pytest 的方法,利用 evaluate 函数批量评估整个数据集。完整代码可参考 github.com/PacktPublis…
from deepeval.metrics import ContextualPrecisionMetric, AnswerRelevancyMetric
from deepeval.test_case import LLMTestCase
### 定义测试用例
test_case = LLMTestCase(
input="What if these shoes don’t fit?",
actual_output="We offer a 30-day no-questions-asked full refund service.",
expected_output="Customers can return the shoes within 30 days for a full refund.",
retrieval_context=["All customers are eligible for a 30-day no-questions-asked full refund service."]
)
### 定义评估指标
contextual_precision = ContextualPrecisionMetric()
answer_relevancy = AnswerRelevancyMetric()
### 运行评估
contextual_precision.measure(test_case)
answer_relevancy.measure(test_case)
print("Contextual Precision Score: ", contextual_precision.score)
print("Answer Relevancy Score: ", answer_relevancy.score)
预期输出:
Contextual Precision Score: 1.0
Answer Relevancy Score: 0.0
在上面的例子中,contextual precision 和 answer relevance 都表现出较高水平。不过,输出中的 answer relevance score 未能反映实际表现,这可能与该框架对中文支持的局限有关。如果使用英文文档测试,预计会获得更准确评估。
DeepEval 不仅为大模型提供强大评估工具,也具备优秀的超参数管理能力,使开发者能够记录每次测试的关键超参数,例如 text chunk size、retrieved top-K values、使用的 embedding models 等。这种能力确保大模型评估在开发和生产过程中都能高效可靠地进行,帮助及时识别并解决潜在问题,从而提升大模型应用的稳定性和安全性。
DeepEval 可以无缝集成到任何 CI/CD 环境中,为大模型应用提供自动化测试支持,确保这些模型在生产环境中持续稳定运行。结合 Confident AI 使用时,它可以在大模型全生命周期中提供持续评估。开发者可以使用 DeepEval 记录评估结果,分析通过或失败指标,优化超参数,调试模型输出,并在生产环境中实现实时评估和数据集增强,从而快速优化 RAG 流程。
Phoenix:交互式模型诊断与分析平台
Phoenix 由 Arize 开发,特点是使用可视化分析技术为大模型提供交互式诊断能力。其核心功能包括自动检测生成答案中的幻觉、识别知识盲区,以及分析输入 prompts。Phoenix 内置 semantic search,使开发者可以快速定位失败案例;多维聚类分析则有助于揭示潜在系统性偏差。该工具在调试复杂对话系统时尤其有效,工程师可以通过可视化界面追踪错误根因。例如,发现模型对特定领域术语的误解,或者识别容易触发错误答案的问题模式。
Phoenix 也会从 retrieval 和 response 两个方面评估 RAG 系统。借助其可视化界面,Phoenix 可以实时监控 RAG 流程输入和输出,支持多模态数据和跨框架操作,例如 LlamaIndex、LangChain,提供可视化分析界面,并重点追踪长期性能趋势。
前面介绍的框架覆盖了从基础性能评估 RAGAS、安全检测 DeepEval,到长期监控 Phoenix 的全谱系需求。如果需要进一步扩展,可以结合 Prometheus 进行运维监控,或者使用 LlamaIndex Evaluator 在特定框架下优化 RAG 系统。
总结
本章分析了 RAG 系统评估中的关键点。其中,retriever evaluation 的重点在于检索相关文档的准确性;而 generator 的评估更加复杂,必须从多个维度考虑。
为了进行综合评估,我们需要同时结合定量和定性指标,并且将人工评估作为不可或缺的补充方法。通过应用一组多样化指标,你可以全面了解 RAG 系统表现,并识别具体需要改进的领域。
下表总结了本章学习的各种评估框架:
| Evaluation framework | Core advantages | Applicable scenarios |
|---|---|---|
| RAGAS | 无参考评估,自动化测试集生成 | 快速验证基础 RAG 系统表现 |
| TruLens | 三元组评估,可视化监控 | 兼容多个框架的综合评估 |
| DeepEval | 安全检测,CI/CD 集成 | 企业级应用的安全和合规评估 |
| Phoenix | 长期趋势分析,多模态支持 | 复杂场景下的可观测性需求 |
表 9.1:RAG 评估框架对比。
Lewis 的观点仍然是,目前还没有一种现成的“一刀切”标准和规范可以用于评估 RAG 系统。RAG 系统评估的本质取决于你想实现的具体任务目标,这会决定你需要准备哪些相关评估数据,以及选择哪些评估标准和框架。如果找不到合适的现有框架,就可能需要自己构建所需评估体系。