做 RAG 演示时,我们很容易把注意力放在“能否答出这个问题”上。真实使用时,用户还会追问:答案依据哪份文件?那份文件是否已经更新?我有没有权限看它?如果没有证据,系统会不会编一个看似合理的结论?
这几个问题指向同一件事:RAG 的交付物不只是回答,而是可以回到原文核对的回答。
先把文档变成可追踪的证据
文档进入知识库时,除了正文,还应留下来源、版本、页码或章节、更新时间和访问范围。切分后,每个片段继续携带这些信息。否则,即使向量检索命中了正确段落,最终引用也可能只剩一个无法定位的文件名。
对于表格、扫描件和混合版式,解析质量通常比换一个更大的生成模型更重要。表头丢失、行列关系错位,后续检索和推理都会建立在错误输入上。因此摄取流程需要保留原件,允许抽样对照解析结果,并能针对某个文档重新处理。
检索不等于“取相似度最高的几段”
一个可用的检索链路通常分成候选召回、重排和证据筛选。关键词检索擅长编号、术语与精确名称;语义检索适合改写后的自然语言问题。两者混合后,再根据问题与片段的对应关系重排,比单一路径更稳。
但分数高不意味着可引用。候选片段还要经过权限过滤、版本过滤和去重。如果问题问的是现行政策,旧版文件即使语义最接近,也不应成为最终依据。过滤应发生在答案生成前,而不是生成后才尝试遮盖。
给模型一条清楚的停止线
当证据不足、互相矛盾或超过用户权限时,系统应该说明缺口,并给出下一步:换关键词、补充范围、联系文档负责人,或转人工确认。把“未找到足够依据”视为成功的安全输出,能减少最难排查的自信误答。
我更愿意把最终结果建模为:
问题 → 已授权的候选证据 → 重排与筛选 → 带引用的回答 / 明确拒答
这条链路中每一步都应能复盘。排障时可以看到原问题、检索词、命中文档、筛选原因、引用片段和最终回答,而不必靠猜测模型“当时在想什么”。
RAG 的可靠性往往来自这些朴素的工程约束。模型能力会继续提升,但证据、权限和版本的责任不会自动消失。
引用要经得起一次点击
一个引用不能只写“来源:员工手册.pdf”。读者至少应能定位到章节或页码,并看到支持这句话的原文范围。若答案把两个段落合并成一个结论,引用应覆盖全部必要条件;若原文有例外条款,不能只引用一般规则。引用定位失败时,系统应降低对答案的确定性,而不是生成一个看似完整的脚注。
文档更新会让引用失效。因此片段应关联稳定的文档标识和版本,原文替换后能区分“新版本同一位置”与“旧版本的历史证据”。对需要留痕的业务,保留可审计的历史引用;对只应提供现行规则的问答,则在检索时排除失效版本。这两种需求不能靠一个“最新文件名”同时满足。
把错误分层,而不是统称幻觉
有时回答错误是模型忽略了正确片段;有时答案从错误片段忠实生成,根因在检索;还有时片段本身因为 OCR 或表格解析已经错了。三者都可能表现为“模型说错了”,但需要不同修复。排障时先看原件与解析结果,再看候选和过滤,最后看答案是否被证据支持。
我会把回归问题分成单段事实、跨段条件、旧版与新版冲突、授权边界以及确实没有答案五类。每次改模型、索引或提示词都按这五类对照。一个可交付的 RAG 系统,不是永远不会错,而是在它错时能找到证据断点,并让同类错误更难再次发生。