这道题其实是在问,当检索这个环节失灵了,系统怎么还能给出一个靠谱的答案。本质上是[[RAG]]系统的边界问题,就是知识库覆盖不到、或者检索质量差的时候,怎么保证不崩。
先说清楚,检索失败不只是没结果。我一般会先区分两种:一种是零结果,[[向量库]]什么都没返回,这可能是[[embedding]]或者索引有问题;另一种是低质量结果,有东西但相似度不够,或者Top-K之间得分差距太大,这种其实更常见更麻烦。
对零结果,我第一反应不是直接放弃,而是查一下是不是Query本身有问题。比如说用户问「退款多久到账」,可能知识库里存的表述是「退款到账周期」,那同义词扩展就很有用。我会先用LLM做一次查询改写,比如把Query拆成子问题,或者用HyDE的方式,让LLM先基于Query生成一段假设的文档,再用这个文档的embedding去检索,往往能捞到东西。
如果改写还不行,那就得靠多路召回兜底了。我会把向量检索和[[BM25]]关键词检索结合起来,再叠加[[知识图谱]]。举个例子,电商客服场景,用户问「满200减30和满300减50能叠加吗」,向量检索可能因为术语不匹配没找到,但BM25能通过「满减」「叠加」这些关键词命中,知识图谱也能给出规则关系。一路不行其他路补上,这是最稳健的架构。
再一个就是降维检索,把相似度阈值调低,先扩大召回范围,让[[重排]]模型去过滤。但这个有前提,就是你的重排模型得够强,不然噪音太多反而影响质量。
如果检索侧怎么都救不回来,那就得靠模型侧兜底了。我会在Prompt里显式告诉LLM:当前没有检索到相关知识,请基于自己的知识谨慎回答,并明确标识这是推测。高风险场景,比如金融合同或者医疗问答,我倾向于直接拒绝,返回「知识库未覆盖该问题」,宁可不答不能错答。这其实是业务容忍度的取舍,客服场景容错率低,就得保守;通用闲聊可以宽松一些。
最后是用户侧闭环。我会把失败的Query记录下来,触发离线分析,看看是不是知识库缺失,然后补充。同时在界面给个「未找到答案,提交人工反馈」的入口,让用户能参与进来。
但说实话,这些策略里有一个隐性前提,就是你的LLM自身知识得有一定可信度。如果模型本身就很弱,那让它基于自身知识回答反而会加重[[Hallucination]]。所以我会更倾向于,在模型侧兜底之前,先评估模型的领域能力,如果不行就干脆拒绝回答,而不是让它猜。
所以整体上,我会把检索失败看成系统设计的一部分,而不是异常。分层兜底,从查询改写、多路召回,到模型侧显式声明,再到用户反馈闭环,每一层都做减法,能救就救,救不了就诚实告诉用户。