|
目前,越来越多的企业已经部署了私有化大模型,并采用检索增强生成(Retrieval Augmented Generation,RAG)技术为大模型外挂专属知识库,让模型能够实时检索到企业的私域知识,从而给出更准确可靠的回答。不过,搭建 RAG 工程化应用绝非一蹴而就的事情,这是一个持续迭代的过程,需要不断优化 RAG 的效果,以更好地满足企业实际的业务需求。为了衡量 RAG 的效果,我们需要对其进行量化评测。RAG 应用评测与传统的功能测试不同,传统功能测试关注的是功能“对不对”,而 RAG 应用评测关注的是效果“好不好”。衡量不是最终目的,而是为了在这个指标的基础上明确具体的应用优化方向。 那么,RAG 应用如何评测呢?目前学界已经有了各种各样的评测方法和指标,乍一看让人眼花缭乱,不知从何下手。其实,无需过于纠结每种具体的评测方法,我们可以从 RAG 的基本概念入手,看看哪些方面需要评测。RAG 全名为“检索增强生成“,顾名思义,它分为”检索“和”生成“两个环节,那么我们可以针对这两个环节进行分别评估,然后对整体再做评估,因此,我们可以把 RAG 评估划分为以下三个类别: 检索环节评估检索环节的主要任务是找到与用户问题相关的文档,因此我们关心的是检索到的内容片段"准不准"和"全不全",据此可以分为以下两个子指标: Context Precision(上下文精确度):评估检索结果中与准确答案相关的内容排名是否靠前,占比是否高(即信噪比)。用大白话说,就是看检索到的内容"准不准"。 Context Recall(上下文召回率):评估有多少与标准答案相关参考资料被成功检索到,越高的得分意味着更少的相关信息被遗漏。用大白话说,就是看检索到的内容片段"全不全"。 举个具体的例子:
在这份检索结果中,我们可以看到: 生成环节评估在生成阶段,大语言模型根据检索到的内容生成答案,我们关心的是生成的答案"准不准"和"是否答非所问",据此可以分为以下 2 个子指标: Faithfulness(事实忠实度):评估生成的答案与检索到的参考资料的事实一致性,检测是否存在"幻觉"(即模型生成的内容在检索结果中能不能找到依据)。具体的实现方法为:将生成的答案分解为多个陈述,检查每个陈述是否能在检索内容中找到支持。 Answer Relevancy(回答相关性):评估生成的答案与用户问题的相关程度,即生成的回答是否解决了用户的问题,是否存在偏离主题、答非所问的情况。实现方法为:计算问题与回答之间的语义相似度,评估回答是否涵盖了问题的核心要点。这一评估可以通过人工打分,或使用余弦相似度、BERTScore 等指标进行衡量。 整体回答质量评估从整体上看,我们主要关心的是一个终极指标是Answer Correctness(回答正确性),即综合考虑检索和生成环节的效果,评估 RAG 应用的回答是否符合要求。从直观感受来看,我们可以认为一个正确的回答应该符合两个条件:语义足够接近标准答案,且与客观事实相符。据此我们可以把回答正确性拆分成以下两个子指标: 语义相似度评估生成的答案与标准答案之间的语义相似度,即回答是否足够接近标准答案。这一指标是通过 embedding 模型得到 回答(answer)和 标准答案(ground_truth)的文本向量,然后计算两个文本向量的相似度。向量相似度的计算有许多种方法,如余弦相似度、欧氏距离、曼哈顿距离等,最常用的是余弦相似度。 事实准确度光有语义相似度还不够,因为大模型很有可能只是照猫画虎地编造了一些看起来与标准答案相似,实则违反客观事实的回答。因此我们还要加入对事实准确度的评估:这是衡量回答(answer)与 标准答案(ground_truth)在事实描述上差异的指标。这一指标与上面说的 Faithfulness(事实忠实度)指标不同,Faithfulness(事实忠实度)对照的只是检索到的参考资料,而 Answer Correctness(回答正确性)则是直接对照标准答案。Faithfulness 高,Answer Correctness 不一定高,因为检索到的参考资料中可能有与标准答案不一致的事实,或者检索到的内容不全。那这个指标怎么计算呢? 首先,为生成的答案(answer)和标准答案(ground_truth)分别生成各自的观点列表。举例如下: answer="功能测试用例设计方法包括等价类划分法、边界值分析法、错误推测法、判定表法、因果图法、正交实验法、场景法和流程图等。"ground_truth="功能测试用例设计方法包括等价类划分法、边界值分析法、错误推测法、判定表法、因果图法、正交实验法、功能正确性测试法和功能适合性测试法等。"
#生成观点列表:answer_points=["功能测试用例设计方法包括等价类划分法","功能测试用例设计方法包括边界值分析法","功能测试用例设计方法包括错误推测法","功能测试用例设计方法包括判定表法","功能测试用例设计方法包括因果图法","功能测试用例设计方法包括正交实验法","功能测试用例设计方法包括场景法","功能测试用例设计方法包括流程图"] ground_truth_points=["功能测试用例设计方法包括等价类划分法","功能测试用例设计方法包括边界值分析法","功能测试用例设计方法包括错误推测法","功能测试用例设计方法包括判定表法","功能测试用例设计方法包括因果图法","功能测试用例设计方法包括正交实验法","功能测试用例设计方法包括功能正确性测试法","功能测试用例设计方法包括功能适合性测试法"]
然后,遍历 answer 与 ground_truth 列表,并初始化三个列表,TP、FP 与 FN。 对于由 answer 生成的观点: TP=["功能测试用例设计方法包括等价类划分法","功能测试用例设计方法包括边界值分析法","功能测试用例设计方法包括错误推测法","功能测试用例设计方法包括判定表法","功能测试用例设计方法包括因果图法","功能测试用例设计方法包括正交实验法"]
FP=["功能测试用例设计方法包括功能正确性测试法","功能测试用例设计方法包括功能适合性测试法"]
对于 ground_truth 生成的观点: FN=["功能测试用例设计方法包括场景法","功能测试用例设计方法包括流程图"]
最后,统计 TP、FP 与 FN 列表的元素个数,并按照以下方式计算 f1 score 分数: f1score=tp/(tp+0.5*(fp+fn))iftp>0else0 在上面的例子中,f1 score = 6 / (6 + 0.5 * (2 + 2)) = 0.75。 分数汇总按照以上方法得到语义相似度和事实准确度的分数后,对两者加权求和,即可得到最终的 Answer Correctness 的分数。 AnswerCorrectness的得分=0.25*语义相似度得分+0.75*事实准确度得分 
自动化评测 RAG 应用的方法以上的评估,如果全靠人工评测,会非常耗时且容易出错。是否有更加智能的自动化评测方法呢?比如,在计算事实准确度的时候需要拆分观点列表和寻找列表之间的匹配项,我们是不是可以使用成熟的推理大模型(比如满血版 DeepSeek)来完成这个任务呢?RAGAS 框架就是这样的一个工具,它可以帮助我们自动化地进行 RAG 应用的评测。它通过结构化指标量化 RAG 系统的检索器和生成器组件的表现,并充分利用大语言模型和 embedding 模型的能力,实现了对 RAG 应用的自动化评测,显著降低了评测任务的投入成本。代码示例如下: fromlangchain_community.llms.tongyiimportTongyifromlangchain_community.embeddingsimportDashScopeEmbeddingsfromdatasetsimportDatasetfromragasimportevaluatefromragas.metricsimportanswer_correctness#数据集data_samples={'question':['张伟是哪个部门的?','张伟是哪个部门的?','张伟是哪个部门的?'],'answer':['根据提供的信息,没有提到张伟所在的部门。如果您能提供更多关于张伟的信息,我可能能够帮助您找到答案。','张伟是人事部门的','张伟是教研部的'],'ground_truth':['张伟是教研部的成员','张伟是教研部的成员','张伟是教研部的成员']}dataset=Dataset.from_dict(data_samples)#执行自动化评测score=evaluate(dataset=dataset,#定义评估指标metrics=[answer_correctness],llm=Tongyi(model_name="qwen-plus-0919"),embeddings=DashScopeEmbeddings(model="text-embedding-v3"))#将评估结果转换为DataFrame格式score.to_pandas()以上流程主要是计算回答正确性,其中通过 DashScopeEmbeddings 模型计算的语义相似度这一子指标,通过大语言模型Tongyi计算的事实准确度。类似地,我们也能计算上下文精确度和上下文召回率: fromlangchain_community.llms.tongyiimportTongyifromdatasetsimportDatasetfromragasimportevaluatefromragas.metricsimportcontext_recall,context_precisiondata_samples={'question':['张伟是哪个部门的?','张伟是哪个部门的?','张伟是哪个部门的?'],'answer':['根据提供的信息,没有提到张伟所在的部门。如果您能提供更多关于张伟的信息,我可能能够帮助您找到答案。','张伟是人事部门的','张伟是教研部的'],'ground_truth':['张伟是教研部的成员','张伟是教研部的成员','张伟是教研部的成员'],'contexts':[['提供⾏政管理与协调⽀持,优化⾏政⼯作流程。','绩效管理部韩杉李⻜I902041⼈⼒资源'],['李凯教研部主任','牛顿发现了万有引力'],['牛顿发现了万有引力','张伟教研部工程师,他最近在负责课程研发'],],}dataset=Dataset.from_dict(data_samples)score=evaluate(dataset=dataset,metrics=[context_recall,context_precision],llm=Tongyi(model_name="qwen-plus-0919"))score.to_pandas()
从评测结果看如何优化RAG应用评测不是最终目的,最终目的是为了基于评测结果针对性地提出优化建议。虽然回答正确性是能够综合性地衡量应用整体效果,但当效果不尽人意时,单纯看这一个指标并不能看出问题出在哪里。这时我们就需要结合4个子指标来全面地评估应用效果。按照RAG的流程顺序,我们应当先看上下文精确度和上下文召回率,这两个指标反映了检索环节的效果。如果这两个指标很低,那么说明检索环节存在问题,可能的原因即对策如下: 上下文召回率低的常见原因: 文档的分块策略不合理,比如使用固定长度分块,导致上下文信息不完整。因此需要优化分块策略,使分块能够尽可能完整地包含上下文信息。 召回的分块数量过少,导致召回的参考信息不充分。因此需要增加召回的分块数量。 使用的嵌入模型能力不足,无法检索到全部的相关信息,因此需要更换更好的嵌入模型。好的embedding模型可以理解文本的深层次语义,如果两句话深层次相关,那么即使“看上去”不相关,也可以获得较高的相似度分数。 用户query模糊不清或缺少关键信息,导致检索效果差。对此,开发者可以设计一个prompt模板,使用大模型来改写query,优化问题的表述方式,补充关键信息,从而提升召回的准确率。
如果这两个指标都很高,那么说明检索环节表现良好,不需要过多关注。那么就能把问题的关注点集中在生成环节了。生成环节的任务主要由大模型来完成,针对大模型有以下优化方向可以尝试: 除此之外,还可以引入self-RAG的方法,即输出最终回答之前让大模型进行自我“反思”,看自己生成的回答是否符合存在不符合事实的情况,如果有则进行修正,然后再进行一轮自我审查,直到确认回复不存在幻觉为止。 |