首页 项目 博客 简历 联系 English
返回列表
2026年7月5日 约 1,549 字 预计 4 分钟读完

07-Golden Set 与评测体系:证明 RAG 是否真的变好

前面几篇已经把 RAG 证据链补到了答案校验:文档有身份,chunk 有结构,检索有 trace,候选能 rerank,上下文能形成 evidence,答案要引用证据,verifier 还会检查事实支持。

#NexaRAG#Golden Set#RAG 评测#项目复盘

07-Golden Set 和评测体系:证明 RAG 是否真的变好

前面几篇已经把 RAG 证据链补到了答案校验:文档有身份,chunk 有结构,检索有 trace,候选能 rerank,上下文能形成 evidence,答案要引用证据,verifier 还会检查事实支持。

接下来还要问一个问题:这些改造到底是否让系统变好。

手工问几个问题覆盖有限。手工测试很容易被样例选择影响,复现成本也高。今天问“小米 15 Pro 电池容量”答对了,只能说明这个样例表现不错;某个答案有引用,也只能说明这一条引用存在;一个无证据问题拒答了,也只能说明这个场景处理得还可以。

所以 NexaRAG 需要 Golden Set 和评测体系。

这篇的核心判断是:

RAG 评测要分层看召回、引用、拒答和忠实性。

GoldenCase 记录问题、答案和证据预期

评测样本定义在 rag/evaluation/cases.pyGoldenCase

id
question
chat_history
expected_sources
expected_chunk_ids
answer_points
must_refuse
expected_citations
type
tags
difficulty

这里最重要的是:Golden Set 除了保存 expected answer,还保存证据预期。

传统问答评测喜欢写一个标准答案,然后比较模型回答是否接近。但 RAG 的关键包括答案文字,也包括证据是否找对。一个答案措辞不同可以接受,但如果引用了错误 chunk,或者正确证据根本未召回,那就是 RAG 链路问题。

所以 NexaRAG 里 expected_chunk_ids 很重要。它让评测可以直接判断:这次检索是否命中应该命中的证据。

answer_points 则用于回答内容层面。它优先强调关键点覆盖。

must_refuse 用于无证据或应该拒答的样本。RAG 既要会答,也要知道什么时候该拒答。

检索评测先看证据是否回来

检索指标在 rag/evaluation/retrieval_metrics.py。核心函数是 compute_retrieval_metrics()

它会把 retrieved docs 规范化成:

rank
chunk_id
source
text
metadata
score

然后和 expected_chunk_idsexpected_sources 比较,得到:

hit_at_k
recall_at_k
precision_at_k
mrr
matched_expected_ids
retrieved_chunk_ids
retrieved_sources

这些指标回答的是检索层问题。

  • Hit@K:前 K 个结果里是否命中目标证据。
  • Recall@K:目标证据召回了多少。
  • Precision@K:前 K 个结果里有多少是目标证据。
  • MRR:第一个正确结果排在多靠前。

如果答案错了,但 retrieval metrics 很好,问题可能在 rerank、context 或生成。
如果 retrieval metrics 很差,优先回到 chunking、query rewrite、BM25/vector/filter 这些层排查。

这就是分层评测的价值。

答案评测看相关性和可信度

答案指标在 rag/evaluation/answer_metrics.py。它会从几个角度评估:

  • answer_point_coverage
  • refusal_score
  • citation_accuracy
  • citation_coverage
  • unknown_citation_rate
  • faithfulness

answer_point_coverage 看答案是否覆盖关键点。
refusal_score 看该拒答时是否拒答、该回答时是否过度拒答。
citation_accuracy 看引用的 evidence 是否对应 expected chunk。
citation_coverage 看 expected chunk 是否都被引用到。
unknown_citation_rate 看是否引用了未知的 evidence id。
faithfulness 看 unsupported claims、numeric warnings、conflicting claims 的比例。

这比单纯“答案对不对”更适合 RAG。

比如一个回答内容大致正确,但引用了未知的 [E9],传统答案评测可能给高分;RAG 评测必须扣分。再比如一个无证据问题,模型拒答了,传统问答评测可能觉得回答缺少内容,在 RAG 场景里这是正确行为。

trace 让评测结果可解释

评测主链路在 rag/evaluation/chain.pyRetrievalEvaluationChain。它有两个核心入口:

  • evaluate_retrieval_case()
  • evaluate_answer_case()

前者评估检索结果;后者结合 answer、trace、verification 和 evidences 评估答案。

其中 evaluate_answer_case() 会从 trace 里提取 evidence:

evidence_items = evidences or evidences_from_trace(trace)

这说明 trace 既是线上调试工具,也服务离线评测。一次失败案例会同时告诉你分数低,以及通过 trace 看失败发生在哪里:

  • expected chunk 未召回。
  • 召回了但未进 final context。
  • final context 有证据但缺少引用。
  • 引用了证据但 verifier 判断 unsupported。
  • 无证据问题缺少拒答。

有 trace,评测报告就能解释数字。

runner 把评测变成可重复流程

脚本入口在 scripts/run_rag_eval.py,主逻辑拆到了 scripts/rag_eval/runner.py

runner.py 支持几种模式:

  • retrieval
  • answer
  • full

在 retrieval 或 full 模式下,它会调用:

knowledge_base.search_with_trace(...)
compute_retrieval_metrics(...)

在 answer 或 full 模式下,它会构建一个测试用 ChatService,跑完整问答链路,再计算 answer metrics。

这种拆分很重要。因为有时候只想看检索是否变好,无需引入生成模型的不稳定;有时候又要看完整链路,包括引用、拒答和 verifier。

评测报告会写到 data/eval_results/,并生成 JSON 和 Markdown。这样每次改 chunking、retrieval_mode、rerank provider,都可以留下可比较结果。

rerank on/off 和 retrieval mode 对比

RAG 改造很容易陷入“我感觉变好了”。评测脚本的一个价值,是把这种感觉变成可对比结果

比如:

rerank=off
rerank=keyword_overlap
retrieval_mode=bm25
retrieval_mode=vector
retrieval_mode=hybrid

如果 hybrid 的 recall 高于 vector,说明 BM25 通道确实补了召回。
如果 rerank 后 MRR 提升,说明重排让正确证据更靠前。
如果 answer faithfulness 没提升,说明检索改好了,但生成或校验还要继续调整。

评测未必每次都给漂亮结果,但它至少能告诉我们:这次改动影响的是哪一层。

这一步解决的内容和下一步

Golden Set 和评测体系解决的是“改造是否有效”的问题。

它让 NexaRAG 从手工试问扩展为用固定样本集评估检索、答案点覆盖、引用、拒答和忠实性。它也把 trace 纳入评测,让失败案例可解释。

评测体系本身也需要持续维护。Golden Set 太小会误导判断,样本类型太单一会掩盖问题,expected_chunk_ids 也会随着 chunking 策略变化需要更新。评测是 RAG 项目的长期护栏

下一篇继续看生产侧知识库问题:文档不可能只新增不变,系统还要支持删除、版本、回滚、重建索引和权限过滤。

小结

NexaRAG 的评测链路把 RAG 质量拆成多层:

  • rag/evaluation/cases.py 定义 GoldenCase。
  • retrieval_metrics.py 评估证据是否召回。
  • answer_metrics.py 评估答案点、引用、拒答和忠实性。
  • chain.py 把 trace、verification 和 evidence 接到答案评测里。
  • scripts/rag_eval/runner.py 把评测变成可重复运行的流程。

有了这套体系,后续每次改检索、rerank、上下文或拒答策略,都能用同一批样本比较,减少只靠肉眼看几个 demo 的判断偏差。

参考材料:

  • NexaRAG rag/evaluation/cases.py
  • NexaRAG rag/evaluation/chain.py
  • NexaRAG rag/evaluation/retrieval_metrics.py
  • NexaRAG rag/evaluation/answer_metrics.py
  • NexaRAG scripts/rag_eval/runner.py
  • NexaRAG scripts/run_rag_eval.py
  • 原 RAG 系列 09-RAG评测体系-从HitKMRR到Faithfulness.md