一个检索失败的现场
在企业知识库问答系统中,用户提问“怎么修上周的那个认证问题”,而知识库里的文档标题是“解决会话中间件中的 JWT 过期错误”。两者描述的是同一件事,但词汇几乎没有重叠。向量检索把用户查询编码成一个向量,再在文档向量空间中找最近邻。嵌入模型忠实编码了查询的语义,但它无法弥补查询与文档之间的词汇鸿沟——用户用口语化的、依赖上下文的表达,文档用规范的、领域术语的表达,两者在向量空间中可能相距很远。
这就是 RAG 系统中最常见的召回失败。分块策略和嵌入模型优化的是索引侧,它们让文档向量更好地表达文档内容,但查询向量仍然来自一个糟糕的输入。查询改写层在查询命中索引之前变换查询,从源头解决词汇不匹配。HyDE(Hypothetical Document Embeddings,假设文档嵌入)是其中一种反直觉的方法:不直接嵌入用户问题,而是让 LLM 先生成一个假设性的答案文档,再用这个文档的嵌入去检索。
为什么原始查询在向量检索中失败
向量检索的基本假设是:查询和相关的文档在语义空间中接近。但用户的查询很少满足这个假设。用户可能引用会话中的先前上下文,使用与文档不同的领域词汇,或者提问的抽象层次与文档不一致。嵌入模型无法修正这一点,它只是忠实地把查询映射到一个向量。
一个具体的例子:用户问“为什么认证中间件在周二部署后开始返回 503 错误?”,文档里写的是“部署期间认证服务故障的常见原因”。查询包含了具体的时间点和错误码,而文档是通用性的描述。如果直接嵌入查询,检索系统可能找不到任何相关文档,因为查询的向量落在了一个文档稀疏的区域。
问题的根源是查询和文档在表达方式上的不对称。查询往往简短、口语化、带有上下文依赖,文档则规范、完整、使用领域术语。这种不对称在密集检索中尤其明显,因为嵌入模型是在大规模语料上训练的,它对查询和文档的编码方式存在差异。HyDE 的思路是:既然查询和文档不在同一个语义区域,那就先生成一个“文档”来代表查询,让这个文档和真实文档在向量空间中更接近。
HyDE 的核心机制:用答案搜索
HyDE 的流程可以分为两步。第一步,给定一个查询,用一个指令跟随语言模型(如 InstructGPT)生成一个假设性文档。这个文档不需要是事实准确的,它只需要捕捉答案的“形式”和“词汇”。例如,对于“怎么修认证问题”,LLM 可能生成一段类似“JWT 过期错误通常发生在会话中间件中,解决方法包括检查 token 有效期、刷新机制……”的文本。第二步,用一个无监督对比学习训练的编码器(如 Contriever)把这段假设文档编码成向量,然后在语料库的向量空间中检索最相似的文档。
为什么这样有效?因为问题和答案占据语义空间的不同区域。一篇解释 JWT 过期错误的文档,看起来远比用户关于认证问题的提问更像其他 JWT 过期相关文档。通过生成一个合理的答案,HyDE 把查询“翻译”成了目标文档的语言,从而在文档空间中定位到正确的邻域。
假设文档的准确性不是关键。HyDE 的有效性来自它捕捉了答案的词汇和句式,而不是内容正确。一个有幻觉但听起来合理的文档仍然占据语义上有用的位置。事实上,HyDE 论文(Luyu Gao 等人,2022 年)指出,生成的文档可能包含虚假细节,但后续的编码器会通过密集瓶颈过滤掉这些错误细节,因为编码器只保留与真实文档相似的语义特征。
与直接检索和查询扩展的对比
直接检索是最简单的基线:把用户查询嵌入,然后检索。它的优点是延迟低、成本低,但词汇鸿沟问题严重。查询扩展(如多查询扩展)生成多个查询变体,分别检索后融合结果,能提高召回率,但成本与查询数量成线性关系。HyDE 只生成一个文档,成本相对固定,但它依赖于 LLM 的生成质量。
下面是一个对比表格,从多个维度比较三种方法。
| 方法 | 核心操作 | 召回率提升 | 延迟开销 | 适用场景 | 主要风险 |
|---|---|---|---|---|---|
| 直接检索 | 嵌入原始查询 | 基线 | 无 | 查询与文档词汇接近时 | 词汇鸿沟导致召回不足 |
| 多查询扩展 | 生成 N 个查询变体,分别检索后融合 | 中高(随 N 增加) | 线性增加(N 倍) | 模糊查询、探索语义邻域 | 成本高,可能引入噪声 |
| HyDE | 生成一个假设文档,嵌入后检索 | 高(平均提升约 6 个百分点,BEIR 基准) | 一次 LLM 调用(约 100-500ms) | 有直接答案的事实性问题 | 生成质量差、领域偏移时失效 |
需要说明的是,表格中的性能数字来自资料。BEIR 基准上的平均召回率提升约 6 个百分点,来自 Tian Pan 的博客文章;延迟数据来自同一来源。这些数字只能作为参考,实际提升取决于语料和查询分布。
生产环境中的实现与延迟权衡
在生产环境中加入 HyDE,意味着在检索之前增加一次 LLM 调用。这个调用会带来额外的延迟。根据资料,在 1-4B 参数规模的较小 LLM 上,HyDE 会增加 43-60% 的查询时延迟;在更大模型上,如果使用专用硬件,延迟成本相对可控。ElevenLabs 的案例显示,通过外部托管 LLM 进行查询改写占其总 RAG 延迟的 80% 以上。他们通过切换到自托管的 Qwen 3-4B 和 3-30B 实例并行推理,并设置一秒超时回退,将中位延迟从 326ms 降至 155ms。
延迟是真实的成本,但可以通过工程手段缓解。一个常用的策略是选择性应用:只有当基线检索的置信度低于阈值时才调用 HyDE。具体实现是,先嵌入原始查询并检索,如果最高相似度得分低于某个阈值,说明检索可能失败,此时再调用 HyDE。这样简单查询走快速路径,复杂查询才付出额外延迟。
另一个策略是使用更小的模型进行查询改写。7B 级模型已经能很好地处理改写任务,延迟远低于前沿模型。此外,可以缓存改写后的查询,因为用户的问题往往相似。还可以将改写与原始查询嵌入并行运行,同时进行两种检索,然后融合结果。
下面是一个生产环境的流程图,展示了选择性应用 HyDE 的决策流程。
flowchart TD
A[用户查询] --> B[嵌入原始查询]
B --> C[向量检索]
C --> D{最高相似度 > 阈值?}
D -- 是 --> E[直接返回结果]
D -- 否 --> F[调用 LLM 生成假设文档]
F --> G[嵌入假设文档]
G --> H[向量检索]
H --> I[融合或替换结果]
I --> J[返回最终结果]
这个流程的关键在于阈值的选择。阈值过高会导致许多简单查询也走 HyDE 路径,增加延迟;阈值过低则无法识别检索失败。工程上通常根据验证集上的召回率曲线来确定阈值。
失效边界与常见失败模式
HyDE 并非万能。它的有效性依赖于几个前提,当这些前提不成立时,HyDE 可能退化甚至损害检索精度。
首先,生成质量是关键。如果 LLM 生成的假设文档与真实文档在词汇和风格上差异很大,那么嵌入向量可能落在错误的区域。例如,对于高度专业化的领域,通用 LLM 可能生成过于泛化的文档,无法匹配领域术语。
其次,HyDE 最适合有直接答案的事实性问题。对于个人化、模糊或高度依赖上下文的查询,假设文档可能偏离目标。例如,用户问“我该选哪个方案?”,这个问题没有标准答案,生成的假设文档可能包含主观建议,与知识库中的客观描述不匹配。
第三,领域适配问题。HyDE 的编码器(如 Contriever)是在通用语料上训练的,如果企业知识库是高度专业化的,编码器可能无法捕捉领域特定的语义。此时,可能需要微调编码器或使用领域特定的嵌入模型。
第四,分布偏移。如果知识库的内容随时间变化,而 HyDE 的生成模型没有更新,可能导致检索结果过时。例如,文档更新后,旧术语被新术语替代,但 LLM 仍然生成旧术语的假设文档。
最后,多跳问题。HyDE 生成一个文档,适合单步检索。对于需要多步推理的问题,如“我们用的是哪个版本的库,该版本有哪些已知漏洞?”,HyDE 可能无法生成包含所有必要信息的文档。此时,子查询分解可能更合适。
可观测性与验证方法
在部署 HyDE 时,需要监控哪些指标?首先,检索召回率是核心指标,可以通过人工标注或自动评估(如 RAGAS)来衡量。其次,端到端答案质量,包括忠实度和相关性。第三,延迟和成本,特别是 LLM 调用的 p50 和 p95 延迟。
工程上,可以通过 A/B 测试来验证 HyDE 是否值得。设置两组:一组使用直接检索,另一组使用 HyDE,比较同一批查询的检索结果和最终答案。注意控制其他变量,如分块策略和嵌入模型。
另一个验证方法是分析失败案例。当 HyDE 检索结果不佳时,检查生成的假设文档是否合理。如果假设文档本身质量差,可能需要改进提示词或更换生成模型。如果假设文档合理但检索结果差,可能是编码器或索引的问题。
与替代方案的权衡
HyDE 不是唯一的查询改写技术。退后提示(Step-Back Prompting)生成一个更抽象的问题版本,适合需要背景知识的复杂诊断问题。子查询分解将多跳问题拆分为原子子查询,适合多跳推理。多查询扩展生成多个查询变体,融合结果,适合模糊查询。
选择哪种技术取决于查询类型。简单事实型查询,HyDE 是首选,因为它直接解决词汇鸿沟。多方面或多跳查询,子查询分解更合适。需要背景上下文的查询,退后提示更有效。模糊查询,多查询扩展可以探索语义邻域。
在实际系统中,通常需要组合使用。一个路由器可以根据查询复杂度选择不同的改写策略。例如,简单查询走快速路径,复杂查询先分解再检索。
未解决的问题
HyDE 仍然有一些未解决的问题。首先,如何自动判断一个查询是否适合 HyDE?目前主要依赖相似度阈值,但阈值的选择需要人工调优。其次,生成模型的选择对效果影响很大,但如何系统性地评估不同生成模型对检索精度的影响,缺乏标准方法。第三,HyDE 与微调检索器的比较:论文显示 HyDE 在零样本设置下表现良好,但如果有标注数据,微调检索器可能更好。最后,HyDE 在多模态场景下的扩展,例如生成图像描述作为查询,还没有充分研究。
对于企业知识库问答,HyDE 是一个值得尝试的查询改写方法。它能在不改变索引的情况下提升召回率,但需要权衡延迟和成本。工程上,选择性应用和缓存是控制开销的关键。理解它的失效边界,才能在生产环境中做出正确的决策。