前面几篇陆续聊了RAG里的数据处理、chunk切分、Embedding模型选择、召回排序还有Prompt设计,很多朋友私下问我最多的问题是:系统搭起来之后,怎么证明它“好用”?用户说回答得不对,但到底哪里不对?优化了一版检索,效果是变好还是变坏了?
这些问题都指向同一个核心命题——RAG评估。
RAG不是单一模型,而是“检索+生成”的组合系统,任何一个环节出问题都可能让用户感知到“答得不好”。但如果你只用一个整体分数去衡量,结果往往是:分数不高不低,你知道系统有问题,却不知道问题出在哪一层。这篇我用自己实际跑评测的经验,把RAG评估拆成检索层评估、生成层评估、端到端评估三层来讲清楚,分享具体的指标、评测集构建方法、评分Prompt设计,以及踩过的一些坑。不管你是正在搭知识库问答系统,还是准备优化已有RAG应用,这套方法都能直接拿去用。
1. RAG评估为什么不能只看一个分数
想评估一个RAG系统,第一件事不是找指标,而是承认这个系统是“组合式”的。
RAG的链路大致是:用户提问→检索模块从知识库中召回候选片段→重排(如果有)→生成模块基于召回的片段生成答案。在这个过程中,检索的质量和生成的质量是独立变量的组合。检索没召回正确答案,生成模型再强,也只能“一本正经地胡说”;检索召回了正确内容,但生成模型没有利用它,答案照样离题。
这就是RAG评估的第一个难点:我们必须同时知道“找没找到”和“答没答对”,而这两个问题不能用一个总分来表达。
我自己遇到过这样一次排查:用户问“异地医保能不能直接结算”,系统的回答讲了一堆本地医保的政策,明明不对。我打开日志一看,Top5检索结果里第三位就是“异地就医备案流程和直接结算说明”,内容完全能回答用户问题。所以问题根本不在检索,而在生成阶段没有把检索到的那一段作为答案来源。如果当时只看端到端准确率,只会得到一个“这个case答错了”,然后可能去调embedding模型,白费功夫。
另外一个容易被忽视的点是,评估指标和用户体验不一定完全对齐。用户觉得“回答还行”,可能是系统给出了常识性内容,但并没有引用知识库;用户觉得“回答不好”,也可能是问题本身超出了知识库范围,属于预期内的漏召回。做RAG评估时,既要看客观指标,也要结合场景定义清楚“什么是好”,不然指标再漂亮,线上用户不买账。
所以我的建议是,把RAG评估拆成三个层次:
- 检索层评估:重点看召回和排序质量,回答“该找的内容有没有找回来、排得对不对”。
- 生成层评估:重点看生成答案的质量,回答“基于检索片段,模型是否给出了忠实、完整的回答”。
- 端到端评估:把整个系统当黑盒,用真实任务模拟用户使用,回答“系统整体能不能解决用户问题”。
这三层并不是三选一,而是互相配合。检索层指标能快速定位检索问题,生成层指标能定位生成问题,端到端指标能汇报给业务方。接下来我每一层具体展开。
2. 检索层评估:找没找到是RAG的地基
检索层的评估是所有RAG评估里性价比最高的一层,因为检索结果客观、好标注、容易自动化。做知识库问答时,80%的错误其实都能追溯到检索没做好。先把这个环节评估清楚,后面的优化才知道方向。
2.1 三类必用的检索评估指标
检索评估的核心逻辑是:给一个测试问题,调用系统的检索接口,拿到Top-K候选片段,然后和人工标注的“正确答案片段”做比对,计算命中情况。
我最常用的三个指标:
Recall@K(也叫Hit Rate或命中率)
统计每个测试问题在返回的前K个片段中,是否至少包含一个“严格相关片段”。把所有问题的命中率取平均,就是Recall@K。
举个例子:评测集有100个问题,K设置为5,其中83个问题在Top5结果里找到了对应的相关片段,那么Recall@5就是0.83。这个指标最直观,也最适合做第一道门槛。如果你的Recall@5低于0.7,基本不用纠结排序和重排,先解决召回覆盖问题。
MRR(Mean Reciprocal Rank)
MRR关心的是第一个正确答案排在第几位。如果正确答案排第一位,贡献1分;排第二,贡献0.5;排第三,贡献0.333,依此类推;如果TopK里完全没有正确答案,贡献0分。所有问题取平均,得到MRR。
这个指标适合那些“一个问题主要依赖一段核心内容”的场景。它比召回率多惩罚了正确答案排序靠后的情况。比如说,两个系统Recall@5都是0.9,但一个常常将正确答案排在第一位,另一个经常排在第五位,MRR就能把两者的差距体现出来。
NDCG(Normalized Discounted Cumulative Gain)
NDCG是搜索排序领域更精细的指标,它支持“相关性分层”标注。比如把每个候与问题标成0(不相关)、1(部分相关)、2(高度相关),然后根据相关性和位置计算累积收益,位置在后面的高相关文档会被“折损”惩罚。最后除以理想排序下的最大得分,得到0到1之间的分数。
NDCG比Recall和MRR信息量大,但标注成本更高,因为你不仅要标出正例,还要给每个相关文档打等级。我的经验是:初级优化看Recall@K和MRR就够了,当检索精度已经不错、想继续优化排序时,再引入NDCG。
2.2 检索评测集怎么构建
评估指标只是计算规则,真正决定评估质量的是评测集。一套合格的检索评测集应该包含:问题、对应的知识库片段ID、相关性等级。
建评测集我的实操路径是这样的:
从线上日志或测试环境里收集真实用户问题,不要自己凭空想问题。哪怕线上只有几十条真实问题,也比拍脑袋编200条问题有价值。真实问题里的语气、口语表达、指代都是编不出来的。
然后对每条问题做两件事:
- 判断这个问题是否应该由当前知识库回答。如果知识库里压根没有相关内容,就把它从评测集里去掉,或者单独放到“不可回答”集合里,避免拉低指标。
- 标注对应的相关片段。打开知识库检索一遍,把可能相关的片段拉出来,人工确认哪几个片段与问题相关,并标记等级。等级建议按0/1/2划分:0不相关,1部分相关(能提供背景但不足以直接回答),2高度相关(片段内容直接包含答案)。
数量上,我建议最少50条,稳妥一点100条以上。如果知识库覆盖多个类别,按类别分层抽样,保证每个业务主题都有样本。
这里有个容易忽略的点:评测集不能是“死”的。知识库会不断更新,如果某些片段被删除或重写,曾经标注的高相关ID可能失效。我每两周会跑一遍“标注一致性检查”,重新验证评测集里的相关片段是否还在知识库中,确保测的是当前系统。
2.3 检索评估的实操流程
平时我做检索层评估,流程可以概括为以下四步:
第一步,准备脚本。写一个Python脚本读入评测集JSON,对每个query调用系统的检索接口,保留Top-5结果及对应的片段ID和得分。
第二步,计算指标。将检索结果与标注集合比对,分别计算Recall@3、Recall@5、MRR。如果标注了相关性等级,再计算NDCG@5。
第三步,导出失败case。凡是在Top5里没有命中高度相关片段的,都格式化成“问题+检索Top5片段+相关片段ID”。然后逐个看失败case,归类失败原因:是问题表述太模糊、知识库切分太大导致片段主题混杂、还是embedding语义匹配不上。
第四步,优化迭代。根据失败原因采取相应的手段,比如调chunk切分大小、换embedding模型、加入关键词/BM25混合检索、引入重排模型。每改一版,重跑一次评估,对比指标变化。
我特别想提一个经验:如果Recall@5很低,先别急着引入重排模型。重排解决的是“好内容没排前面”的问题,但前提是“好内容被召回了”。要是候选池里压根没有正确答案,rerank再强也白搭。此时优先看召回:是不是chunk切得太粗、太细,是不是embedding模型分不太清领域术语,需不需要机械词匹配兜底。
反过来,如果Recall@5已经不错但端到端答案还是不对,那就可以把评估重点转移到生成层。
3. 生成层评估:答案质量到底怎么打分
生成层评估比检索层复杂,因为没有绝对“标准答案”,生成的回答往往语义多样。这一层的目标不是判断“字面对不对”,而是判断“质量够不够好”。
3.1 生成质量评估的四个核心维度
我评估生成质量时,通常围绕四个维度展开。你可以根据业务实际情况选择,不需要每次都全部用。
忠实性:答案内容是否完全基于检索到的片段,有没有捏造事实。比如知识库片段只说“报销比例根据医院级别不同而不同”,生成回答却补充了“三甲医院报销70%”,这个具体比例如果没有上下文支持,就是不忠实。忠实性是RAG生成质量的最重要维度,幻觉问题主要靠它暴露。
完整性:答案是否覆盖了用户问题的所有要点。用户的提问往往包含多个意图,比如“报销比例是多少,需要带什么材料”,系统只回答了比例,漏掉了材料清单,就是完整性不足。
相关性:答案是否回答了用户真正的问题,有没有扯一些无关背景。相关性低通常表现为“说了很多,但一句有用的都没有”。
有帮助性:答案是否在实际场景中能帮用户解决问题,考虑的可读性、格式、可操作性。比如给用户一堆政策条文,不如直接告诉“第一步做什么,第二步做什么”更有帮助。
每个维度用1-5分打分时,要对分数区间做清晰定义,否则标注人员之间会产生很大分歧。比如:
- 5分:答案严格引用片段信息,覆盖用户所有需求点,直接解决问题;
- 3分:答案部分正确,但遗漏关键信息或有一处不准确表述;
- 1分:答案大部分内容与片段无关,或者有明显虚构。
有了维度定义之后,接下来就是选择打分工具。
3.2 三种生成评估方法怎么选
基于规则的指标:比如答案长度、关键词覆盖率、标点符号完整度、是否存在引用来源等。优点是便宜、可重复,缺点是很表面。比如关键词覆盖率高不代表语义正确。我只会在自动化流水线里把它当作“快速报警”信号,不会作为核心结论。
LLM-as-Judge:让一个能力较强的LLM扮演评委,按照评分标准给生成回答打分。这是目前实践中平衡成本和效果最好的方式。核心是评分Prompt的设计,后面我会给一个可直接用的Prompt示例。
人工评估:组织业务方或标注员按同一套标准打分。准确度高,但速度慢、成本高。我通常只用来抽小样本,比如每次抽50条,验证LLM评判结果的可信度,以及建立一份“锚定样例集”帮助校准标准。
这三者不是互斥关系。建议最少做“规则指标+LLM评分”的组合,定期抽一批人工复核。
3.3 LLM-as-Judge评分Prompt设计示例
给LLM当评委的Prompt,要遵循“先定义任务、再给出输入、最后明确打分标准”的结构。我给一个通用的忠实性和完整性双维度评分Prompt:
你是一位严谨的RAG质量评估员。你需要根据“参考片段”来评判“系统回答”的质量,不允许使用片段以外的知识。 用户问题: {{question}} 参考片段: {{context}} 系统回答: {{answer}} 请从以下两个维度打分(每项1-5分): 忠实性:系统回答是否严格基于参考片段?是否存在幻觉或与片段矛盾的内容? - 5分:回答中的关键信息完全来自片段,且不包含任何额外编造内容。 - 3分:回答大部分来自片段,但存在一处不准确或片段中未提及的细节。 - 1分:回答大量虚构事实,或与片段明显矛盾。 完整性:系统回答是否覆盖了用户问题的所有关键点? - 5分:覆盖全部问题点,且每个点都有明确说明。 - 3分:回答了主要问题,但遗漏了一个次要点。 - 1分:只回答了很少一部分,或完全答非所问。 请按如下JSON格式输出,不要包含多余解释: {"faithfulness_score": 0, "faithfulness_reason": "...", "completeness_score": 0, "completeness_reason": "..."}使用这个Prompt时有几个注意事项:
第一,参考片段数量不要一次给太多。当片段超过5个时,LLM容易“看漏”内容,打分稳定性会下降。如果检索返回了10个片段,可以只取Top5或按段落截断。
第二,多维度打分比单维度总分更稳定。单给一个总分,模型的权重分配不可控;分维度要求模型分别判断,维度含义更聚焦。
第三,不要让“生成模型”自己当评委。很多团队用同一家公司的小模型既做生成又做评估,会出现明显的“自我偏好”,给自己打高分。条件允许时,选择能力更强、来源不同的模型作为评估模型,效果会好很多。
3.4 生成评估的实现步骤
具体跑一批生成评估,我一般这样操作:
从评测集里抽50到100条问题,用系统完整跑一遍,把“用户问题、检索片段、系统答案”一起存下来。然后调用LLM评分接口,对应每个维度得到分数。我还会把每次评分的reason也存下来,方便出问题时回溯。
跑完之后统计各维度的平均分和分布。比如“忠实性”平均分4.2但“完整性”只有2.8,说明系统回答质量总体可以,但经常漏答要点。这时优先调Prompt:要求模型回答时先列出问题所有子需求,再逐项回答。
我还会让LLM同时输出一个简单分类:这篇回答的失败原因是“检索不充分”还是“生成没利用好片段”,这样可以直接辅助定位问题层。分类标签不要搞得太细,就三到四个:检索缺失、检索相关但生成遗漏、生成幻觉、其他。
有了这些信号,你就能从“我的系统大概不行”进化到“我的系统目前主要毛病是检索召回不够,尤其长尾问题”。优化方向也就清楚了。
4. 端到端评估:把系统放回真实使用场景
检索层和生成层的指标都是“分环节”的,但业务方和用户只看整体效果。所以还得有一个端到端的评估方式,模拟真实用户调用,判断系统最终能不能解决问题。
4.1 端到端评估的两种常见形式
一种是任务型评测:构造一问一答的标准测试集,每个问题带一个参考答案(基于知识库内容的标准答案),然后把系统当成黑盒调用,拿生成答案和参考答案比较。这种方式操作简单,适合版本回归、A/B对比。
另一种是自动指标评测:不强制依赖标准答案,而是评估“生成答案是否忠实于检索片段”以及“答案是否贴合用户问题”,然后把这两个子分数合成一个综合分。这种形式更像是对RAG质量的校验,不依赖人工写标准答案,扩展性好。
我更推荐两者结合:任务型评测保证“绝对正确性”,自动指标评测覆盖“语义质量”。如果时间和人力只够做一种,先做任务型评测,问题更可控,也更容易解释给业务方听。
4.2 端到端评测集和评分方法
构建端到端评测集时,和检索评测集最大的区别是:每个问题要有一条标准答案。标准答案从知识库片段里提炼,不要增加知识库之外的额外事实。
比如知识库片段是“本产品支持7天无理由退货,需要保持商品完好”,标准答案就写成“支持7天无理由退货,条件是商品完好”。写的时候尽量精炼,但保留关键实体和数字。
评分环节,我推荐用LLM来做“语义一致性判断”,而不是用字符匹配:
你是一个答题判卷员。请根据标准答案,判断系统回答是否正确。 用户问题:{{question}} 标准答案:{{reference_answer}} 系统回答:{{answer}} 评分标准: - 正确:系统回答与标准答案的关键信息一致,无错误事实。 - 部分正确:系统回答包含部分正确信息,但遗漏关键点或含有错误。 - 错误:系统回答答非所问或关键信息错误。 请先给出结论(正确/部分正确/错误),再给出原因。统计时,计算“正确率”和“正确+部分正确率”。我自己更关注“正确+部分正确率”,因为RAG场景里,用户问题多变,标准答案又未必是唯一解,过度追求100%严格正确率会误伤一些其实可用但表述不同的回答。
4.3 实操:端到端评估怎么跑
端到端评估流程我放在自动化流水线里,每次代码或配置更新后自动触发:
第一步,加载端到端评测集,包含问题、标准答案、可选难度标签。
第二步,调用完整RAG接口,收集系统答案和检索到的Top-K文档。
第三步,调用LLM判定每个回答的“正确/部分正确/错误”,同时统计各难度分组的表现。
第四步,输出报告:整体正确率,各分组正确率,错误案例列表。
这个流程跑一次大概十几分钟,成本主要取决于评测集大小和选用的评判模型。日常开发中,端到端指标不需要天天跑,我习惯在每次改动embedding、chunk策略、prompt或重排模型后跑一次,保持评估记录的更新。
4.4 不要忽略线上真实反馈
评测集是过去经验的沉淀,但线上用户总会出现你没想到的问题,所以线上反馈指标也要纳入评估体系。
基础的线上指标包括:用户点踩率、点踩后追问率、用户主动复制答案率、会话跳出率。更完善的团队会给答案加“有帮助/没帮助”按钮,让用户直接反馈。
关键是把线上反馈闭环起来:当用户点“没帮助”时,系统自动记录这次会话的原始输入、检索片段、生成答案和后继对话。这些bad case会持续积累,我每个月都会把它们汇总,挑出高频类型补充进评测集。
这里要提醒一下:线上反馈是滞后指标。新版本上线后,用户反馈数据通常要积累一到两周才有统计意义。所以不能只靠线上反馈做快速迭代,必须搭配离线评测集做回归。两者的定位是:离线评测找方向和防回归,线上反馈验效果和补盲区。
5. 实操途中踩过的几个大坑
RAG评估方法论听起来不复杂,真正跑起来,各种意外情况特别多。我把实战里反复踩过的坑写下来,提前避一避。
5.1 评测集数据泄漏导致分数虚高
最典型的问题是把调优数据混进了评测集。比如你从测试环境收集问题的时候,顺手把之前已经用来微调研判模型或调整hyperparameter的case也放进去了,那评估结果就会失真,因为模型已经在这些数据上做过拟合。
解决方法是:评测集一旦确定,就单独冻结。任何调参、修改Prompt的过程都不允许把评测集内容当作“训练材料”。如果评测集的一部分被污染了,宁可删掉那几条,也不要心存侥幸。
另外,知识库更新也会造成一种“隐式泄漏”:之前标注的正确答案片段被新版本改写了,或者知识库里新增了更多重复内容,导致检索更容易命中。所以每次知识库更新后,要跑一遍评测集的ID有效性检查,保证对照关系还是成立的。
5.2 LLM-as-Judge 的自我偏好和随机性
LLM当评委最大的风险是“它不一定公正”。我实测下来,同一个答案,A模型打4分,B模型打2分都见过。如果评委和生成模型来自同一家且参数规模较小,还会出现给自己人打高分的情况。
应对办法:
- 评委模型和生成模型不要同一款,尽量用能力更强、更主流的强模型;
- 不要用单次打分作为结论,同一个case可以调用两次,分别用两个不同评委模型,取较低分或取均值;
- 跑批量评估时,固定一个评委模型版本,不要中途换模型,否则前后的分数没有可比性。
如果发现评委分数波动很大,建议筛选一部分case做双人人工标注,用人工聚合结果来校准自动评判的尺度。
5.3 只看平均分,忽略分布和长尾
平均分很容易骗人。我遇到过一次整体忠实性从4.0涨到4.3,看上去很顺利,但按问题类型一拆,发现“政策咨询类”得分反而下跌了0.5。原因是为了提升多数简单问答的质量,模型输出的风格变得更简短,在长文本政策解读类问题上反而缺乏细节。
所以评估报告不要只放一个总分,要按问题类型、知识库类别、问题长度等维度做分组统计。我习惯把“困难问题”单独拉出来跑一个困难子集,这个子集的涨跌权重比整体平均分大得多。
5.4 检索指标和生成指标互相矛盾时的排查逻辑
有一类情况:检索Recall@5只有0.55,但端到端正确率居然有0.8。可能的原因有两个。
一个可能是评测集里问题重复度较高,很多问题的答案都来自同一个高频片段,被检索召回一次,就命中了好几条相似问题。这种情况需要清洗评测集,去除过于相似的问题。
另一个更隐蔽:生成模型在某些问题上根本没用检索片段,靠自身常识答对了,让端到端分数虚高。这对RAG系统来说并不是好消息,因为当问题超出常识范围时,系统依然会“自信答题”,容易出现幻觉。所以我一发现检索指标和生成指标相差太大,会着重检查:生成过程是否真的把检索片段当作参考答案来源。最简单的方法就是看忠实性分数,如果忠实性很低但端到端正确率很高,基本说明模型在脱离知识库答题,这时要优化Prompt,强制加入“只能基于给定材料回答,不能使用内部知识”的约束。
5.5 评估成本控制
每次迭代都让最强的LLM评委跑几百条case,时间长、花费高。我的做法是分级评估:
- 日常快速迭代:用开源小模型批量粗评,只统计召回率和关键词覆盖,半小时出结果;
- 重要节点:抽100条case用强模型评委打分,加上人工核对;
- 正式发版:完整评测集端到端跑一遍,输出详细报告。
这样既能及时反馈,又不会让评估成本拖慢迭代节奏。
最后分享一点个人的体会
RAG评估做到最后,比的不是指标多花哨,而是流程是否简洁有效。我自己经历过的最大转变是:从“为了评估而评估”,变成了“评估服务于决策”。每一次跑评估,目标都是回答一个具体问题,比如“换成新的embedding模型会不会更好”“把chunk大小调到256会不会漏信息”“Prompt里加引用格式会不会让答案更专业”。带着问题去评估,效率会高很多。
还有一个很多人不知道的小技巧:每个版本的评估报告里,除了数字,一定要保存10个典型的bad case。版本迭代时,先看旧版和新版在这些bad case上的表现,再去看平均分。因为平均分反映总体趋势,而bad case能告诉你具体改善或恶化的是什么。我这些年下来,靠这个习惯避开了好几次“分数看着在涨,用户体验却在变差”的尴尬。
RAG评估不是一次性项目,它是这个系统成长的仪表盘。把评测集、评分脚本、报告模板沉淀成自动化流水线,之后的每次优化都有据可依,心里会很踏实。希望这篇“篇六”能帮你把自己的RAG系统看得明明白白。如果对检索优化、chunk切分策略怎么评估和调整感兴趣,后面我再继续写。