这两年,向量检索突然就火了。随着大模型和RAG的普及,向量检索从一个小众的技术,变成了很多项目的标配。我们团队这两年做了好几个用到向量检索的项目,从最开始的简单demo,到后来的生产级系统,踩了不少坑,也积累了一些经验。

这篇文章我想总结一下向量检索的最佳实践,从向量生成、索引构建、检索优化到评估监控,分享我们在实际项目中总结的经验。如果你正在做或者准备做向量检索相关的项目,希望这些经验能帮到你。

什么是向量检索

先简单说说什么是向量检索。

传统的检索是关键词匹配,你输入一个关键词,系统找到包含这个关键词的文档。这种方式的问题是,只能匹配字面意思,不能理解语义。比如你搜"怎么让电脑变快",一篇标题是"电脑提速技巧"的文章可能就搜不到,因为没有匹配的关键词。

向量检索就不一样了。它先把文本转换成向量(一串数字),语义相近的文本,向量的距离就近。检索的时候,把你的查询也转换成向量,然后找到和查询向量距离最近的那些文档。这样就能实现语义检索,找到意思相近但用词不同的内容。

向量检索的核心是两个东西:一是把文本转换成向量的模型(通常叫嵌入模型),二是高效存储和搜索向量的数据库(通常叫向量数据库)。

这两年大模型火了之后,向量检索成了RAG(检索增强生成)的核心组件。先通过向量检索找到相关的文档,再把文档传给大模型,让大模型基于这些文档来回答问题。这样既能利用大模型的理解能力,又能解决大模型知识过时和幻觉的问题。

实践一:选对嵌入模型

第一个最佳实践,是选对嵌入模型。

嵌入模型是向量检索的基础,模型选得不好,后面再怎么优化都没用。不同的嵌入模型,在不同的任务上表现差异很大。

我们最开始用的是一个通用的开源嵌入模型,效果一般。后来换了一个针对中文优化的模型,检索效果提升了很多。再后来,我们根据自己的业务场景,用领域数据做了微调,效果又提升了一截。

选嵌入模型的时候,有几个要点。第一,要看语言支持。如果你的数据是中文的,一定要选对中文支持好的模型,很多英文模型在中文上的表现很差。第二,要看领域适配。如果是医疗、法律等专业领域,通用模型的效果可能不好,需要用领域微调的模型。第三,要看维度和性能。维度越高,表达能力越强,但存储和计算的成本也越高。要在效果和性能之间找平衡。

还有一个经验是,不要盲目追求最新的模型。新模型虽然在基准测试上表现好,但在你的具体业务场景上不一定好。一定要用自己的数据做测试,选在你的数据上表现最好的模型。

实践二:做好文本切分

第二个最佳实践,是做好文本切分。

向量检索不是把整篇文档直接转换成向量,而是先把文档切成小块(chunk),然后每个小块转换成一个向量。切分的方式,对检索效果影响很大。

我们最开始用的是最简单的固定长度切分,每500个字符切一块。效果很不好,经常把一个完整的句子切成两半,导致语义不完整。后来我们改成了按段落切分,效果好了很多。再后来,我们用了语义切分,根据语义的完整性来切分,效果又提升了。

文本切分有几个要点。第一,要保持语义完整。尽量不要把一个完整的意思切开,每个chunk应该是一个相对完整的语义单元。第二,要控制chunk的大小。太大了,向量表达的信息太杂,检索不精准;太小了,上下文不够,语义不完整。一般来说,几百到一千个字符比较合适。第三,可以用重叠切分,相邻的chunk之间有一部分重叠,这样能避免重要的信息刚好在切分边界上被漏掉。

还有一个技巧是,在每个chunk里加上一些元信息,比如文档的标题、章节、作者等。这些信息能帮助模型更好地理解chunk的语义,提升检索的准确度。

实践三:选对索引方式

第三个最佳实践,是选对索引方式。

向量数据库有多种索引方式,不同的索引方式在速度、精度、内存占用上有不同的表现。选对索引方式,能在保证精度的前提下,大幅提升检索速度。

常见的索引方式有几种。Flat是暴力搜索,精度最高,但速度最慢,只适合数据量小的场景。IVF是倒排文件索引,先聚类再搜索,速度快,精度略有损失。HNSW是层次化的图索引,目前最流行,速度和精度都很好,是大部分场景的首选。

我们的项目用的是HNSW,效果很好。但HNSW有几个参数需要调,比如M(图的最大度数)和efConstruction(构建时的搜索宽度)。这两个参数影响索引的构建速度、内存占用和查询精度。我们最开始用默认参数,效果一般,后来根据数据量和查询需求调了参数,性能提升了不少。

选索引方式的时候,要根据你的数据量和查询需求来选。如果数据量不大(几万条以内),Flat就够了,精度最高。如果数据量中等(几十万到几百万),HNSW是最好的选择。如果数据量很大(上千万以上),可能需要用更复杂的索引方式,或者做分片。

实践四:混合检索

第四个最佳实践,是用混合检索,而不是纯向量检索。

很多人以为有了向量检索就不需要关键词检索了,其实不然。向量检索擅长语义匹配,但在精确匹配上不如关键词检索。比如搜索一个产品型号、一个人名、一个专有名词,关键词检索的效果反而更好。

我们最开始只用向量检索,发现有些查询的效果不好。比如用户搜一个具体的错误码,向量检索返回的结果不太相关,因为错误码这种东西,语义模型很难理解。后来我们加了关键词检索,把向量检索和关键词检索的结果做融合,效果提升了很多。

混合检索的做法是,同时用向量检索和关键词检索,然后把两路的结果做融合排序。融合的方式有很多种,最简单的是加权求和,给向量检索和关键词检索各一个权重,然后按综合得分排序。复杂一点的可以用学习排序的方法,训练一个模型来做融合。

我们的经验是,大部分场景下,混合检索的效果都比纯向量检索好。除非你的数据完全是语义性的,没有需要精确匹配的内容,否则都建议用混合检索。

实践五:重排序

第五个最佳实践,是加一个重排序的步骤。

向量检索返回的是和查询向量最近的结果,但"最近"不一定等于"最相关"。因为向量检索是近似搜索,而且嵌入模型也不是完美的,返回的前几个结果里,可能有一些其实不太相关。

重排序就是用一个更精确的模型,对向量检索返回的前N个结果重新排序,把最相关的排到前面。重排序模型比嵌入模型更精确,因为它可以同时看查询和文档,做更精细的匹配。

我们的项目加了重排序之后,检索的精准度提升了很明显。特别是在RAG场景下,重排序能让大模型拿到更相关的文档,回答的质量也更高。

重排序的代价是增加了延迟,因为要多跑一个模型。所以一般只对向量检索返回的前20到50个结果做重排序,而不是对所有结果重排。这样既能提升精度,又不会增加太多延迟。

实践六:评估和监控

第六个最佳实践,是建立评估和监控体系。

很多人做向量检索,就是搭起来能跑就行,没有做评估和监控。结果上线之后,发现检索效果不好,也不知道哪里出了问题。

我们的经验是,一定要建立评估体系。准备一批标注好的测试数据,每个查询对应相关的文档。然后定期跑评估,看召回率、精确率、NDCG等指标。这样就能知道检索效果是好了还是差了,改了配置之后效果有没有提升。

除了离线评估,还要做线上监控。监控查询的延迟、返回结果的数量、用户的点击率和满意度等。如果发现延迟突然升高,或者点击率突然下降,就能及时发现问题。

还有一个重要的监控是数据漂移。随着时间的推移,你的数据分布可能会变化,用户的查询也可能变化。原来的嵌入模型和切分方式可能不再适用。通过监控,能及时发现数据漂移,然后做相应的调整。

实践七:增量更新

第七个最佳实践,是做好增量更新。

很多向量数据库支持增量插入,但增量插入的性能和效果需要注意。如果你的数据是持续增长的,每天都有新的文档进来,就要考虑增量更新的策略。

我们最开始是每天全量重建索引,因为数据量不大。后来数据量变大了,全量重建要花好几个小时,就改成了增量插入。增量插入很方便,新文档进来直接插进去就行。但要注意,增量插入太多之后,索引的质量可能会下降,需要定期做优化或者重建。

还有一个问题是删除和更新。向量数据库的删除一般是软删除,数据还在索引里,只是标记为删除。删除太多之后,会影响查询性能,需要定期做清理。更新一般是先删后插,要注意原子性,避免出现数据不一致。

如果你的数据更新很频繁,要特别注意向量数据库的并发性能。有些数据库在高并发写入的时候,查询性能会下降很多。一定要做压力测试,确保在你的写入量下,查询性能能满足需求。

实践八:成本控制

第八个最佳实践,是控制成本。

向量检索看起来简单,但实际用起来,成本可能很高。特别是数据量大、查询量大的时候,向量数据库的服务器费用、嵌入模型的调用费用、重排序模型的费用,加起来是一笔不小的开销。

我们总结了几个控制成本的方法。第一,优化向量维度。在效果可接受的前提下,尽量用维度低的模型,存储和计算的成本都会降低。第二,用量化。向量数据库一般支持标量量化或者乘积量化,能大幅降低内存占用,对精度的影响很小。第三,缓存。对常用的查询结果做缓存,避免重复计算。第四,批量处理。嵌入生成和索引构建尽量批量处理,比一条条处理效率高很多。

还有一个经验是,不要一开始就上最复杂的方案。先用最简单的方案跑起来,看效果和成本能不能接受。如果不行,再逐步优化。很多时候,一个简单的方案就能满足需求,不需要搞很复杂的架构。

常见的坑

最后说几个我们踩过的常见的坑。

第一个坑是,只看召回不看精确。很多人只关注能不能召回相关的文档,不关注返回的结果里有多少不相关的。但在RAG场景下,不相关的文档会严重影响大模型的回答质量。所以精确率和召回率同样重要。

第二个坑是,忽略了嵌入模型的更新。嵌入模型更新之后,向量的空间会变化,旧的向量和新的向量不在同一个空间里,不能混用。如果升级了嵌入模型,一定要重新生成所有的向量。

第三个坑是,测试数据和实际数据不一致。很多人在测试的时候用公开数据集,效果很好,但上线之后用自己的数据效果很差。一定要用自己的真实数据做测试和评估。

第四个坑是,过度优化。向量检索的优化是无止境的,但很多时候,80%的效果来自20%的优化。不要为了一点点提升,搞很复杂的架构,增加维护成本。先把基础做好,再考虑高级优化。

写在最后

向量检索这两年发展很快,从一个小众技术变成了很多项目的标配。但很多人对它的理解还停留在"把文本转成向量然后搜索"的层面,实际生产中需要考虑的问题要多得多。

选对模型、做好切分、选对索引、混合检索、重排序、评估监控、增量更新、成本控制,这些都是生产级向量检索系统需要考虑的。把这些做好了,才能真正发挥向量检索的价值。

当然,技术在不断发展,今天的最佳实践,明天可能就过时了。保持学习,不断实践,才能跟上技术的发展。

最后用一句话来结束这篇文章:"好的系统不是用了最先进的技术,而是在合适的场景用了合适的技术,并且把细节做好了。"

愿每一个技术人,都能在实践中积累经验,做出高质量的系统。