这道题问的是怎么提升[[RAG]]里检索阶段的质量,本质上就是怎么让检索更精准地命中回答真正需要的信息。我会从查询、召回、排序、索引几个环节来说,但重点不是列全所有方法,而是讲清楚在什么场景下该选什么,以及实际落地时容易踩的坑。
先说查询侧。标准做法是直接拿用户问题去做向量检索,但问题往往又短又模糊,比如用户问“这个能退吗”,在电商客服场景里,你得知道他说的是哪个商品、什么原因。所以我会做查询改写,最常用的是 HyDE,就是让LLM先生成一个假设的回答,然后用这个答案去检索。这么做的好处是语义更丰富,但前提是LLM生成的假设不能太离谱,如果领域很专业、模型没训练过,反而会引入噪声。另一个是查询分解,比如“对比A和B的退款政策”,我会拆成“A的退款政策”和“B的退款政策”分别检索再合并。这里有个边界:如果问题本身很简单,改写反而画蛇添足,我只会对意图模糊或复杂推理的问题做。
再讲召回策略。纯向量检索对专业术语、商品ID这类精确匹配很弱,所以我会用 [[混合检索]],把向量相似度和 [[BM25]] 关键词匹配结合起来。比如在退款场景,用户说“订单号12345”,关键词匹配能直接命中,向量反而可能因为语义偏移而漏掉。具体落地时,我会把两个分数加权融合,权重根据业务调,比如客服对话场景语义更重要,向量权重大一些;而查订单号或错误码,关键词权重大一些。还有一种增强是[[稀疏检索]],像SPLADE这种学习式稀疏向量,能弥补纯向量的盲区,但实现成本高,我一般只在长尾实体查询时才考虑。
然后是排序和索引。召回阶段一般拿到Top-K,但精度不够,需要精排。我会用 [[Cross-Encoder]] 对Top-50做[[重排]],因为它做交互打分,精度高很多。但慢,所以我会做多阶段级联:先用向量快速召回Top-200,再用BM25过滤掉明显不相关的,最后用Cross-Encoder精排Top-20。这里有个坑:如果第一步召回就漏了关键文档,后面再怎么精排也救不回来,所以召回阶段Recall要优先。索引层面,[[分块]]策略很关键。固定长度切分会把语义割裂,比如一个退款政策条款被切到两个块里,检索时哪个都不完整。我会按语义切分,用句子边界或段落边界,保证每个块语义独立。另外,我会建摘要索引,对每个块生成一句话摘要,检索时先匹配摘要,减少噪声。但摘要本身也有精度损失,所以我会保留原文,在精排阶段用原文打分。
最后说说落地时的取舍。我不会把所有方法都堆上去,因为每加一层都意味着延迟和成本。我更倾向先分析业务场景:如果是FAQ类问题,查询改写和混合检索就够了,重排可以不要;如果是复杂推理,比如企业SOP合规文档,我会加上查询分解和重排。上线前我会特别关注两个风险:一是改写引入的[[幻觉]],二是混合检索的融合权重不合理导致召回偏科。我会用一批历史query做回放,对比Recall@K和最终回答质量,调好再上线。
这里有个延伸点:最近[[GraphRAG]]在检索阶段引入[[知识图谱]]做实体关系扩展,能处理多跳推理问题,但构建和维护图谱成本很高。我其实很好奇,在什么业务场景下,GraphRAG的收益能覆盖它的成本?
所以我的核心观点是:检索质量不是堆方法,而是理解业务场景后做精准的取舍。