这道题问的是[[RAG]]检索不准怎么办,在我看来,本质是两件事没对齐:一是信息源怎么拆和怎么标,二是匹配逻辑怎么调。拆得不对,后面怎么改都难。我从数据构建、检索优化和后处理三个角度讲一下我的做法。
先说数据构建。文档切分很多人直接按固定字数截断,但这对语义是破坏性的。我一般会按语义边界来切,比如标题、段落,还会加一个重叠窗口,保证上下文连贯。举个例子,处理客服退款政策文档时,我会把“退款条件”和“退款流程”作为两个独立块,但每块末尾带上下一块的标题,这样检索时不会漏掉跨块信息。另外,我会给每个块打上元数据标签,比如时间、来源、类别,这样检索时可以按这些字段做预过滤。还有一个很重要的点,就是构造难负样本。训练[[Embedding]]模型时,我会加入语义相近但答案错误的段落,让模型学会区分“看着像但不对”的情况,这对提升判别能力非常关键。
再说检索优化。这里有个常见的误区,就是只依赖向量检索。实际上,向量检索在语义匹配上强,但在精确关键词匹配上弱,比如订单号、政策条款编号。所以我会用[[混合检索]],把[[BM25]]关键词和向量双路召回结合起来,再合并排序。查询改写也很实用,比如用大模型把用户的问题做同义词扩展或指代消解,把“它”换成具体的商品名。还有一个技巧是HyDE,就是先生成一个伪答案,再用这个伪答案去检索,能有效弥合查询和文档之间的语义鸿沟。当然,这些方法的前提是你的Embedding模型在领域数据上做过微调,否则效果会打折扣。
后处理是最后的把关。我会加一个[[重排序]]层,用[[Cross-Encoder]]对召回的结果做精排,因为它能计算查询和文档的交互注意力,比[[Bi-Encoder]]更准。同时,我会做置信度过滤,设定一个相似度阈值,低于阈值的直接丢弃,避免低质量片段进入生成器。还有一个做法是上下文压缩,用一个小模型把长文档摘要成关键信息,减少噪声。这里有个坑:重排序模型本身有计算开销,如果召回量太大,延迟会飙升,所以我会把召回数控制在20以内,再精排取前3。
说到评估,我除了用MS MARCO、Natural Questions这些开源数据集,一定会构建自己的业务评测集,覆盖真实场景的bad case。比如在金融风控场景,我会专门构造一些“相似但不相关”的案例来测试模型的抗噪声能力。
最后,我更倾向把整个流程看成一套组合拳,而不是单一技术。数据构建是地基,检索优化是骨架,后处理是精装修。如果只能选一个,我会优先把数据切分和难负样本做好,因为这是最根本的。