文章摘要
RAG召回效果差时,很多团队第一反应是“多生成几个查询”。但Multi-Query、HyDE和问题分解解决的并不是同一种缺陷:Multi-Query主要缓解用户措辞与文档表达不一致;HyDE通过生成一段假设性文档,将极短或抽象问题映射到更接近语料的Embedding空间;问题分解则把需要多跳证据的复杂问题拆成多个可独立检索的子问题。
三种策略都可能提高Recall,但也会带来更多模型调用、更多向量检索、更大的候选集合、更高Reranker成本和更复杂的错误传播。HyDE生成的假设文档还可能带有虚构细节,问题分解可能遗漏全局约束,Multi-Query则容易产生大量同义重复Query。
Spring AI的模块化RAG已经提供RewriteQueryTransformer和MultiQueryExpander等查询处理组件,并支持通过RetrievalAugmentationAdvisor组合检索流程。本文从召回缺陷、输入类型、语料特征、延迟、Token成本、可解释性、权限、评测和降级等维度,给出三种策略的适用边界、组合方法与生产落地决策树。
一、先确定你要修复的到底是什么问题
查询增强不是通用增益开关。
在引入任何策略前,先把失败分成以下类型。
1. 措辞不匹配
用户:
为什么账户一直转圈?文档:
登录会话刷新失败导致前端持续加载这是表达角度不同,Multi-Query通常有效。
2. 用户问题过短或过于抽象
用户:
渠道控盘文档是完整行业方案,包含:
- 经销商流向;
-终端动销;
-防窜货;
-费用核销;
-扫码风控。
短Query的Embedding信息不足,HyDE可能有帮助。
3. 多跳问题
某产品在华东区域销量下降,是渠道库存上升、终端覆盖下降,还是活动核销异常导致?需要分别检索:
- 销量;
-渠道库存;
-终端覆盖;
-活动核销。
这是问题分解场景。
4. 精确Token丢失
HTTP 429 ZX-4100B 合同编号HT-2026-0081这不是Multi-Query或HyDE优先解决的问题,而应先保护原始Token并使用Sparse检索。
5. 索引本身缺失或错误
如果正确文档根本没有入库,查询增强只会更昂贵地返回错误结果。
二、Multi-Query的工作方式
Multi-Query由LLM将一个问题生成多个语义角度不同的查询。
原问题 ↓ Query 1:从业务术语角度改写 Query 2:从技术症状角度改写 Query 3:从原因诊断角度改写 ↓ 分别检索 ↓ 去重与融合Spring AI提供MultiQueryExpander,可以设置生成数量,并默认将原始Query包含在扩展列表中。
概念代码:
MultiQueryExpanderexpander=MultiQueryExpander.builder().chatClientBuilder(chatClientBuilder).numberOfQueries(3).includeOriginal(true).build();List<Query>queries=expander.expand(newQuery(userQuery));三、Multi-Query最适合什么场景
1. 用户表达多样
同一业务概念有多种叫法:
防窜货 窜货预警 跨区流通 异地扫码 渠道异常流向2. 文档语言与用户语言不同
用户说口语,文档写正式术语。
3. 召回需要多个角度但不需要多跳推理
例如“订单为什么无法取消”,可能需要:
- 状态限制;
-时间限制;
-权限限制;
-库存占用。
4. 查询较完整但单次Embedding召回不稳定
Multi-Query通过多个向量入口扩大候选。
四、Multi-Query的主要风险
1. 查询同质化
模型生成:
如何取消订单? 订单取消方法是什么? 怎样进行订单取消?三条几乎相同,只增加成本。
2. 实体与约束被改坏
生成Query可能修改:
- 编号;
-否定;
-时间;
-权限范围。
每条扩展Query都必须经过保护校验。
3. 候选集合膨胀
3条Query、每条Top 30:
最多90个候选Reranker和上下文裁剪成本会显著增加。
4. Recall增加但Precision下降
扩展角度过宽会引入大量看似相关但不回答问题的文档。
五、Multi-Query的生产控制
publicrecordMultiQueryPolicy(intmaximumQueries,inttopKPerQuery,booleanincludeOriginal,doubleminimumDiversity,intmaximumFusedCandidates,Durationdeadline){}生成后执行:
实体保护 ↓ 语义去重 ↓ 预算裁剪 ↓ 并行检索 ↓ 稳定融合查询多样性可以用Embedding相似度约束:
if(cosineSimilarity(queryAEmbedding,queryBEmbedding)>0.95){removeDuplicate(queryB);}六、HyDE的工作方式
HyDE即Hypothetical Document Embeddings。
流程:
用户问题 ↓ LLM生成一段“可能回答该问题的假设文档” ↓ 对假设文档生成Embedding ↓ 在真实语料向量空间中检索相似文档重要区别:
假设文档不是最终答案, 也不应该直接作为证据交给用户。它只是检索桥梁。
例如用户输入:
渠道控盘HyDE可能生成:
渠道控盘通常通过经销商流向追踪、终端库存监控、区域防窜货、费用核销和扫码数据分析实现……这段文本包含更丰富的领域词汇,Embedding更容易靠近相关行业方案文档。
七、HyDE最适合什么场景
1. Query极短
RAG幻觉 渠道动销 设备离线2. 文档是长篇专业叙述
用户只给概念,文档却是说明书、方案书或论文。
3. 没有标注数据进行Retriever微调
HyDE原始研究针对零样本稠密检索,使用生成的假设文档作为中间表示。
4. 用户不知道领域术语
模型可以把用户描述扩展为语料中常见的专业表达。
八、HyDE的主要风险
1. 虚构细节影响检索方向
假设文档可能生成不存在的:
- 产品名;
-法规;
-版本;
-原因;
-结论。
虽然HyDE只用于Embedding,但虚构实体仍可能把向量推向错误区域。
2. 不适合精确编号查询
ZX-4100B错误码E1027假设文档会稀释关键Token。
3. 成本高于普通改写
假设文档通常比Query长,生成与Embedding成本更高。
4. 可解释性弱
需要保存假设文档、模型版本和检索结果,才能解释为什么召回某些文档。
九、HyDE的安全实现
publicrecordHyDEQuery(StringrawQuery,StringhypotheticalDocument,Set<String>preservedEntities,StringmodelProfile,StringpromptVersion){}Prompt必须约束:
1. 不得发明具体编号、人名、金额或日期。 2. 只生成领域相关的通用说明文本。 3. 保留原始Query中的全部关键实体。 4. 不输出最终结论。 5. 不将假设文档展示为真实证据。检索时建议:
原始Query向量检索 +HyDE向量检索 +原始Query稀疏检索而不是只使用HyDE。
十、问题分解的工作方式
问题分解把一个复合问题转换成多个子问题。
原始: 为什么某区域销售下降? 子问题: 1. 该区域出货量变化是什么? 2. 经销商库存是否上升? 3. 活跃终端数是否下降? 4. 促销核销是否异常?每个子问题独立检索,随后聚合证据。
十一、问题分解适合什么场景
1. 多跳证据
最终结论依赖多份文档或多个数据源。
2. 比较问题
方案A与方案B在成本、延迟和安全方面有什么差异?3. 原因分析
需要分别查找多个可能因素。
4. 需要跨系统检索
- 知识库;
-业务数据库;
-指标平台;
-工具接口。
5. 复杂合规判断
需要同时满足多个条件。
十二、问题分解的主要风险
1. 子问题遗漏全局约束
原问题:
仅分析华东区域2026年第二季度的经销商。某个子问题可能丢掉:
- 华东;
-2026年第二季度;
-经销商。
2. 子问题之间重复
多个子问题可能检索同一证据,浪费成本。
3. 错误传播
分解错误后,后续检索再准确也没有意义。
4. 需要聚合逻辑
最终答案必须说明:
- 哪个子结论来自哪些证据;
-子结论是否互相冲突;
-证据是否完整。
5. 延迟高
如果串行执行:
分解LLM +N次检索 +N次Rerank +聚合LLMP95会明显上升。
十三、问题分解的数据模型
publicrecordDecomposedQueryPlan(StringoriginalQuery,List<SubQuery>subQueries,Set<String>globalConstraints,AggregationStrategyaggregationStrategy,intmaximumParallelism,Durationdeadline){}publicrecordSubQuery(StringsubQueryId,Stringtext,Set<String>inheritedConstraints,Set<String>requiredEvidenceTypes,intpriority,booleanmandatory){}每个子问题必须显式继承全局约束。
十四、三种策略核心对比
| 维度 | Multi-Query | HyDE | 问题分解 |
|---|---|---|---|
| 主要目标 | 扩展表达角度 | 改善短Query语义表示 | 拆解多跳任务 |
| 典型输入 | 单一但措辞多样 | 过短、抽象 | 复合、多条件 |
| 检索次数 | 多次 | 通常原始+HyDE | 每个子问题一次或多次 |
| 额外生成 | 短Query列表 | 较长假设文档 | 子问题计划 |
| 延迟 | 中 | 中 | 高 |
| Token成本 | 低到中 | 中 | 中到高 |
| 实体风险 | 中 | 中高 | 高 |
| 可解释性 | 较好 | 中 | 较好但链路长 |
| 适合Sparse | 原始Query适合 | 不适合直接替代 | 每个子问题可适配 |
| 最常见失败 | 同义重复 | 虚构方向 | 遗漏约束 |
十五、不要按“复杂度越高越先进”选型
错误思路:
问题分解最复杂 → 能力最强 → 所有请求都使用正确思路:
使用解决当前缺陷所需的最小策略简单FAQ使用问题分解会增加:
- 延迟;
-成本;
-随机性;
-排障难度。
十六、推荐决策树
Query是否包含精确编号、型号或错误码? ├─ 是:原始Query+Sparse优先,必要时受控改写 └─ 否:继续 问题是否包含多个独立子目标或需要多跳证据? ├─ 是:问题分解 └─ 否:继续 Query是否过短、抽象,且语料是长篇专业文本? ├─ 是:原始Query+HyDE └─ 否:继续 主要问题是否是用户措辞与文档表达不一致? ├─ 是:Multi-Query └─ 否:原始Query或普通Rewrite十七、可以组合,但必须分层
推荐组合一:
原始Query +Multi-Query +Sparse/Dense +RRF推荐组合二:
短抽象Query +HyDE +原始Query Dense +原始Query Sparse +Rerank推荐组合三:
复杂问题分解 ↓ 每个子问题根据特征选择Raw/Multi-Query/HyDE ↓ 子问题内融合 ↓ 跨子问题证据聚合禁止无上限组合:
5个子问题 × 5个Multi-Query × 原始+HyDE × TopK 50这会产生数千候选和不可接受成本。
十八、统一策略路由器
@ServicepublicclassQueryEnhancementStrategyRouter{publicQueryEnhancementStrategyroute(QueryFeaturesfeatures,RetrievalBudgetbudget){if(features.exactTokenDensity()>0.5){returnQueryEnhancementStrategy.RAW_HYBRID;}if(features.multiHopScore()>0.75&&budget.allowDecomposition()){returnQueryEnhancementStrategy.DECOMPOSE;}if(features.abstractnessScore()>0.8&&features.queryLength()<20&&budget.allowHyde()){returnQueryEnhancementStrategy.HYDE_AND_RAW;}if(features.ambiguityScore()>0.55&&budget.allowMultiQuery()){returnQueryEnhancementStrategy.MULTI_QUERY;}returnQueryEnhancementStrategy.RAW_ONLY;}}十九、预算模型
publicrecordRetrievalBudget(intmaximumGeneratedQueries,intmaximumSearchRequests,intmaximumCandidates,intmaximumRerankDocuments,intmaximumInputTokens,BigDecimalmaximumCost,Durationdeadline){}每种策略估算成本:
publicrecordStrategyCostEstimate(intgenerationCalls,intembeddingCalls,intretrievalCalls,intrerankCandidates,intestimatedTokens,BigDecimalestimatedCost,DurationestimatedLatency){}预算不足时按顺序降级:
问题分解 → Multi-Query → Rewrite → Raw Hybrid二十、候选融合
多查询召回不能简单拼接。
常见方法:
- 去重后取最高分;
-加权分数;
-RRF;
-DBSF;
-统一Reranker。
RRF示例:
score(document)=Σ1/(k+rank_i(document))实现时稳定Key应包含:
tenant_id +document_id +document_version +chunk_id不能只按正文Hash去重,否则不同版本可能被错误合并。
二十一、权限不能在增强之后补
Multi-Query、HyDE和问题分解都不能扩大用户权限。
每一次检索必须携带同一个:
AccessContext +Metadata Filter +ACL不能让子问题生成:
查询所有客户合同然后再期待答案阶段不泄露。
二十二、如何评测真实增益
指标至少包括:
Recall@K MRR NDCG Precision@K required_document_recall forbidden_document_rate claim_support_rate P50/P95延迟 单请求成本 候选数量 Reranker输入量按查询类型分Slice:
- 短Query;
-精确Token;
-多跳;
-口语;
-多轮;
-高风险;
-无证据。
全局平均提升不能掩盖精确编号查询退化。
二十三、PoC设计
同一数据集运行:
Baseline:Raw Hybrid Candidate A:Multi-Query Candidate B:Raw+HyDE Candidate C:Decomposition记录:
每条Case召回文档 生成Query 假设文档 子问题 融合排名 Rerank结果 最终答案 成本 延迟概率性生成至少重复3次。
二十四、推荐上线策略
阶段一:影子
只记录候选策略,不影响用户。
阶段二:低风险Query
先开放:
- FAQ;
-无精确编号;
-无副作用;
-无权限敏感。
阶段三:按Slice扩大
分别观察:
- Recall提升;
-Precision下降;
-成本;
-延迟;
-错误实体。
阶段四:保留策略开关
rag:query-enhancement:multi-query-enabled:truehyde-enabled:falsedecomposition-enabled:false每种策略独立回滚。
二十五、常见错误
所有Query都生成5个变体 只使用增强Query,丢弃原始Query HyDE假设文档直接作为真实证据 问题分解不继承全局过滤条件 候选不去重直接送Reranker 不限制查询数量和并发 只看Recall,不看Precision与成本 没有保存生成Query,无法复现二十六、上线前检查清单
□ 已明确当前召回缺陷类型 □ 精确Token查询优先保留原始Query □ Multi-Query执行语义去重 □ HyDE不作为最终证据 □ HyDE Prompt禁止发明具体实体 □ 子问题继承全部全局约束 □ 所有分支使用同一AccessContext □ 查询、检索和候选数量均有预算上限 □ 候选使用稳定文档Key去重 □ 融合后再进入统一Reranker □ 每种策略独立可关闭和回滚 □ 评测同时检查Recall、Precision、延迟和成本 □ 高风险Slice单独设置门禁总结
Multi-Query、HyDE和问题分解分别解决:
表达不一致 语义表示不足 复杂问题不可一次检索推荐原则是:
精确查询保留Raw 表达多样使用Multi-Query 短抽象查询尝试HyDE 多跳任务使用问题分解真正成熟的RAG系统不会固定使用一种查询增强策略,而是根据Query特征、风险、预算和真实评测结果动态选择,并始终保留原始Query作为安全基线。