首页 / 文章

向量数据库的工作原理:嵌入、向量搜索与人类记忆。

基于内存的向量搜索思维模型:在RAG的向量数据库中,嵌入、相似度、最近邻索引及元数据过滤器是如何工作的。

发布者:REACTAPP.TOP阅读约 9 分钟2096 词

来源: Your Brain Is a Vector Database. It Just Doesn’t Call Itself That.

多年过去,可能完全不会想起曾经的童年老师。然而,一阵粉笔灰的味道、学校食堂的气味,或是回家路上常听到的歌曲,就能立刻让那个人清晰地浮现在脑海中。人们从未刻意去查找过那个人的名字,只是类似的事物出现时,记忆便自行浮现。

这正是语义搜索、检索增强生成(RAG)以及人工智能推荐系统试图复制的东西,尽管不够完美但十分认真,而实现这一功能的基石就是向量数据库。通过关联回忆可以很好地构建一个思维模型,用来解释什么是向量、如何衡量相似度、最近邻搜索的效率如何,以及这些要素如何构成一个检索流程。同时它也指出了类比失效的地方,因为那些正是实际系统容易出错的地方。

按含义而非名称存储

人类的记忆没有字母顺序索引。并不存在名为“食物”的心理文件夹,其中又包含名为“意大利菜”的子文件夹,而该子文件夹下还有名为“披萨”的文件。传统数据库正是通过这种严格的层级结构来组织数据的:每条记录都位于固定的地址,可通过精确的键来查找。

而记忆则是通过含义和关联来组织的:依据情境、感受以及事物之间的相互关系。披萨这个概念会让人联想到周五的夜晚、那不勒斯的旅行、令人舒适的食物、层层叠叠的奶酪、牛至的香气,或许还有那个毁掉了所有自制面团的大学室友。想到披萨并不会打开某个单一的文件,而是会唤醒一系列相互关联的记忆,其中关联最紧密的记忆会首先浮现。

向量数据库正是运用了这一原理。数据项是根据其含义来存储的,检索时则是根据它们与查询内容的相似度来决定,而非依赖键是否完全匹配。

嵌入向量编码的内容

要理解这种数据库,首先需要明白它存储了什么。这里的向量其实就是代表含义的有序数字列表。

机器本身并无法理解披萨的含义。通过处理海量文本,嵌入模型能够学习到单词所代表的概念。“Pizza”会出现在“cheese”、“Italian”、“dough”、“oven”和“slice”等词附近。这些词所处的语境与“sushi”不同,但与“flatbread”或“calzone”的语境有很大重叠。

该模型将这些模式压缩成固定长度的数字列表,通常包含几百到几千个数值;384和1,536是常见的规模。单个数字并无可读的标签,但它们共同将某个项目精确地定位在高维空间中。关键在于:含义相似的输入会生成彼此靠近的向量。“披萨”的向量会靠近“扁平面包”,而与“季度盈利报告”的向量相距甚远。

换言之,含义被转化为距离。其他所有概念都源于这一转换。

相似性是谱系而非匹配

传统的查询是二元的:一行数据要么满足条件,要么不满足。如果按“狗”进行过滤,得到的将是包含“狗”这个词的行,而不会出现“幼犬”、“金毛猎犬”或“忠诚的四足伙伴”等相关内容。

语义相似度则用一个分数来替代这种非黑即白的答案,该分数表示两种含义的相似程度。以一个示例性评分标准来看,“幼犬”相对于“狗”的得分可能是0.94,“狼”的得分约为0.71,而“发票”的得分则在0.08左右。这种度量方法通常是余弦相似度,或是点积、欧几里得距离等相关的距离度量,具体选择取决于嵌入模型的训练方式。

这类似于粉笔灰效应:并非精确匹配,而是某个线索触发了附近的记忆,这些记忆又会进一步激活其邻近的记忆。在向量数据库中,其机制是数值化的。查询会被转换成向量,数据库则会返回那些向量与之最为接近的存储项。所谓“接近”指的是含义相似。

正因如此,搜索“如何修复缓慢的数据库查询”时,即便这两个短语几乎没有任何共同词汇,也可能会找到标题为“大规模下优化查询性能”的文档。因为它们表达的是相同的意图,所以其向量彼此接近。

关于数值的一个注意事项

相似度分数是相对的,而非绝对的。某个嵌入模型给出的0.8分无法与另一个模型给出的0.8分直接比较,即便在同一模型内,其典型范围也会因应用领域而异。应将这些分数视为对候选项进行排序的依据,若要设定阈值,应基于自身数据进行调整,而非选择某个整数。

一个相关的补充说明:单纯的基于关键词的SQL语言无法表达语义相似性,但这并不意味着SQL数据库不能用于此用途。如下文将介绍的pgvector这类扩展,可为Postgres添加向量列和相似度运算符,从而使这种功能得以在关系型数据库中实现。

大规模下的最近邻搜索

数据库究竟是如何找到最接近的向量的?这一核心操作被称为最近邻搜索,而提升其速度正是向量数据库存在的主要原因。

可以将每个存储的项想象成银河系中的一颗星星,根据其含义进行排列,相关项则聚集在同一区域。当有查询时,就相当于在那个银河系中加入了一颗新星,然后查询距离它最近的五颗现有星星。

简单的处理方法是将查询项与每个存储的向量计算距离,对结果进行排序后返回最接近的几项。对于数千个向量来说,这种方法速度很快且完全足够。但一旦数量达到数百万甚至数十亿,与所有向量进行比较就会迅速变得极其耗时。

因此,生产系统依赖于近似最近邻(ANN)算法。它们不会逐一检查每一颗星体,而是通过索引将搜索范围缩小到有希望的区域,从而以一定的精度损失换取速度上的巨大提升。目前最常用的算法是HNSW,即分层可导航小世界算法。虽然使用向量数据库时无需了解其内部机制,但应当知道正是这一算法使得对上亿个嵌入向量的搜索能够在毫秒级时间内完成。

“近似”这一概念值得重视。人工神经网络索引有时会错过真正的最近邻,而其找到真正最佳结果的比率——即召回率——取决于那些在内存、延迟与准确性之间进行权衡的索引参数。如果在大规模应用中检索质量出现莫名其妙的波动,那就值得检查索引设置;我们的针对生产环境RAG优化HNSW索引指南对相关参数进行了深入讲解。

向量数据库的内部机制

从根本上说,向量数据库是一种为特定任务优化过的存储方式:用于存储向量,并能非常快速地执行针对这些向量的最近邻搜索。

想象这样一个图书馆,它不采用杜威十进制分类法,而是根据书籍所传达的情绪来摆放书籍。关于悲伤的书籍与关于失去的书籍放在一起,这些书籍又与关于孤独的书籍相邻,接着是关于孤立的书籍,再往后则是独自探险的回忆录。这些分类并非由人工设定,而是因为喜欢某一类书籍的读者往往也会想要其他相关的书籍,从而形成了这样的排列。

Pinecone、Weaviate、Chroma和Qdrant都是这类图书馆的例子。你可以将文档嵌入、产品描述、转换为向量的图像或用户行为模式加载到这些系统中,它们会维护索引,以便在藏品不断增加时仍能实现快速检索。

每条存储的记录通常包含三部分:

  • 唯一标识该条记录的ID。
  • 代表其含义的向量。
  • 可选的元数据,如标题、日期、类别或来源URL,可用于筛选结果。

元数据的价值远超表面所见。一个实际的查询需求可能是:找出与查询内容最相似的五份文档,但仅限过去30天内、且仅来自工程团队知识库的文档。这其实就是向量搜索与元数据过滤的结合,而大多数生产系统都依赖这种组合方式。过滤的应用方式也很重要:在相似度搜索之后再进行过滤可能会导致结果数量少于预期,因此请检查数据库是否在搜索过程中就进行了过滤。

RAG检索流程的端到端介绍

无论它存在于RAG系统、语义搜索功能中,还是任何利用存储知识的应用程序中,检索过程都遵循相同的四个步骤。

  1. 嵌入内容。所有需要支持搜索的文档、文章、产品描述或记录都会经过嵌入模型处理,生成的向量会与原始内容一同存储。较长的文档通常会先被分割成多个片段,因为用一个向量来表示整份手册会导致太多信息相互混淆。
  2. 使用相同的模型对查询进行嵌入。这并非可选步骤。不同的嵌入模型会在不同的向量空间中生成向量,因此用某个模型的查询去对比另一个模型的文档,得到的距离值毫无意义。更换模型意味着需要重新对整个集合进行嵌入处理。
  3. 执行搜索。查询向量会被送入数据库,通过最近邻搜索找到存储中最接近的向量,随后返回最相关的结果,通常还会附带相似度得分。
  • 利用这些结果。在RAG流程中,检索到的段落会被作为上下文传递给语言模型,因此答案基于真实文档而非猜测。在推荐系统中,这些结果就是推荐内容;在搜索功能中,它们则是展示给用户的搜索结果。
  • 从用户的角度来看,相关答案会在瞬间出现。其背后是先将含义转化为数字,再在数百万条存储内容中进行比对,返回最接近的匹配项,最终用真实内容生成响应。

    为何向量搜索如今无处不在

    不久前,向量数据库还只是用于构建语义搜索或专用推荐系统时的小众工具。如今,它们已成为许多人工智能应用的标准组成部分。RAG需要一个地方来存储和查询文档嵌入向量。智能体通过语义来查询知识库。大规模推荐系统则依赖向量相似度。而多模态搜索,比如根据文本描述查找图片或根据上传的照片查找产品,同样也是通过向量来实现的。

    如果你正在基于大型语言模型进行实际应用开发,很有可能你已经在使用向量搜索,或者很快就会依赖它。令人欣慰的是,其核心理念其实早已为人所熟知:自从人类诞生以来,记忆系统就一直在为我们的感官所接收的信息检索最相关的关联内容。向量数据库只是用数字代替了信息内容,并能在毫秒级时间内处理数百万条数据,实现同样的功能。

    记忆类比的局限性

    将大脑比作记忆有助于直观理解,但实际应用中存在一些差异:

    • 记忆会持续适应;而嵌入模型则是固定的。如果所在领域的词汇发生变化,向量本身不会自动更新。
    • 记忆能轻松融合上下文;向量仅能捕捉输入的内容。分割不当或包含噪声的源文本会导致相近向量质量低下。
    • 相似性并不等同于相关性。两段文本可能在含义上相近,但只有一段真正能回答问题,正因如此许多系统会额外加入关键词搜索或重排步骤。

    动手实践

    无需构建任何基础设施即可进行实验:

    • ChromaDB 可在 Python 环境中本地运行,无需账户、API 密钥或部署,安装和初始化只需几行代码。它非常适合学习和小型项目。
    • Qdrant 提供免费的云服务层级以及简洁的 Python 客户端,若您希望获得接近生产环境的功能而又不想自行管理服务器,它是不错的选择。在实际使用前请先了解当前的层级限制。
    • pgvector 是 Postgres 的扩展功能。如果您已经在使用 Postgres,它无需额外创建数据库即可实现向量搜索,从而保持技术栈的简洁性。

    无论选择哪种方案,工作流程都是一样的:选定嵌入模型,对内容进行嵌入处理,存储向量数据,对输入的查询进行嵌入处理后再进行搜索。核心概念保持不变,只有客户端库会有所不同。

    简述其核心思路

    • 嵌入模型将含义转化为位置,从而使相似的项彼此靠近。
    • 相似度分数用于对候选项进行排序;需根据自身数据调整阈值。
    • 如HNSW这样的近似最近邻索引会在一定程度上牺牲召回率,以换取大规模应用时的更高速度。
    • 元数据过滤器可将原始相似度转化为符合时间、来源及访问规则的答案。
    • 查询与文档必须使用相同的嵌入模型,检索质量不仅取决于数据库,还与数据分块方式及数据质量密切相关。

    相关阅读

  • 调整HNSW索引与扩展向量搜索以适配生产环境中的RAG系统:了解HNSW的M参数和ef参数如何影响召回率、延迟和内存使用,学习如何在Chroma中设置这些参数,以及何时通过垂直扩展或分片方式来扩展向量数据库。
  • 当向量RAG无法满足需求时的基于本体的上下文工程:当语义涉及多系统的数据时,仅靠嵌入向量无法实现数据关联。基于本体的上下文工程可通过类型化事实、数据来源验证及邻域分析工具,为大型语言模型提供更有依据的回答。