你有没有过这样的经历:走进一家餐厅,面对满墙菜单却只能说“我想吃点热乎的”。厨师一头雾水,服务员反复追问,最后端上来一碗不合胃口的汤。用户向搜索引擎提问时,也经常扮演这种“说不清需求”的顾客——输入“最佳学习方法”,心里想的其实是“如何在一个月内通过数据分析师面试”。查询改写(Query Rewriting)就是那个善解人意的服务员:听懂你的弦外之音,把模糊的需求翻译成厨师能精准执行的菜单。而本文的主角 Query2Doc 与 HyDE,是两种顶级的“翻译技巧”——前者让你先描述“想象中这道菜的样子”,后者让你先描述“吃完之后的感觉”,再反推菜品。无论哪种,都是为了让大模型(LLM)把一句话问话,变成一段能让检索系统(厨师)大展身手的完整描述。

岗位关联

对于搜索推荐算法工程师,掌握 Query2Doc 与 HyDE 是驾驭 RAG 检索质量的必备技能。它能帮助你在零标注、零微调的前提下显著提升召回效果,是 LLM 时代搜索系统中性价比最高的优化手段之一。

目录
  1. 可视化演示
  2. 查询改写基础
  3. Query2Doc原理
  4. HyDE原理
  5. 双法对比
  6. 工程实现
  7. 评估体系
  8. 应用实战
  9. 趋势展望
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

本节配有交互动效(进入视口后自动加载,约 3KB)。

原始查询的语义不足问题 Query: "Python GIL" 短查询(2-3词)面临的语义歧义 \u26a0 语义鸿沟 查询改写Query2Doc与HyDE可视化:展示LLM查询扩展策略、假设文档嵌入及工程优化。

查询改写基础

想象餐厅里那位迷茫的顾客:“我想吃点热乎的。”这句话信息量太少——是汤?是面?是炖菜?推荐系统的“菜单”(文档库)里,每道菜都有固定的名字(词表),而顾客用的是生活语言。查询改写要做的,就是在这个中间架一座桥:把顾客口语化的、含混的、带指代的表达,翻译成菜单世界里能对号入座的语言。

查询改写通常出现在三类场景:第一,用户输入过于简短,缺少关键词,如输入“手机”但想找“防水安卓手机评测”;第二,口语与书面语不匹配,用户说“好用吗”而文档里写的是“用户体验良好”;第三,多轮对话中含有指代,比如“它怎么样”中的“它”到底指哪款产品。这些场景共同的特点是:原始查询与目标文档之间存在巨大的词汇鸿沟(lexical gap)。

完整的查询改写流程是一个三段式管道:改写(Rewrite)→ 增强(Expand)→ 检索(Retrieve)。先由大模型根据指令与原始查询生成改写结果,再将改写结果与原查询拼接或融合,最后用融合后的查询向量去文档库中检索。这一流程可以用一个简洁的公式概括:

回到餐厅的比喻:改写指令就像服务员培训手册里“如何引导顾客描述菜品”的话术,大模型是那位训练有素的服务员,而 q' 就是最终写下单子上的那行文字——既保留了顾客的意图,又让后厨能立即执行。

q′=LLM⁡(I改写;q)\displaystyle q' = \operatorname{LLM}\left(I_{\text{改写}}; q\right)
这个公式表示:改写后的查询 q' 等于大模型根据改写指令 I 与原始查询 q 生成的结果。
  1. 原始查询 $q$用户输入的初始语句,例如“我想吃点热乎的”,它是整个改写的起点。
    q=用户原始输入\displaystyle q = \text{用户原始输入}
  2. 改写指令 $I_{\text{改写}}$一段告诉大模型“如何改写”的系统提示词,例如“请将用户查询改写成包含关键信息的搜索查询”。
    I改写=系统提示词模板\displaystyle I_{\text{改写}} = \text{系统提示词模板}
  3. 生成查询 $q'$大模型结合指令与原查询生成的新查询,它应当更具体、更接近文档库的用词习惯。
    q′=LLM⁡(I改写;q)\displaystyle q' = \operatorname{LLM}\left(I_{\text{改写}}; q\right)

Query2Doc原理

既然顾客说不清想吃什么,不如先让他描述“这道菜端上桌时应该是什么样”。Query2Doc 正是这个思路:它让大模型基于一个简短的查询,生成一段“很像文档”的文字(称为伪文档),再把这段伪文档与原始查询拼接在一起,作为最终检索的输入。这段伪文档不需要很准确,只需要在主题上“靠近”真实文档,就能显著缩小查询与文档之间的语义鸿沟。

Query2Doc 的核心思想是“以文档补查询”。它基于一个直觉:如果查询本身是一段完整的文档,那么它与文档库中任何一篇文档的向量相似度都会更稳定、更有区分度。具体做法是:将原始查询 $q$ 输入 LLM,用 prompt 引导其生成一段长度为 150-300 词的文档,记为 $d_{\text{gen}}$;然后将 $q$ 与 $d_{\text{gen}}$ 拼接,得到融合查询 $q_f$;最后用 $q_f$ 的 embedding 执行稠密检索。

qf=q⊕dgen\displaystyle q_f = q \oplus d_{\text{gen}}

1. 拼接符号 $\oplus$:表示将两段文本按顺序连接,$q \oplus d_{\text{gen}}$ 就是“原始查询在前,生成文档在后”的新文本。

qf=concat(q, dgen)\displaystyle q_f = \text{concat}(q,\ d_{\text{gen}})

2. 原始查询 $q$:保留用户的原始意图,避免生成文档的偏差带偏检索方向。

q=原始查询文本\displaystyle q = \text{原始查询文本}

3. 生成文档 $d_{\text{gen}}$:由 LLM 基于 q 生成的伪文档,充当查询与文档库之间的“翻译中间人”。

dgen=LLM⁡("请写一段文档"; q)\displaystyle d_{\text{gen}} = \operatorname{LLM}\left(\text{"请写一段文档"};\ q\right)

Query2Doc 最吸引人的地方是零样本(zero-shot):不需要任何标注数据、不需要微调检索模型,只需调用一次现成的 LLM 就能拿到检索增益。在 BEIR 等标准基准上,Query2Doc 相比直接查询通常能带来 3-5 个百分点的 Recall@K 提升。回到餐厅:顾客描述“这道菜应该有一碗热汤、几片牛肉、一把面条”,服务员把这段话连同“想吃热乎的”一起递给后厨——后厨立刻明白,这碗“伪描述”比那句含糊的话靠谱得多。

HyDE原理

如果 Query2Doc 是让顾客描述“菜的样子”,那么 HyDE(Hypothetical Document Embeddings,假想文档嵌入)就是让顾客直接描述“吃完之后的感觉”。HyDE 的思路更加激进:让 LLM 针对查询 $q$ 直接生成一段“假想答案”(hypothetical document),然后用这段假想答案的向量去文档库中检索近邻,而不是用查询本身的向量。

HyDE 的关键洞察在于:生成式模型比判别式模型更擅长把握“答案长什么样”。虽然假想答案的细节可能是错的,但它的语句结构、词汇分布与真实文档高度相似,因此它的向量通常落在真实相关文档附近。这一步用公式表达非常简洁:

HyDE 同样无需微调、无需标注数据,但它对 LLM 的生成质量更敏感:如果假想答案偏离了真实文档的风格,检索效果可能反而不如原始查询。这就像让顾客描述“吃完之后的感受”,如果顾客想象力太丰富,说出“像是坐在云端”这种抽象的话,后厨依然无从下手。因此在文档风格稳定、主题集中的领域(如法律条文、医疗指南),HyDE 往往表现出色。

D∗=Top-⁡kd∈Csim⁡(E(h假), E(d))\displaystyle \mathcal{D}^* = \operatorname{Top-}k_{d \in \mathcal{C}} \operatorname{sim}\Bigl(E(h_{\text{假}}),\ E(d)\Bigr)
HyDE 将假想文档 h 编码为向量,再在文档集合 C 中找出与它向量最相似的 k 篇文档作为检索结果。
  1. 假想文档 $h_{\text{假}}$LLM 针对查询生成的一段假设性答案,例如查询“RAG怎么优化”,假想文档就是一段以“RAG优化通常包括……”开头的文字。
    h假=LLM⁡("请写一段假设答案"; q)\displaystyle h_{\text{假}} = \operatorname{LLM}\left(\text{"请写一段假设答案"};\ q\right)
  2. 编码器 $E(\cdot)$将文本映射为稠密向量的模型,如 Contriever、GTR 等,假想文档与真实文档都送入同一编码器。
    E:文本→R768\displaystyle E: \text{文本} \rightarrow \mathbb{R}^{768}
  3. 相似度 $\operatorname{sim}$ 与 Top-k用余弦相似度衡量向量距离,取分数最高的 k 篇文档作为检索结果。
    D∗=Top-⁡kd∈Csim⁡(E(h假), E(d))\displaystyle \mathcal{D}^* = \operatorname{Top-}k_{d \in \mathcal{C}} \operatorname{sim}\bigl(E(h_{\text{假}}),\ E(d)\bigr)

双法对比

两位“翻译高手”各有绝活。Query2Doc 像一位稳重的服务员:它把原话连同补充描述一起交给后厨,绝不偏离顾客本意,因此效果稳健、翻车概率低。HyDE 则像一位大胆的品酒师:它凭一句“这酒有橡木桶的味道”直接去酒窖里找酒,找对了惊艳全场,找错了南辕北辙。

从实现机制上看,两者的差异可以概括为三点:第一,Query2Doc 改写的是查询侧的文本,检索时使用“查询+伪文档”的拼接向量;HyDE 则直接放弃原查询向量,只用假想文档的向量做近邻搜索。第二,Query2Doc 对 LLM 输出质量的要求较低——即便伪文档质量一般,拼接后的查询仍保留原始信息;HyDE 则完全押注在假想答案的向量质量上。第三,从召回表现来看,Query2Doc 在大多数通用数据集上表现更稳定,而 HyDE 在主题高度集中的垂直领域有更高的上限,但方差也更大。

选型建议可以归纳为一个简单的判断标准:如果文档库的主题分散、风格多样(如通用网页搜索),优先选择 Query2Doc;如果文档库主题集中、格式规范(如法律法规、论文库),值得尝试 HyDE,并做严格评测对比。两者并非互斥——在工程实践中,完全可以同时运行两种改写,分别检索后取并集,把“谁说得准”交给下游重排模型去裁决。这就像让沉稳的服务员和大胆的品酒师分别推荐一道菜,把两道候选都端到评审(重排模型)面前,让专家定夺。

工程实现

纸上谈兵容易,真把“改写-检索”部署到线上系统时,工程细节决定成败。首先是最关键的 Prompt 设计。Query2Doc 的 prompt 通常类似:“你是一个搜索助手,请根据以下查询写一段相关的文档,用于提高检索效果。”而 HyDE 的 prompt 则强调生成“假设性答案”:“请直接回答以下问题,假设你拥有所有背景知识:……”。prompt 中应明确要求的文档长度、语气风格和包含的关键要素,这些都会显著影响改写质量。

向量化环节同样不可忽视。为了让检索质量稳定,改写后的查询与文档库中的文档应使用同一个编码器(如 GTR、Contriever),否则会出现“查询向量空间与文档向量空间不一致”的问题。此外,要区分编码器的输入上限:Query2Doc 拼接后的文本较长,需要确认编码器支持最大序列长度(通常 512 token),超长部分要做截断或分段池化。

检索融合是最后一道工序。最常见的做法是“改写查询检索结果 ∪ 原始查询检索结果”的召回归并——因为改写有时会引入噪音,保留原始结果相当于上一道保险。融合后的候选集交由重排模型(如 cross-encoder)精排。工程上还要设计好缓存与降级策略:改写有额外延迟(一次 LLM 调用),可对高频查询做缓存;当 LLM 服务超时或 fail 时,应优雅降级到原始查询检索。这些看似琐碎的细节,恰恰是线上检索系统稳定性的基石。

评估体系

如何判断这位“翻译服务员”干得好不好?不能只听他说“我翻译得很准”,要看顾客是否真正满意——在检索系统里,就是看检索结果是否真的把相关文档捞了上来。评估查询改写最常用的离线指标是 Recall@K(前 K 个结果中包含相关文档的比例)和 MRR(第一个相关结果的倒数排名)。前者关注“有没有捞到”,后者关注“排得够不够靠前”。

为了标准化对比,学术界常用 TREC 系列数据集与 BEIR 基准。BEIR 涵盖了 18 个异构检索任务,包括生物医学、金融、新闻等,是衡量查询改写方法泛化能力的黄金标准。一个值得注意的细节是:不同数据集上 Query2Doc 与 HyDE 的表现排名可能截然不同,因此实验结论必须注明测试集与配置,不能笼统地说“方法 A 优于方法 B”。

消融实验是评估的另一半。要分别验证三个问题:改写的 prompt 中哪些内容真正起作用;拼接查询中原始查询与生成文档各自贡献了多少(尝试只使用生成文档、只使用原始查询、两者拼接三种设定);检索编码器更换后增益是否依旧成立。一个好的消融实验能帮你判断:性能提升到底是“改写”这个操作带来的,还是仅仅因为输入变长、信息变多。这就像餐厅试菜时要分别测试“换了主厨”和“换了食材”到底哪个让菜品变好吃的。

应用实战

理论落地时,查询改写在 RAG 与搜索场景中各有经典打法。在 RAG 场景中,用户提问往往口语化且信息稀疏,直接检索经常召回不相关片段。工程上通常把 Query2Doc 放在检索前:先将用户问题改写成一段“背景介绍”,再与原始问题拼接后检索,最后用生成器基于召回片段作答。例如面向企业知识库的问答系统,用户问“报销流程咋走”,Query2Doc 会生成“企业费用报销的流程包括提交申请、主管审批、财务审核……”的伪文档,从而精准命中知识库中的《报销管理制度》。

电商搜索是另一个高频落地场景。长尾商品查询如“适合送男友的生日礼物”包含大量主观描述,而商品标题是“机械键盘 青轴 电竞”。HyDE 在此类场景中生成“送男友的礼物应该体现科技感与实用性,比如机械键盘……”的假想答案,向量更贴近商品标题的语义空间。实际部署时还要注意多路召回:改写结果只是其中一路,要与同义词扩展、类目预测等传统信号并联,用重排模型统一打分。

应用中的常见坑点有三:一是改写结果过度自信——LLM 可能生成与事实不符的伪文档,污染检索向量,因此必须保留原始查询作为兜底;二是延迟预算失控——每条查询增加一次 LLM 调用会显著抬高 P99 延迟,需要缓存与异步化;三是不做端到端评估——只盯着改写结果的文本相似度,而忽略最终生成答案的准确率。每一项坑点都是“翻译服务员”在实际餐厅中可能犯的错,需要靠完善的监控与评测体系来兜底。

趋势展望

查询改写技术正沿着三个方向演进。第一个方向是与 RAG 深度协同:不再把改写当作独立的前置模块,而是让 LLM 在生成时“感知”检索结果,根据召回情况动态调整改写策略——就像服务员端上第一道菜后,根据顾客的反馈再决定是否需要重新推荐。

第二个方向是自适应改写。不同查询对改写的需求差异巨大:有的查询本身就很精确,改写反而引入噪音;有的查询极度模糊,必须大幅扩展。未来的系统会用一个小型分类器(或 LLM 自身)判断查询的“模糊度”,动态决定是否改写、用 Query2Doc 还是 HyDE、生成多长的伪文档。这相当于给服务员配备了一份“顾客表情解读手册”,不再对所有客人使用同一套话术。

第三个方向是多模态查询改写。随着多模态大模型的发展,查询不再局限于文本——用户可能上传一张图片问“这件衣服有没有其他颜色”,或者输入一段语音描述需求。多模态改写将把图像、语音等线索融入检索查询中,这超出了传统文本改写的边界。虽然这些方向尚未完全成熟,但底层逻辑依然清晰:改写的本质,永远是缩小用户表达与文档表达之间的鸿沟,只是鸿沟的两岸正在变得越来越宽。

AI 应用场景

企业知识库 RAG 问答优化

阶段:检索增强生成(RAG)的检索前处理

解决的问题:员工提问通常口语化、带指代(如“上次那个政策咋说的”),直接检索知识库经常召回不相关内容,导致生成答案胡编乱造。使用 Query2Doc 将员工提问改写为“政策文件风格”的背景描述,再与原始问题拼接检索,能显著提升相关片段的召回率,从而提升最终答案的准确性。

具体案例:某大型企业的内部客服机器人,在接入 Query2Doc 后,知识库召回命中率从 61% 提升到 78%,“报销标准是什么”这类高频问题的答案准确率提升明显,同时无需标注数据,仅靠调整 Prompt 即可上线。

电商长尾商品搜索

阶段:搜索系统的召回增强模块

解决的问题:用户表达(“通勤穿的百搭鞋子”)与商品标题(“牛皮小白鞋 女 软底”)之间存在巨大词汇鸿沟,传统词匹配召回失效。HyDE 生成“通勤、百搭、舒适、适合搭配工装裤的女鞋”的假想答案,在稠密向量空间中找到更接近用户意图的商品。

具体案例:某电商平台对 20 万条长尾查询做 A/B 实验,使用 HyDE 改写的实验组相比对照组,商品点击率提升 5.2%,成交转化率提升 3.1%。由于长尾查询量大且重复率低,采用了异步改写 + 结果缓存的方式控制成本。

法律/医疗垂直领域文档检索

阶段:垂直领域检索系统的查询扩展

解决的问题:法律、医疗领域的提问常常是自然语言描述(“公司不给我交社保怎么办”),而法规条文是规范书面语。这类文档库主题高度集中、格式规范,恰好是 HyDE 最擅长的主场——假想答案的向量能稳定落在相关法条附近。

具体案例:某法律科技公司开发智能法规检索工具,用户输入生活化问题后,HyDE 生成“用人单位未依法缴纳社会保险费的法律责任……”的假想答案,再从法规库中检索,Top-5 召回准确率相比直接检索提升 22%。

Python 演示

python74 行
import mathimport reimport heapq DOCS = [    "查询改写是RAG系统的关键组件,用于弥合用户表达与文档词汇之间的差距",    "HyDE通过大语言模型生成假想文档,再用假文档的向量执行最近邻检索",    "Query2Doc让LLM基于查询生成一段文档,拼接原查询后一起编码检索",    "向量检索常用余弦相似度衡量查询与文档的语义距离",    "RAG检索阶段的质量直接影响生成答案的事实准确性",    "零样本查询改写无需微调,仅依赖LLM的指令跟随能力",    "评估查询改写需要同时关注召回率与排序质量的提升",    "多轮对话中的指代消解是查询改写的重要应用场景",] def tokenize(text):    return re.findall(r"[\w\u4e00-\u9fa5]+", text.lower()) def build_index(corpus):    vocab = {}    dfs = {}    doc_vecs = []    for doc in corpus:        toks = tokenize(doc)        vec = {}        for t in toks:            vec[t] = vec.get(t, 0) + 1            dfs[t] = dfs.get(t, 0) + 1        doc_vecs.append(vec)    for t in dfs:        vocab[t] = len(vocab)    return vocab, dfs, doc_vecs def tfidf_vec(text, vocab, dfs, n):    toks = tokenize(text)    vec = [0.0] * len(vocab)    tf = {}    for t in toks:        tf[t] = tf.get(t, 0) + 1    for t, c in tf.items():        if t in vocab:            idf = math.log((n + 1) / (dfs.get(t, 0) + 1)) + 1.0            vec[vocab[t]] = c * idf    return vec def cos_sim(a, b):    dot = sum(x * y for x, y in zip(a, b))    na = math.sqrt(sum(x * x for x in a)) or 1.0    nb = math.sqrt(sum(y * y for y in b)) or 1.0    return dot / (na * nb) def search(query_text, corpus, k=3):    vocab, dfs, doc_vecs = build_index(corpus)    qvec = tfidf_vec(query_text, vocab, dfs, len(corpus))    scored = [(cos_sim(qvec, dvec), i) for i, dvec in enumerate(doc_vecs)]    return heapq.nlargest(k, scored) def query2doc_fake_llm(query):    return "该文档阐述了" + query + "的核心思想,包括方法定义、实现流程与典型应用。" def hyde_fake_llm(query):    return "这个问题的答案重点介绍" + query + ",具体步骤是定义问题、改写扩展、向量检索与融合排序。" def main():    q = "RAG查询改写怎么做"    print("原始查询:", q)    print("Top:", [DOCS[i] for _, i in search(q, DOCS)])    q_q2d = q + " " + query2doc_fake_llm(q)    print("Query2Doc Top:", [DOCS[i] for _, i in search(q_q2d, DOCS)])    h = hyde_fake_llm(q)    print("HyDE Top:", [DOCS[i] for _, i in search(h, DOCS)]) if __name__ == "__main__":    main()
目的:用词频向量 + 余弦相似度搭建一个微型检索系统,分别对比原始查询、Query2Doc 拼接改写、HyDE 假想文档三种输入方式的检索结果差异,直观展示查询改写的价值。
  1. def tfidf_vec(text, vocab, dfs, n):将文本转为 TF-IDF 权重向量,模拟真实场景中的稠密向量编码器
  2. idf = math.log((n + 1) / (dfs.get(t, 0) + 1)) + 1.0稀有词获得更高权重,让改写后的长文本更突出主题词
  3. def cos_sim(a, b):计算两个向量的余弦相似度,作为检索打分的核心依据
  4. return heapq.nlargest(k, scored)取出相似度最高的 k 篇文档,模拟 Top-k 召回
  5. def query2doc_fake_llm(query):模拟大模型生成一段“文档风格”的伪文本,代替真实 LLM 调用
  6. q_q2d = q + " " + query2doc_fake_llm(q)执行 Query2Doc 的拼接操作,这是它与 HyDE 最本质的区别
  7. h = hyde_fake_llm(q)生成 HyDE 的假想答案,后续直接用 h 检索而非原始查询

常见误区

误区“Query2Doc 和 HyDE 这么复杂,肯定要用标注数据微调检索模型才能生效吧?不然改写结果跟原来有啥区别?”

正解这两者的核心卖点恰恰是零样本(zero-shot)。它们不训练、不微调任何参数,只是设计一个好的 Prompt,调用现成的 LLM 生成伪文档,再用现成的编码器向量化。就像餐厅引入一位新服务员,不需要把厨师重新培训一遍,只要教服务员一套新话术就能改善点菜体验。

为何常见:习惯了传统 IR 中“训练-微调”的范式,容易把一切质量提升都归因于模型参数的变化,忽略了 prompt 工程本身就能带来显著的检索增益。

误区“HyDE 让 LLM 编一段假答案,可 LLM 编的内容经常是错的,错误答案怎么可能帮我找到正确答案?”

正解HyDE 的核心洞察恰恰是:假想答案的细节对不对不重要,只要它的词汇分布、句式结构与真实文档相似,它的向量就会落在相关文档附近。这就像顾客说“这酒有橡木桶味”——他真的喝过吗?不重要,品酒师凭这句话就能找到那瓶酒。实验证明,即使假文档与真实答案差距很大,检索效果依然可观。

为何常见:人们以“内容是否真实”的直觉判断检索信号的好坏,而忽略了向量检索关注的是语义分布而非字面事实。

误区“查询改写不就是把'想吃热乎的'扩展成'热汤 热面 热菜'这些关键词吗?”

正解Query2Doc 和 HyDE 的要点是生成一段连贯、完整的文档或答案,而不是一个关键词列表。连贯文本经过编码器后能形成更稳定的语义向量,而关键词列表只是一个稀疏词袋,丢失了语法与语序信息。这就像给厨师一张写满食材清单的纸条,而不是一句通顺的“请做一碗有牛肉和面条的热汤”。

为何常见:经典查询扩展(如伪相关反馈)都是围绕关键词做文章,容易让人把新方法与旧方法混为一谈。

误区“既然用了大模型改写,效果肯定比直接检索好,没必要保留原始查询了吧?”

正解改写可能引入噪音,尤其当 LLM 对查询的理解出现偏差时,改写结果反而会把检索带偏。因此工程实践通常采用“改写结果 ∪ 原始查询”的召回融合策略,并为改写增加缓存与降级路径。这就像服务员虽然帮你翻译了点菜需求,但原话仍然要保留在订单备注里,以防翻译出错时还能追溯。

为何常见:把模型能力神化,忽视了生成过程的不确定性,以及线上系统对稳定性的要求。

误区“Query2Doc 生成伪文档,HyDE 生成假想答案,不都是让 LLM 写一段话吗?换了个名字而已。”

正解两者虽然都依赖 LLM 生成文本,但检索信号的使用方式有本质区别:Query2Doc 生成的伪文档与原始查询拼接,检索时仍保留查询本身的信号;HyDE 生成的假想答案完全替代查询向量,检索信号全部来自 LLM 的生成结果。前者是“扩充”,后者是“置换”,这决定了它们在稳定性、适用场景和失败模式上的显著差异。

为何常见:只看到表面的“LLM 生成文本”,忽略了向量检索阶段对生成结果的利用方式不同,而这一步才是效果差异的关键来源。

面试题

Q1. Query2Doc 的核心思想是什么?

单选题 · easy

  • A.用查询改写成多个同义词扩展
  • B.让 LLM 生成文档来扩充查询← 正确答案
  • C.对文档进行重排序再拼接
  • D.用伪标签训练小型检索器

答案:B。Query2Doc 的核心就是让 LLM 基于查询生成一段伪文档,再与原始查询拼接后检索。A 是传统查询扩展,C 是重排阶段的事,D 属于微调范式,都与 Query2Doc 的零样本思想不符。

Q2. HyDE 中的“假想文档”是指什么?

单选题 · easy

  • A.从知识库中抽样的真实文档
  • B.LLM 生成的假想答案文档← 正确答案
  • C.用户历史点击过的文档
  • D.人工标注的标准答案段落

答案:B。HyDE 用 LLM 直接生成一段假设性答案,作为检索的查询向量。A、C 都是真实存在的文档,D 需要人工标注,都不是 HyDE 的做法。

Q3. Query2Doc 与 HyDE 共同的依赖前提是什么?

单选题 · mid

  • A.必须微调 BERT 编码器
  • B.需要大规模标注数据对
  • C.依赖大模型零样本生成能力← 正确答案
  • D.依赖倒排索引的精排模型

答案:C。两种方法都直接用大模型生成伪文档或假想答案,不训练、不微调,核心依赖是 LLM 的指令跟随与零样本生成能力。A、B 都有违零样本原则,D 与改写环节无关。

Q4. 以下哪些场景适合触发查询改写?

多选题 · mid

  • A.查询过短缺少关键实体词← 正确答案
  • B.口语表达与文档书面语不匹配← 正确答案
  • C.检索资源完全不受延迟限制
  • D.多轮对话中包含指代消解← 正确答案

答案:ABD。A 缺少关键信息、B 词汇鸿沟、D 指代不明确都是典型的改写触发场景。C 资源充足不代表改写必要性,改写解决的是语义鸿沟而非资源问题。

Q5. Query2Doc 拼接公式 q_f = q ⊕ d_gen 的核心目的是什么?

单选题 · mid

  • A.减少向量维度以降低内存
  • B.融合原始查询与生成文档的语义信号← 正确答案
  • C.压缩长文档以提高召回速度
  • D.消除编码器的词汇表偏差

答案:B。拼接让检索输入同时包含用户原意与文档风格上下文,是 Query2Doc 稳定性的关键。A、C 是工程优化,D 是编码器层面的问题,都与拼接目的无关。

Q6. 评估查询改写效果时通常使用哪些指标?

多选题 · mid

  • A.召回率 Recall@K← 正确答案
  • B.倒数排名 MRR← 正确答案
  • C.模型参数量大小
  • D.生成文档的字数长度

答案:AB。Recall@K 衡量召回质量,MRR 衡量排序质量,两者是检索增强的核心指标。C 是模型规模属性,D 是生成文本属性,都不能直接反映检索效果。

Q7. 相比微调方案,零样本查询改写最大的工程优势是什么?

单选题 · hard

  • A.无需构造标注数据对即可上线← 正确答案
  • B.推理速度可以提升近一倍
  • C.改写结果必然更加准确
  • D.完全消除了检索延迟开销

答案:A。零样本最大的优势是省去数据构建与训练流程,Prompt 调好即可上线。B、D 不成立(改写反而增加延迟),C 不保证准确,零样本效果也可能不如针对性微调。

Q8. HyDE 检索失败的典型原因是?

单选题 · hard

  • A.假想文档与真实文档的向量分布偏离← 正确答案
  • B.生成假想文档的速度过快
  • C.向量维度设置过小
  • D.检索返回的结果数量太多

答案:A。HyDE 完全依赖假想文档的向量做近邻搜索,一旦 LLM 对查询的理解偏了,假想文档的分布就会远离真实相关文档。B、C、D 属于工程配置问题,不是方法本身的核心失效原因。

Q9. RAG 系统中融合查询改写时,以下哪些做法是合理的?

多选题 · hard

  • A.改写结果与原始查询做召回并集← 正确答案
  • B.对高频查询做改写结果缓存← 正确答案
  • C.拒绝任何改写失败导致降级
  • D.端到端评测生成答案的质量← 正确答案

答案:ABD。并集召回可防改写噪音,缓存控制成本,端到端评测确保整体收益,这些都是合理实践。C 恰恰相反,系统应设计优雅降级,而非拒绝服务。

Q10. Query2Doc 与 HyDE 在检索信号使用上的本质区别是?

单选题 · extreme

  • A.Q2D 扩充查询文本而 HyDE 用生成答案向量← 正确答案
  • B.HyDE 必须微调而 Query2Doc 是零样本
  • C.Q2D 使用稀疏向量而 HyDE 必须稠密向量
  • D.HyDE 输出多条文档而 Q2D 只输出一条

答案:A。Query2Doc 将生成文档与查询拼接后再编码,查询信号仍保留;HyDE 则直接用假想答案向量替代查询向量做近邻检索。B 错误(两者皆零样本),C 错误(两者都用稠密向量),D 错误(两者都只生成一条文本)。