向量存储
此概念概述侧重于文本索引和检索以简化说明。 然而,嵌入模型可以是多模态的,向量存储可用于存储和检索超越文本的各种数据类型。
概览
向量存储是专门的数据存储,支持基于向量表示对信息进行索引和检索。
这些向量被称为嵌入,它们捕获了已嵌入数据的语义含义。
向量存储通常用于搜索非结构化数据,例如文本、图像和音频,以基于语义相似度而非精确关键词匹配来检索相关信息。

集成
LangChain 拥有大量的向量存储集成,允许用户轻松切换不同的向量存储实现。
请查看 LangChain 向量存储集成的完整列表。
接口
LangChain 为使用向量存储库提供了标准接口,允许用户轻松在不同向量存储库实现之间切换。
该接口包含用于在向量存储中写入、删除和搜索文档的基本方法。
关键方法包括:
add_documents: 将文本列表添加到向量存储中。delete: 从向量存储中删除一批文档。similarity_search: 搜索与给定查询相似的文档。
初始化
LangChain 中的大多数向量在初始化向量存储时,都接受一个嵌入模型作为参数。
我们将使用 LangChain 的 InMemoryVectorStore 实现来说明该 API。
from langchain_core.vectorstores import InMemoryVectorStore
# Initialize with an embedding model
vector_store = InMemoryVectorStore(embedding=SomeEmbeddingModel())
添加文档
要添加文档,请使用 add_documents 方法。
此 API 与 Document 对象列表配合使用。
Document 个对象均具有 page_content 和 metadata 属性,使其成为存储非结构化文本及相关元数据的通用方式。
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)
您通常应为添加到向量存储的文档提供 ID,这样在添加同一文档多次时,您可以更新现有文档,而不是重复添加。
vector_store.add_documents(documents=documents, ids=["doc1", "doc2"])
删除
要删除文档,请使用 delete 方法,该方法接受一个文档 ID 列表作为参数。
vector_store.delete(ids=["doc1"])
搜索
向量存储嵌入并存储添加的文档。 如果我们传入一个查询,向量存储将嵌入该查询,在已嵌入的文档上执行相似性搜索,并返回最相似的文档。 这捕捉了两个重要概念:首先,需要有一种方法来衡量查询与任何嵌入文档之间的相似性。 其次,需要一种算法来高效地在所有嵌入文档上执行这种相似性搜索。
相似度指标
嵌入向量的一个关键优势是,它们可以使用许多简单的数学运算进行比较:
- 余弦相似度: 衡量两个向量之间夹角的余弦值。
- 欧几里得距离: 测量两点之间的直线距离。
- 点积: 衡量一个向量在另一个向量上的投影。
相似度度量的选择有时可以在初始化向量存储时进行。请查阅您正在使用的特定向量存储的文档,以了解支持哪些相似度度量。
- 请参阅 Google 关于在嵌入中考虑的相似性度量的此文档。
- 查看 Pinecone 关于相似度度量的博客文章。
- 查看 OpenAI 的 常见问题解答 (FAQ),了解在使用 OpenAI 嵌入时应采用何种相似度度量方法。
相似度搜索
给定一个用于衡量嵌入查询与任意嵌入文档之间距离的相似度度量标准,我们需要一种算法来高效地搜索所有嵌入文档以找到最相似的那些。
有多种方法可以实现这一点。例如,许多向量存储库实现了HNSW(分层可导航小世界),这是一种基于图形的索引结构,支持高效的相似度搜索。
无论底层使用何种搜索算法,LangChain 向量存储接口都为所有集成提供了一个similarity_search方法。
该方法将接收搜索查询,创建嵌入,查找相似文档,并以Documents列表的形式返回它们。
query = "my query"
docs = vectorstore.similarity_search(query)
许多向量存储支持在similarity_search方法中传递搜索参数。请查阅您正在使用的特定向量存储的文档,以了解其支持的参数。
以Pinecone为例,有几个重要的通用概念参数:
许多向量存储支持k,用于控制返回的文档数量;以及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
元数据过滤
向量存储库实现了一种搜索算法,用于高效地搜索所有嵌入文档以找到最相似的文档,但许多向量存储库还支持对元数据进行过滤。 元数据过滤通过应用特定条件(例如从特定来源或日期范围检索文档)来帮助缩小搜索范围。这两个概念可以很好地协同工作:
- 语义搜索: 直接查询非结构化数据,通常通过嵌入或关键词相似度实现。
- 元数据搜索: 对元数据应用结构化查询,过滤特定文档。
元数据过滤的向量存储支持通常依赖于底层向量存储的实现。
这是使用 Pinecone 的示例用法,展示我们如何过滤所有元数据键为 source 且值为 tweet 的文档。
vectorstore.similarity_search(
"LangChain provides abstractions to make working with LLMs easy",
k=2,
filter={"source": "tweet"},
)
- 查看 Pinecone 关于使用元数据进行过滤的文档。
- 查看支持元数据过滤的 LangChain 向量存储集成列表。
高级搜索与检索技术
虽然像 HNSW 这样的算法为许多情况下的相似性搜索提供了基础,但还可以采用其他技术来提高搜索质量和多样性。
例如,最大边际相关性(Maximal Marginal Relevance) 是一种用于使搜索结果多样化的重排序算法,它在初始相似性搜索后应用,以确保结果集更加多样化。
第二个例子是,一些向量数据库提供内置的混合搜索功能,以结合关键词搜索和语义相似性搜索,从而融合两种方法的优势。
目前,LangChain 向量存储库中没有统一的方法来执行混合搜索,但它通常作为关键字参数暴露,并通过similarity_search传入。
有关更多详细信息,请参阅这份关于混合搜索的操操作指南。
| 名称 | 何时使用 | 描述 |
|---|---|---|
| Hybrid search | When 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. |