Skip to main content
在 GitHub 上打开

矢量存储

先决条件
注意

为简单起见,本概念性概述重点介绍基于文本的索引和检索。 但是,嵌入模型可以是多模态的,并且向量存储可用于存储和检索文本以外的各种数据类型。

概述

矢量存储是专用数据存储,支持基于矢量表示进行索引和检索信息。

这些向量称为嵌入向量,用于捕获已嵌入的数据的语义含义。

矢量存储通常用于搜索非结构化数据(如文本、图像和音频),以根据语义相似性而不是确切的关键字匹配来检索相关信息。

矢量存储

集成

LangChain 拥有大量的 vectorstore 集成,允许用户在不同的 vectorstore 实现之间轻松切换。

请参阅 LangChain vectorstore 集成的完整列表

接口

LangChain 提供了一个用于 vector store 的标准接口,允许用户轻松地在不同的 vectorstore 实现之间切换。

该接口由在 vector store 中写入、删除和搜索文档的基本方法组成。

主要方法包括:

  • add_documents:将文本列表添加到向量存储中。
  • delete:从向量存储中删除文档列表。
  • similarity_search:搜索与给定查询类似的文档。

初始化

LangChain 中的大多数 vector 在初始化 vector store 时都接受 embedding 模型作为参数。

我们将使用 LangChain 的 InMemoryVectorStore 实现来说明 API。

from langchain_core.vectorstores import InMemoryVectorStore
# Initialize with an embedding model
vector_store = InMemoryVectorStore(embedding=SomeEmbeddingModel())
API 参考:InMemoryVectorStore

添加文档

要添加文档,请使用add_documents方法。

此 API 适用于 Document 对象列表。Document对象都有page_contentmetadata属性,使其成为存储非结构化文本和相关元数据的通用方法。

from langchain_core.documents import Document

document_1 = Document(
page_content="I had chocolate chip pancakes and scrambled eggs for breakfast this morning.",
metadata={"source": "tweet"},
)

document_2 = Document(
page_content="The weather forecast for tomorrow is cloudy and overcast, with a high of 62 degrees.",
metadata={"source": "news"},
)

documents = [document_1, document_2]

vector_store.add_documents(documents=documents)
API 参考:文档

通常,您应该为添加到向量存储中的文档提供 ID,因此 这样,您可以更新现有文档,而不是多次添加同一文档。

vector_store.add_documents(documents=documents, ids=["doc1", "doc2"])

删除

要删除文档,请使用delete方法,该方法获取要删除的文档 ID 列表。

vector_store.delete(ids=["doc1"])

Vector 存储嵌入并存储添加的文档。 如果我们传入查询,vectorstore 将嵌入查询,对嵌入的文档执行相似性搜索,并返回最相似的文档。 这捕获了两个重要概念:首先,需要有一种方法来测量查询和任何嵌入文档之间的相似性。 其次,需要有一种算法来有效地在所有嵌入文档中执行这种相似性搜索。

相似度指标

embeddings 向量的一个关键优点是可以使用许多简单的数学运算来比较它们:

  • 余弦相似度:测量两个向量之间角度的余弦值。
  • 欧几里得距离:测量两点之间的直线距离。
  • 点积:测量一个向量到另一个向量的投影。

有时可以在初始化 vectorstore 时选择相似性指标。请参考 到您正在使用的特定 VectorStore 的文档,以查看支持哪些相似性指标。

延伸阅读
  • 请参阅 Google 提供的此文档,了解嵌入时要考虑的相似性指标。
  • 请参阅 Pinecone 关于相似性指标的博客文章
  • 请参阅 OpenAI 的常见问题解答,了解与 OpenAI 嵌入一起使用的相似性指标。

给定一个相似性指标来衡量嵌入式查询和任何嵌入式文档之间的距离,我们需要一种算法来有效地搜索所有嵌入式文档以找到最相似的文档。 有多种方法可以做到这一点。例如,许多矢量存储实现了 HNSW(分层可导航小世界),这是一种基于图形的索引结构,允许高效的相似性搜索。 无论后台使用何种搜索算法,LangChain vectorstore 接口都有一个similarity_search方法。 这将获取搜索查询、创建嵌入、查找类似文档,并将它们作为文档列表返回。

query = "my query"
docs = vectorstore.similarity_search(query)

许多 vectorstore 支持使用similarity_search方法。请参阅您正在使用的特定 vectorstore 的文档,了解支持哪些参数。 举个 Pinecone 示例,几个参数是重要的一般概念: 许多 vectorstores 支持k,用于控制要返回的 Documents 数量,以及filter,它允许按元数据筛选文档。

  • query (str) – Text to look up documents similar to.
  • k (int) – Number of Documents to return. Defaults to 4.
  • filter (dict | None) – Dictionary of argument(s) to filter on metadata
延伸阅读
  • 请参阅 操作指南 有关如何使用similarity_search方法。
  • 请参阅 集成 页面 有关可传递到similarity_search方法。

元数据筛选

虽然 vectorstore 实现了一种搜索算法来有效地搜索所有嵌入的文档以找到最相似的文档,但许多 vectorstore 还支持对元数据进行过滤。 元数据筛选通过应用特定条件(例如从特定来源或日期范围检索文档)来帮助缩小搜索范围。这两个概念可以很好地协同工作:

  1. 语义搜索:直接查询非结构化数据,通常通过嵌入或关键字相似性。
  2. 元数据搜索:对元数据应用结构化查询,筛选特定文档。

向量存储对元数据筛选的支持通常取决于基础向量存储实现。

以下是 Pinecone 的示例用法,显示我们筛选出具有 metadata 键的所有文档sourcewith valuetweet.

vectorstore.similarity_search(
"LangChain provides abstractions to make working with LLMs easy",
k=2,
filter={"source": "tweet"},
)
延伸阅读

高级搜索和检索技术

虽然在许多情况下,像 HNSW 这样的算法为高效的相似性搜索提供了基础,但可以采用其他技术来提高搜索质量和多样性。 例如,最大边际相关性是一种用于使搜索结果多样化的重新排名算法,该算法在初始相似性搜索之后应用,以确保结果集更加多样化。 作为第二个示例,一些向量存储提供内置的混合搜索,以结合关键字和语义相似性搜索,这结合了这两种方法的优势。 目前,没有统一的方法来使用 LangChain vectorstores 执行混合搜索,但它通常作为关键字参数公开,该参数通过similarity_search. 有关更多详细信息,请参阅此混合搜索操作指南

名字适用情形描述
Hybrid searchWhen combining keyword-based and semantic similarity.Hybrid search combines keyword and semantic similarity, marrying the benefits of both approaches. Paper.
Maximal Marginal Relevance (MMR)When needing to diversify search results.MMR attempts to diversify the results of a search to avoid returning similar and redundant documents.