日期:2026-09-28
我们知识库向量规模涨到上亿条后,原先的暴力检索越来越慢,切到 IVF 索引后召回率却掉了,员工搜不到该搜到的文档,知识库口碑直线下滑。我们进场时,这个知识库每天被内部几万人搜,暴力检索一次要扫上亿向量,延迟高到员工宁可去问人,IVF 上线后快是快了,但该搜到的偏偏漏掉,投诉换了个方向。
当时团队提过把 IVF 的聚类中心数调大,但调大了索引体积暴涨,内存又顶不住,陷入两难。结论很清楚,亿级向量别死磕暴力检索,IVF 配 PQ 省成本,但 nprobe 和聚类数得靠评测反推,不能拍脑袋。这个项目让我意识到,向量检索的难处不在快,在快的同时把该召回的保住,召回率才是知识库的生命线。
新方案做 IVF_PQ 索引,聚类把向量分桶,PQ 把高维向量压缩存储,检索时先定位几个最近的桶再精排,又快又省内存。nprobe 动态调节,常规查询探少量桶保速度,重要查询探更多桶提召回。聚类中心数按数据规模和内存预算设,不盲目拉高。
召回率离线评测接进来,定期用标注集跑一遍看漏了多少,badcase 单独拉出来分析。上线后我们跟过一个法务检索场景,员工搜合同条款,原来暴力检索慢得没人用,IVF_PQ 快了但漏了部分条款,调 nprobe 后漏的又找回来,员工才肯用。
IVF 聚类中心数最怕定错,太少桶太粗漏召回,太多桶太细索引膨胀。我们按向量规模和内存上限算中心数,压测里看召回随中心数变化的拐点,选性价比最高的那一档。nprobe 动态调节难在平衡,探的桶多召回高但慢,探的少快但漏。我们按查询重要性和延迟预算分级,关键检索多探几桶,闲时查询少探保速度。
PQ 压缩精度是隐性坑,压太狠向量失真,近邻关系打乱。我们按维度选 PQ 分段数,压测召回不达标就调细分段,不让压缩吃掉精度。召回率评测要持续,数据一直在涨,今天达标的参数明天可能漏,我们做定期回归,badcase 进清单跟踪。
核心配置如下,索引与评测要双管:
index:
type: IVF_PQ
n_clusters: 向量规模+内存上限反推(取召回拐点)
nprobe: 动态(关键检索多探/闲时少探)
pq_segments: 按维度选(压缩不伤精度)
eval:
recall_offline: 标注集定期回归
badcase: 进清单跟踪检索耗时从上亿向量暴力扫描的十几秒降到毫秒级,IVF_PQ 先落桶再精排,员工搜一下立刻出结果,知识库使用率明显回升。召回率从 IVF 初版的八成出头提到九成五以上,nprobe 动态调节把关键查询漏掉的文档找回来,员工搜不到的投诉少了。
存储成本降了约一半,PQ 压缩把高维向量压小,同样内存能存更多向量,亿级规模也不怕。badcase 数从每月几十个降到个位数,离线评测持续抓漏,知识库口碑从下滑转稳。我们对比过,上线前员工宁可问同事也不搜系统,检索慢加漏结果双重劝退;上线后内部搜索日活涨了约四成,员工愿意自己查了。
召回率一接进监控大盘就设了阈值告警,低于阈值立刻亮灯,不会悄无声息把文档漏掉,我们也能主动看见召回掉了,不用再等员工投诉。
我们还把召回率接进监控大盘,低于阈值就告警,避免悄无声息漏文档坑了员工。我们复盘时算过一笔账,知识库检索慢加漏结果双重劝退,员工宁可问同事也不搜系统,上线后内部搜索日活涨约四成,这部分本该是知识库替员工消化掉的重复提问。一个季度跑完因搜不到导致的重复提问工单降约五成,那次把聚类中心数拍高想保召回却内存爆掉的教训,让我们把压测做成固定动作,每次数据涨都先跑回归再动参数。员工后来养成了搜之前先信系统的习惯,知识库从被人嫌弃变成了真在用的工具,这才是召回率治理的终点。
上亿向量别死磕暴力检索,IVF 配 PQ 省成本,但 nprobe 和聚类数得靠评测反推。我们起手把聚类中心数拍高想保召回,结果内存爆了索引建不起来,后来按内存上限取召回拐点才落稳,那次拍脑袋让我们把压测做成了固定动作。nprobe 要动态,关键查询多探桶、闲时少探,一刀切要么慢要么漏。PQ 分段别压太狠,压缩吃掉精度召回就垮。召回率评测要持续,数据天天涨,今天达标的参数明天可能漏,badcase 进清单跟踪才不丢。下一步想把查询语义热度接进 nprobe,热查询自动多探保体验。
案例片段(已脱敏): IVF_PQ 索引(聚类分桶加 PQ 压缩),nprobe 按查询重要性动态调节;聚类中心数按规模与内存反推取召回拐点;PQ 分段按维度选;离线标注集定期回归召回率,badcase 进清单。某阶段统计:检索耗时由十余秒降至毫秒级;召回率由 IVF 初版 80%+ 提至 95%+;存储成本降约 50%;badcase 由月数十个降至个位数;内部搜索日活涨约 40%。