RAG 答得像那么回事,但引用对不上
有一次用户反馈:回答看起来挺专业,但点开引用,发现对不上。
我一开始不信。检索结果是我看着召回的,回答也是基于这些结果生成的,怎么会对不上?直到我把回答里的 [1]、[2] 一个个对应回原文,才发现问题:回答是对的,引用是错的。
这比“答错”更麻烦。答错,用户会怀疑;引用错,用户会相信。
先别急着换模型
第一反应是模型不够好,想换更大的模型。但我忍住了,先把链路拆开:
- 用户问题有没有被正确理解;
- 检索有没有召回到真正相关的证据;
- 召回的内容有没有被正确压缩;
- 生成时有没有把引用和证据绑定;
- 引用编号有没有在压缩、合并、重排中错位。
一查,问题在 2 和 5:检索召回了不少“主题相关”的段落,但不是“能支撑结论”的证据;压缩时又把几段拼在一起,引用编号还是按拼接顺序来的,和原文对不上。
检索“相关”不等于“有用”
原来的检索是单路向量召回,看的是语义相似。问题是,很多段落的语义和问题很像,但里面没有可引用的结论。
后来加了几件事:
- 混合检索:关键词和向量一起用,避免只靠语义漂移;
- 元数据过滤:时间、类型、来源范围先收窄;
- 重排:召回一批之后,再用更细的模型排一次;
- 证据阈值:分数不够的,不进上下文。
不是越多越好。上下文塞得越满,模型越容易“看见什么说什么”。
引用要绑定,不是编号
以前的做法是:把几段材料拼成一个长文本,前面加 [1][2],让模型自己引用。模型很容易把编号当装饰。
后来改成:每段材料带一个稳定的 evidenceId,生成时要求模型引用 evidenceId,后处理再映射成 [1][2]。如果模型引用了不存在的 ID,直接判失败,重试或降级。
再加一层校验:回答里的关键句,和引用段落的原文做重叠/蕴含检查。对不上,就把这句标成“证据不足”,而不是硬答。
评测不能只看“答得像不像”
我们一开始的评测,是找几个人看回答“专不专业”。结果大家都觉得挺专业,但引用错误没人发现。
后来改成三层:
- 检索层:Recall@K、MRR,看该找的有没有找到;
- 引用层:引用准确率、证据覆盖率,看引用能不能支撑结论;
- 回答层:忠实度、完整性,看有没有编。
再准备一小套金标问题,每个问题标好“必须出现的证据”。数量不用多,几十条就能暴露大部分问题。
最后一句
RAG 不是“把文档塞进向量库,然后让模型回答”。它更像一个证据系统:先找到证据,再让模型基于证据说话,最后检查它有没有胡说。
检索决定上限,引用决定可信度,评测决定你能不能持续变好。
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 王德明
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果