先看三句用户问题。
“这个怎么申请?”
“理赔和索赔有什么区别?”
“等待期。”
第一句依赖上一轮对话,不知道“这个”指什么就无法检索。
第二句包含两种可能出现在文档里的表达,系统需要覆盖不同措辞。
第三句只有一个抽象概念,信息太少,向量很容易飘到一堆相近主题。
这三类问题都可能被笼统地归入“Query 优化”,但适合的处理方法并不一样。
如果不分类型,每个问题都先交给大模型改写,不仅多一次调用,还可能把原本清楚的编号、否定和限制条件改错。
重写、扩写和 HyDE 分别解决什么?
Query 重写追求的是“把问题说完整”。
用户问“这个怎么申请”,系统要结合有限的对话历史,把它恢复成类似“年假怎么申请”这样可以脱离上下文独立理解的问题。
错别字、口语填充、缩写和省略也可以通过重写处理。重点是尽量保持原意,而不是把一句话写得更漂亮。
Query 扩写追求的是“让不同表达都能被找到”。
用户说“理赔”,文档可能写“索赔”;用户说口语词,知识库可能使用专业术语。扩写可以保留原问题,同时生成若干同义表达或子查询,各自检索后合并候选。
HyDE 追求的是“让检索代理更像文档”。
短 Query 往往只有一个主题词,而知识库里的答案通常是一段陈述。HyDE 先让模型生成一段可能的答案,再把这段假设文档向量化,用来检索真正资料。
它借用的是假设文本的语义形状,不是假设文本里的事实。

重写补全一条问题,扩写覆盖多种说法,HyDE 用假设文档辅助语义检索。三者都只是检索代理。
这三种方法可能同时出现,但不应该无条件叠加。
多轮指代问题先做重写,已经得到清晰独立问题后,未必还需要 HyDE。
明确术语只是文档措辞不同,可以扩写同义词,不必让模型重新编一段答案。
短而抽象的问题如果原词也很重要,可以让原 Query 与 HyDE 并行,而不是只保留假设文本。
Query 重写最容易改错什么?
重写听起来只是换一种表达,实际会触碰用户意图。
第一类风险是指代补错。
上一轮同时提到两个对象,用户说“它”,模型可能选择错误对象。系统如果只检索改写后的问题,后面每一步都会围绕错误实体展开。
第二类风险是否定丢失。
“哪些情况不支持”如果被改成“支持哪些情况”,关键词仍然相近,意图却完全相反。
第三类风险是约束丢失。
时间、版本、地区、对象和数量都是检索范围的一部分。重写后只剩主题词,系统可能召回旧版本或错误对象。
第四类风险是把新话题误当追问。
用户上一轮问报销,下一轮直接问另一项制度。重写模型如果过度依赖历史,可能把新问题强行接到旧主题上。
因此,重写输出最好满足几个检查。
它应该能够独立理解,保留实体、否定和限制条件,不额外添加用户没有提供的事实,并且在证据不足时允许保持原句或请求澄清。
检查最好建立在结构化结果上,而不是只接收一条改写文本。重写器可以同时返回独立问题、保留的实体、否定词、时间范围、使用了哪段历史以及是否存在歧义。服务端再把这些字段与原 Query 对照:原问题有否定而结果没有,或结果新增了无法从历史定位的实体,就拒绝这次改写并回到原路线。
下面是一个教学输出示意,只表达约束,不对应具体模型接口:
{
"standalone_query": "年假怎么申请",
"resolved_from_turn": "turn-2",
"entities": ["年假"],
"negation_preserved": true,
"ambiguous": false
}
结构化并不代表结果一定正确,它只是让错误可检查。若历史中同时存在年假与病假,ambiguous 应触发澄清,而不是为了满足 Schema 强行选择一个实体。
历史也不是越多越好。
重写只需要能消解当前问题的相关对话。把整段长历史全部交给模型,旧话题会增加误判,也增加调用成本。
Query 扩写为什么会增加噪声?
扩写的好处是覆盖更多文档措辞,代价是查询数量和候选数量一起增长。
一个词如果扩出很多相近表达,每个表达再各自召回一批内容,最终候选里可能出现大量近重复 Chunk。
更危险的是扩写词不等义。
日常表达中的近义词,放到专业文档里可能有不同边界。模型动态扩出的相关词,也可能只是主题相关,并不能互换。
所以扩写需要明确来源和合并规则。
可控的领域同义词适合由词典维护。复杂语义可以让模型生成候选,但要保存每个扩写版本,并限制数量。
多路结果合并时,可以按稳定 Chunk ID 去重,并记录每条候选由哪些 Query 找回。这样既能识别多路共同命中,也能排查哪条扩写引入了噪声。
扩写还可以用于多条件问题。
一个问题同时问申请条件和办理材料时,可以拆成两个子查询,各自检索,再合并互补证据。但拆分之后要检查最终证据是否覆盖完整问题,不能只回答其中一半。
HyDE 为什么有效,又为什么危险?
向量检索比较的是 Query 与文档在语义空间中的接近程度。
问句通常很短,文档却以完整陈述出现。HyDE 生成的假设答案包含更多主题词和上下文,向量形式可能更接近真正答案文档。
但这段假设答案没有经过知识库验证。
它可能补错实体、时间和结论,也可能在资料根本没有答案时生成一段看似完整的说明。
如果系统把假设答案直接展示给用户,就已经越过了 RAG 的证据边界。
即使只用它做检索,也存在带偏风险。错误假设会把向量推向错误主题,随后召回一批“支持”假设的相似文本。
更稳妥的方式是把 HyDE 当成一条可撤销的检索路线。
原 Query 仍然保留,假设文本单独记录。两路可以并行召回,再根据稳定 ID 合并。若 HyDE 路线没有带回可核验证据,最终回答不能引用假设文本补空白。
精确编号、产品名、错误码和法规条款更依赖原词命中。先生成自然语言假设,反而可能稀释关键字符。这类问题通常应优先走关键词或精确过滤。
资料中明确没有答案时,也要谨慎使用 HyDE。它提高“找到相似内容”的机会,不等于提高“找到正确答案”的机会。
怎样给三种方法做路由?
路由可以先从可解释规则开始,不必一开始就让模型决定一切。
含有“这个、它、那项”等指代,并且相关历史里有明确对象时,进入重写。
含错别字、缩写或口语表达,且不改变实体和否定的情况下,可以做轻量纠错与规范化。
用户表达与文档术语可能不同,或者问题包含多个信息点时,考虑扩写或拆分。
Query 很短、抽象、没有精确编号,并且原向量召回表现不稳定时,才把 HyDE 放进候选路线。
产品编号、错误码、明确标题和法规条款,优先保留原词并走关键词检索。
意图不清、多个对象都可能成立时,与其强行改写,不如请用户澄清。

先判断缺少的是历史、表达覆盖还是文档式语义,再选择重写、扩写或 HyDE。精确词与高歧义问题有独立出口。
规则不可能覆盖所有问题,但它有两个价值。
一是让系统知道为什么触发某种方法,二是给后续评测提供清晰分组。等积累了真实 Query 与失败标签,再考虑训练分类器或用模型路由。
路由输出应包含“为什么走这条路”和“失败后回哪里”。例如检测到指代才调用重写,重写未保留实体就退回原 Query;只有短抽象问题且没有精确标识时才增加 HyDE;多路候选没有合格证据时进入无答案,而不是继续串更多生成步骤。每个分支都有终止条件,才能避免 Query 优化变成不可控的调用链。
缓存也要按处理版本隔离。原 Query 相同,但历史不同,重写结果可能完全不同;同义词表、提示词或模型升级后,产物也会变化。缓存键至少要包含会影响结果的会话上下文摘要和处理版本,不能只用用户输入文本,否则上一段对话的实体可能被复用到另一段会话。
什么时候应该直接向用户澄清?
Query 优化的目标不是让系统无论如何都搜出内容。
有些问题缺少的信息无法从对话历史安全补全。
例如用户说“这个能不能退”,上一轮同时出现了两个对象;或者用户只问“怎么处理”,系统不知道他在问申请、报销还是故障。
此时重写模型如果自行选一个对象,后面的检索链路可能非常流畅,却从起点就错了。
澄清适合用在几类情况。
第一,存在多个同样合理的指代对象。
第二,缺少会改变答案的关键限制,例如地区、版本或用户身份。
第三,问题同时可能落到不同知识库或处理流程。
第四,原问题过短,而 HyDE 或扩写的候选方向差异很大。
澄清问题也要尽量具体。
与其问“请提供更多信息”,不如列出系统已经识别到的两个对象,让用户选择。这样既减少来回沟通,也避免模型重新自由猜测。
当然,频繁澄清会打断体验。
所以是否澄清也应进入评测。可以记录出现歧义时,直接检索、自动改写和请求澄清分别产生什么结果。高风险业务更看重意图正确,低风险资料搜索则可能接受并行宽召回。
关键原则是:无法可靠补全的信息,不要被一句看似标准的改写藏起来。
为什么必须保留原 Query?
原 Query 是用户意图最直接的证据。
如果只保存改写结果,出现错误时只能看到一条看起来很标准的问题,却不知道模型删掉了哪个词、从哪段历史补了哪个实体。
每次请求至少应记录原 Query、选用的历史、路由类型、重写结果、扩写列表、HyDE 文本、每条路线的候选和最终合并结果。
保留原 Query 还有两个恢复方式。
一种是改写路线没有找到合格证据时,退回原问题重新检索。
另一种是从一开始就让原问题与处理后问题并行召回,再合并去重。后者覆盖更稳,但候选和成本更高。
是否并行要通过评测决定,不能默认多一条路线就一定更好。
还要为处理产物标记版本。
改写提示词、同义词表和模型升级后,同一 Query 可能得到不同结果。没有版本记录,坏样本无法稳定复现。
多路合并还要保留“候选是怎样来的”。
同一个 Chunk 可能同时被原 Query、扩写 Query 和 HyDE 找回。合并时可以只保留一份正文,但不能把通道信息丢掉。多路共同命中可能是一条有用信号,某一路反复引入噪声也需要从日志中看出来。
如果只留下最终综合分,就无法判断这条候选是原词精确命中,还是被错误假设带回。调试 Query 优化时,来源通道与最终排名同样重要。

指代补错、否定丢失、扩写噪声和 HyDE 错误假设需要不同检查,但共同底线都是保留原 Query 与处理记录。
四种 Query 优化故障,分别在哪个分支发生?
指代补错要查重写结果,噪声增加要查扩写分支,假设带偏要查 HyDE,明确问题变差则先查路由为什么没有保留原 Query。
“这个怎么申请”没有召回
先看对话历史中是否有唯一明确对象,再看重写结果是否成为独立问题。
如果历史有多个对象,不要默认选择一个。重写置信不足时应保留原句或发起澄清。
否定问题被改成正面问题
比较原 Query 与重写 Query,检查“不、不能、除外”等意图是否保留。
再查看正确例外条款在哪一路被找回,不能只看最终回答是否通顺。
错误码经过改写后反而搜不到
这类精确标识应保留原词,优先走关键词或结构化过滤。
如果路由仍然触发自然语言扩写,说明 Query 分类边界需要调整。
HyDE 生成了错误假设
检查假设文本添加了哪些原问题不存在的实体和结论,再比较原 Query 与 HyDE 两路候选。
假设内容不能进入最终证据。没有真实文档支持时,系统应拒绝用它补答案。
怎样评估 Query 优化是否有效?
先按失败类型建立问题集。
至少包含口语改写、指代、省略、错别字、同义词、否定、多条件、精确编号、短抽象 Query 和无答案问题。
每条问题保存参考意图、正确证据和不允许丢失的约束,例如否定、时间或对象。
然后在同一知识库与检索配置下比较四组:原 Query、重写、扩写、HyDE。需要时再增加原 Query 与处理结果并行的组合。
检索层看 Recall@K 和第一条正确证据名次,确认正确资料是否被带回。
意图层检查实体、否定、时间和范围是否保持。召回更多内容,却把“不支持”改成“支持”,不能算提升。
工程层记录额外调用、候选数量、近重复、处理耗时与版本。
无答案样本还要检查错误处理是否让系统更容易强行回答。
路由本身也要单独评估。
某条重写方法在指代问题上有效,不代表路由器能准确识别指代问题。如果正确方法经常没有被触发,单独评测算法会高估整体效果。
因此评测记录要区分两层:假设已经选对方法时,它能否改善证据排名;面对混合 Query 时,路由是否把问题送到了正确分支。
还可以做逐步消融。先只运行原 Query,再分别加入重写、扩写和 HyDE,最后测试路由组合。每一步都保存新增找回的正确证据、被挤出候选的证据、近重复和额外耗时。这样能回答“是哪一种处理修好了哪类问题”,也能发现三种方法全部串联后是否只是增加成本。
对于意图保持,可以设置硬性不变量:产品编号、错误码、时间、地区、对象与否定不得无依据改变;扩写可以新增同义表达,却不能覆盖原 Query;HyDE 文本永远不能成为最终引用。硬性不变量先拦截方向性错误,Recall@K 等排序指标再衡量收益,两者不能相互抵消。
评测还要保留无处理基线和成本账。每个分组记录额外模型调用、处理耗时、多路候选数与去重后数量,才能判断新增召回是否值得。某种方法若只在很少一类问题上有效,就应缩小触发范围,而不是让所有请求承担延迟。
线上发现坏样本时,先根据日志重放原 Query、历史选择、路由结果和各路候选,再修改规则。若只保留最终答案,团队无法知道是重写改错、扩写带偏、HyDE 假设错误,还是后续排序没有选中正确证据。
还要检查不需要处理的问题。
一批明确标题和编号 Query 应该作为负向样本,验证路由不会滥用改写。只测试困难问题,会让系统倾向于给所有输入增加复杂处理,却看不到清楚问题被改坏的代价。
每次改动提示词、词典或路由规则后,应同时回放需要重写与不需要重写的两组问题。这样才能判断系统是在扩大能力,还是把风险转移到原本稳定的查询上。

既要看正确证据是否上升,也要检查原意有没有被改坏、候选是否重复,以及无答案风险有没有增加。
自动生成 Query 可以帮助扩充初稿,但参考意图和证据仍需核对。否则改写模型生成的问题与评测标准来自同一种偏差,很容易得到虚假的好结果。
重写、扩写与 HyDE 被追问时怎么选
不要按名词逐个背定义。先说当前 Query 缺的是上下文、表达覆盖还是文档式语义,再说明对应分支的偏差来源和回退路径。
重写和扩写最核心的区别是什么?
重写通常把一个问题变成更完整的一句话,重点是准确表达原意。扩写生成多个表达或子查询,重点是覆盖不同文档措辞。
改写没有结果时,为什么要退回原问题?
因为改写可能补错实体或删掉关键字。原 Query 是用户原始意图的保底路线,不能被不可逆覆盖。
扩写结果怎样合并?
按稳定 Chunk ID 去重,保留候选来自哪些扩写 Query,再统一融合或重排。这样能控制重复,也方便排查噪声来源。
HyDE 的假设答案错了,为什么有时还能检索?
因为它借用的是完整陈述的语义表示,不要求每个事实都正确。但错误假设仍可能带偏召回,所以必须保留原 Query 并只使用真实文档作为最终证据。
哪些 Query 不应默认改写?
明确标题、错误码、产品编号、法规条款和其他精确实体。这些问题的原词本身就是最强检索信号。
三种方法能不能全部串起来?
技术上可以,工程上不应默认如此。每增加一路都会增加延迟、候选与偏差来源。先判断问题缺口,再启用最小必要处理。
用“路由—回退—证据”收住 Query 优化
把三种方法放进同一条可控链路时,重点不是全部串联,而是说明何时启用、怎样保留原意,以及最终证据从哪里来:
Query 重写、扩写和 HyDE 解决的不是同一个问题。重写用于纠错和补全指代,把依赖历史的问题恢复成独立 Query;扩写生成同义表达或子查询,覆盖文档中的不同措辞;HyDE 先生成假设文档再做向量检索,适合短而抽象、问句和文档陈述差异大的问题。
三种方法都会带来偏差。重写可能补错实体或丢否定,扩写可能增加噪声与重复,HyDE 可能用错误假设把召回带偏。因此我会按 Query 类型路由,始终保留原问题。精确编号和标题优先走原词检索,高歧义问题请求澄清,处理后无结果则回退原 Query,或者让两路并行后按稳定 ID 合并。
评测时按指代、同义、否定、精确词、短 Query 和无答案分组,比较原始、重写、扩写和 HyDE 的 Recall@K 与正确证据名次,同时检查意图保持、候选重复、额外耗时和强行回答风险。最终答案只使用真实检索证据,不能把 HyDE 的假设文本当事实。
收尾要让面试官看见一次明确决策:为什么这类 Query 需要处理,处理后怎样发现原意被改坏,又怎样退回原问题。没有与简历对应的实测结果,就只说评测方法和待验证边界,不把教学示例包装成真实收益。