Multi-query Retrieval

Multi-query Retrieval 是用 LLM 生成多个不同角度的查询,分别检索后合并去重的策略。它提高了检索的召回率。

#type / concept #status / evergreen #tech / ai

[!info] related notes

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]

常见坑

  1. 查询太多: 生成 10 个查询,检索 10 次,延迟太高
  2. 查询太相似: 生成的查询都是同一角度
  3. 不做去重: 相同文档重复出现

参考资料

创建于 2026/6/30 更新于 2026/7/15