先看一个很常见的回答样式:
“这项费用可以报销。来源:员工手册.pdf。”
乍一看,它比没有来源的回答可靠很多。但点开文件以后,你可能发现员工手册有几十页,相关章节只讲报销范围,没有说这项费用一定可以报销。
文件名是真的,结论却不一定由文件支持。
这就是 RAG 面试里经常被一句“让模型标引用”带过的问题:
RAG 的引用怎样做到可以核验?为什么答案后面有一个来源编号还不够?
面试官继续追问时,通常会问到四件事:
- 引用编号由谁生成,模型能不能自己编?
- 编号指向真实原文,为什么仍可能是错引?
- 一句话需要两段证据时,引用怎样表示?
- 文档更新和重新切分后,旧引用还能不能打开?
引用为什么不是生成阶段临时加一下?
引用链的起点在文档解析,而不是 Prompt。
PDF 在解析时不能只抽出一串纯文本。文字框、页面布局、表格和图片等内容经过处理后,还要保留页面与位置信息。Chunk 进入索引时,应该能回答它来自哪个文档、哪一页、哪个章节,以及原文在页面上的位置。
这些 metadata 有不同职责。
doc_id 和 chunk_id 用来稳定识别内容。kb_id 用来限制搜索范围。章节标题和章节路径帮助用户理解上下文。页码、幻灯片编号、视频时间段或 bbox 坐标,负责把用户带回原位置。
如果解析时只保存了纯文本,页码和位置已经丢失,生成阶段再聪明也无法可靠补回来。模型可以猜一个页码,却不能把猜测变成证据。
检索返回 Chunk 时,不应只有内容和相似度分数,还要一起带回文档 ID、知识库 ID 和原始位置。引用系统应该沿用这条已有的数据链,而不是让模型凭语言能力重新描述来源。

文件名只能告诉用户大概来自哪里,可核验引用还要定位到当时用于回答的具体证据。
所以,回答末尾写“来源:某某.pdf”最多完成了文档级提示,还没有完成陈述级归因。
真正需要回答的是:这句话由哪一段原文支持,点击后看到的原文是否就是模型当时读到的内容。
一条引用是怎样生成的?
可以把完整链路拆成六步。
第一步,解析和切分时记录来源 metadata。
第二步,检索只从当前用户有权访问的知识库和文档版本中取候选。
第三步,服务端为本轮进入上下文的 Chunk 分配临时编号,比如 [1]、[2]、[3]。
第四步,Prompt 传给模型的是“编号、原文、必要的来源信息”,并要求事实陈述标注对应编号。
第五步,生成后检查模型用到的编号是否真实存在,再检查陈述和证据之间的支持关系。
第六步,服务端把编号映射成文档标题、章节、页码、原文摘录和可跳转位置。

编号只在本轮回答里使用,真正稳定的是后端保存的文档、版本、Chunk 和原位置。
这里有一个关键边界:编号必须来自服务端提供的证据集合。
假设本轮只给模型三段原文,模型却输出了 [7]。服务端不能因为格式看起来正确就接受它。这个编号不在本轮上下文中,应该标记为无效引用。
同样,模型不应该凭记忆写出文件名。即使文件名碰巧存在,也无法证明它是本轮检索结果,更无法证明模型依据的是该文件。
受控编号先解决“引用对象是否真实存在”,但还没有解决“这段原文是否支持这句话”。
编号是真的,为什么结论仍可能错?
下面只是一个教学问题,不对应真实客户或项目事件。
问题是:“核辐射是否在保障范围内?”
候选一讲的是保险责任,候选二讲的是责任免除。模型回答“核辐射不在保障范围内”,却把候选一标成来源。
编号一确实存在,原文也确实与保险范围有关,但它没有支持“核辐射不在保障范围”这条结论。
这就是引用有效性和证据支持性的区别。
前者检查编号能不能映射到真实候选,后者检查原文能不能推出对应陈述。
更严格的做法,是把答案拆成可以核验的事实句。对每句话分别检查:引用的原文是否包含关键实体,时间、数字和否定关系是否一致,结论是否只是主题相关,还是确实能由证据推出。
规则可以先拦一批明显错误。例如答案里出现某个数字,引用原文中却没有这个数字;答案说“禁止”,原文只说“建议”;答案说当前版本,证据却来自已停用版本。
剩下的语义关系可以用 NLI 或另一个模型辅助判断,但自动判断不是最终真值。它仍需要用人工标注样本校准,尤其是政策、法律、医疗等高风险内容。
一条事实还可能需要多段证据。
如果问题要比较两个方案,分别来自两份文档,模型只引用其中一份,就无法支持完整结论。如果结论需要先找到规则,再结合例外条件,两段原文都应该进入引用。

先检查编号是否存在,再检查原文是否支持陈述,最后检查回答所需证据是否完整。
“一句话挂一个来源”不是硬规则。真正的规则是:这句话包含的事实,需要哪些证据,就引用哪些证据。
Prompt 引用和后处理归因,怎么选?
Prompt 引用最容易落地。
系统把检索内容编号,要求模型在事实句后写出编号。好处是模型生成时就知道证据边界,回答和引用可以一起组织,用户读起来也自然。
它的问题同样明显。模型可能忘记标注,可能把整段话只挂一个编号,也可能给语义相近但不支持结论的片段贴上引用。
后处理归因走另一条路。
模型先生成答案,服务端把答案拆成句子,再从本轮候选中寻找每句话的支持证据。一种实用的组合是:先用句子相似度缩小候选,再用 NLI 或另一个核验模型判断“证据是否支持这条陈述”。相似度负责找相关内容,NLI 负责区分支持、矛盾与无法判断,两者的角色不同。
后处理的优点是控制更细,可以单独标出没有证据支持的句子。缺点是增加计算成本,而且如果检索阶段根本没有找到正确证据,后处理也无能为力。
实际设计不必二选一。
可以先让模型按受控编号生成,再对数字、日期、条款、适用范围等高风险句做后处理核验。低风险的解释性连接句不必都跑昂贵判断,事实性陈述则提高检查等级。
无论选哪种方式,都必须保留原始答案、事实句、候选证据、引用关系和核验结果。出了错,才能知道是模型漏引、服务端映射错,还是检索根本没有找对内容。
四种错引,分别断在哪一环?
第一种,只给文件名,不给原位置
用户看到“制度手册.pdf”,却不知道具体在第几页、哪个章节。
先检查 Chunk metadata 是否保留页码、章节和位置。如果这些信息在解析阶段就没有写入索引,生成端无法修复。解决重点在入库链路,而不是继续改 Prompt。
第二种,引用编号存在,但支持了别的事实
答案说“需要三项材料”,引用原文只列出其中一项。
先把答案拆成事实要点,再核对原文覆盖了哪些要点。完整结论需要多段证据时,应返回多个引用,或者缩小回答范围。
第三种,否定关系被引用错
原文写“以下情况不适用”,答案却说“以下情况适用”,同时仍然引用这段原文。
词面高度重合会让相似度看起来很好,但结论方向相反。数字、否定词、时间和条件词需要单独检查,不能只靠句向量相似度。
第四种,文档更新后跳到了另一段
旧答案保存的是“第 5 个 Chunk”,文档重新切分以后,第 5 个 Chunk 已经变成别的内容。
引用不能只依赖数组顺序。需要保存文档版本、稳定 Chunk ID 和原位置。旧答案可以继续指向旧版本,也可以明确提示来源已更新,但不能悄悄跳到新内容。
这四类错误分别来自 metadata、证据完整性、语义方向和版本管理。它们不可能靠一句统一 Prompt 全部解决。
文档更新后,引用怎样不失效?
文档更新是引用系统最容易遗漏的工程问题。
如果只保存页码,新增一页后后续页码可能整体变化。如果只保存 Chunk 序号,重新切分后顺序也会变化。如果只保存一小段原文,重复段落又可能让定位产生歧义。
更稳妥的引用记录至少包含文档稳定 ID、文档版本、Chunk 稳定 ID、原始页码或时间位置,以及生成回答时使用的证据快照或校验信息。
用户查看旧答案时,系统要明确它引用的是哪个版本。新版本已经替换规则时,可以提示“此回答基于旧版资料”,而不是把旧结论套到新文档上。
更新流程还要跑引用回归。选取一批已经存在的答案,检查链接是否可打开、定位是否一致、原文是否仍与当时证据相同。
引用展示怎样避免制造新的误解?
后端引用关系正确,前端展示仍然可能误导用户。
如果页面只展示一个醒目的文件名,却把真正支持结论的原文折叠得很深,用户会把“来自这个文件”误认为“这句话已经被文件证明”。更清楚的展示应该让答案中的编号、来源卡片和原文片段一一对应。
来源卡片至少可以显示文档标题、章节路径、页码或时间位置,以及与答案直接相关的短原文。用户点击后,再打开完整文档并定位到原位置,而不是只跳到文件首页。
当一句话有多个来源时,界面要显示多个编号,并说明它们分别支持哪一部分。把两个来源合成一个模糊的“综合资料”,会让用户无法核验推理链。
当系统只能找到部分支持时,也不应该给出和完全核验相同的视觉状态。可以区分“已找到直接证据”“需要结合多段证据”“未找到直接支持”,但这些标签必须来自后端核验结果,不能由前端猜测。
权限同样是引用链的一部分。
用户有权看到答案,不一定有权打开原文全文。系统需要在生成和展示前确认引用目标的访问范围。如果答案引用了用户无权查看的文档,既可能泄露标题和原文,也会出现一个永远打不开的“可信来源”。
更稳的做法是在检索时就应用权限过滤,只允许可访问证据进入模型。引用跳转再次校验权限,防止链接被转发后绕过访问控制。
引用导出和分享还要带版本信息。截图或复制文本离开系统后,用户至少能知道结论基于哪一版资料、检索于什么时间。不能把动态知识库里的回答包装成永远不变的事实。
因此,引用系统不仅是一个模型任务,也是解析、权限、版本和交互共同完成的产品能力。
还要注意答案改写带来的引用漂移。
模型第一次生成的句子可能能被原文直接支持,后续为了让表达更简洁,又把两个句子合成一个更强的结论。引用编号虽然被原样保留,新的结论却超出了原证据。
所以,事实核验应针对最终展示文本执行,而不是只核验生成过程中的中间版本。答案经过润色、翻译、摘要或格式化后,只要事实表达发生变化,就需要确认引用关系仍然成立。
同样,引用原文不宜只截取一个命中的关键词。过短的摘录可能隐藏前后否定和例外,过长又让用户难以看出依据。来源卡片应展示能够独立理解的最小完整语义单元,并允许继续展开上下文。
表格证据还要保留表头和行列关系。只展示某个单元格数值,用户不知道它属于哪个字段。图片或流程图则需要原图位置和经过验证的文字说明,不能让 OCR 片段代替完整视觉关系。
这些细节共同决定了用户点击来源以后,看到的是可以判断真假的证据,而不是又一段脱离上下文的文本。
引用关系应该保存成什么数据?
如果系统只把 [1] 留在答案字符串里,后续很难审计。更可复查的做法,是把答案、陈述和证据之间的关系保存成独立记录,而不是依赖展示文本里的编号顺序。
一条归因记录至少需要包含回答版本、事实句或字符范围、证据 Chunk 的稳定 ID、文档版本、原始位置和支持关系。支持关系不能只有“相关”,还应区分直接支持、需要多段共同支持、相互矛盾和无法判断。自动核验时,再记录核验器版本、输入证据和判定结果,方便后续用人工结论纠正。
临时编号只是当前页面的展示层。用户看到的 [1] 可以随着排序变化,但它在服务端必须映射到稳定证据身份。答案重新生成或编辑后,也要创建新的回答版本,不能让旧编号继续挂在已经改变含义的句子上。
多证据陈述需要显式保存组合关系。例如一个结论同时依赖通用规则和例外条款,两条证据缺一不可。若数据结构只存一串来源列表,系统无法判断删除其中一条后结论是否仍然成立。把它记录为“该陈述由证据 A 与证据 B 共同支持”,回归时才能检查完整性。
还要保存当时的访问边界。文档后来被删除、权限收紧或版本替换时,引用记录本身不能成为绕过权限的入口。展示层应再次鉴权,并根据数据策略决定显示受控摘录、提示来源失效,还是限制旧答案访问。
这类结构化记录让排查有明确入口:编号无效查映射,点击位置错误查版本和坐标,结论不受支持查陈述与证据关系,答案改写后错引查回答版本。否则所有问题都会混成一句“模型引用不准”,最终只能反复调整 Prompt。
怎么证明引用真的可靠?
评测集不能只标参考答案,还要标每个事实要点对应的正确证据。
至少准备五类样本。
第一类,单句由单段原文直接支持。
第二类,一句话需要两段或两份文档共同支持。
第三类,候选主题相关但不支持结论,用来测试错引。
第四类,答案包含数字、否定、时间和适用范围,用来测试细粒度一致性。
第五类,文档版本更新和重新切分,用来测试引用稳定性。
评测时分别统计引用覆盖、无效编号、错引、漏引和多证据完整性。还要做点击验证,确保用户最终看到的原文就是当时用于回答的证据。
自动核验模型的结果要和人工判断对照。模型把某句话判为“有支持”,不能直接当成系统已经正确。尤其当证据很长、存在例外条款或需要跨段推理时,人工抽检不可省略。

可靠引用既要检查答案和证据,也要检查编号、跳转、权限与版本。
引用追问怎么接:先分对象、支持和版本
后续每一问都先判断坏的是来源对象、陈述支持关系,还是文档更新后的版本映射,再选择对应核验手段。
让模型只回答检索内容,是否就不需要引用核验?
仍然需要。模型可能错误理解原文、漏掉例外条件,或者给正确文件贴上错误结论。内容受限不等于陈述和证据天然对齐。
为什么不直接让模型输出文件名和页码?
模型不能凭空知道可靠位置。文件名、页码和坐标必须来自解析与检索 metadata,服务端再完成编号映射。否则格式正确也可能是编出来的。
相似度高,能不能说明原文支持答案?
不能。相似度只能说明主题接近。否定关系、数字、条件和多段证据都可能在高相似度下出错,需要更细的支持关系判断。
NLI 能不能彻底解决错引?
不能。NLI 自身也会误判,而且长文档、领域术语和多跳证据会增加难度。它适合作为辅助筛查,仍要经过本领域人工样本校准。
文档删除后,旧引用怎么办?
要根据数据策略决定保留受控快照、显示来源失效,还是限制旧答案访问。无论哪种,都不能把旧引用悄悄映射到另一份新内容。
从编号走到可核验引用
现场回答沿着“来源数据、服务端编号、陈述核验、版本回跳”四步展开,重点是每一步都能被重新检查:
RAG 的引用不是在答案末尾加一个文件名,而是一条从解析到展示的数据链。入库时,每个 Chunk 要保留文档 ID、稳定 Chunk ID、章节、页码或原始坐标。检索后由服务端给本轮证据分配编号,模型只能引用这些真实编号,生成后服务端再映射回具体文档版本和位置。
我会把引用检查分成三层。第一层检查编号是否真的出现在本轮上下文,第二层把答案拆成事实句,判断所引原文是否支持对应陈述,第三层检查完整答案需要的证据是否都已覆盖。数字、否定、时间和适用范围会做更严格核验,NLI 或另一个模型只能做辅助,仍要用人工样本校准。
文档更新时不能只保存页码或 Chunk 顺序,还要保存文档版本和稳定 ID。评测会覆盖无效编号、漏引、错引、多证据引用和版本更新,并实际点击检查用户看到的原文是否就是当时的证据。这样引用才是可核验链路,而不是看起来专业的装饰。
最后用三个可核验问题收口:来源信息由哪一层写入,原文为什么足以支持这条陈述,内容更新后当时的证据链还能否被复查。只在 Prompt 里要求“标注来源”,回答不了这三个问题。