自建一套向量检索,装库是最简单的一步。真正花时间的是分块怎么切、索引参数怎么配、文档改了怎么删旧数据,还有那套迟早要补的评测。
我在本机用容器起过几套向量库,也踩过一个很难查的坑:把同一个 embedding 模型两个版本产出的向量写进了同一个集合,那天的检索结果基本是随机的,排查到半夜才发现问题。
这篇按踩坑的顺序,把这条链路真正难的地方讲一遍。
先想清楚它要回答什么问题
向量检索擅长的是「意思相近」。用户问「报销流程」,文档里写的是「费用申请审批」,字面不重合但意思接近,这就是它发挥作用的地方。
它不擅长精确匹配。订单号、错误码、型号这类字符串,拿向量去查很可能查不到。所以真正能用的方案基本都是混合检索:关键词一路兜住精确命中,向量一路补齐语义召回,两路结果合并再排序。
如果你的场景里大多数查询是「找某个编号」,那向量库不是第一优先级,倒排索引更合适。这点先想清楚,能省掉很多白干。
分块决定了答案质量的上限
大部分「检索不准」追到根上都在分块。
按固定字数切最省事,也最容易出事:一句话被劈成两半,表格切断了表头,代码块从中间截开。检索到半张表,模型再强也编不出正确结论。
我的做法是按文档结构切:标题层级当一级边界,代码块、表格、列表尽量整块保留。每个块前面再拼一行上下文,写明它出自哪份文档的哪一章,让这个块离开原文之后仍然读得通。
块多大是取舍。太大,一个块里塞了好几个主题,召回时噪声多;太小,上下文不够,模型要拼更多块才能答完,成本跟着涨。这个值只能拿自己的数据试出来。
相邻块之间留一点重叠,能缓解「答案正好压在切分点上」的情况。代价是向量条数和存储都变多,重叠比例别随手设。
向量化:模型换了,整库就得重建
第二条最容易翻车的规则:一个集合里的向量必须来自同一个模型、同一个版本。
不同模型(甚至同一次升级前后的两个版本)产出的向量不在同一个空间里,混在一起算相似度没有意义,表现就是结果看起来完全随机。所以模型名和版本要写进元数据,重建的时候才说得清。
距离度量也要和归一化方式对齐。用余弦相似度就统一做归一化;用内积要清楚自己有没有归一化;用欧氏距离要留意数值范围。这几件事对不上,排序就会悄悄错。
用本地小模型还是调远端接口,是另一组取舍。本地可以离线、单条成本固定、数据不出机器;远端通常效果更好、维护省心,但断网就用不了,还按量计费。自己搭知识库,我倾向先用本地模型把链路跑通。
索引参数是在用内存换速度
向量检索默认走近似最近邻,也就是接受「不保证找到绝对最近的那几条,但足够接近」。图索引(HNSW 这一类)是常见选择,查询快,代价是内存——它除了存向量本身,还要存图结构。
内存不够有两条路:换索引类型(倒排加聚类的 IVF 系,配合乘积量化的方案),或者给向量做量化,比如降到 8 位整数,把存储压下来。量化的代价是召回下降,降到什么程度要用评测说话,不能凭感觉。
还有一点常被忽略:建索引是重活,写数据的时候查询延迟会明显抖,所以重建一般放到低峰期做。
增量更新和删除是最难的部分
新增文档很简单,难的是修改和删除。
文档更新之后,如果旧向量没清掉,同一份内容的新旧两个版本会同时被检索到,用户会看到自相矛盾的答案。我的处理是逻辑删除加定期重建:删除只打标记,检索时过滤掉,重建时再物理清除。
重建期间不能停服务,所以要么双写两个集合,要么建好新集合再切别名,切之前先跑一遍评测做对比。
集合最好按业务拆开。全混在一个大集合里,权限过滤和重建都会变麻烦。
没有评测集,调参就是碰运气
我一开始改完参数就随手搜几个问题看「感觉对不对」。这种调法没什么意义:问题是随机挑的,判断标准是心情。
后来补了一套最小评测:从真实提问里挑几十条,人工标出每条应该命中的文档。这样每次改分块、换模型、调参数,都能跑同一套对照,看命中情况有没有变化。
指标看两个就够了:前几条里有没有命中正确答案,以及正确答案排在第几。
检索效果不好的时候,先回头看分块,再怀疑模型。换模型是最后一步。
部署时容易被低估的几件事
内存。全量向量通常要常驻内存,这是主要成本项,而且内存比磁盘贵得多。容量规划得按内存算,不是按磁盘算。
备份和恢复。重建一次要多久,最好真的演练一遍。只写在文档里的恢复方案等于没有。
监控。查询延迟的分位数、索引大小、召回率的变化,这几个数比 CPU 占用更早暴露问题。
- 1分块按文档结构切,块里带上所属章节
- 2向量化固定模型版本,度量与归一化对齐
- 3建索引内存换速度,量化换容量
- 4检索重排先粗召回一批,再用小模型精排
- 5评测回归换任何一环,都跑同一套对照集
结论
自建向量检索这件事,把库跑起来只占很小一部分工作量。真正决定它好用不好用的,是分块切得干不干净、向量有没有保持同源、索引参数和内存配不配得上,以及有没有一套能说清好坏的评测。
顺序别搞反:先把数据和评测做扎实,再去纠结索引和模型。
本文不构成任何技术或经营建议,具体选型请结合自己的数据实测后再定。