资源中心 技术干货 艾体宝干货 | Qdrant如何从多层导航图搭建生产级向量检索?

艾体宝干货 | Qdrant如何从多层导航图搭建生产级向量检索?

生产级检索

从多层导航图、三个核心参数,到 Filterable HNSW、ACORN、查询规划与存储优化,一次讲清 Qdrant 如何把近似最近邻算法变成可落地的向量检索系统。

在 RAG、语义搜索、智能客服和推荐系统中,向量数据库要回答的并不只是”谁和 Query 最像”。真正的业务问题往往是:

在百万乃至亿级向量中,如何在满足租户、权限、状态、时间等条件的前提下,快速找到最相关的 Top-K,并把延迟、召回率和资源成本控制在可接受范围内?

HNSW 解决了其中最核心的一步——如何不扫描全部向量,也能快速接近真正的近邻。

艾体宝 Qdrant 则继续向前走了一步:它把 HNSW 与业务过滤、查询规划、分片分段、后台优化、磁盘存储和量化机制组合起来,形成了一套生产级检索链路。

如果只记住一句话,可以记住这句:

为什么不能永远使用暴力搜索?

Query Vector = [0.23, 0.81, 0.14, …]

精确搜索需要把 Query 与 100 万个向量逐一计算距离,再从结果中选出 Top-K。它的优势是结果准确,代价是计算量会随数据规模近似线性增长。

当查询量、向量维度和数据规模同时上升时,问题会迅速放大:

  1. 数据从 10 万增长到 1 亿,单次查询需要比较的向量数量增加约 1000 倍;
  2. 多租户、高并发场景会让距离计算持续消耗 CPU;
  3. 即使磁盘能装下全部向量,延迟也未必能满足在线业务的 SLA。

HNSW 的目标不是”免费获得完全准确的结果”,而是:

只检查一小部分更有希望的候选向量,用少量、可调节的召回损失,换取数量级上的检索加速。

因此,HNSW 属于 ANN(Approximate Nearest Neighbor,近似最近邻)算法。

先建立直觉:HNSW 是一张多层导航地图

HNSW 的全称是 Hierarchical Navigable Small World。可以把它理解成一张”多层道路网络”:

  1. 上层节点少、跨度大,像高速公路,负责快速跳到目标区域;
  2. 中间层像城市主干道,负责缩小搜索范围;
  3. Layer 0 包含全部向量,像社区道路,负责在局部仔细寻找 Top-K。
>一次 HNSW 查询” 
 style=”max-width:100%; margin-bottom:30px;”
 ><p style= 图 1:红色路径表示 Query 从入口 A 出发,经 D 快速接近 E 所在区域。

假设有二维向量 A~G,Query 位于 E 附近。传统扫描会逐一比较 A、B、C、D、E、F、G;HNSW 则可能经历:

阶段路径
最高层A → D 快速跨区域跳跃
中间层围绕 D 定位缩小搜索范围
最底层D → E 展开局部候选并返回 Top-K

真实实现并不是一次性比较最高层的所有节点,而是从入口开始进行贪心导航:只要邻居比当前节点更接近 Query,就继续向更好的邻居移动;无法继续改善时,再下降一层。

这种设计的价值在于:把”全局找针”变成”先找到大致街区,再在街区内找门牌号”。

多层图是怎样建出来的?

HNSW 不需要先运行一次聚类来挑选”中心节点”。每插入一个新向量时,系统会随机为它分配最高层级,而且进入更高层的概率会快速衰减。

因此通常会形成:

Layer 3:极少数节点
Layer 2:少量节点
Layer 1:较多节点
Layer 0:全部节点

如果节点 x 的最高层级是 Layer 1,那么它会同时存在于 Layer 1 和 Layer 0,但不会进入 Layer 2。

插入 x 的过程可以概括为:

  1. 随机确定 x 的最高层级;
  2. 从当前最高层入口开始,逐层寻找更接近 x 的区域;
  3. 在 x 能进入的每一层保留一批候选邻居;
  4. 从候选中选择部分节点,与 x 建立连接;
  5. 当节点连接过多时,执行裁剪,尽量兼顾距离和方向多样性。

※邻居选择并不等于”机械地保留最近的几个点”。如果所有边都指向同一方向,图容易形成局部拥堵,跨区域导航能力也会变差。HNSW 的启发式选择会尽量保留具有导航价值的连接。

一个完整的查询过程是怎样的?

假设:

Query 位于 E 附近
入口节点是 A

第一步:从最高层进入

最高层只有:

A — D — G

计算 Query 与 A、D、G 的距离。

假设:

Query 到 A:很远
Query 到 D:较近
Query 到 G:较远

搜索从 A 移动到 D。

此时不用经过 B、C,就已经快速从 A 跳到了 D 附近。

第二步:进入中间层

从 D 对应的 Layer 1 节点开始。

Layer 1 可能是:

A — C — D — F — G

继续比较 D 的邻居:

  1. C 比 D 更远;
  2. F 也可能比 D 更远;
  3. D 仍然是当前最好节点。

于是从 D 下降到 Layer 0。

第三步:在最底层精细搜索

Layer 0 包含:

A、B、C、D、E、F、G

从 D 开始检查附近节点:

D → E
D → C
E → F

发现 E 与 Query 最接近,最终返回 E 以及 E 附近的其他 Top-K 节点。

完整过程相当于:

最高层:A → D
中间层:D 附近定位
最底层:D → E,并检查 E 周围候选

而不是:

A、B、C、D、E、F、G 全部比较

三个参数,控制三个不同阶段

HNSW 最常见的三个参数是 m、ef_construct 和 hnsw_ef。

HNSW 最常见的三个参数

图 2:三者共同影响召回率,但付出的成本并不相同。

参数生效阶段直观含义增大后的典型影响
m建图每个节点的连接预算召回率 ↑ 内存/磁盘 ↑ 建索引时间 ↑ 可选路径 ↑
ef_construct建图建图阶段候选池图质量 ↑ 建索引时间 ↑ 查询召回潜力 ↑ 单次查询不直接变慢
hnsw_ef查询查询阶段候选池召回率 ↑ 查询延迟 ↑ 最终返回数仍由 Top-K 决定

生产调优原则:先满足 Recall,再在 SLA 内选择资源成本最低的组合。

m:每个节点有多少条可选道路

m 较小时,图更稀疏,占用资源更少,但关键路径不足时更容易错过真实近邻。m 较大时,节点之间有更多替代路线,通常有利于召回率,但会增加索引体积、建图成本和邻居遍历工作量。

需要注意,m 更适合被理解为连接预算或上限,而不是”每个节点一定恰好有 m 条边”。

ef_construct:图本身修得好不好

插入新节点 X 时,系统必须先在已有图中寻找合适的邻居。ef_construct 越大,建图时考察的候选越多,错过关键连接的概率通常越低。

它决定的是离线建图质量,不会像 hnsw_ef 一样直接成为每次查询的候选规模。可以把它理解成修路阶段的勘探预算。

hnsw_ef:查询时愿意探索多少可能路线

查询进入 Layer 0 后,会维护待探索候选和当前最好结果。hnsw_ef 越大,系统越愿意继续探索其他分支,找到真实近邻的概率通常越高,但查询耗时也会增加。

hnsw_ef 不等于最终返回数量。例如:

Top-K = 10
hnsw_ef = 128

表示搜索阶段可以保留和探索较大的候选池,但最终仍只返回 10 条结果。

为什么 HNSW 可能”找错”?

HNSW 没有查看所有向量,因此存在近似误差。

假设真实最近邻 X 位于另一个图分支,但搜索从入口出发进入了局部区域 C。如果图的连接不足、建图时缺少关键边,或者查询阶段过早停止,就可能返回 C 而不是 X。

提高以下参数通常可以降低这种风险:

参数作用
m 增大图中可选路径更多
ef_construct 增大图的连接质量通常更高
hnsw_ef 增大查询时探索更多候选分支

但三者都不是免费的:

  1. 更多连接意味着更高内存或磁盘占用;
  2. 更多建图候选意味着更长索引构建时间;
  3. 更多查询候选意味着更高延迟。

因此,HNSW 的核心并不是”把参数拉满”,而是让召回率、P95 延迟、构建时间和资源成本达到业务可接受的平衡。

艾体宝 Qdrant 不只是”用了 HNSW”

如果把原始 HNSW 看作一张高效的导航图,Qdrant 的价值在于:它让这张图能够进入真实业务环境。

Qdrant不止有一张HNSW图

图 3:一次查询可能经过过滤基数估算、策略选择、分片分段检索和全局 Top-K 合并。

Qdrant 不只有一张 HNSW 图。生产级检索是一条协同链路:过滤与规划决定”怎么搜”,分片与分段决定”去哪里搜”,索引与存储决定”以什么成本搜”。

Filterable HNSW:让过滤发生在图遍历过程中

业务查询通常不是纯向量检索,而是:

寻找与 Query 最相关的文档 AND tenant_id = A AND status = published AND department IN [sales, support]

如果先做普通 HNSW,再对结果做过滤,可能出现一个问题:前 100 个近邻大多不符合条件,过滤后只剩 2 条;如果先过滤再暴力扫描,在中等选择率下又可能很慢。

Qdrant 的 Filterable HNSW 会利用 Payload Index,在 HNSW 图中增加与过滤值有关的连接,并在图遍历期间直接应用过滤条件。这样,向量相似度和业务约束不必被拆成两个互不理解的步骤。

Qdrant Filterable HNSW

图 4:过滤会让普通图中的部分路径失效;过滤感知连接帮助搜索继续到达符合条件的候选区域。

这也是为什么 Qdrant 官方建议:对高频过滤字段尽早创建 Payload Index,最好在大规模数据写入前完成。这样后台构建 HNSW 时就能把过滤相关连接纳入图结构。

对于严格的组合过滤或大量软删除数据,Qdrant 还提供 ACORN 搜索策略。它会在直接邻居大量被过滤时,进一步探索邻居的邻居,以额外计算成本换取更好的过滤召回表现。

查询规划:小范围扫描,大范围走 HNSW

过滤后只剩 10 个候选时,计算 10 次距离通常比启动 HNSW 图搜索更划算;过滤后仍有 50 万个候选时,HNSW 更有价值。

Qdrant 可以使用 Payload Index 提供的基数估计,在不同检索路径之间做选择。full_scan_threshold 就参与了这类决策。

一个特别容易被误解的细节是:

full_scan_threshold 的单位是 KB 级向量数据量,不是 Point 数量。

因此,full_scan_threshold = 10 表示约 10 KB 的向量数据阈值,而不是”过滤后少于 10 个 Point 就扫描”。不同向量维度对应的 Point 数量不同,不能直接把这个值当作条数。

Collection、Shard、Segment:实际并非只有一张图

学习算法时,可以先把一个 Collection 想成一张 HNSW 图。但在 Qdrant 的实际存储中,数据会组织成:

Collection → Shard → Segment

因此,Qdrant 处理的是一个系统级问题:

召回率 × 查询延迟 × 内存占用 × 磁盘占用 × 建索引时间

HNSW 负责高效导航,存储与量化机制负责让这套导航能力在不同硬件预算下落地。

一个更准确的 Qdrant 配置示例

下面用 REST 配置展示参数所处的位置。数值仅用于说明,生产环境必须以实测结果为准;不同 Qdrant 版本的默认值也可能变化。

PUT /collections/hnsw_demo
{
  "vectors": {
    "size": 768,
    "distance": "Cosine",
    "on_disk": true
  },
  "hnsw_config": {
    "m": 16,
    "ef_construct": 100,
    "full_scan_threshold": 10000,
    "on_disk": true
  },
  "optimizers_config": {
    "indexing_threshold": 20000
  },
  "on_disk_payload": true
}
    

查询阶段再通过 hnsw_ef 控制搜索范围:

POST /collections/hnsw_demo/points/query
{
  "query": [0.23, 0.81, 0.14],
  "params": {
    "hnsw_ef": 128,
    "exact": false
  },
  "limit": 10,
  "with_payload": true
}
    

如果设置:

"exact": true
    

Qdrant 会绕过 HNSW,执行精确搜索。它适合生成 Ground Truth、验证召回率,或者在数据规模较小时作为基线,但通常不是大规模在线查询的首选路径。

怎样从业务指标反推参数?

生产调优不应该从”网上推荐 m = 16 还是 m = 32″开始,而应该从业务目标开始。

推荐验证流程是:

  1. 固定数据集、Query 集合、Top-K 和过滤条件;
  2. 使用 exact=true 生成 Ground Truth;
  3. 分组测试不同 m 和 ef_construct,等待索引完成;
  4. 对每组索引测试多个 hnsw_ef;
  5. 先筛选 Recall 达标的配置;
  6. 再剔除 P95 延迟不满足 SLA 的配置;
  7. 在剩余方案中优先选择索引更小、构建更快的组合;
  8. 检查 indexed_vectors_count、Segment 数量和 Optimizer 状态,避免”部分 Plain Search”让实验结果失真。

例如,下面两种方案都可能达到相似 Recall:

方案 A:m 较小 + hnsw_ef 很大
索引较省,但每次查询需要更努力

方案 B:m 和 ef_construct 较高 + hnsw_ef 适中
建图更贵,但在线查询可能更稳定

最终选择取决于业务是”写多查少””写少查多”,还是对内存、冷启动、P95 延迟有更严格要求。

四个常见误区

误区一:HNSW 能保证返回真实 Top-K

不能。HNSW 是近似检索算法。需要用精确搜索构造 Ground Truth,再用 Recall@K 衡量它找回了多少真实近邻。

误区二:所有参数越大越好

参数增大通常意味着更高资源成本。生产配置的目标是”满足业务指标的最低成本”,而不是参数最大化。

误区三:一个 Collection 就是一张 HNSW 图

这是便于学习的简化。实际索引位于 Segment 层;查询需要跨 Segment、Shard 获取局部候选并合并。

误区四:full_scan_threshold 和 indexing_threshold 表示向量条数

两者都使用 KB 级数据量口径。向量维度不同,相同阈值对应的向量条数也不同。

总结:HNSW 是骨架,艾体宝 Qdrant 是完整的系统

HNSW 的核心流程可以压缩成两句话:

建图阶段:随机分层 → 逐层定位 → 用 ef_construct 寻找候选 → 用 m 控制连接

查询阶段:高层快速跳跃 → Layer 0 用 hnsw_ef 扩展候选 → 返回 Top-K

而 Qdrant 在此基础上继续解决了真实业务中的关键问题:

  1. 用 Filterable HNSW 和 ACORN 处理”语义相关且满足业务条件”;
  2. 用 Payload Index 和查询规划决定走 Full Scan 还是图搜索;
  3. 用 Shard、Segment 和 Optimizer 管理分布式数据与后台索引;
  4. 用 on_disk、内存映射和量化控制资源成本;
  5. 用精确搜索提供可验证的召回率基线;
  6. 用局部检索与全局合并,返回 Collection 范围内的 Top-K。

所以,Qdrant 的价值不只是”集成了一个 HNSW 算法”。更准确地说,它把一个优秀的 ANN 算法扩展成了可过滤、可规划、可分布、可优化、可验证的生产级向量检索系统。

对客户而言,最终获得的也不只是”搜索更快”,而是:

在业务规则不被牺牲的前提下,用可控的准确率与资源成本,稳定支撑更大规模、更高并发的语义检索。

注:本文示意图均为原创绘制,用于解释算法与产品机制,不代表 Qdrant 内部数据结构逐行实现。

>> 点击了解 Qdrant向量数据库 详情

技术工程师-史工