08. Query Rewrite、Multi-Query 和 HyDE 分别是什么?

整理 Query Rewrite、Multi-Query 和 HyDE 分别是什么? 的核心概念、工程要点与面试回答。

简单回答

这三者都是优化 RAG 检索质量的 Query 变换技术。Query Rewrite 是用 LLM 把用户的原始提问改写成更适合检索的形式;Multi-Query 是把一个问题拆成多个不同角度的子查询分别检索后合并结果;HyDE(Hypothetical Document Embeddings)是让 LLM 先生成一个假设性的答案文档,用这个假设答案去做检索。三者的共同目标是弥合用户提问和知识库文档之间的"语义鸿沟"。

详细解释

问题的根源:Query-Document Mismatch

RAG 效果不好,很大一部分原因不在模型或向量库,而在用户的提问本身。用户的提问方式和知识库文档的表述方式经常存在巨大差异——这叫"语义鸿沟"(Semantic Gap)。

比如用户问"上次说的那个方案改了吗"——这句话有指代不清的问题("上次"是什么时候,"那个方案"是哪个),直接拿去检索基本不可能找到正确文档。又比如用户问"系统崩了",而文档里用的是"服务异常中断"——语义相近但表述完全不同。还有一种常见情况是用户的问题本身就很复杂,涉及多个方面,一次检索很难同时覆盖所有相关信息。

Query Rewrite、Multi-Query 和 HyDE 就是从不同角度解决这个问题的。

Query Rewrite

Query Rewrite 是最直观的方案:用 LLM 把用户的原始提问改写成更清晰、更适合检索的 query。改写可以包括:补全指代("上次那个方案"→"Q3 的营销预算方案",前提是有上下文信息)、扩展缩写和术语、把口语化表达转成书面化表达、去除无关的寒暄语等。

在多轮对话场景中,Query Rewrite 尤其重要。因为后续的提问通常依赖前面的对话上下文。比如用户先问"RAG 是什么",然后追问"它和微调有什么区别"——"它"指的是 RAG,但如果直接拿"它和微调有什么区别"去检索,可能匹配不到 RAG 相关文档。Query Rewrite 可以结合对话历史,把当前查询改写成独立的完整查询:"RAG 和微调有什么区别"。

实现上通常是一个简单的 LLM 调用:

请根据对话历史,将用户的最新问题改写为一个独立的、适合用于搜索的查询。
不要回答问题,只输出改写后的查询。

对话历史:
{history}

用户最新问题:{query}
改写后的查询:

Multi-Query

Multi-Query 的思路是:一个用户问题可能有多个检索角度,与其只用一个 query 去检索,不如从多个角度生成多个不同的 query,分别检索后合并去重结果。

比如用户问"大模型在金融领域有哪些落地应用",可以拆成:

  • "大模型 金融 应用场景"
  • "LLM 银行 保险 投资 应用"
  • "GPT 金融 风控 智能客服"

不同的 query 可能从向量库中召回不同但互补的文档,合并后覆盖面更广。

实现上也是一个 LLM 调用,让模型基于原始问题生成 3~5 个不同角度的检索 query。然后分别检索,合并所有结果(通常用并集去重),再送入 Rerank 做统一排序。

Multi-Query 的代价是检索次数成倍增加,延迟会上升。好处是 Recall 通常会明显提升,特别是对于复杂的、多面向的问题。

HyDE(Hypothetical Document Embeddings)

HyDE 的思路比较巧妙。它不是去改写 query,而是让 LLM 先基于 query 生成一个"假设性的答案文档"——即假设知识库中存在一个完美回答这个问题的文档,那个文档大概长什么样。然后用这个假设文档的 Embedding 去检索,而不是用原始 query 的 Embedding。

背后的直觉是:用户的 query 通常很短(几个词到一两句话),而知识库中的文档是长文本。短 query 和长文本在 Embedding 空间中的分布可能有差异(这叫 query-document 长度不对称问题)。如果把 query 先"展开"成一段和目标文档格式相似的文本,Embedding 的匹配精度可能更高。

HyDE 的过程:

  1. 把用户 query 发给 LLM:"请回答以下问题(即使你不确定也请尽量回答):{query}"
  2. LLM 生成一段回答(可能是不准确的,但格式和风格接近真实文档)
  3. 把这段回答做 Embedding
  4. 用这个 Embedding 去向量库检索

HyDE 的优点是对于某些 query-document 差距很大的场景效果不错。缺点也很明显:多了一次 LLM 调用,增加延迟和成本;LLM 生成的假设文档如果方向跑偏了,检索结果可能反而更差。所以 HyDE 不是万能的,需要在具体业务上做测试。

三者的对比和选择

Query Rewrite 是最基础也最常用的,特别是在多轮对话场景下几乎是必需的。成本低、收益稳定。

Multi-Query 适合问题比较复杂、涉及多个方面的场景。代价是延迟增加。可以和 Query Rewrite 配合使用——先改写,再拆分。

HyDE 适合 query 非常短或者 query-document 表述差异非常大的场景。但它增加了 LLM 调用的延迟和不确定性,实际项目中使用率不如前两者。

实际中这三者不是互斥的,可以组合使用。比如先做 Query Rewrite 处理多轮对话的指代问题,再做 Multi-Query 增加召回覆盖面。

面试时可以这样答

这三者都是为了解决 RAG 中的 Query-Document 语义鸿沟问题。

Query Rewrite 最基础,用 LLM 把用户的模糊提问改写成更精确的检索 query。在多轮对话里特别重要,因为后续提问常常有指代、省略,直接拿去检索效果很差。

Multi-Query 是把一个问题从多个角度拆成多个子 query 分别检索,合并结果。好处是覆盖面更广、Recall 更高,代价是检索次数增加、延迟上升。

HyDE 思路比较巧——先让 LLM 生成一个假设性的答案,用这个答案的 Embedding 去检索。直觉是假设答案在格式和风格上更接近真实文档,Embedding 匹配会更准。但多了一次 LLM 调用,而且假设答案跑偏了反而会误导检索。

实际项目中 Query Rewrite 基本是标配,Multi-Query 看场景复杂度决定是否加入,HyDE 要在具体业务上测试才知道有没有收益。三者也可以组合使用。

常见追问

  1. Query Rewrite 在多轮对话中具体怎么做?需要把全部历史都传给 LLM 吗?
  2. Multi-Query 生成的多个 query 检索结果怎么合并?怎么去重?
  3. HyDE 在什么情况下效果反而会变差?