关键词、向量与混合检索
三种找法各有各的盲区,实际系统几乎都是混着用。
三种找法各有各的盲区,实际系统几乎都是混着用。 「做知识库=上向量库」是个流传很广的简化。实际上向量有一整块明确的盲区,而老式的关键词检索恰好补得上。这一节讲怎么配。所谓检索再生成,最早就是 RAG 论文提出的路线:先从资料里取一段,再交给模型生成答案。rag-paper 你会遇到的现象:
- 用户输入一个订单号或产品型号,知识库完全找不到
- 换成同义说法能找到,一用精确术语反而找不到了
- 上线新功能后,用户用新名词提问,全部召回失败
两种找法
关键词检索看字面重合。用户搜什么词,就去找含有那些词的文档,按词频和稀有度打分。这是搜索引擎用了几十年的老办法,成熟、快、可解释。
它的强项是精确串:订单号、产品型号、法条编号、人名、错误码。这类东西没有同义词,字面就是全部信息。
它的弱项是换个说法就抓瞎。用户说「我不想要了」,文档里写的是「退货」,字面零重合,直接漏掉。
向量检索看意思接近程度。强弱正好反过来:同义改写、口语提问、概念相近的内容它都能找到;但遇到精确串就不灵了。
为什么向量对精确串不行?因为一个订单号在训练语料里没什么语义,转成坐标之后和其他一串数字挤在一起,分不出彼此。它擅长「差不多」,而订单号恰恰不能差不多。
还有两个向量的软肋值得记住:对否定不敏感(「支持」和「不支持」坐标很近),以及对新词无能为力——你们上个月刚起名的新功能,向量模型训练时没见过,它不知道该放在地图的哪个位置。而关键词检索对新词毫无压力,字面匹配就行。
为什么要混合
看那张图:两者的强弱几乎是互补的。只上一种,等于主动放弃一半的召回能力。
混合检索的做法很朴素:两路分别召回一批结果,合并去重,再统一排序。工程量不大,多数向量数据库和搜索引擎都内置了这个能力。针对 RAG 失败模式的研究也得出同样的经验:单一检索在语义相近但字面不同的查询上,是最常见的翻车点之一。rag-failure-points
合并时有个细节:两种检索的分数不在一个量纲上,不能直接加。常见做法是按排名而不是分数来融合——每路结果按名次给权重再合并。你不需要懂具体算法,但要知道这是个需要调的地方,默认配置未必最优。
实践中的经验是:混合检索几乎总比单一检索好,尤其在企业知识库这种既有大量口语提问、又有大量编号型号的场景里。
重排是关键一步
召回之后还有一步,很多团队会跳过,但它通常是整个检索链路里性价比最高的一环。
思路是这样的:召回阶段追求不漏,所以宁可多召一些——两路合起来拿 30 到 50 段。但这么多段不能全塞给模型,既贵又会把重点稀释掉。
于是加一个重排模型:把问题和每一段放在一起判断「这段能不能回答这个问题」,重新打分,取最好的三五段。
它和向量的关键区别在这里:向量是问题和文档各自算坐标再比距离,信息在压缩时就丢了;重排是两者一起读,判断得准得多。代价是慢一些、贵一些,但因为只处理几十段,总成本仍然很低。上一节说的「相似不等于相关」,主要就靠这一步来纠正。
怎么配
给一套可以直接照做的起手配置。
**第一步,两路并行召回。**向量一路、关键词一路,各取 20 到 30 段。
**第二步,合并去重。**同一段被两路都召到,说明它很可能真的相关,可以给个加成。
**第三步,重排取前 3 到 5 段。**具体几段要实测——太少会漏,太多会稀释,还费钱。
**第四步,设一条分数下限。**重排后最高分都很低,说明库里没有相关内容,应该走「不知道」的分支,而不是硬拿几段去编。
另外补一条经常被忽略的:**先看看你的用户到底在怎么问。**把真实的提问日志拉出来看一百条,你会很快发现自己的场景是偏口语还是偏精确串,配比该往哪边倾斜。这比调任何参数都有效,而且多数团队从来没做过。
