跨越"语义鸿沟":为什么RAG系统离不开Query重写

核心摘要

在RAG系统中,检索质量直接决定了最终生成的回答质量,即所谓的”Garbage in, garbage out(垃圾进,垃圾出)”。然而,人类用户的真实提问往往是口语化、简略、缺乏上下文或包含多重意图的

Query重写(Query Rewriting) 就是在用户的原始提问和检索系统(如向量数据库)之间加入一个”翻译/优化”层,利用大模型(LLM)将低质量的原始提问转化为更适合检索的高质量Query。

本文将系统梳理 Query 重写的核心价值、主流技术方案,并提供一套可直接落地的选型决策框架


为什么我们需要Query重写?

在理想状态下,用户会输入完美的、关键词精准的提问,但这在现实应用中几乎不存在。RAG系统引入Query重写主要为了解决以下四个痛点:

多轮对话中的”上下文缺失”与”指代不清”

在Chatbot场景中,用户习惯于连续追问。

  • User 第一轮: “特斯拉目前的CEO是谁?”(系统回答:马斯克)
  • User 第二轮: “他今年多大了?”
  • 灾难发生: 如果直接把”他今年多大了?”转化为向量去数据库中检索,向量数据库会匹配到无数包含”他”、”多大”的无关文档。因为检索系统本身没有记忆。
  • 重写的价值: 通过Query重写(上下文压缩/指代消解),系统会将第二轮问题重写为:“埃隆·马斯克今年多大了?”,从而实现精准检索。

词汇不匹配(语义鸿沟与表达习惯差异)

用户提问的用词,往往与专业文档中的用词存在巨大差异。

  • User提问: “吃完饭肚子疼怎么回事?”
  • 医学文档内容: “餐后腹痛可能由胃溃疡或胆囊炎引起……”
  • 灾难发生: 传统的关键词检索(BM25)会直接在词汇层面失配。向量检索理论上可以捕捉语义相似性,但当嵌入模型未经医疗等专业领域微调时,口语表达与专业术语在向量空间中的距离依然可能偏大,同样导致检索不准。
  • 重写的价值: 将Query扩展为包含同义词和专业术语的形式:“饭后肚子疼 餐后腹痛 消化不良 症状 原因”,覆盖更多可能命中的表达方式。

复杂问题与多跳推理(Multi-hop Reasoning)

用户经常在一个句子里提出需要综合多方信息才能回答的问题。

  • User提问: “对比一下2023年第三季度苹果和微软的营收增长率。”

  • 灾难发生: 数据库里通常没有一篇文档正好把这两者放在一起对比。直接检索这个长句,可能只搜到苹果的财报,或者只搜到微软的财报。

  • 重写的价值: 将复杂问题拆解(Decomposition)为多个子查询:

    • 子查询 1: “2023年第三季度苹果的营收增长率”
    • 子查询 2: “2023年第三季度微软的营收增长率”

    系统分别检索这两条信息,再交给LLM进行综合对比。

提问过于宽泛或抽象

  • User提问: “讲讲人工智能。”
  • 灾难发生: 这种提问在包含数百万文档的企业知识库中会触发海量毫无关联的匹配。
  • 重写的价值: 结合系统设定的角色或当前业务场景(如HR系统),重写为:“人工智能在人力资源和招聘领域的应用案例”,使检索更有针对性。

业界主流的Query重写技术与方案

了解了”为什么”,我们来看看在工程实践中(如LangChain、LlamaIndex等框架中)常用的几种Query重写策略:

指代消解与上下文重写

  • 原理: 把历史对话记录和当前问题一起发给LLM,让LLM生成一个脱离上下文也能看懂的独立问题(Standalone Query)。
  • 应用场景: 所有具备多轮对话能力的RAG系统(最基础也是最必要的重写)。
  • LangChain支持: create_history_aware_retriever 原生支持,开箱即用。

查询扩展 (Query Expansion / Multi-Query)

  • 原理: LLM针对原始问题,从不同的角度生成多个相关的问题(通常是3-5个)。
  • 机制: 将这多个问题分别进行向量检索,取检索结果的并集,再通过 RRF(Reciprocal Rank Fusion,倒数排名融合)算法 将多路结果合并排序,从而大大提高检索的召回率(Recall)
  • 注意: RRF 是一种排名融合算法,与基于 Cross-Encoder 的语义重排序(Reranking)是两个不同的概念,切勿混淆。
  • 例子:
    • 原问题:”气候变化对北极熊有什么影响?”
    • 扩展问题:”全球变暖如何改变北极熊的栖息地?”、”海冰融化对北极熊觅食的威胁有哪些?”
  • LangChain支持: MultiQueryRetriever 原生支持。

RAG-Fusion

  • 背景: 由开发者 Adrian Raudaschl 于2023年提出,是 Multi-Query + RRF 的工程化整合方案,在社区获得了广泛关注。
  • 原理: 与 Multi-Query 类似,核心区别在于对 RRF 融合步骤的更强调和规范化——同一文档在多个子查询结果中排名越靠前,最终加权得分越高,从而让真正相关的文档浮出水面。
  • 适用场景: 知识库庞大、单次检索召回率不足、需要综合多个角度信息的场景。

HyDE (Hypothetical Document Embeddings - 假设性文档嵌入)

  • 出处: 2022年由卡内基梅隆大学(CMU) 等机构提出,论文为《Precise Zero-Shot Dense Retrieval without Relevance Labels》。
  • 原理: 非常巧妙的逆向思维。遇到用户提问时,先让大模型(”盲猜”)生成一篇假设性的答案(文档)。虽然这个答案可能包含幻觉或事实错误,但它的句式结构和词汇分布与真实的参考文档非常相似。然后,用这篇”假文档”的向量去检索数据库里的”真文档”。
  • 为什么有效: 因为”文档到文档”的向量匹配,通常比”简短提问到长文档”的匹配效果更好。用户的提问往往只有十几个字,而语料库里的文档动辄数百字,两者的向量天然存在分布差异;HyDE 将提问侧的向量”升维”到与文档相近的长度和风格。
  • LlamaIndex支持: HyDEQueryTransform 原生支持。

退一步提示 (Step-back Prompting)

  • 出处: 谷歌DeepMind提出的技术(2023年)。
  • 原理: 当遇到非常具体的细节问题时,让大模型后退一步,生成一个更宽泛、更高维度的背景问题,先检索出底层原理文档,再用该背景知识辅助回答具体问题。
  • 例子:
    • 原问题:”为什么我的Python代码里 x = [1,2]; y = x; y.append(3) 会导致 x 也变成 [1,2,3]?”
    • 退一步重写:”Python中的变量引用机制和可变对象(Mutable Objects)是如何工作的?”
    • 效果: 先检索到 Python 内存模型/引用机制的通用原理文档,模型以此为背景,再回答具体的代码问题,准确率显著提升。
  • 适用场景: 技术支持、故障排查、学习问答等场景,用户的具体问题往往指向某个更基础的原理性知识盲区。

FLARE (Forward-Looking Active REtrieval)

  • 背景: 2023年由 UCBerkeley 等机构提出,适合需要生成长文本的场景。
  • 原理: 与上述静态重写不同,FLARE 是迭代式的动态重写策略。模型在生成回答的过程中,一旦遇到低置信度的预测(即模型”不确定”该写什么),就自动暂停,以当前预测内容为 Query 主动触发一次新的检索,补充上下文后继续生成。
  • 适用场景: 报告生成、长文摘要等长文本输出场景,不适合低延迟的实时问答。

技术方案横向对比

技术方案 解决的核心问题 额外延迟 额外成本 实现复杂度 典型适用场景
上下文重写 多轮指代消解、上下文缺失 所有多轮对话场景(必选)
Query Expansion / Multi-Query 召回率不足、单角度覆盖窄 ⭐⭐ 企业知识库、宽覆盖检索
RAG-Fusion 多路结果融合与排名质量 ⭐⭐ 知识库庞大、需综合多角度
HyDE 短查询-长文档向量匹配差 ⭐⭐ 学术/技术文档、专业知识库
Step-back Prompting 细节问题缺乏背景原理支撑 技术支持、故障排查、学习问答
FLARE 长文本生成中的知识不完整 ⭐⭐⭐ 长报告生成、深度摘要

选型决策框架

不同场景对 Query 重写的需求差异很大。下图提供一个可直接落地的决策路径:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
你的系统是多轮对话吗?
└─ 是 → 【上下文重写】是必选基础项,其他技术在此之上叠加
└─ 否 → 直接评估以下场景

用户提问简短,但文档都是长篇专业文档(学术、法律、医学)?
└─ 是 → 优先考虑【HyDE】

用户提问涉及比较、综合多方信息或多跳推理?
└─ 是 → 优先考虑【Multi-Query / RAG-Fusion + 子查询拆解】

用户的具体问题背后有更基础的原理知识需要检索?
└─ 是 → 优先考虑【Step-back Prompting】

需要生成长篇报告/摘要,且生成过程中知识需求动态变化?
└─ 是 → 优先考虑【FLARE】

单次检索召回率不理想,文档覆盖面广但密度低?
└─ 是 → 优先考虑【Multi-Query / RAG-Fusion】

黄金组合推荐:

  • 多轮问答(标准): 上下文重写 + Multi-Query
  • 技术/专业知识库: 上下文重写 + HyDE
  • 企业级复杂问答: 上下文重写 + Multi-Query + Step-back Prompting(三层叠加)
  • 长文本生成场景: 上下文重写 + FLARE

组合使用:实际工程中如何叠加

上述技术并非互斥,在生产环境中通常是流水线式叠加使用的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
用户输入


[第一层] 上下文重写(Contextual Rewrite)
│ 将多轮指代消解为独立问题

[第二层] 问题分类路由
│ 简单直接问题 → 直接检索
│ 复杂/多跳问题 → Multi-Query 拆解
│ 过于细节问题 → Step-back 退一步
│ 专业文档场景 → HyDE 生成假设文档

[第三层] 检索 + RRF 融合
│ 多路结果通过 RRF 合并

[第四层] 语义重排序(Reranking,可选)
│ Cross-Encoder 对候选文档精排

[最终] 送入 LLM 生成答案

成本控制技巧: 第一、二层的 Query 重写可以使用体积小、速度快的轻量级模型(如 GPT-4o-mini、Qwen-7B 等),而非每次都调用 GPT-4 级别的大模型,在保持效果的同时将延迟和成本控制在合理范围内。


何时不引入Query重写

Query 重写并非所有场景的最优解。以下情况引入反而可能有害:

  1. 用户本身是专业人员,提问已经足够精准。 例如开发者在代码助手里粘贴完整报错信息,再次重写可能导致信息丢失(Semantic Drift)。
  2. 对延迟极度敏感的实时场景。 如语音助手、实时客服,额外的 LLM 调用会带来不可接受的响应延迟。
  3. 知识库规模极小(百条以内)。 检索本身不存在精度问题,引入重写只是增加了不必要的复杂度。
  4. 知识库内容高度结构化,用户查询意图明确。 如数据库查询、代码文档检索,传统关键词或精确匹配往往优于语义检索。

Query重写的代价与挑战

虽然Query重写能大幅提升RAG的准确率,但它并非完美无缺的银弹,引入它需要权衡以下成本:

  1. 延迟增加 (Latency): 引入重写意味着在检索前多了一次LLM的调用。这通常会增加几百毫秒到几秒的响应时间,对实时性要求极高的场景不友好。(解决方案:使用体积更小、速度更快的专门做重写的小模型来替代庞大的GPT-4)。
  2. 成本上升 (Cost): 额外的LLM调用意味着消耗更多的Token,增加了系统的运行成本。
  3. 重写偏移 (Semantic Drift): 有时候大模型”自作聪明”,错误理解了用户的真实意图,导致重写后的Query与用户想问的内容南辕北辙,反而降低了检索质量。
  4. 重写质量强依赖Prompt工程: 重写效果高度依赖 Prompt 设计质量,需要针对不同业务场景持续迭代 Prompt,存在一定的维护成本。

如何衡量Query重写的效果

引入 Query 重写后,如何验证它真的有效?工程实践中常用以下指标:

  • Hit Rate(命中率): 检索结果中包含正确答案的提问比例,是最直接的指标。
  • MRR(Mean Reciprocal Rank,平均倒数排名): 衡量正确文档在检索结果列表中的平均排位,排名越靠前,MRR 越高。
  • Context Precision / Context Recall: 来自 RAGAS 评测框架,分别衡量检索文档的精确度(有多少是相关的)和召回度(相关文档被检索到的比例)。
  • A/B 对照实验: 在灰度流量中,对比开启/关闭 Query 重写两组的最终答案质量(可通过 LLM-as-Judge 自动化评分)。

最小化验证路径: 从 Hit Rate 开始,构建一组包含多轮对话、词汇不匹配、复杂多跳三类问题的评测集(20-50条),在引入重写前后对比 Hit Rate 变化,即可快速判断投入是否值得。


总结

在RAG系统中,向量检索天然依赖于文本特征的相似度,而用户提问往往是随性且充满信息缺失的。

Query重写扮演了 “提问翻译官” 的角色,它填补了用户意图与数据库索引之间的鸿沟。选型时的核心逻辑是:

  • 上下文重写 是多轮对话场景的强制项,无论如何都应该引入;
  • Multi-Query / RAG-Fusion 是提升召回率的通用解法,性价比高;
  • HyDE 在专业文档检索场景中效果最为突出;
  • Step-back Prompting 适合以原理性知识为核心的问答系统;
  • FLARE 是长文本生成场景的特化方案,不适合实时对话。

没有一种技术是万能的,理解每种方案背后的问题假设,才能在具体场景中做出正确的取舍。