跳到正文
HANDS-ON PROJECT 03 · RAG EVALUATION

别先问 RAG 回答得像不像,先问证据到底有没有进来

这个项目故意不用外部向量库和大模型起步。先用标准库把文档身份、召回、融合、引用和评测合同跑通;之后无论替换 embedding、reranker 还是生成模型,旧问题集和失败样例都能告诉你改动究竟改善了哪一层。

问题进入版本化知识库后分成词法和语义两路检索,候选经过融合与证据检查;被支持的事实带引用进入回答,无依据内容在闸门被阻止
直觉总览:检索器负责把证据送进来,生成器负责只用证据作答,引用再把每个结论接回原文。三层必须分别记分,下面的 SVG 给出精确数据合同。 查看原图 ↗
01 · 先定义“做成了”

RAG 不是一个总分,而是两场连续考试

第一场考“资料员有没有把正确页找来”,第二场考“回答者有没有只依据这些页作答”。两场混成一个准确率,系统即使碰巧猜对答案,也会把检索失败藏起来。TREC 2024 已把文档相关性、信息 nugget 覆盖和逐句 citation / support 分开评估;2026 RAGTIME 仍要求多方面报告和引用证据。R05R09

RETRIEVAL

证据有没有出现

对每道题保存一个或多个 relevant chunk ID,检查 top-k 命中、首个命中位置与排序质量。

ANSWER

结论是否被支持

保存必须出现的事实、允许的拒答和引用要求,分别检查正确性、支持度与引用范围。

VERSION

答的是哪一版

语料、索引、embedding、reranker 和 Prompt 都要版本化;否则同一分数无法被复现。

固定样例 · 退款问题

题目不是只有一句“正确答案”

问题:标准订阅几天内能退款,额度有什么限制?
Gold evidence:handbook.md::退款规则
必须覆盖:“7 个自然日”与“已使用超过 20% 月度额度不支持自动退款”。如果回答写对 7 天,却引用发票段落,answer correctness 可能通过,citation precision 仍应失败。

02 · 完整机制

离线索引和在线回答,用同一个 chunk 身份接起来

解析器不要只吐出一串文本。每个 chunk 要保留来源、标题、版本、哈希与切分位置;BM25 和 dense 索引都引用同一个 chunk ID,引用渲染才不会在最后一刻“猜来源”。

RAG 两阶段数据流:离线把带来源、版本、哈希与 ACL 的文档解析为 chunk manifest,建立 BM25 和 dense 索引;在线问题先携租户与角色通过 ACL eligibility gate,只在授权语料上做两路召回、RRF 与 rerank,最终证据再次过 ACL 检查后才生成带引用和版本的回答。
绿色是版本化索引构建,蓝色是词法与证据流,紫色是 embedding 流,橙色是两道权限闸门。ACL 必须先缩小检索域,再对最终 evidence 做 fail-closed 复核。 查看原图 ↗

解析:先尊重文档结构

Markdown 可按标题切;HTML 要去导航与模板;PDF 还要处理页眉、脚注、表格和阅读顺序。解析错误会让后面最好的 embedding 也只能检索到乱码。

Chunk:完整语义与可召回性之间取舍

块太大,会混入无关段落并挤占上下文;块太小,限制条件与结论可能分家。示例先按标题,再对超长段落做固定长度和 overlap;生产项目要用固定问题集扫多个边界。

Hybrid:让两种检索器互补

BM25 对产品名、错误码、数字和原词匹配很强;dense 可能找到“反悔”和“撤销删除”这样的近义表达。本地 hashing dense 只用来跑接口,不冒充真正语义模型。

Rerank:把贵计算留给少量候选

先从两个廉价检索器拿到候选,RRF 合并,再让交叉编码器或 LLM reranker 看 query 与 chunk 的联合关系。候选中没有 gold chunk 时,reranker 无法凭空补回来。

03 · 无 Key 跑通

先跑协议 smoke,再替换真正的模型接口

项目在 examples/rag-eval。只依赖 Python 标准库,包含一份版本化手册、4 道固定问题、BM25、deterministic hashing 向量、RRF、reranker 接口和 JSON 报告。

TERMINAL · CPU ONLY
cd examples/rag-eval
python3 rag_eval.py --smoke
预期输出结构 · 具体分数以当前代码为准
{
  "retrieval_hit@3": 1.0,
  "retrieval_mrr": 1.0,
  "answer_keyword_recall": 0.875,
  "answer_citation_precision": 0.875,
  "answer_citation_recall": 1.0,
  "answer_citation_coverage": 1.0
}
report: .../examples/rag-eval/report.json
不要误读 smoke

示例只有 4 道合成题,得分高只证明端到端合同可运行。hashing baseline 把词项映射到固定维度,不具备现代语义 embedding 的泛化能力;替换它时应保持 Embedder.embed(texts) 接口,并在报告中写入模型、维度、归一化与 revision。当前 schema v4 已记录代码、问题、ACL、语料哈希,以及 tokenizer、BM25 k1/b、dense 维度与归一化、RRF k、候选深度、reranker 和 top-k;三类输入的 dataset version 必须一致。报告不保存 chunk 正文、角色列表或原始回答,每条引用还必须与当前 evidence 的 source/version/hash 全匹配,任意额外 text/quote 不会落盘。但 hash 证明的是身份,不是保密:标题、命中 ID 与低熵答案哈希仍可能泄露元数据,因此报告标为 evaluation-team-confidential,仍须继承 ACL、audience 过滤与保留期。

04 · 第一块记分牌

先定位“找到没有”,再讨论“排得好不好”

对于每道问题,把返回的 chunk ID 与 gold evidence 比较。若问题需要多个方面,单一 Hit@k 不够,还要检查 relevant chunks 的覆盖率或 graded relevance。

Hit@k有没有

top-k 只要出现任意相关 chunk 就为 1。适合最小门槛,但看不出命中在第 1 还是第 k。

MRR来得多早

取第一个相关结果名次的倒数:第 1 名是 1,第 4 名是 0.25。适合每题主要寻找一个答案片段。

Recall@k找得多全

相关 chunk 有多个时,检查 top-k 覆盖了多少。复杂问题只找到其中一页,最终回答容易缺方面。

nDCG@k顺序多合理

允许“高度相关、部分相关”不同等级,并对靠前结果给更高权重。标注成本也更高。

RRF · 只使用名次,不混不同分数量纲

同一 chunk 在 BM25 第 1、dense 第 4

若 k=60,它得到 1/(60+1) + 1/(60+4)。另一 chunk 若只在 dense 第 1,只得到 1/(60+1)。RRF 的好处是不用把 BM25 分数和 cosine 分数硬归一到同一尺度;代价是会丢掉原始分数差距,因此 k、候选深度和检索器集合都要写入版本。

05 · 第二块记分牌

答案要同时过事实、证据与版本三道门

“读起来像对的”不是指标。最小项目用必须关键词、引用 precision / recall,以及“每题是否至少有一条引用”的答案级 presence rate 作确定性检查;这个报告键沿用 answer_citation_coverage,但它不是逐 claim 支持率。生产环境可再加入人工标注或 LLM judge,并用人工样本校准 judge 的偏差和波动。RAGChecker 与 ARES 都把自动指标放回人工相关性或少量人工验证集上检验,而不是把 judge 输出直接当真值。R07R08

RAG 评测分层图:固定问题集依次定义 retrieval labels、answer labels 和版本账本;检索记分牌包含 Hit at k、MRR 和 nDCG,答案记分牌包含正确性、引用支持度和版本一致性;底部固定保留检索漏召回、无依据回答、缺引用、旧版本引用与 ACL 泄漏五类失败回归。
两块记分牌分别找责任层。底部五类失败样例不是一次性 bug,而应永久保留在回归集中。 查看原图 ↗
CLAIM

事实覆盖

问题要求的关键条件是否都出现?只说“可以退款”却漏掉 7 天与 20% 限制,属于不完整。

SUPPORT

引用支持

每个可核验结论是否能在引用 chunk 中直接找到?引用相关主题但不支持具体数字,仍不通过。

FRESHNESS

版本一致

答案引用的 source/version/hash 是否属于当前发布语料?旧政策即使曾经正确,也不能冒充当前答案。

06 · 五类失败回归

失败样例要能复现,而不是只留一句事故描述

每个失败案例都保存输入问题、当时索引与模型版本、检索列表、证据、输出与期望判定。修复后把它留在测试集,防止下次换 chunk 或 Prompt 时复发。

F01 · RETRIEVAL MISS

正确 chunk 没进 top-k

先查解析、chunk 边界、词法召回、query rewrite 与候选深度。不要先要求生成模型“更聪明”。

F02 · UNSUPPORTED

证据没有,答案却很确定

加入 claim—citation 支持检查和证据不足拒答;同时确认 Prompt 没鼓励模型用参数记忆补空白。

F03 · NO CITATION

结论可能正确,但来源为空

把 citations 作为生成输出 schema 的必填字段;答案渲染层不能在事后用相似度“配一个看起来像的来源”。

F04 · STALE VERSION

引用的是上一版政策

索引切换与应用发布要原子化;每个引用携带版本与 hash,读路径拒绝混用新旧 manifest。

F05 · ACL LEAK

无权限内容先被检索、再被界面遮住

租户、角色、文档有效期必须在 sparse 与 dense 两路召回前过滤,并在交给生成模型前再校验;前端不显示不能撤回已经进入上下文的泄露。

07 · 一次只改一个变量

从便宜、可解释的改动开始扫

固定问题集、语料版本和 k,先做单变量消融。否则 embedding、chunk、reranker 与 Prompt 一起换,即使分数变好,也无法知道收益来自哪里。

Chunk sweep

对比按标题、固定 180/240/360 字、不同 overlap。记录 chunk 数、平均长度、Recall@k、上下文 Token 与引用可读性。

Retriever ablation

分别跑 BM25-only、dense-only、hybrid RRF。若 hybrid 没提升,检查两路结果是否真的互补,而不是高度重复。

Reranker gate

固定召回候选,比较无 reranker、轻量 overlap、交叉编码器;同时记录延迟和 gold chunk 被错误降权的案例。

Answer contract

固定 evidence,只改 Prompt、输出 schema 或生成模型。这样答案退化时不会误怪检索器。

08 · 失败排查

先找到责任层,排查会快很多

把一次失败保存为可读 trace:query → sparse/dense 排名 → RRF → rerank → final evidence → answer → citations。下面是最常见的症状与第一检查点。

中文问题完全搜不到,但复制原文能搜到

本地 tokenizer 或 embedding 可能不适配中文;先打印分词结果,再确认 dense 模型的语言覆盖、query/document 是否使用正确前缀、向量是否按模型要求归一化。

top-20 有 gold,rerank 后掉出 top-3

责任在 reranker 或输入截断。检查 query—chunk 拼接顺序、最大长度、标题是否被保留;为这条样例单独保存 rerank 前后分数。

答案引用了正确文档,却不支持具体数字

文档级引用太粗。改为 chunk 或句子级引用,并逐 claim 检查支持度;不要把“同一份手册”视作所有说法都被支持。

离线通过,线上偶尔引用旧版

检查索引、缓存与应用配置是否非原子切换。答案返回 manifest version,日志按版本分组;蓝绿发布时不要让新 Prompt 读旧索引。

RESEARCH LEDGER

一手来源与证据边界

优先使用论文、官方文档、官方模型卡和代码仓库。页面中的数字只代表来源所述设置,不自动外推到其他模型与数据。

R01
Retrieval-Augmented Generation for Knowledge-Intensive NLP TasksLewis et al. · NeurIPS 2020

RAG 的检索—生成基本问题设定;页面不把论文中的具体系统当作所有现代 RAG 的唯一架构。

R02
BEIR: A Heterogeneous Benchmark for Zero-shot Evaluation of Information Retrieval ModelsThakur et al. · 2021

异构检索任务与 nDCG、Recall 等指标;提醒检索器不能只在单一语料上判断。

R03
Reciprocal Rank Fusion Outperforms Condorcet and Individual Rank Learning MethodsCormack, Clarke, Büttcher · SIGIR 2009

RRF 的原始方法来源;示例使用 score = Σ 1/(k+rank),k 是需记录的配置。

R04
RAGAS: Automated Evaluation of Retrieval Augmented GenerationEs et al. · EACL 2024

RAG 答案与上下文评测的自动化思路;LLM-as-judge 仍需人工校准,不能当绝对真值。

R05
TREC 2024 RAG Search TrackNIST TREC · 2024

官方 topics、文档相关性、nugget 与 citation/support judgments;用于说明检索、内容覆盖和引用支持需要分层衡量。

R06
Dense Passage Retrieval for Open-Domain Question AnsweringKarpukhin et al. · EMNLP 2020

双编码器 dense retrieval 的经典公开实现与实验边界。

R07
RAGChecker: A Fine-grained Framework for Diagnosing Retrieval-Augmented GenerationRu et al. · NeurIPS 2024 Datasets and Benchmarks

把 retrieval 与 generation 继续拆成 claim recall、context precision、context utilization、noise sensitivity 等诊断指标,并用人评做 meta-evaluation。

R08
ARES: An Automated Evaluation Framework for Retrieval-Augmented Generation SystemsSaad-Falcon et al. · NAACL 2024

Context relevance、answer faithfulness、answer relevance,以及用少量人工标注和 Prediction-Powered Inference 校准自动 judge。

R09
Call for Participation in TREC 2026 — RAGTIMENIST TREC · 核查于 2026-07-17

当前长报告任务继续强调多方面覆盖、跨语言检索与逐项引用支持,说明单一答案正确率不足以验收 RAG。