多跳问题的拆解与回填:让RAG答对「对比类」问题的工程方法

📅 2026/4/26 ✍️ 小文 📖 约 1 分钟

为什么问「A和B哪个适合我」时RAG总是答非所问?拆开多跳检索的三层结构,给出查询拆解、子答案回填、交叉验证与合成提示的完整实现思路。

单跳检索死在什么地方

用户问:“我们公司 50 人,主要做跨境 B2B,应该选 Coze、Dify 还是 n8n?”

这不是一个查询,是三个查询加一次综合判断。如果用这段原话去做向量检索,命中的会是”Coze 介绍""Dify 介绍""n8n 介绍”三个彼此不相关的片段,模型拿到三份产品简介,写出一段谁都没错的废话。

多跳(multi-hop)问题的失败,通常不在模型,在检索阶段就把问题结构丢了。

三层结构:拆解 → 并行 → 回填

第一层:识别问题类型并拆解

不是所有问题都需要多跳。先做分类:

类型例子是否需要拆解
事实型”Dify 支持私有化部署吗”否
对比型”A 和 B 哪个更适合我”是,按维度拆
条件型”预算 5 万,选哪个”是,先查约束再匹配
递进型”A 的团队做的另一个产品是什么”是,串行依赖
聚合型”这个领域有哪些主流方案”部分,需要多轮补全

拆解的关键是按维度而不是按实体。对比型问题应该拆成”成本""部署方式""上手难度""扩展性”四个维度,每个维度去检索两个产品的信息——这样才能形成真正的对比,而不是两段简介并列。

第二层:并行检索与结构化抽取

每个子问题独立检索,但不要把检回的原文直接给最终模型。中间加一步抽取:对每个子问题,产出一个结构化结论。

{
  "dimension": "部署方式",
  "options": {
    "Coze": "SaaS 为主,开源版功能受限",
    "Dify": "支持私有化,社区版可自托管",
    "n8n": "完全可自托管"
  },
  "confidence": 0.82,
  "sources": ["doc-1231", "doc-8842"]
}

这一步的价值:把 3 份 2000 字的文档压缩成 300 字的结构化事实,误差不会在合成阶段被放大,而且可以逐维度追溯来源。

第三层:合成前先查缺口

得到结构化结果后,做一个”完整性检查”:哪些维度有选项缺失?哪些置信度低于 0.6?

缺口处理有两条路:

  • 补检索:针对缺失的维度重新生成查询(“n8n 定价 2026”),再跑一轮
  • 显式声明:补不到就在答案里说”关于 X,公开资料不足”

第二条比沉默和编造都重要。用户能接受”不知道”,不能接受”编的”。

容易忽略的一点:递进型问题的时间顺序

“OpenAI 的前首席科学家后来创办的公司叫什么”这类问题,两个跳之间有严格的先后依赖。并行检索会失败,因为第二个查询必须等第一个的答案。

处理方式:在拆解阶段标注依赖关系,形成一个 DAG,按拓扑序执行。实现上不需要复杂框架,一个带依赖检查的循环就够:

pending = {q for q in subqueries}
while pending:
    ready = [q for q in pending if deps_satisfied(q)]
    results = run_parallel(ready)
    pending -= set(ready)

合成阶段的提示词要挡住三个坏习惯

最终合成时,模型最容易犯三个错:

  1. 平均主义:把两个产品说得一样好。要在提示里要求”必须给出明确的推荐条件和适用边界”。
  2. 忽略用户约束:用户说 50 人、跨境 B2B,答案却完全不提这些条件。要把约束单独列出来并要求逐条回应。
  3. 伪造缺失信息:某个维度没查到,就自己补一个”通常来说”。要显式允许”资料不足”。

一份可用的合成提示骨架:

以下是用户问题与结构化检索结果。
要求:
1) 先用一句话给出结论与推荐
2) 逐维度对比,每个结论后标注 [来源ID]
3) 若某维度 confidence < 0.6,标注"资料有限"
4) 最后给出"什么情况下不选这个方案"
5) 不得引入检索结果以外的事实

第 4 条特别有用——强迫模型思考反面,往往能暴露出它其实没把握。

成本与收益的权衡

多跳方案的成本是单跳的 2–4 倍(查询数 × 模型调用)。所以必须做前置判断:

  • 先用一个极小的分类器(甚至规则)判断是否为多跳,单跳问题走原路
  • 拆解阶段用小模型,合成阶段才用大模型
  • 缓存”维度 → 结构化结果”,同一实体的重复查询可直接复用

经验数据:在对比类问题占 30% 的客服场景里,引入多跳后这类问题的满意度提升了 25 个点,整体成本上升 40%。这个交换通常值得——因为这类问题正是用户最不满意的部分。

小结

多跳不是”多检索几次”。它的核心是把问题的结构显式化:拆成维度、并行取证、结构化中间结果、查缺口、再合成。做不到中间的结构化,检索多少次都只是把噪音堆得更高。

📤 分享到