想象你要去一个巨型档案馆里找一位从未见过的证人。你只记得一个模糊关键词:“红围巾”。直接把这个词报给值班人员,他在几十万张照片里翻找,效果很差。但你如果先在门口让一位经验丰富的画像师写一段“这位证人如果真的出现在这里,他的肤色、发型、衣着、活动区域可能是……”的文字,再请工作人员拿着这张画像去比对照片库,命中率会立刻变高。HyDE(Hypothetical Document Embeddings)正是给 RAG 检索配了一位“画像师”。它先用大模型把用户的一句短查询扩写成一篇假设答案文档,然后把这篇文档编码成向量,用向量去文档库里寻找真实相关的文档。因为短查询和长文档在语义表达上隔着一段“鸡同鸭讲”的距离,而假设答案文档在长度、语体和信息密度上都更接近目标文档,所以检索召回率更高。尤其在没有任何历史检索样本的零样本场景,这种方法往往比直接查询嵌入更稳。下面我们就用画像师的故事,拆解 HyDE 的原理、实现与边界。
对 AI 从业者来说,掌握 HyDE 等于掌握一个低成本、零样本的召回增强技巧,能让 RAG 系统在知识密集问答和企业检索中立刻看到效果提升。
可视化演示
本节配有交互动效(进入视口后自动加载,约 3KB)。
检索的尴尬
档案室的玻璃柜后有几万张照片,有人只丢下一句话:“我要找一个系红围巾的人。”工作人员对着照片库扫了一圈,发现每张照片里都有或红或灰的围巾,根本无从下手。问题不在照片库,而在那句线索太短、太模糊。RAG 检索也会遇到一模一样的尴尬:用户输入一个短问题,文档库里的每一篇文档却都是完整的长文本,两者在“体型”和语言风格上差距悬殊。
在向量检索里,系统先用嵌入模型把查询和文档分别编码成向量,再计算相似度。直观来说,只有两三行字的问题,和洋洋洒洒几百字的技术文档,会被嵌入模型放到语义空间的不同区域。即便意思相近,短查询与长文档之间的向量也可能并不接近,这就是语义鸿沟。
这一现象在零样本场景下尤其明显:没有历史点击日志来告诉我们哪些查询对应哪些文档,嵌入模型只能靠通用语义做判断。短查询越口语化、越抽象,召回结果就越容易漂移。于是,一个朴素的想法浮出水面:能不能在检索之前,先把短查询“养大”,变成一篇文档后再去比较?
回到档案室的例子:红围巾这个线索太短,工作人员只能按颜色扫一遍,当然容易漏掉真正目标。于是档案室主任想到了一个办法——先请画像师补全线索。
- 查询与文档q 是用户输入,d 是库中候选文档,sim 计算二者语义相似度。
- 向量化映射v_q、v_d 是由嵌入模型分别编码得到的文本向量。
- 余弦相似度用向量夹角的余弦值衡量方向一致性,结果越大越相似。
- 排序取 TopK对候选文档逐一打分后,分高者排在前列,取前 k 个。
核心思想
画像师出场了。他先向目击者详细询问,然后写出一段文字:这位证人如果是我们要找的人,他大概会穿着藏青色大衣、围着酒红色围巾、左手戴表,常在东区咖啡馆出现。工作人员拿着这段文字去照片库比对,不再只凭一条模糊线索。
HyDE 的核心思想完全一样。它先让大模型针对用户问题生成一段“假设答案文档”(Hypothetical Document),然后再把这篇假设文档当作查询输入,编码成向量去检索真实文档。整个过程可以理解成:不直接用问题原文搜索,而是先让模型写一篇“如果这个问题有答案,答案文档里大概会写什么”的草稿,再拿草稿当钥匙。
所以 HyDE 不是改变文档库,也不改变召回后的排序逻辑,它只改变查询侧的表达。原始查询是短句,假设文档是段落,后者的长度和语体与目标文档更接近。把假设文档嵌入成向量后,再与文档向量计算相似度,就能更好地跨越语义鸿沟。
画像师补全的细节未必完全真实,但足够让工作人员聚焦。HyDE 的假设文档也一样,它并不需要一字不差,只要语义轮廓接近真实答案,检索效率就会提升。
- 假设文档\hat d 是大模型根据查询 q 生成的虚拟答案文档,不是库中的真实文档。
- 嵌入画像\mathbf{v}_{\hat d} 是假设文档经嵌入模型得到的向量,它承载查询意图。
- 替代检索后续用 \mathbf{v}_{\hat d} 作为查询向量,与真实文档的向量计算相似度。
文档生成
画像师不是凭空乱画,他需要一套问话方法和格式:先问脸型,再问衣着,最后问活动地点。HyDE 里的 LLM 也需要一份设计良好的生成指令,指令越清晰,画像越稳定。
常见的做法是在 prompt 里告诉 LLM:你现在要写一段“如果该问题有答案,那么标准答案文档可能这样写”的文本。模型会以自回归的方式逐字生成:给定用户问题 q,LLM 在每一步预测下一个 token,直至生成完整假设文档。由于输出的是自然语言段落,它自然带有文档的语体特征,长度也向目标文档靠拢。
设计指令时要注意几点:第一,要求模型输出完整段落而非关键词;第二,可以让模型先拆解问题,再写答案草稿;第三,可以结合领域特征,例如法律场景要求引用条款结构。生成质量直接决定后续检索上限。
只要问法对,画像师画出的画像就有章法。同理,只要 prompt 设计得好,LLM 生成的假设文档就会向着文档库的语体靠拢,为后续匹配铺路。
- 条件概率p_\theta 是生成模型在给定 q 时输出假设文档 \hat d 的概率。
- 自回归展开整篇文档的概率等于每个 token 概率的乘积,当前位置只依赖之前生成的 token 与原始问题。
- 解码生成实际应用时通过贪心解码或采样,得到一段完整假设文档。
向量匹配
画像画好后,工作人员不会用眼睛一张张扫照片,而是把画像上的关键特征转成一组数字编码,然后让计算机按特征距离排序。HyDE 的向量匹配也遵循同样的逻辑。
假设文档经过嵌入模型(如 BGE、E5、OpenAI Embedding)编码后,变成一个高维向量;文档库中的每一篇文档也预先生成好向量。当检索请求到来时,系统计算画像向量与所有文档向量的余弦相似度,按分数从高到低排序,取前 k 个文档作为召回结果。这个流程与常规向量检索完全一致,只是查询向量来源换成了假设文档。
向量空间是检索的最终坐标系。在这个坐标系里,文本越近语义越近;嵌入模型越好,坐标越能容纳文档级语义。HyDE 的价值,就是一开始就把查询向量放到了更靠近真实文档的区域。
照片库按特征编码排好了索引,画像一来就能快速比对。向量检索也是这样:文档向量提前建好,HyDE 只负责把查询侧画像调得更准。
- 文档库D 是全部候选文档,每个 d 都有预计算的文档向量 \mathbf{h}_d。
- 画像向量\mathbf{h}_{\hat d} 是假设文档的嵌入向量,是查询侧的“文档化表达”。
- TopK 召回对所有文档算余弦分,返回分数最高的 k 个文档。
优势局限
画像找人法有用,但画像师也可能画出偏差。比如目击者记忆模糊,画像师又把红围巾画成绿围巾,拿着错误画像去比对,反而可能错过真目标。HyDE 正在真实性与幻觉之间走钢丝。
优势在于零样本和无需标注:没有历史检索样本时,直接查询嵌入往往只能捕捉字面相似度,而 LLM 生成的假设文档能补出语义细节,让召回率显著提升。局限也来自生成环节:LLM 如果“自信地胡编”,假设文档会失真;失真会在嵌入、相似度计算中逐级传导,最终放大成更差的检索结果。换句话说,HyDE 不是免费的午餐,它把一部分检索风险转移给了生成模型。
实际使用中,我们可以用 delta 衡量 HyDE 的效果:假设文档向量与真正答案文档的相似度,减去原始查询向量与真正答案文档的相似度。如果 delta 大于零,说明画像比原话更接近目标;如果小于零,说明画像失真比短查询带来的鸿沟更严重。
所以档案室不会让画像师随便画。工程师也不会盲目用 HyDE,而是先用少量样例统计 delta,确认画像平均质量够好后再接入线上系统。
- 目标文档d^* 是文档库中真正相关的答案文档,用于检验画像质量。
- 两路对照前项是假设文档向量与目标文档向量的相似度,后项是原始查询向量与目标文档向量的相似度。
- 增益判断\Delta 大于 0 表示画像有效,小于 0 表示生成误差占了上风。
落地场景
画像找人适合什么场景?档案室照片质量高、目标有相对稳定特征时最有效;如果照片全是大头贴而且目标戴着口罩,画像就难发挥。HyDE 的落地场景也有类似取舍。
在知识密集型问答(如医疗、法律、科研)中,用户问题短而专业,答案文档长而规范,HyDE 能显著提高召回质量。在企业内部文档检索中,常见问题是员工查询语义含糊,比如“去年合规整改怎么做”,而文档标题可能完全不含这些词;HyDE 先生成一份“假设整改报告”,再检索真实报告,命中率更高。
效果评估通常用 Recall@k,即前 k 个召回结果中相关文档的比例。在 A/B 测试中,可以对比直接查询嵌入与 HyDE 的 Recall@k 和 Precision@k,同时监控生成耗时。一般来说,生成假设文档会增加一次 LLM 调用,需要平衡时效与召回收益。
选择 HyDE,就像在档案室门口增加一个画像师岗位:适合高价值、长文档、零样本的场景;若查询本身已经很长、很结构化,画像带来的增量就会变小。
- 相关文档集合D_\text{rel} 是人工标注的相关文档,是评估的基准真相。
- 召回集合\mathcal{R}_k 是系统返回给用户的前 k 个文档。
- 交集占比召回到的相关文档数除以 k 与相关总数中的较小值,防止分母大于全集。
代码实践
画像流程跑通后,下一步就是把它写成自动化流水线。在代码里,我们把“画像师”“比对照片”“返回结果”三个环节拆成函数,方便在不同文档库中复用。
伪代码思路很简单:第一步,准备大模型接口和文档向量库;第二步,写一个 generate_hypothetical_document 函数,将用户查询与 prompt 模板拼接后交给 LLM;第三步,把返回的假设文档传入 simple_embed 得到向量,与所有文档向量计算余弦相似度,按分数排序返回 top-k 文档。真实项目里会把 simple_embed 换成 SentenceTransformer 等嵌入模型,并用向量数据库做 ANN 检索。
代码考核时,可以用 Precision@k 衡量前 k 条结果中有多少真正相关,避免只追求召回而忽略准确率。
这段代码就是一个微型画像工作室:LLM 负责画,Embedding 负责编码,向量比对负责找人。理解了这几十行,HyDE 的主干就算彻底落地了。
- 前 k 结果\mathcal{R}_k 是按相似度排序后截取的前 k 条。
- 相关命中数统计这 k 条中属于相关文档集合的数量。
- 归一化除以 k,得到前 k 条结果中的相关密度。
AI 应用场景
知识密集型问答系统
阶段:检索召回 / 查询改写
解决的问题:医疗、法律、科研等场景中,用户问题往往只有一句话,而答案藏在长文档里。传统直接查询嵌入容易丢失语义细节,短查询与长文档之间的鸿沟让召回率偏低。HyDE 先生成一段“如果答案文档存在会怎么写”的假设文档,再用该文档向量检索真实指南或条款,缩短查询与文档的语义距离。
具体案例:某医疗问答平台上线 HyDE 后,用户输入“抗抑郁药停药后的戒断反应有哪些”,系统先让 LLM 生成一段假设的药物说明,再检索药品说明书和临床指南,最终答案引用可溯源文档,相关文档的召回率明显提升。
企业知识库检索
阶段:文档召回 / 检索策略
解决的问题:企业员工查询口语化、简略化,但知识库文档标题规范、正文冗长。例如“去年数据合规整改的范围”直接搜索可能只匹配“数据”“整改”,漏掉真正的合同附件和合规清单。HyDE 把一句话扩写成“假设整改报告”,更像与企业文档同频的查询画像。
具体案例:某咨询公司把 HyDE 接入内部知识库后,员工提问“新产品上线前要做哪些风险评估”,系统先生成一份假设的风险评估纪要,再召回既往项目复盘、合规 checklist 和安全报告,检索命中率提升约 20%。
Python 演示
import mathimport refrom collections import Counter def tokenize(text): return re.findall(r"[\w]+", text.lower()) def simple_embed(text): return Counter(tokenize(text)) def cosine(v1, v2): common = set(v1) & set(v2) dot = sum(v1[t] * v2[t] for t in common) norm1 = math.sqrt(sum(v * v for v in v1.values())) norm2 = math.sqrt(sum(v * v for v in v2.values())) return dot / (norm1 * norm2) if norm1 and norm2 else 0.0 def generate_hypothetical_document(query, llm=None): # 真实项目可替换为大模型接口 if llm is not None: return llm(query) return f"An answer document about {query} usually includes definition, background, key steps and summary." def hyde_retrieve(query, docs, llm=None, k=1): hypo = generate_hypothetical_document(query, llm) hypo_vec = simple_embed(hypo) # 用假设文档向量替代查询向量 scored = [(cosine(hypo_vec, simple_embed(doc)), doc) for doc in docs] scored.sort(reverse=True, key=lambda x: x[0]) return [doc for _, doc in scored[:k]], hypo if __name__ == "__main__": query = "what is zero-shot learning" docs = [ "zero-shot learning lets a model recognize unseen classes.", "transfer learning moves knowledge between tasks.", "RAG enhances LLM answers with an external knowledge base.", ] results, hypo = hyde_retrieve(query, docs, k=2) print("hypothetical document:", hypo) for i, doc in enumerate(results, 1): print(f"retrieved {i}: {doc}")
def generate_hypothetical_document(query, llm=None):封装画像师,默认用模板模拟 LLM,真实可传入大模型接口。hypo_vec = simple_embed(hypo)把假设文档变成词频向量,模拟嵌入过程。scored = [(cosine(hypo_vec, simple_embed(doc)), doc) for doc in docs]让画像和每个文档照片比对,得到相似度分数。scored.sort(reverse=True, key=lambda x: x[0])按相似度从高到低排序,确保最相关的文档排在最前。return [doc for _, doc in scored[:k]], hypo截取前 k 个文档返回,同时把假设文档也交给调用方检查质量。
常见误区
误区我刚用 HyDE 时以为大模型生成的假设文档就是最终要发给用户的答案,所以特别纠结假设文档本身对不对、全不全。
正解HyDE 的假设文档只是中间画像,用于召回真实文档。真实文档拿回来之后,生成模型会重新参考事实作答;画像质量影响检索,但不直接等于最终输出。
为何常见:很多人一看到“生成答案”就以为是生成阶段,忘了它在检索阶段只是查询改写工具。
误区假设文档越长越详细越好,最好让模型写满一千字,这样向量里包含的信息才够多。
正解不是越长越好。假设文档要与目标文档的长度和语体匹配,太长的画像会混入大量无关细节,反而把向量带偏。应当用 prompt 约束结构,写一段“存在答案时文档会怎么描述”的精炼草稿。
为何常见:因为直觉上觉得更多信息能提升检索,忽略了向量对噪声敏感,细节太多反而拉远距离。
误区HyDE 能完全替代向量数据库和嵌入模型,只要有大模型就够了,文档库可以直接拿去生成。
正解HyDE 只改造查询侧,向量检索、相似度计算、ANN 索引这些基础设施一个都不能少。假设文档最终也要靠嵌入模型和向量库才能召回真实文档。
为何常见:把 HyDE 理解成大模型端到端搜索,混淆了召回与生成两个阶段。
误区HyDE 一定比直接查询嵌入好,既然论文里说零样本有效,线上无脑启用就行。
正解HyDE 的优点集中在零样本短查询场景,但存在误差放大和额外延迟。如果查询本身已经是一段完整描述,或者生成模型经常幻觉,直接查询甚至更稳。上线前应该用少量标注样本对比 Recall@k 和 Precision@k。
为何常见:看到 benchmark 提升就忽略失败案例,陷入“新方法必然更强”的误区。
面试题
Q1. HyDE 生成的“假设文档”在检索流程中的主要作用是什么?
- A.直接回答用户问题,省去生成阶段
- B.编码为向量后代替原始查询去检索← 正确答案
- C.作为新文档永久加入知识库
- D.替代嵌入模型训练训练语料
答案:B。假设文档是检索用的画像,不是最终回复;编码后替代原始查询去向量库比对,故选 B。A 错在跳过生成阶段,C 错在加入知识库,D 错在替代嵌入模型训练。
Q2. HyDE 主要想解决 RAG 检索中的哪类问题?
- A.向量数据库的磁盘占用过高
- B.短查询与长文档之间的语义鸿沟← 正确答案
- C.大模型生成内容速度过慢
- D.文档标签体系的混乱
答案:B。HyDE 专门针对“短查询 vs 长文档”的语义表达鸿沟,先把查询变长。磁盘、速度、标签都不是核心痛点。
Q3. 在 HyDE 的标准流程中,正确的执行顺序是什么?
- A.查询→假设文档→嵌入→向量检索← 正确答案
- B.假设文档→查询→向量检索→嵌入
- C.嵌入→查询→假设文档→向量检索
- D.向量检索→查询→假设文档→嵌入
答案:A。标准流程是先让 LLM 生成假设文档,再嵌入成向量,再用向量去检索真实文档。B、C、D 的顺序都颠倒了。
Q4. 为什么 HyDE 在零样本场景下表现更明显?
- A.零样本时大模型运行速度更快
- B.没有检索日志,原始查询往往太短太泛← 正确答案
- C.零样本时文档库规模会自动变小
- D.零样本时嵌入模型无需加载
答案:B。零样本场景没有历史日志来弥补查询太短的问题,HyDE 的生成长文本相当于无中生有补出上下文。速度、库规模、模型加载与它无关。
Q5. 下列哪些说法符合 HyDE 的“误差放大”特性?
- A.假设文档出现幻觉会带偏后续检索← 正确答案
- B.嵌入模型会自动把所有生成错误抹平
- C.LLM 生成质量直接影响最终召回结果← 正确答案
- D.向量相似度计算能将误差归零
答案:AC。假设文档如果有幻觉,等于画像画歪,后续检索都会偏;嵌入模型并不会“自动纠错”。B、D 都把误差消除想得太理想,误差会沿链路放大,故 A、C 正确。
Q6. 若目标文档库是专业法律文书,HyDE 的生成指令应重点强调什么?
- A.尽量输出口语化的互联网表达
- B.按法律文书的段落结构与术语起草← 正确答案
- C.只输出关键词列表而非完整段落
- D.必须复述用户查询的每一个字
答案:B。法律检索场景中,画像要在语体和结构上贴近法律文书,才能和真实合同、条款向量更近。口语化、关键词列表、复述原文都偏离目标文档形态。
Q7. 下面哪些评估指标适合衡量 HyDE 对召回效果的提升?
- A.Recall@k← 正确答案
- B.Precision@k← 正确答案
- C.生成模型困惑度
- D.向量维度大小
答案:AB。召回与排序效果用 Recall@k、Precision@k 衡量;困惑度是生成模型指标,向量维度与文本语义无关。A、B 能反映 HyDE 是否真的把相关文档排到前面。
Q8. HyDE 中“文档嵌入”所嵌入的对象是什么?
- A.用户输入的原始查询字符串
- B.LLM 生成的假设文档字符串← 正确答案
- C.文档库中所有标题字符串
- D.用户点击日志中的关键词
答案:B。HyDE 的“文档嵌入”对象是 LLM 生成的假设文档,不是原始查询。原始查询只是画像师的输入,标题和日志更不是查询嵌入对象。
Q9. 下面哪种情况更适合使用 HyDE?
- A.用户查询本身就是完整长段落
- B.短查询且文档库以长文为主← 正确答案
- C.文档库仅有几十个短标签
- D.检索结果要求毫秒级且无额外调用
答案:B。HyDE 适合短查询配长文档的零样本场景。如果查询已是完整段落,画像增量有限;超短标签库和毫秒级低延迟场景也不适合额外调用 LLM。
Q10. 关于 HyDE 与直接查询嵌入的比较,哪些说法正确?
- A.假设文档在长度上更接近真实文档← 正确答案
- B.假设文档可能引入大模型幻觉← 正确答案
- C.生成质量差时 HyDE 可能不如直接查询← 正确答案
- D.HyDE 在所有数据集上必然更优
答案:ABC。假设文档确实在长度上靠近真实文档,但也可能引入幻觉,生成差时比直接查询嵌入更差,因此 A、B、C 都对。D 的“必然更优”忽略了误差放大风险。