
向量数据库里的大海捞针:RAG是如何在毫秒内找到答案的
说实话,大多数人聊起大模型的时候,目光都集中在模型本身有多强——参数有多少亿、上下文窗口有多长。但我干了这么多年科技内容观察,有一个感受越来越强烈:真正的瓶颈根本不在生成端,而在检索端。 你让ChatGPT回答一个问题,它能不能答好,不完全取决于模型有多聪明,而取决于它能不能在海量知识库里,把真正相关的那一小撮信息捞出来。
这就是RAG——检索增强生成——正在解决的核心问题。上一期我们聊过文档怎么被切块、怎么变成向量、怎么存进向量数据库。这一期,我决定把目光往深了挖:当你真正发起一次查询,系统是怎么在毫秒级别从几十亿条向量里,把最接近你问题的那些结果找出来的?
这里面的门道,比大多数人想象的要复杂得多。
HNSW:把最近邻搜索变成高速公路网
先说最主流的方案——HNSW,全称Hierarchical Navigable Small World,中文叫"分层可导航小世界图"。这个名字听起来很拗口,但我跟你讲,它的核心思想其实非常直觉。
想象你要在北京市找一个地址,你不会挨家挨户问对吧?你会先看它在哪个区,再看它在哪个街道,最后精确到门牌号。HNSW就是这个逻辑的分层版本。 它把所有的向量分成多层,上层稀疏、下层密集。每次搜索时,从最上层最快的"高速公路层"出发,快速定位到一个大概的区域,然后逐层往下逼近,直到在最底层找到精确的最近邻。
数据上来说,HNSW在10亿量级的向量数据库里,单次查询延迟通常能控制在10毫秒以内。这什么概念?你眨一下眼大概300毫秒,它已经能完成三十次查询了。Meta(Facebook)的FAISS库在2017年最早把这个算法工程化,后来几乎所有主流向量数据库——Milvus、Qdrant、Weaviate——都把HNSW作为默认索引。
我个人判断,HNSW之所以能一家独大,根本原因是它在两个指标上做到了绝佳平衡:查询速度和精度。 它的搜索不是精确的暴力匹配,而是近似最近邻搜索(ANN),但精度通常能到95%以上。换句话说,它用1%的计算代价,换来了几乎一样的准确度,这笔账太划算了。
IVF:聚类的力量——先分类再搜索
但HNSW不是银弹。当向量维度特别高、或者数据分布极其稀疏的时候,纯HNSW有时候会在"高速公路"上跑偏。所以工程实践中,另一个出场率极高的方案是IVF——倒排文件索引(Inverted File Index)。
IVF的思路用一句话说就是:先聚类,再搜索。 训练阶段,系统会用K-Means算法把全部向量分成N个簇(Cluster),每个簇有一个中心点,每个向量归属于离自己最近的中心点。搜索阶段,给定一个查询向量,系统先找到距离最近的K个簇中心,然后只在这些簇内部做精确搜索。
这样做为什么快?因为搜索空间从全量N条一下子缩减到了K个簇。假设你有100万条向量,分成1024个簇,每次查询只需要在样本量级远更小的子集里搜索。
当然,IVF有个关键调参点叫nprobe,它控制你查询多少个最近的簇。nprobe越大,精度越高,但速度越慢。这就是一个经典的工程取舍:你在精度和性能之间反复横跳,直到找到一个业务能接受的甜点。
在Qdrant和Milvus的实现里,IVF-Flat和IVF-PQ是两个常见变体。PQ是Product Quantization的缩写,中文叫乘积量化,简单说就是把高维向量压缩成短编码,大幅降低内存占用,但代价是精度略有损失。我见过一些团队的实践:使用IVF-PQ后,内存占用能降低4到8倍,同时召回率(Recall)还能维持在90%以上。这个trade-off对于超大规模部署来说非常诱人。
BM25:当关键词比语义更重要
好,现在你可能有个疑问:向量检索这么强,是不是传统关键词搜索就没用了?我的判断是,远远没有。 现实场景里,有一类查询向量检索天然吃亏——那就是实体精确匹配。
举个例子:用户搜索"GPT-4o的发布价格"。"GPT-4o"是一个精确的专有名词,但在向量空间里,"GPT-4"或者"GPT4"可能embedding出来差距还挺大的。你想让"GPT-4o"和"GPT4"被识别为同一个意思,模型得学很久。但BM25不需要学,它就是统计词频和文档频率。
BM25是1994年提出的算法,中文语境里也叫Okapi BM25。它在信息检索领域统治了将近三十年。它的核心思想是:一个词在文档里出现得越多,同时在整个语料库里出现得越少,这个词就越重要。 经典的TF-IDF的进阶版,但加入了文档长度归一化,避免短文档被长尾词刷高权重。
这里有个关键数据值得注意:Elasticsearch从2019年开始,就把BM25作为默认排序算法(取代了之前的TF-IDF)。全球估计有超过80%的企业搜索系统底层跑的都是Elasticsearch。这意味着BM25每天处理的查询量是天文数字。
混合搜索与重排序:1+1>2的工程哲学
到了这里,你可能已经猜到业界下一步怎么做了——把向量检索和关键词检索合起来用。 这就是混合搜索(Hybrid Search)的逻辑。
具体怎么混合?最常见的有两种策略。第一种是并行混合:同时跑向量搜索和BM25搜索,各自拿到一批结果,然后按固定权重(比如7:3)合并排序。第二种是顺序混合:先用一种方法召回候选集,再用另一种做精细化排序。
但重排序(Re-Ranking)这一步才是真正让RAG系统脱胎换骨的地方。假设向量检索从1000条结果里捞出Top-50,BM25也捞出Top-50,合并后可能有80条去重结果。这80条里怎么排出最终顺序?
这个任务交给了一个专门的模型——Cross-Encoder。 和向量检索用的Bi-Encoder不同,Cross-Encoder会把查询和文档一起喂进模型,计算出更精确的相似度分数。代价是什么?Cross-Encoder每次推理的计算量是Bi-Encoder的N倍(N是候选文档数),所以它只负责最后一轮重排,不会拿来跑全量搜索。
Facebook在2020年开源的DPR(Dense Passage Retrieval) 论文里就验证了:纯向量检索的Recall@20大概在60%-70%,加上BM25混合后能提升到75%-80%,再加Cross-Encoder重排序后,可以摸到90%以上。每一步都是百分点级别的提升,听起来不大,但在实际RAG系统里,直接决定了你最后生成的回答是答非所问还是精准命中。
Cohere、Google Vertex AI Search这些商业产品,底层走的都是这套组合拳。
最后说几句
写到这里,我有一个特别深的感受:RAG的检索链路,其实就是一部人类在"速度"和"精度"之间反复博弈的工程史。HNSW用分层换速度,IVF用聚类换规模,BM25用词频换精确匹配,Cross-Encoder用算力换最终精度。每一种算法单拿出来都不完美,但组合在一起,就构成了今天大模型"实时回答"背后的底层基础设施。
下一期, Mehul Ligade 的系列文章会进入Part 3。我个人判断,那一期大概率会聚焦在生成阶段——模型怎么利用检索到的片段组织回答,以及如何处理"检索质量差但硬撑着生成"这个最难的问题。如果你想深入理解RAG全貌,建议把前两期一起对照着看。
检索是根基,生成是花朵。根扎得有多深,花才有可能开得有多盛。
