RAG 答错先别换模型:从证据到答案的五项检查
一个 RAG 助手回答“退货申请需要在五天内送达”,但当前规则其实是“完整申请收到后,三个工作日内送达”。错误可能来自过期文档、分块丢失条件,也可能来自模型误读。只看最终答案,无法定位原因。
本文围绕原文的五项检查,把排障顺序整理成可执行步骤。文中的退货规则全部是虚构示例,用于说明技术方法。
1. 先保存一条能解释错误的 Trace
至少保留原始问题、实际查询、过滤条件、召回片段 ID 与版本、选入提示词的完整上下文、最终答案和引用映射。
{"question":"退货申请何时必须送达质检?","query":"退货 申请 质检 截止时间","filters":{"status":"active"},"chunk_ids":["returns-2023#04"],"context_version":"1.4","prompt_context":"申请须在五个自然日内送达。","answer":"五个自然日内送达。","citations":["returns-2023#04"]}这是诊断记录示例,不是真实系统日志。对外分享时应脱敏,并保留关键规则和条件。脱敏记录适合检查逻辑,但不一定还能逐字重放生产请求。
2. 检查一:回答需要的段落召回了吗
从权威源文件出发,找到真正支持答案的段落,再检查解析结果、索引和召回列表。主题相似不等于证据充分:多段“退货流程”说明,也不能代替具体的截止时间条款。
问题若包含产品代码、政策编号或精确术语,可以比较关键词检索、向量检索和混合检索。不要只因为语义分数高就认为检索成功。
一个快速实验是固定问题、模型和指令,手动提供正确段落。如果回答改善,优先检查召回和上下文链路。但单次改善只缩小调查范围,不足以证明某个组件是唯一根因。
3. 检查二:段落是否当前有效且适用
旧政策可以和问题高度相关,却不适用于今天。检查来源、版本、生效时间、适用对象与摄取记录,确认当前版本确实完成同步。
文件名叫“最新”或标签写着active,都不能替代核对。历史资料可继续保留用于追溯,但查询当前规则时应采用对应版本策略。时间敏感问题还应明确用户询问的是现在还是过去某个时间点。
4. 检查三:完整规则真的进入了上下文吗
把源文、召回片段和最终prompt_context三者逐一比较。
如果“收到完整申请后”被分到另一个块,损失发生在分块阶段;如果召回片段中有这句话,组装后的提示词却没有,损失发生在上下文选择或截断阶段。
表格标题、单位、条件、例外和脚注尤其容易丢失。结构化分块、携带标题和必要的相邻内容都是可实验的方案,但没有适用于所有文档的固定块大小。增加片段数也可能引入噪声,应同时测质量与延迟。
5. 检查四:答案的每条主张是否有支持
当前规则完整进入模型后,再检查模型是否保留了“工作日”和起算条件。
| 维度 | 关注什么 |
|---|---|
| 相关性 | 检索内容是否与问题有关 |
| 证据一致性 | 答案是否由提供的上下文支持 |
| 正确性 | 是否符合验证过的当前事实 |
| 引用质量 | 指定来源是否支持对应主张 |
模型准确复述过期政策,可以与上下文一致,却仍然不符合当前事实。有引用也不自动正确:必须确认引用对应的段落支持那个具体数字或条件。
自动评测有助于批量筛选,但细小限定词和多版本冲突仍值得人工抽查。
6. 检查五:缺少证据时如何回答
空召回并不证明知识库中没有答案。先排除摄取与检索故障,再决定是否属于真正的知识覆盖缺口。
如果用户缺少某项会影响规则选择的信息,可以澄清;如果资料根本没有相关政策,继续追问用户也不能生成证据,应说明无法确认或转人工。
提示词可以要求证据不足时停止回答,但仍需要评测。只增加拒答用例,会让“什么都不答”的系统看起来更安全;必须保留可回答的控制问题,检查是否过度拒答。
7. 把一次修复变成回归集
建议包括常规问题、改写提问、精确编号、旧版本陷阱、跨块条件和不可回答问题。每次只改一个可控组件,再重新运行完整链路,对比新旧 Trace。
如果修的是索引或检索,只重放旧的prompt_context不够,因为那只验证生成阶段。只有确认完整当前证据已经送达模型、模型仍反复遗漏条件时,比较其他生成模型才是有证据支持的下一步。