AI CXYKK AI 教程
REF 检索质量和引用来源
面向程序员 · RAG 工程进阶课

检索质量和引用来源:让 AI 找得准、答得有依据

RAG 的成败不只看模型会不会写。第一步是检索质量:正确资料有没有被找回来、有没有排在前面、有没有被权限和版本过滤。第二步是引用来源:模型的关键结论能不能追到真实资料。

召回决定有没有资料 正确资料没被检索出来,后面模型再强也只能猜。
排序决定用哪些资料 召回了一堆资料,但正确资料排太后,仍然进不了上下文。
引用决定能否审查 答案没有 sourceId,就很难判断它是基于资料,还是模型自己补出来的。
校验决定是否可信 sourceId、quote、chunkId 都要能在本轮检索结果里找到。
retrieve(query) topK=3
1
product-import-prd-v2#sec-3.2:失败处理
0.91
2
openapi-product-v4#import-task-result
0.84
3
product-faq-v3#import-errors
0.76
answer.sourceId
quote matches chunk
01 · 先给定义

检索质量是 RAG 的第一道质量门

检索质量不是“查到了几条”。真正要看的是:正确资料有没有召回,是否排在足够靠前的位置,是否符合版本和权限要求,是否能支撑最终答案。

Recall

召回

正确资料有没有被找出来。没召回,答案只能靠猜。

Ranking

排序

正确资料是否排在前面,能不能进入上下文。

Filter

过滤

版本、权限、业务域、状态是否过滤正确。

Citation

引用

答案里的关键结论是否能追到来源片段。

一句话记住 RAG 的质量先看检索,再看生成。检索错了,模型生成得再自然,也只是把错误资料包装得更像答案。
02 · 检索失败类型

答案错了,先别急着怪模型

最终答案出错,可能发生在检索链路的任何一步。程序员要能把问题拆开看:没找回来、找错了、排错了、过滤错了,还是引用错了。

Missing

正确资料没召回

知识库里有答案,但检索没找出来。常见原因是切片差、别名缺失、query 写法不匹配。

Wrong

召回了相似但错误的资料

相邻系统、旧版本、相似字段容易混进来。模型会基于这些资料答错。

Low Rank

正确资料排太后

topK 只取前几条时,正确资料可能被挤出上下文。

Bad Filter

权限或版本过滤错误

无权限资料进了上下文,或者最新资料被过滤掉。

No Citation

答案没有引用

无法判断回答是否基于资料,后续也无法审查。

Fake Citation

引用是模型编的

sourceId 不存在,或者 quote 并不在原文里。

03 · 查询理解和改写

用户问题不一定适合直接拿去检索

用户会用口语、简称、错别字、业务别名来提问。检索系统要先理解问题,再改写成更适合知识库的查询。

原始问题

表达口语化,检索不稳定

导入挂了能不能下失败明细?
  • “挂了”是失败。
  • “失败明细”可能是错误明细、失败行、导入结果。
  • 缺少业务域:商品、订单还是库存。
改写查询

更贴近知识库表达

{
  "intent": "query_import_failure_detail_download",
  "domain": "product",
  "queries": [
    "商品批量导入 失败明细 下载",
    "商品导入 错误明细 失败行",
    "import task error detail export"
  ]
}

改写不是为了让答案更长,而是提高召回正确资料的概率。

补业务域

同一个“导入”可能发生在商品、订单、库存。业务域能减少误召回。

补别名

SKU、商品编码、货号可能指同一类概念。别名表能提高召回。

保留原问题

改写后的 query 用于检索,原问题仍要给模型,避免语义被改坏。

04 · 召回质量

召回看的是正确资料有没有回来

召回质量通常用评测集衡量。每个问题都提前标注“应该命中的资料”。检索后看这些资料是否出现在 topK 结果里。

召回评测样例

{
  "question": "商品导入失败后是否支持下载错误明细?",
  "expectedSources": [
    "product-import-prd-v2#sec-3.2",
    "openapi-product-v4#import-task-result"
  ],
  "retrievedTop5": [
    "product-import-prd-v2#sec-3.2",
    "product-faq-v3#import-errors",
    "order-import-prd-v1#sec-2.1"
  ]
}
Recall@K 正确资料是否出现在前 K 条结果里。
Hit Rate 每个问题是否至少命中一条正确资料。
Coverage 高频问题是否都有可召回资料。
Noise Rate 召回结果里无关资料占比有多高。
05 · 排序和重排

召回到不等于用得上

检索会召回一批候选资料,但上下文窗口有限。排序和重排负责把更相关、更权威、更适合当前用户的资料放到前面。

排序因素 为什么重要 例子
语义相关性 片段是否真的回答当前问题。 失败明细问题应命中失败处理,而不是导入入口。
版本新鲜度 旧版本资料可能口径过期。 v3 文档应排在 v1 文档前面。
来源权威性 正式 PRD 和接口文档比聊天记录更可信。 OpenAPI > 会议纪要 > 群聊摘录。
权限适配 用户无权资料不能进入上下文。 客服不能看到内部安全策略原文。
业务域匹配 相邻系统很容易误召回。 商品导入不应优先用订单导入文档。

重排前

1. order-import-prd-v1
2. product-import-faq-v3
3. product-import-prd-v2

语义相似但业务域和版本不一定合适。

重排后

1. product-import-prd-v2
2. product-import-faq-v3
3. openapi-product-v4

更贴近当前问题和业务系统现状。

06 · 引用来源设计

引用不是装饰,是答案的证据链

企业应用里,引用来源要能支持审查。只显示“参考资料 1”不够,最好能包含 sourceId、chunkId、片段标题、引用文本和置信说明。

引用字段建议

  • sourceId:原始文档或资料版本。
  • chunkId:具体知识片段。
  • title:片段标题,方便人类识别。
  • quote:支持结论的原文短句。
  • claimId:引用支持哪条结论。
  • retrievedRank:检索结果中的排名。

结构化引用示例

{
  "claim": "当前版本不支持下载错误明细。",
  "citations": [
    {
      "sourceId": "product-import-prd-v2",
      "chunkId": "product-import-prd-v2#sec-3.2",
      "title": "失败处理",
      "quote": "当前版本不支持下载错误明细",
      "retrievedRank": 1
    }
  ]
}
引用粒度要够细 只引用整篇文档,审查成本仍然很高。最好引用到具体段落或 chunk,让人能快速定位。
07 · 引用校验

模型写出的引用也要验

模型可能编 sourceId,也可能把 A 文档里的话说成 B 文档的引用。后端要检查引用是否来自本轮检索结果,quote 是否能在原文里找到。

1 收集引用 读取模型输出中的 citations。
2 检查来源 sourceId 是否来自本轮检索。
3 检查原文 quote 是否能在 chunk 中匹配。
4 检查结论 引用是否真的支持该 claim。
5 标记风险 缺引用、假引用、弱引用分开处理。
6 决定流转 通过、重试、降级或人工审核。
for (const citation of answer.citations) {
  assert(retrievedChunkIds.includes(citation.chunkId));
  assert(chunkText(citation.chunkId).includes(citation.quote));
  assertCitationSupportsClaim(citation, answer.claims);
}
08 · 评测指标

检索和引用要分开评测

一个 RAG 系统可能检索很好但引用差,也可能引用格式很好但资料召回差。指标要拆开,不要只看最终答案满意度。

指标 衡量什么 怎么使用
Recall@K 正确资料是否出现在前 K 条结果里。 衡量召回能力,适合检索阶段。
MRR 第一个正确结果排得有多靠前。 衡量排序质量。
nDCG 多个相关结果的排序质量。 适合有多级相关性标注的评测集。
Citation Coverage 关键结论是否都有引用。 衡量引用覆盖率。
Citation Precision 引用是否真的支持结论。 衡量引用准确性。
Groundedness 答案是否基于检索资料,而不是凭空生成。 衡量 RAG 答案可信度。
检索 Recall@K、MRR、nDCG、Noise Rate。
引用 Coverage、Precision、sourceId 有效率。
答案 准确率、拒答质量、可读性、完整性。
线上 点踩率、人工修改率、无答案率、延迟。
09 · 排查手册

答案错了,要沿链路定位

不要只问“模型为什么答错”。RAG 排查要从用户问题开始,一步步看查询改写、召回、排序、上下文、生成和引用校验。

现象 优先排查 修复方向
正确资料没出现 切片、别名、query rewrite、索引更新 补别名、重切片、更新索引、增加关键词检索。
旧资料排在前面 version、status、updatedAt、重排规则 旧版本降权或过滤,最新资料提权。
答案没有引用 Prompt、输出 schema、后端校验 强制 citations,缺引用则重试或人工审核。
引用不存在 sourceId 校验、chunkId 校验 只允许引用本轮检索结果。
引用正确但结论错 模型推理、Prompt、上下文冲突 让模型逐条 claim 绑定引用,冲突时列待确认项。
检索结果太多噪声 业务域过滤、文档类型过滤、重排 加元数据过滤,优化 reranker 和 topK。
10 · 企业案例

商品导入失败明细:从错误答案到定位问题

用户问:“商品导入失败后能不能下载错误明细?” 模型回答“支持下载”,但实际系统不支持。我们按 RAG 链路排查。

1 看问题 识别为商品导入失败处理。
2 看召回 是否召回 product-import-prd-v2。
3 看排序 旧 FAQ 是否排在正式 PRD 前。
4 看上下文 是否同时放了冲突资料。
5 看引用 sourceId 是否支持“支持下载”。
6 修链路 旧资料降权,强制引用校验。

修复后的答案格式

{
  "answer": "当前版本不支持下载错误明细,只展示失败行数和错误原因。",
  "claims": [
    {
      "claim": "当前版本不支持下载错误明细",
      "citation": {
        "sourceId": "product-import-prd-v2",
        "chunkId": "product-import-prd-v2#sec-3.2",
        "quote": "当前版本不支持下载错误明细"
      }
    }
  ],
  "openQuestions": [
    "是否计划在下一版本支持错误明细下载?"
  ]
}
11 · 面试问答

回答要能拆开检索链路

面试里如果只说“用向量库检索”,不够。更好的回答是:怎么衡量检索质量,怎么做引用,怎么排查错误答案。

什么是检索质量?

检索质量指 RAG 系统能否为用户问题找到正确、相关、最新、权限合规的资料,并把这些资料排在能进入上下文的位置。

我会从召回、排序、过滤和引用几个维度看,而不是只看返回了几条结果。

如何评测检索质量?

先准备评测集,每个问题标注应该命中的资料。然后看 Recall@K、MRR、nDCG、Noise Rate 等指标。

如果正确资料没有出现在 topK,说明召回有问题;如果出现在很后面,说明排序或重排有问题。

引用来源应该怎么设计?

每条关键结论最好带 citations,里面包含 sourceId、chunkId、title、quote 和 retrievedRank。

后端要校验 sourceId 和 chunkId 是否来自本轮检索结果,quote 是否能在原文里匹配。这样能避免模型编引用。

RAG 答案错了怎么排查?

我会按链路排查:用户问题是否被正确理解,query rewrite 是否合理,正确资料是否召回,排序是否靠前,权限和版本过滤是否正确,上下文是否冲突,引用是否支持结论。

不要一上来就调 Prompt。很多时候是知识库、检索或重排的问题。

引用正确是否就代表答案正确?

不一定。引用存在只能说明有来源,仍要判断引用是否真的支持结论。

比如引用里说“当前版本不支持下载”,但模型结论写成“支持下载”,这就是引用和结论不一致。需要做 citation precision 或 groundedness 检查。

12 · 练习和速查

判断 RAG 答案是否站得住

好的 RAG 答案要经得起追问:资料从哪里来,为什么排在前面,是否最新,用户是否有权看,引用是否真的支持结论。

练习 A:定位问题

1
正确资料在知识库里,但没被检索到 优先查切片、别名、关键词、query rewrite 和索引更新。
2
正确资料排第 8,topK 只取 5 排序或重排有问题,也可以调整 topK 和上下文预算。
3
答案有 sourceId,但 sourceId 不在检索结果里 这是无效引用。后端要拒绝或重试。
4
引用存在,但原文不支持结论 需要做 claim-citation 对齐检查,必要时转人工。

练习 B:用一句话说清楚

  • 解释 Recall@K 看什么。
  • 解释 MRR 为什么能反映排序质量。
  • 解释 sourceId 和 chunkId 的区别。
  • 解释为什么引用也要校验。
  • 解释答案错了为什么要先看检索链路。

检索质量和引用来源速查表

环节 要问的问题 合格标准
查询理解 用户问题是否被正确改写? 保留原意,补业务域、别名和关键词。
召回 正确资料是否出现在 topK? 高频问题 Recall@K 达到目标。
排序 正确资料是否排在前面? MRR、nDCG 稳定,旧资料不会抢占前排。
过滤 版本、权限、业务域是否正确? 无权限资料和废弃资料不进入上下文。
引用 关键结论是否有 sourceId 和 quote? 引用来自本轮检索,quote 能在原文匹配。
一致性 引用是否支持结论? claim 和 citation 能对齐,不偷换含义。
排查 答案错了能定位到哪一步? 日志记录 query、topK、重排、上下文、引用校验。