要把用户嘴里的「退货流程」和文档里那句「商品寄回后多久能退款」对上,靠的不是字面匹配。文本被切成片段、送进模型、变成一串几百上千维的浮点数之后,检索就从「找相同的词」变成了「找附近的点」。向量数据库处理的,正是这类「找附近」的请求。
距离是怎么变成一次查询的
一句话被编码成向量,语义相近的句子在空间里靠得近——这是整套做法的前提,也是最脆弱的地方。编码模型一换,坐标系就变了,旧向量和新向量不能混着用;这件事往往在项目上线几个月后才暴露出来,因为没人会记得当初那批历史数据是用哪个版本的模型算的。
索引层面常见的思路是用「近似」换速度:不保证一定返回离得最近的那些点,只保证大概率返回。召回率和延迟之间的这条曲线,得由业务自己定位置。答错一次的代价有多大,比把耗时压到多少毫秒更值得先想清楚。
麻烦往往不在索引
真正耗时间的是过滤和更新。用户的查询几乎从不只是「找相似」,还带着租户、权限、时间范围、文档状态这些硬条件。先过滤再算距离,和先算距离再过滤,结果与开销都不一样,不少实现要在这两者之间做折中,而折中的效果很难在演示环境里看出来。
删除也是。文档下线了,向量还留在索引里,能不能立刻不出现,取决于具体实现。还有增量写入:数据每天变一部分,是全量重建,还是接受索引逐渐碎片化——这是一笔要持续付下去的运维账,不是一次配置能解决的。
它并不总是必需的
如果数据只有几千条,一次遍历算相似度可能比维护一个独立服务更省心;如果关键词检索已经能把大部分查询答准,剩下的再谈语义也不迟;如果现有关系型数据库的扩展已经够用,多引入一个向量数据库,就多一份备份、监控和升级的负担。判断依据不是技术新不新,而是你的问题是不是「语义相近」的问题,以及规模是否已经让暴力比较变得昂贵。
真要动手之前,我会先弄清几件事
- 查询里有多少必须带硬性过滤条件,这些条件在系统里能不能高效执行。
- 数据多久变一次,删除后要不要求立刻不可见,重建索引的时间窗口能不能接受。
- 团队愿意为一个新的有状态服务付出多少运维成本,出故障时由谁来定位。
还有一点常被忽略:解码这一端的能力上限,往往比检索端更早到。系统把相关段落找了出来,可如果模型读不懂拼在一起的上下文,换什么索引都救不回来。把向量数据库当成默认答案,容易掩盖真正的问题——是数据没切好,还是查询本身就没法说清楚。