# RAG 评测实战（五）：引用都挂上了，证据真的撑住了吗？

> 重算 ALCE 公开历史生成结果：区分引用标记、句子支持与单条证据，拆开问题宏平均和句子微平均，检查引用截断、重复编号与空答案。附固定版本下载器、零依赖审计代码、结果和边界测试。

- 作者：芝士AI吃鱼
- 发布日期：2026-10-05
- 主题：RAG、AI工程、引用审计、评测
- HTML 正文：[https://ai-knowledgepoints.cn/blog/rag-evaluation-05-citation-audit](https://ai-knowledgepoints.cn/blog/rag-evaluation-05-citation-audit)
- Markdown 永久链接：[https://ai-knowledgepoints.cn/blog/rag-evaluation-05-citation-audit/index.html.md](https://ai-knowledgepoints.cn/blog/rag-evaluation-05-citation-audit/index.html.md)

引用本文时，请注明作者与 HTML 正文链接。Markdown 版本用于机器阅读，与 HTML 正文共享同一内容来源。

## 正文

一段答案后面挂满了方括号，看起来总比空口断言可靠。点开引用，资料也确实存在。检查似乎已经走完，直到有人追问：这条材料究竟支持了句子里的哪一件事？

引用可以装得很整齐，分母却可能悄悄换了。按题平均和按句平均不是同一个问题；正文写了五个引用，也不保证评测器真的检查了五个。要把生成后的答案交给[上一篇的发布门禁](https://ai-knowledgepoints.cn/blog/rag-evaluation-04-release-gates)，先得知道那一个支持率，究竟怎么算出来。

本篇不再编写合成回答充当模型输出。实际运行的是一套原创 Node.js 审计程序，输入来自 ALCE 项目公开存档的真实历史模型输出及既有人工、自动评审记录。**本文没有调用生成模型，没有重新运行 NLI 模型，也没有新增真人标注。** 重跑的是数据核验和统计，不是重现当年的模型生成过程。资料核对日期：2026 年 10 月 5 日。

## 1. 先把可复现的范围圈出来

[ALCE 论文](https://arxiv.org/abs/2305.14627v2)把带引用生成的评价拆成多个维度，其中包括答案正确性与引用质量。本文只研究其公开引用评审档案中的一个固定切片，不用这一小块材料替整个 RAG 系统打总分。这是上游选定模型与问题的人类评审样本，不是完整 ASQA 数据集的随机无偏评测。

输入锁定在官方仓库提交 `246c476a4edfc564266b7346b6e29ef4861ae937` 的 [human_eval_citations_completed.json](https://github.com/princeton-nlp/ALCE/blob/246c476a4edfc564266b7346b6e29ef4861ae937/human_eval/human_eval_citations_completed.json)，选择 `asqa` 下的 `asqa-gpt-35-turbo-gtr-shot2-ndoc5-42-azure.json`。这是一个有名称、有原始字节、有问题 ID 的历史配置，而不是今天还能原样调用的模型接口。档案未提供可唯一恢复的服务端模型快照；配置名中的模型别名，不能被写成精确权重版本。

复现分两层：下载器检查提交地址和 SHA-256，保证拿到指定字节；审计器检查字段、配对、标签取值和分母约定，保证这些字节按同一规则被计数。前一层不能证明标注正确，后一层也不能证明旧知识今天仍然正确。二者合起来能回答的是：**这份存档里的结果，在明确规则下怎样汇总，哪里有分歧。**

网站仅提供原创代码、统计结果和可定位的问题 ID，不打包复制整份模型回答与检索段落。源仓库有 MIT 许可，但检索材料涉及 Wikipedia 等底层来源，不能据此假定所有来源文字都变成 MIT。下载器把原始 JSON 留在读者本地；若要再分发原文，应另行检查相应材料的许可与署名要求。原始 JSON 始终作为数据读取，不执行其中任何内容。

## 2. 三种检查对象，别挤进一个支持率

第一层是结构：一句话有没有 `[1]` 这样的数字标记，能不能找到引用记录，记录与答案是否对应。正则表达式适合做这种工作。它不会理解时间、条件、否定或因果，更不会判断一篇文档有没有支持整句话。

第二层是句子与一组证据：把这一句关联的资料放在一起，是否支持句子中的全部事实性内容。本文直接读取上游的句子标签。它是一次既有评审的结果，并非脚本在本次运行中读懂了证据。

第三层是句子与单条引用：这一条证据支持了多少。上游[人工评审说明](https://github.com/princeton-nlp/ALCE/blob/246c476a4edfc564266b7346b6e29ef4861ae937/human_eval/README.md)区分无支持、部分支持和完整支持。部分支持未必没有价值：一个复合句可能需要两条资料共同支撑。但如果其中一条只支持半句，不能把它展示成单独证明整句话的万能引用。

考虑一个明确标为教学例子的句子：“设备支持离线检索，并且断网后仍能自动同步。”材料甲只说离线检索，材料乙说联网后同步。找到两个相同关键词，检查不出断网条件被改写；两个引用也不能把错误条件拼成正确答案。这里的例子用于说明审查对象，没有计入后面的真实档案统计。

命题级审计应继续把复合句拆成最小可核查命题，保留条件、时间、主体与数量，再分别寻找支持。本文档案提供的是句子级标签，不能从它倒推出每个命题的真值，更不能编造命题级准确率。因此本次实现停在句子与引用层；这是可复现范围的边界，不把尚未完成的细粒度标注写成已经测过。

![引用审计区分数字标记、句子与证据集合、单条引用和命题级支持；本次只重算既有句子及引用记录，没有重新执行语义评审。](https://ai-knowledgepoints.cn/images/articles/rag-evaluation-05/audit-levels.svg)

AI 辅助制作的原创机制图。各层检查对象不同，结构校验不能替代语义判断。

[查看竖版大图](https://ai-knowledgepoints.cn/images/articles/rag-evaluation-05/audit-levels-mobile.svg)

## 3. 先数清题、句子和引用发生次数

本次完整读取所选配置的 100 个问题记录，没有按答案好坏抽取子集。其中 99 个有非空输出，1 个为空；另有一个名为 `overall_results` 的汇总键，它不是第 101 道题。空输出保留在问题级分母中，按零分计入；句子级分母只包含档案划分的 236 个句子单位，不能凭空给空回答制造一句话。沿用的分句中包含只有引用标记的单位和未带引用的拒答表达；本文不重新分句，也不把每个单位都当成独立事实命题。

| 检查对象 | 分子 / 分母 | 本次结果 |
| --- | --- | --- |
| 有数字引用标记的句子 | 205 / 236 | 86.86% |
| 上游人工标签认为完全被支持的句子 | 168 / 236 | 71.19% |
| 上游自动标签认为完全被支持的句子 | 171 / 236 | 72.46% |
| 有引用、但人工标签未判完全支持的句子 | 37 / 205 | 18.05% |
| 所有句子都被人工标签判为支持的回答 | 59 / 100 | 59% |

这些行的分母有意写出来。37/205 只问“已经挂了引用的句子里，还有多少没获得完整支持标签”，不能写成全部句子的失败率；59/100 把完整回答作为单位，也不会被长答案多写几句话而放大权重。句子级失败不等价于整句事实为假，可能是证据不足、引用错配、条件遗漏或既有标注分歧，具体原因需要回看原文。

若先计算每道题内部的句子支持比例，再对 100 道题等权平均，人工结果是 **74.69%**，自动结果是 **75.35%**。前表的 71.19% 和 72.46% 则先汇总所有句子，属于句子微平均。较长答案在微平均中占更多单位；宏平均让每道题权重相同。两个结果都可计算，但报告必须说明关注的是“平均一题”还是“平均一句”。空答案的零分约定也要随指标一起保留，不能在打印表格前顺手过滤。

引用处还有一个更隐蔽的岔口。236 个句子的文本中出现 **306 次数字引用标记**，存档里却只有 **290 个已评分的引用记录**。按固定版本 [eval.py](https://github.com/princeton-nlp/ALCE/blob/246c476a4edfc564266b7346b6e29ef4861ae937/eval.py) 的默认上限核对，每句最多计入前三次引用；共有 10 句超过三次，合计有 16 次不在当前计分记录内。这里验证的是数量形状与默认规则一致；存档的引用记录缺少可直接核对的原始编号字段，程序不据此保证每一条的身份映射绝对正确。

其中还有 2 个句子重复使用同一引用编号。本文按标记出现次数和存档记录次数统计，没有偷偷去重，也没有把重复编号当成两篇不同文档。若产品想评价“不同证据来源的覆盖”，就需要另一种去重后的定义，并且重新审查关联关系；不能直接改分母而沿用当前标签。

![实际审计包含100题、236句、306次数字引用和290个已评分引用记录；1个空答案留在问题分母，16次超出前三条范围的标记不冒充已有标签。](https://ai-knowledgepoints.cn/images/articles/rag-evaluation-05/denominator-ledger.svg)

AI 辅助制作的原创统计图。数字来自本次运行结果，只描述固定历史存档。

[查看竖版大图](https://ai-knowledgepoints.cn/images/articles/rag-evaluation-05/denominator-ledger-mobile.svg)

290 个引用记录的原始人工标签分别为：完整支持 195 个、部分支持 58 个、无支持 37 个。这个三分表不能直接改名为“引用精确率”。上游 [analyze.py](https://github.com/princeton-nlp/ALCE/blob/246c476a4edfc564266b7346b6e29ef4861ae937/human_eval/analyze.py) 还有一条组合规则：句子整体先获支持，单条引用再至少有部分贡献，才计为接受。

按这条规则重新计算，人工接受 228/290，引用记录微平均为 78.62%；逐题先平均、空记录按零再汇总，则为 76.58%。自动接受 218/290，微平均 75.17%，逐题宏平均 74.36%。部分支持的 58 条里，有 34 条所在句子获整体支持，24 条没有；这些数字说明单条标签与整句标签怎样共同影响结果，不意味着脚本重新证明了每条证据的必要性。

档案里甚至存在 1 条“单条引用完整支持、所在句子却未获完整支持”的记录。审计器保留这个不一致线索，不擅自改标签让表格整齐。汇总字段也不是万能真值：本文从底层记录重算，不把文件中的旧总分直接当成本次结果。

## 4. 自动评审与人工记录，差在哪些句子

把人工句子标签作为对照行、自动标签作为列，236 个配对单位得到下面的表。这里的“对照”只是统计方向，不预设人工标签绝对正确。

| 上游句子标签 | 自动未判支持 | 自动判支持 | 行合计 |
| --- | --- | --- | --- |
| 人工未判支持 | 51 | 17 | 68 |
| 人工判支持 | 14 | 154 | 168 |
| 列合计 | 65 | 171 | 236 |

两边有 205/236 个句子判断相同，即 86.86%；但这个比例恰好与前面的引用标记出现率相同，只是数值巧合，两个指标没有同一个含义。对照人工记录看，自动判支持而人工未判的有 17 句，反向有 14 句，总共有 31 句分歧。不能把 171−168=3 当成“只有三句需要复查”。

报告也保留引用记录组合规则下的四格计数：双方都不接受 37 条，自动接受而人工不接受 25 条，人工接受而自动不接受 35 条，双方接受 193 条，合计 290 条。两层分歧分别定位不同问题，不适合混在一个分母里。

这里的“人工”指上游公开文件给出的标签，不能被扩大解释为本次组织了多位标注员或证明了所有人的共识。程序不把重复引用当作独立标注员，不把同一句的多条证据当作多张支持票，也不根据输出好坏筛掉难例。

自动与人工有分歧时，单看总支持率接近，会遗漏方向相反的错误。一个系统在某些句子上过于宽松，在另一些句子上过于保守，两种偏差可能在平均数里互相抵消。审计报告保留问题 ID 和句子序号，供读者回到原始材料逐一检查；它不通过多数票宣告某一个判断必然正确。

更不能拿这些旧档案为当前评审模型做能力背书。没有重跑模型，没有新样本，也没有领域迁移检验。对真实业务，下一步是拿固定的当下输出和证据，按明确定义重新标注，记录分歧原因，再考察新评审器。本文得到的只是一个可运行的接入点：让每一项结果都能追到它实际对应的材料。

## 5. 让重跑先失败在输入，而不是成功地产生错表

附件只依赖 Node.js 内置模块。实际执行环境为 Linux x86_64、Node.js v24.19.0。先下载这几份文件到同一目录：

- [download.mjs：固定来源与字节校验](https://ai-knowledgepoints.cn/examples/rag-evaluation-05/download.mjs)
- [source.mjs：固定来源清单与校验函数](https://ai-knowledgepoints.cn/examples/rag-evaluation-05/source.mjs)
- [audit.mjs：输入校验与统计程序](https://ai-knowledgepoints.cn/examples/rag-evaluation-05/audit.mjs)
- [test.mjs：合成边界与真实存档回归测试](https://ai-knowledgepoints.cn/examples/rag-evaluation-05/test.mjs)
- [results.json：本次实际运行结果](https://ai-knowledgepoints.cn/examples/rag-evaluation-05/results.json)
- [README.md：来源、命令和指标定义](https://ai-knowledgepoints.cn/examples/rag-evaluation-05/README.md)

```bash
node download.mjs
node audit.mjs > reproduced.json
node test.mjs
```

下载器将固定源文件写入操作系统临时目录，打印实际路径；审计器无参数时读取同一默认位置。若已有该提交的源文件，可运行 `node download.mjs --from /绝对路径/源文件.json`，仍须通过相同哈希验证；也可用 `node audit.mjs --input /绝对路径/源文件.json --out reproduced.json` 显式指定读写位置。下载与审计均不需要 API 密钥。完整命令和文件清单见 README。

输入校验应优先检查评审数组与句子数一致，标签属于文档规定的集合，问题身份不被重名覆盖，空输出与空句子记录一致。它不应该在遇到无法解释的形状时自动截断数组，然后照常给出漂亮百分比。本文对上游的特殊结构逐项声明：汇总键不是问题、空答案保留在问题分母、引用计分有数量上限。真实业务若采用不同规则，应该显式换版本，而不是改一行过滤条件却沿用同一个指标名称。

边界测试使用单独构造的微型合成数据，包括字段缺失、标签非法、配对错位与分母变化等情况。**合成数据只用于测试程序行为，不作为模型效果数据。** 真实存档结果则独立回归，避免只验证一个特意为公式写出来的顺利例子。哈希校验也有独立测试，源文件被截断或替换时应停止，而不能悄悄把另一批数据计入同一份报告。

## 6. 回到知识库：保存能解释争议的最小记录

把这个实验接到自己的 RAG 管线，不要先追求一个统一的“可信度”。先保存问题身份、实际答案、证据身份与版本、句子或命题边界、引用关系、评审规则和原始评审结果。隐私材料保存在受控位置，公开调试附件使用脱敏材料；一个可复现报告不需要把用户文档全量复制到公开仓库。

结构检查与语义检查分别报告。失效引用可以直接定位到编号；部分支持则需要展开句子，说明缺的是哪项条件；空答案应保留为可见结果，同时另行区分合理拒答、服务失败与无意空输出。本文原始档案不足以解释空输出的运行原因，因此没有把它自动判为安全拒答。

证据集合也要保留审查范围。若系统只让评审器看前三条引用，页面却展示五条，报告应该同时写明“展示了多少”和“检查了多少”。需要审查全部引用时，增加预算、重跑评审、重新记录分母；不能靠把旧分数贴回全部引用旁边完成扩容。

系列前四篇分别处理证据召回、切块身份、候选融合和发布门禁。这一篇补上生成结果与支持证据之间的连接：从真实存档里还原分母、审查范围与分歧，让下一次谈“引用支持率”时，可以直接打开记录问清楚它支持了什么。

系列导航：

- [第一篇：证据召回与答案支持](https://ai-knowledgepoints.cn/blog/rag-evaluation-01-evidence-to-answer)
- [第二篇：切块与稳定证据映射](https://ai-knowledgepoints.cn/blog/rag-evaluation-02-chunking-evidence-mapping)
- [第三篇：两路词法、RRF 与重排](https://ai-knowledgepoints.cn/blog/rag-evaluation-03-rrf-candidate-reranking)
- [第四篇：评审校准与离线发布门禁](https://ai-knowledgepoints.cn/blog/rag-evaluation-04-release-gates)
- 本篇：真实历史输出的引用审计与统计重放
- [RAG 主题文章](https://ai-knowledgepoints.cn/blog?tag=RAG)

想讨论自己的引用记录，可以从 [AI 实践路线](https://ai-knowledgepoints.cn/planet)了解知识星球的讨论方向；公众号入口在[关于页](https://ai-knowledgepoints.cn/about#wechat)。带上脱敏后的句子、对应证据和失败类别，会比单独一张总分截图更容易找到问题。

本文文字、示例代码与图解由 AI 辅助制作；上游数据、人工标签与自动评审结果的来源及本次运行边界已列明。本文不代表对任何当代模型或生产知识库的质量认证。
