这道题其实在问一个很本质的问题:[[RAG]]系统里,你到底用什么方式把用户问题和知识库里的内容连接起来。说白了,就是检索这一步,你是靠关键词硬匹配,还是靠语义向量找意思相近的。两种思路各有各的舞台,真正落地的时候,大部分场景都是混着来的。
先说[[稀疏检索]],最典型的就是 [[BM25]] 和 [[TF-IDF]]。它的核心是精确匹配关键词,优点特别明显:零训练成本,拿来就能用,索引也轻,CPU就能跑。比如电商场景搜订单号、商品ID,或者企业内部搜政策文档编号,这种场景下向量检索反而容易跑偏,BM25基本不会出错。但它的死穴是没法处理语义相似,用户说‘苹果手机’,文档里写‘iPhone’,BM25就断了。再比如口语化的客服问题,‘我买的东西一直没到’和‘物流异常’,BM25很难把它们关联起来。所以它适合关键词强相关的场景,不适合语义理解。
再来说[[稠密检索]],也就是 Dense Retrieval。现在主流的有DPR和[[ColBERT]]两种思路。DPR是[[双塔]]结构,把query和文档都编码成一个固定维度的向量,然后用 [[Faiss]] 或者 Milvus 做 [[ANN]] 近似检索。好处是能抓语义相似,但坏处也很明显:压缩成一个向量后,细粒度的匹配信息就丢了。比如‘红颜色的裙子’和‘裙子是红色的’,DPR能对上,但‘苹果手机充电器’和‘iPhone充电头’,DPR可能就不如ColBERT。ColBERT走的是 Late Interaction 路线,它保留文档里每个token的向量,最后再做细粒度的 MaxSim 操作,精度确实更高。但代价是存储量爆炸,要存所有token向量,延迟也上去了。所以ColBERT更适合对精度要求极高、但对延迟不那么敏感的场景,比如法务合同审核。
那真实落地怎么选呢?我一般会看场景。如果是电商搜索,关键词强相关,我会以BM25为主,稠密检索做补充。如果是智能客服、知识问答这类语义理解优先的,我会用稠密检索,而且最好是微调过的。但大部分通用场景,我倾向走 [[Hybrid Search]],就是两路召回:BM25出一批,稠密向量出一批,然后用 [[Rerank]] 模型或者规则融合。这里有个坑:稠密向量的质量很大程度上取决于[[Embedding]]模型是不是在目标数据上调过。如果直接拿通用模型,比如BERT,去搜小红书那种口语化、带表情、图文混排的内容,召回率会很难看。所以我上线前一定会做对比实验,拿一批真实query,人工标注相关文档,算 Recall@K。如果召回率不达标,我会考虑用对比学习微调,负样本采‘难负例’,比如同batch其他样本或者BM25高分但不相关的文档。
还有一个点值得注意:向量的维度选择对检索精度和存储成本影响很大。比如你用768维还是384维,在召回率上差异可能不大,但索引大小和查询延迟能差好几倍。这个取舍在实际工程里特别关键,但不是所有场景都需要高维向量。
所以总结下来,我会把RAG检索看成一场‘关键词与语义’的平衡游戏。没有银弹,只有根据场景做取舍。我更倾向于先搭一套混合检索的基线,然后基于badcase分析,看是语义还是关键词拖了后腿,再针对性优化。