跳到主要内容

测试检索-生成接缝:RAG 系统中的集成测试盲区

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的检索器在 94% 的情况下都能返回正确文档。你的 LLM 在给定良好上下文时能正确回答 96% 的问题。可以上线了。能出什么问题?

把这两个数字相乘:0.94 × 0.96 = 0.90。在不考虑任何边缘情况、提示词格式问题、token 截断,以及检索器与正确文档一起返回的干扰文档之前,你就已经损失了 10% 的查询。但更深层的问题不是这个算术——而是你的单元测试永远不会发现这一点。检索器在隔离测试中通过了。生成器在隔离测试中通过了。失败的是两者的组合,而大多数团队对此没有任何测试。

这就是检索-生成接缝:检索器交付内容与生成器实际能够使用的内容之间的接口。它是生产 RAG 系统中测试最不充分的边界,也是大多数故障的根源。

为什么单元测试无法捕获接缝故障

标准的 RAG 测试方案看起来是这样的:编写一组查询,检查检索器是否返回相关文档,然后在一组精心策划的(查询,上下文)对上评估生成质量。两者都通过了。你部署上线。用户开始提 bug。

问题在于,单元测试是针对你控制的输入来评估每个组件的。在生产环境中,生成器接收的是你的检索器实际构建的上下文——包括其失败案例。"检索器测试上下文"与"生产检索器上下文"之间的差距,正是复合故障的藏身之处。

考虑以下这些接缝特有的故障模式:

  • 截断使答案消失。 你的检索器返回了一个 2,000 token 的文档,答案位于最后 400 个 token 中。你将上下文窗口配置为 1,500 个 token。该文档通过了检索器的相关性检查。答案永远无法到达生成器。
  • 干扰文档污染。 你检索了 top-5 文档。四个正确;一个语义相似但事实相互矛盾。你的生成器在努力全面作答时,将它们混合在一起。检索器测试计算了 precision@5 并认定通过。
  • 结构不匹配。 你的生成器在干净、格式良好的文档上经过微调。你的检索器返回原始 HTML 片段、脱离上下文的表格单元格,或中间断句的分块边界。两个组件测试都没有发现这一点,因为检索器针对干净文档测试,生成器也针对干净上下文测试。
  • 归因消除。 生成器产生了一个听起来正确的答案,但实际上并非基于检索到的上下文——它在使用参数化记忆。你对生成器的单元测试检查了答案质量,而非基础性。

"RAG 七大故障点"框架系统性地识别了这些问题:内容缺失、未排在前列的相关文档、在整合时被排除的文档、未能提取相关信息、格式错误、特异性不当以及答案不完整。注意这些问题是多么清晰地分布在检索故障、接缝故障和生成故障之间——然而大多数团队只对端点进行监控。

设计接缝级测试

测试接缝需要模拟真实检索输出的测试夹具,而非理想化的测试上下文。目标是让你的生成器接触检索器实际会产生的上下文分布。

合成上下文注入是基础技术。与其在手工精心制作的黄金标准上下文上测试生成,不如将检索器的实际输出直接输入生成评估器。这意味着对一组有代表性的查询运行检索器,捕获完整的检索上下文(包括排名、分数和任何检索后压缩),然后将这个精确的上下文输入生成评估器。

三类夹具涵盖了大多数接缝故障:

  1. 正确上下文。 检索器找到了答案。验证生成器是否忠实地提取了它。这是你的基线——如果在这里失败,你有生成问题,而非接缝问题。
  2. 相关但不充分的上下文。 检索器找到了主题相关的文档,但没有一个包含具体答案。验证生成器是否回答"不知道",而非凭空捏造。大多数团队完全跳过这类夹具。
  3. 矛盾上下文。 检索器找到了包含相互冲突声明的文档。验证生成器是否明确承认不确定性或解决冲突,而非悄悄选择其中一个。

每类夹具都能告诉你不同的事情。第一类故障指向你的提示词或模型。第二类故障指向你的置信度校准和拒答行为。第三类故障指向你的上下文结构和生成提示词。

接缝测试只有在与组件测试分开失败时才有用。如果检索器单独测试通过而接缝测试失败,你已将问题定位到交接处。这是可操作的。如果一切都同时失败,你什么都没学到。

指标分割:检索召回 vs. 有据可查的准确性

最常见的评估错误是使用单一端到端准确性指标来评估整个管道。当它下降时,你不知道应该调整嵌入模型还是提示词。

能可靠定位责任的指标分割:

检索端指标:

  • 上下文召回率: 检索集是否包含回答问题所需的所有信息?低上下文召回率意味着你的嵌入模型或分块策略是问题所在——而非你的生成器。
  • 上下文精确率: 相关块的排名是否高于不相关块?低精确率意味着你向生成器传递了太多噪声。
  • Recall@K / Precision@K: 传统信息检索指标,在 A/B 测试中用于比较嵌入模型和重排器时很有用。

接缝特定指标:

  • 上下文相关性: 在实际传递给生成器的块中(经过截断、重排后),有多少比例是相关的?这与上下文召回率不同——它衡量的是组装好的上下文窗口质量,而非只是检索候选的质量。
  • 答案归因率: 在生成答案中的声明里,有多少比例可以追溯到上下文中的特定段落?在答案质量高时归因率低,意味着你的模型在使用参数化知识而非检索到的上下文——这在某些用例中没问题,但在其他情况下很危险。

生成端指标:

  • 忠实度: 答案中有多少声明得到了所提供上下文的支持(且未被反驳)?这是 RAG 的主要幻觉检测器。
  • 答案相关性: 生成的输出是否真正回答了被问的问题?出人意料地与忠实度分离——模型可以忠实于糟糕的上下文,但答案仍然不相关。

在同一测试集上同时运行这些指标。故障模式会告诉你去哪里查找:

加载中…
References:Let's stay in touch and Follow me for more thoughts and updates