我觉得这道题其实是在问一个很本质的问题:当你面对一个[[RAG]]系统的时候,怎么在精度、速度和成本这三个维度上做取舍。说白了,召回链路没有银弹,每个策略都有它的适用边界和代价。
先说检索效率。很多人上来就推[[HNSW]],但HNSW其实更适合中等规模、对延迟要求高的场景,比如在线客服。如果数据量到了千万级甚至亿级,我会更倾向用[[IVF-PQ]]或者ScaNN,因为HNSW的内存占用太大了。举个例子,一个电商客服系统,商品政策和退款规则大概几百万条,用HNSW能毫秒级召回,没问题。但如果是企业内部的SOP文档库,上亿条,HNSW可能把128G内存吃满,这时候IVF-PQ加量化压缩就香多了,FP32到INT8的裸向量每维从4到1字节,但总索引含ID/图/码本;质量变化和能否接受要按目标题集验证,不能承诺2%以内。这里有个前提:如果你的业务场景对精度极其敏感,比如医疗诊断,那量化压缩就要慎用,得先做A/B测试。
再一个,相关性提升。我见过很多团队只靠向量检索,结果关键词匹配一塌糊涂。实际上,真正落地的方案往往是[[混合检索]],[[Dense Retrieval]]加[[Sparse Retrieval]]一起上。比如用户搜“退款”,向量能召回“退货”“赔付”这些语义相近的,但[[BM25]]能精准命中“退款流程”这个短语。所以我会把两条路的结果做加权融合,权重根据场景调。然后还有查询优化,比如用户问“订单异常怎么办”,我会先生成一个假设文档“当订单状态为异常时,用户应联系客服并提供订单号”,用这个假设文档去检索是HyDE思路;也可能偏题,需与原query作消融并记录额外模型成本。
结果出来之后,是否加精排要比较质量收益和延迟成本,不能一概要求。我通常用两阶段:先向量召回Top-200,再用[[Cross-Encoder]]或者[[ColBERT]][[重排]]到Top-10。重排不扩展输入候选集合,可改善最终Top-K排序;它无法找回漏召回的文档。不同K的Recall、排序质量与延迟须实测,不能固定说提升10–15个点且只多几毫秒。不过要注意,重排模型不能太大,否则延迟会崩,我一般用BGE-Reranker那种轻量级的。
可扩展性这块,我特别关注增量更新。要区分增量添加与删除。Faiss HNSW支持add,新向量不必每次全量重建;直接remove不支持,修改/删除需逻辑失效、重建或其它实现。并发写入与查询还要遵循具体线程安全约束。所以我会用支持segment机制的数据库,比如Milvus,新数据先写小segment,后台慢慢合并。或者用双缓冲策略:一个base索引只读,一个delta索引接受增量写入,查询时合并结果。另外冷热分层也很关键,热点数据放内存,冷数据放SSD,能省不少钱。
说到增量更新,其实还有一个坑很多人没意识到:删除操作。如果你直接在图索引上删向量,召回质量会急剧下降,因为图的邻居关系断了。我通常的做法是软删除,维护一个删除ID列表,查询时过滤掉,然后后台异步重建。这块如果深挖,会涉及到图索引的动态维护和一致性保证,挺有意思的。
所以整体上,我更倾向于把召回链路看成一套可组合的乐高积木,没有固定的最佳实践,只有针对业务场景的权衡。比如对延迟敏感的用HNSW加量化,对精度要求高的用混合检索加精排,对成本敏感的做冷热分层。关键是上线前一定要压测,用真实query回放,对比Recall@K和延迟,不达标就回滚。