Multi-query Retrieval
Multi-query Retrieval 是用 LLM 生成多个不同角度的查询,分别检索后合并去重的策略。它提高了检索的召回率。
#type / concept
#status / evergreen
#tech / ai
[!info] related notes
- 所属 MOC: RAG Engineering MOC
- 相关: Query Rewriting, Retriever
Multi-query Retrieval
一句话定义
Multi-query Retrieval 是用 LLM 生成多个不同角度的查询,分别检索后合并去重。一个问题可以有多种表述方式,多查询提高了召回率。
核心原理
流程
用户问题: "膝关节不稳定怎么康复"
│
▼
LLM 生成多个查询:
- "膝关节不稳定康复方法"
- "膝关节稳定性训练"
- "前交叉韧带损伤康复"
- "膝关节周围肌肉强化"
│
▼
每个查询独立检索 → 4 组结果
│
▼
合并去重 → 最终结果
Python 实现
class MultiQueryRetriever:
def __init__(self, llm, retriever):
self.llm = llm
self.retriever = retriever
async def retrieve(self, query: str, num_queries: int = 3, top_k: int = 5) -> list[Chunk]:
# 1. 生成多个查询
queries = await self.generate_queries(query, num_queries)
# 2. 并行检索
tasks = [self.retriever.retrieve(q, top_k=top_k) for q in queries]
results = await asyncio.gather(*tasks)
# 3. 合并去重
all_chunks = []
seen_ids = set()
for chunks in results:
for chunk in chunks:
if chunk.id not in seen_ids:
all_chunks.append(chunk)
seen_ids.add(chunk.id)
return all_chunks[:top_k * 2]
async def generate_queries(self, query: str, n: int) -> list[str]:
prompt = f"""
请从不同角度生成 {n} 个搜索查询,用于查找与以下问题相关的信息:
问题: {query}
请输出 {n} 个查询,每行一个:
"""
result = await self.llm.chat(prompt)
return result.strip().split("\n")[:n]
常见坑
- 查询太多: 生成 10 个查询,检索 10 次,延迟太高
- 查询太相似: 生成的查询都是同一角度
- 不做去重: 相同文档重复出现