引言
在信息检索和推荐系统中,使用向量来表示文档的语义信息已经成为一种标准做法。为了提高检索精度,尤其是在文档较长或主题较多样时,存储每个文档的多个向量是非常有益的。这篇文章将探讨如何为每个文档创建多个向量,并使用LangChain的MultiVectorRetriever来实现高效的检索。
主要内容
为什么使用多个向量表示一个文档?
- 小块划分:将文档划分为较小的片段,并分别嵌入(例如,使用
ParentDocumentRetriever)。 - 文档摘要:为每个文档创建一个摘要,与原文或替代文嵌入。
- 假想问题:生成文档可能回答的假想问题,并嵌入这些问题以提高检索能力。
LangChain的MultiVectorRetriever
LangChain为处理多个向量提供了一个基础实现,MultiVectorRetriever。这个工具允许我们将小片段的向量与父文档关联,从而在检索到文档片段时能返回完整文档。
代码示例
以下是一个使用LangChain创建多个向量的完整示例:
import uuid
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
from langchain.retrievers.multi_vector import MultiVectorRetriever
# 使用API代理服务提高访问稳定性
loaders = [
TextLoader("example_essay.txt"),
TextLoader("another_example.txt"),
]
docs = []
for loader in loaders:
docs.extend(loader.load())
text_splitter = RecursiveCharacterTextSplitter(chunk_size=10000)
docs = text_splitter.split_documents(docs)
# 使用向量存储来索引子文档
vectorstore = Chroma(
collection_name="full_documents", embedding_function=OpenAIEmbeddings()
)
# 父文档的存储层
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)))
# 查询示例
retrieved_docs = retriever.invoke("特定查询词")
print(len(retrieved_docs[0].page_content))
常见问题和解决方案
-
如何选择合适的片段大小?
片段大小应与应用场景的语义粒度和计算资源权衡。较小的片段可以更好地捕获细节,但会增加向量数量和存储需求。 -
如何保证API的稳定性?
由于网络限制,建议使用API代理服务来保障访问的稳定性。
总结及进一步学习资源
使用多个向量表示文档,可以显著提高检索系统的精度和效率。我们使用LangChain的MultiVectorRetriever简化了这一过程。读者可以进一步探索LangChain文档以深入了解其强大功能。
进一步学习资源:
参考资料
- LangChain API参考文档
- OpenAI Embeddings的实现细节
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
—END—
10万+

被折叠的 条评论
为什么被折叠?



