RAR 学习之RAG 查询 优化技术学习指南

0 阅读24分钟

副标题:从入门到精通


📖 本书简介

本书系统地介绍了 RAG(检索增强生成)系统中的查询优化技术,从基础概念到高级应用,从理论原理到实践代码,帮助读者全面掌握提升 RAG 检索效果的核心技术。

🎯 适合读者

  • 初学者:想了解 RAG 检索优化的入门读者
  • 开发者:正在构建 RAG 系统的工程师
  • 面试官:想了解 RAG 技术面试要点的招聘者
  • 研究者:关注信息检索与 LLM 结合的研究人员

📚 核心内容

  1. Query Rewriting(查询重写) - 让问题更清晰
  2. HyDE(假设文档嵌入) - 用答案搜答案
  3. Multi-Query(多查询检索) - 多角度问问题
  4. 评估指标 - MRR、NDCG 详解
  5. 结果融合 - RRF 倒数排名融合
  6. 五大策略 - 速度/召回/平衡/成本/质量优先

💡 本书特色

  • 12 岁能听懂:复杂概念用比喻和故事解释
  • 面试导向:每个章节都有面试回答模板
  • 代码实战:完整的 Python 实现示例
  • 成本分析:详细的性能与成本对比
  • 策略选择:不同场景的最优方案

版本信息

  • 版本:v1.0
  • 整理日期:2026-04-13

================================================================================

RAG 查询优化技术 学习指南 目录

第一部分:基础概念

第 1 章 Query Rewriting(查询重写)

文件: 02-query-rewriting.md

  • 通俗理解(12 岁能听懂)
  • 三种主要方法
  • 为什么需要它
  • 面试回答指南(3 分钟版本)
  • 技术架构
  • 常见追问

第 2 章 评估指标:MRR 和 NDCG

文件: 03-evaluation-metrics.md

  • MRR 通俗理解与计算
  • NDCG 通俗理解与计算
  • MRR vs NDCG 对比
  • 面试回答模板

第二部分:核心技术

第 3 章 HyDE(假设文档嵌入)

文件: 04-hyde.md

  • 通俗理解(12 岁能听懂)
  • 面试回答指南
  • 为什么有效(4 个原因)
  • 反直觉的事实
  • 适用场景
  • 与 Query Rewriting 对比

第 4 章 Multi-Query(多查询检索)

文件: 05-multi-query.md

  • 通俗理解(12 岁能听懂)
  • 核心概念拆解
  • 与 Query Rewriting 对比
  • 面试回答指南
  • 优势与成本分析(6-8 倍详解)
  • 优化策略

第 1 章 Query Rewriting(查询重写)

1.1 通俗理解(12 岁能听懂)

问题从这里开始 📚

想象你有一个特别聪明的图书管理员朋友,但你不会说话,总是说不清楚自己想要什么书。

假设你想找关于"苹果"的资料,但你只说了两个字:

"苹果"

图书管理员会想:

  • 是要找苹果水果的营养资料?
  • 还是要找苹果公司的产品?
  • 还是要找苹果手机的评测?

你说的话太简单了,图书管理员帮不到你。

Query Rewriting 就像一个"翻译官" 🔄

查询重写的作用就是:把你说的简单问题,翻译成清楚的问题

你说的重写后变成
"苹果""苹果公司的历史和主要产品"
"怎么胖了""如何通过饮食和运动健康增重"
"python list""Python 编程语言中列表的使用方法"

三种主要方法 🔧

1. 补全信息

把缺少的部分补上。

  • 你说:"怎么变强?"
  • 重写:"如何通过锻炼让肌肉变强?"
2. 换个说法

用更容易理解的方式说同一件事。

  • 你说:"AI 咋回事?"
  • 重写:"人工智能的基本原理是什么?"
3. 拆开问

一个大问题拆成几个小问题。

  • 你说:"怎么学好编程?"
  • 重写:
    • "编程入门需要学什么?"
    • "如何提高编程能力?"
    • "有哪些编程学习资源?"

为什么需要它?🎯

在 RAG(检索增强生成)系统里,如果查询不清楚,就找不到正确的资料

就像一个搜索引擎:

  • 你搜 "python" → 可能找到蛇的资料 🐍
  • 重写后搜 "Python 编程语言教程" → 找到正确的编程资料 💻

查询重写让你的问题更容易被搜索引擎理解,找到更准确的答案。

一张图总结

原始问题 → [查询重写] → 清晰的问题 → [搜索] → 更好的答案
   ❌           ✅           ✅          ✅         ✅
  模糊       翻译一下     容易搜索    找到资料   解决问题

就像你有一个会说话的朋友,帮你把磕磕巴巴的话变成清楚的问题!


1.2 面试回答指南

回答框架(3 分钟版本)

1️⃣ 先给定义(15 秒)

"Query Rewriting 就是把用户的原始查询转换成更适合检索的形式,目的是提高检索的准确率。"

2️⃣ 说明为什么需要(30 秒)

"用户查询通常有两个问题:

  1. 太简短 —— 比如只搜 'python',不知道是蛇还是编程语言
  2. 表述模糊 —— 比如 '怎么变强',缺少上下文

直接拿这种查询去检索,召回的文档质量会很差,后续生成也会受影响。"

3️⃣ 讲核心技术(1 分钟)

"主要有三种方法:

① 查询扩展(Query Expansion)

  • 添加同义词或相关词,比如 '手机' → '智能手机 评测 推荐'
  • 技术:可以用 LLM 生成、可以用词向量找近义词

② 查询改写(Query Reformulation)

  • 换个更清晰的说法,比如 'AI 咋回事' → '人工智能基本原理'
  • 技术:通常用 LLM 做 paraphrase

③ 查询分解(Query Decomposition)

  • 把复杂问题拆成多个子问题,比如 '对比 iPhone 和华为'
    • 'iPhone 的主要特点'
    • '华为手机的主要特点'
  • 技术:LLM + 提示词工程"
4️⃣ 结合实际应用(30 秒)

"在 RAG 系统里,查询重写通常放在检索之前

用户查询 → [Query Rewriting][检索][生成]

我在项目里用过 LLM 来做重写,比如用这样一个 prompt:

将以下查询改写成更适合搜索引擎的形式:
原始查询:{query}
要求:补充上下文,使用明确术语

效果提升很明显,尤其是处理简短查询时。"

5️⃣ 加分项(可选,展示深度)

"进阶做法还有:

  • 多查询检索:生成 3-5 个变体并行检索,然后去重融合
  • 用户历史感知:结合用户之前的查询补充上下文
  • 假设文档嵌入(HyDE):让 LLM 生成一个假设答案,用答案的嵌入去检索"

1.3 面试小贴士

要点说明
先给定义让面试官知道你真的懂
结构化用 1、2、3 分点说,显得有条理
结合实际说一个你用过的具体方法/项目
不要背概念用自己的话讲,可以举例

1.4 常见追问

Q: 怎么评估查询重写的效果?

"看检索阶段的指标,比如 MRR、NDCG,或者看最终答案质量(人工评估或 LLM-as-a-judge)"

Q: 重写会不会引入噪声?

"会,所以要控制重写幅度。可以用少样本提示让 LLM 保持原意,或者设置置信度阈值,低置信度时用原始查询"

Q: 和 RAG 其他优化方法比怎么样?

"查询重写是查询侧优化,和索引侧优化(比如 chunk 策略、元数据过滤)是互补的,可以一起用"


1.5 技术架构

┌─────────────┐     ┌──────────────────┐     ┌──────────┐     ┌──────────┐
│ 用户查询     │ →   │ Query Rewriting  │ →   │  检索器   │ →   │  生成器   │
│ (原始问题)   │     │ (查询重写模块)    │     │ (Retriever)│   │ (Generator)│
└─────────────┘     └──────────────────┘     └──────────┘     └──────────┘
                           │
                           ├──→ 查询扩展 (同义词、相关词)
                           ├──→ 查询改写 (Paraphrase)
                           └──→ 查询分解 (多子问题)

1.6 核心要点总结

关键概念

  • 定义:将原始查询转换为更适合检索的形式
  • 目标:提高检索准确率
  • 位置:检索前的预处理步骤

三种方法

方法做法示例
查询扩展添加同义词"手机" → "智能手机 评测 推荐"
查询改写换说法"AI 咋回事" → "人工智能基本原理"
查询分解拆问题"对比 A 和 B" → "A 的特点"+"B 的特点"

面试关键词

  • 翻译官比喻
  • 检索前优化
  • 补充上下文
  • LLM 生成

================================================================================

第 2 章 评估指标:MRR 和 NDCG

2.1 MRR(平均倒数排名)

通俗理解

MRR 只关心:第一个正确答案排在第几名?

计算例子

假设有 3 个用户查询,每个查询的检索结果如下(✓ 表示正确答案):

查询排名 1排名 2排名 3排名 4排名 5第一个正确答案的排名倒数 (1/排名)
查询 131/3 ≈ 0.333
查询 211/1 = 1.0
查询 321/2 = 0.5

MRR = (0.333 + 1.0 + 0.5) ÷ 3 = 1.833 ÷ 3 ≈ 0.611

公式

MRR=1Qi=1Q1ranki\text{MRR} = \frac{1}{|Q|} \sum_{i=1}^{|Q|} \frac{1}{\text{rank}_i}

其中:

  • Q|Q| = 查询总数
  • ranki\text{rank}_i = 第 i 个查询的第一个正确答案的排名

特点

优点缺点
计算简单,好理解只关心第一个正确答案
适合只要找到一个答案就足够的场景不关心后面还有多少正确答案
值域 [0, 1],1 最好如果前 10 个都没答案,MRR=0

适用场景

  • 问答系统(用户只需要一个正确答案)
  • 客服机器人
  • 事实性查询("珠穆朗玛峰多高")

2.2 NDCG(归一化折损累计增益)

通俗理解

NDCG 关心两件事:

  1. 正确答案有没有排在前面
  2. 越相关的答案是不是排得越靠前?

核心思想

NDCG 有三个关键概念:

① 相关性打分 (Gain) 给每个结果打分(0-3 分):

  • 3 分 = 非常相关
  • 2 分 = 比较相关
  • 1 分 = 有点相关
  • 0 分 = 不相关

② 折损 (Discounted) 排名越靠后,价值越低。公式:

折损后的增益 = 相关性得分 / log₂(排名 + 1)
排名折损因子说明
11.0无折损
20.63打 6 折
30.5打 5 折
50.35打 35 折
100.21打 2 折

③ 归一化 (Normalized) 除以"理想情况下的最高分",让结果在 0-1 之间。

完整计算例子

用户搜 "python 教程",检索结果和相关性打分:

排名文档相关性 (0-3)折损因子折损后增益
1Python 入门教程31.03.0
2Python 进阶20.631.26
3Python 网站30.51.5
4Python 新闻10.390.39
5蟒蛇饲养指南00.320

DCG@5 = 3.0 + 1.26 + 1.5 + 0.39 + 0 = 6.15

理想排序(IDCG) 应该是把最相关的排前面:

排名理想相关性折损因子折损后增益
131.03.0
230.631.89
320.51.0
410.390.39
500.320

IDCG@5 = 3.0 + 1.89 + 1.0 + 0.39 + 0 = 6.28

NDCG@5 = DCG / IDCG = 6.15 / 6.28 = 0.98

(越接近 1 越好,0.98 说明排序非常接近理想状态)


2.3 MRR vs NDCG 对比

维度MRRNDCG
关心什么第一个正确答案所有结果的相关性 + 排序
相关性分级只有对/错可以有 0-3 多级
适用场景问答、事实查询搜索、推荐
计算复杂度简单较复杂
如果第一个就对了MRR=1NDCG 可能 <1(后面排错了)

2.4 面试回答模板

如果面试官问:"怎么评估 RAG 的检索效果?"

"检索阶段的评估主要看两个指标:

MRR(平均倒数排名):只关心第一个正确答案排第几名。适合问答系统,因为用户通常只需要一个正确答案。计算公式是 1/排名,MRR 越接近 1 越好。

NDCG(归一化折损累计增益):同时考虑相关性和排序质量。它假设:① 相关性有等级(0-3 分),② 排名越靠后价值越低。NDCG 也适合搜索场景,因为用户会浏览前几条结果。

在 RAG 里,如果更关注答案质量,用 MRR;如果更关注检索文档的整体相关性,用 NDCG。实际项目中,我通常会同时监控这两个指标。"


2.5 一张图总结

┌─────────────────────────────────────────────────────────────┐
│                  MRR vs NDCG 对比                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  MRR(平均倒数排名)                                         │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  只关心:第一个正确答案排第几?                       │   │
│  │  公式:1/排名                                        │   │
│  │  场景:问答系统、事实查询                            │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  NDCG(归一化折损累计增益)                                  │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  关心两件事:                                        │   │
│  │  ① 正确答案有没有排前面?                            │   │
│  │  ② 越相关的是不是越靠前?                            │   │
│  │  场景:搜索、推荐                                    │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  选择建议:                                                  │
│  ├── 用户只需要一个答案 → MRR                               │
│  ├── 用户会浏览多个结果 → NDCG                              │
│  └── 实际项目 → 两个都监控                                  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

2.6 核心要点总结

MRR 关键点

  • 只看第一名:只关心第一个正确答案的排名
  • 计算简单:1/排名,然后求平均
  • 适合问答:用户只需要一个正确答案的场景

NDCG 关键点

  • 看全部:考虑所有结果的相关性
  • 看排序:越相关的应该越靠前
  • 多级相关:可以有 0-3 分的细致打分

面试关键词

  • 倒数排名
  • 折损累计增益
  • 相关性分级
  • 排序质量

================================================================================

第 3 章 HyDE(假设文档嵌入)

3.1 通俗理解(12 岁能听懂)

一个故事

情景 1:直接去找

你想找一本关于**"恐龙"**的书,跑到图书馆对图书管理员说:

"恐龙"

图书管理员很困惑,可能给你一本恐龙图片书、恐龙知识书、或恐龙故事书——不一定准确。

情景 2:先描述答案,再去找

这次你先请一个很聪明的朋友帮你想象:

"一本讲恐龙的书,里面应该有:霸王龙、三角龙、侏罗纪、化石、灭绝原因..."

然后你拿着这个描述去找图书管理员:

"我想找一本讲霸王龙、三角龙、侏罗纪时期、恐龙化石和灭绝原因的书"

图书管理员马上就知道你要什么了!

HyDE 就是这个"聪明的朋友"。

HyDE 的核心思想

先编一个"假答案",再用这个"假答案"去找"真答案"

工作流程

你问:"恐龙怎么灭绝的?"
        ↓
   ┌────────────────────┐
   │  HyDE (聪明朋友)     │
   │  帮你编一个假答案:  │
   │ "恐龙灭绝是因为..."  │
   └────────────────────┘
        ↓
   用"假答案"去搜索
        ↓
   找到"真答案"的文档

3.2 面试回答指南(2-3 分钟版本)

1️⃣ 先给定义(20 秒)

"HyDE 是 Hypothetical Document Embeddings 的缩写,中文叫'假设文档嵌入'。

它的核心思想是:先让 LLM 生成一个假设的答案,再用这个假设答案的向量表示去检索真实文档

简单说,就是'用答案搜答案',而不是'用问题搜答案'。"

2️⃣ 说明为什么需要(30 秒)

"直接检索用户查询有两个问题:

① 问题空间和答案空间不一致

  • 用户问:'怎么减肥?'
  • 文档写:'控制饮食摄入,增加运动频率...'
  • '减肥'和'控制饮食'字面不同,但语义相关

② 查询太简短,信息密度低

  • 用户只搜 'python list',嵌入向量包含的语义信息很少

这两种情况都导致检索效果不好。"

3️⃣ 讲工作原理(40 秒)

"HyDE 的流程分三步:

第一步:生成假设答案 用 LLM 根据用户问题生成一个假设的答案文档。

第二步:嵌入假设答案 把假设答案转换成向量表示。

第三步:检索相似文档 用假设答案的向量去检索,找到语义相似的真实文档。

关键在于:即使假设答案内容不准确,它的语言风格、关键词、语义方向都和真实文档接近,所以向量表示也接近。"

4️⃣ 说明为什么有效(40 秒)

"HyDE 有效有三个原因:

① 填补语义鸿沟 把'问题空间'映射到'答案空间',让查询和文档在同一语义空间里。

② 利用 LLM 的预训练知识 LLM 读过大量文本,知道答案通常长什么样、包含哪些关键词。

③ 增加信息密度 假设答案比原始查询更长、更具体,嵌入向量包含更多语义信息。

实验表明,HyDE 在开放型问答、复杂查询上效果提升明显。"

5️⃣ 结合实际应用(20 秒)

"在我的 RAG 项目里,我试过 HyDE 的方法:

# 伪代码
hypothetical_doc = llm.generate(f"请为以下问题生成一个详细的答案:{query}")
query_embedding = embedder.encode(hypothetical_doc)
results = vector_db.search(query_embedding, top_k=5)

对于简短查询和复杂问题,检索质量确实有提升,但会增加一次 LLM 调用和一点延迟。"


3.3 HyDE 为什么有效?(深入理解)

原因 1:填补"问题 - 答案"的语义鸿沟

问题空间和答案空间不一样

问题答案
"怎么减肥?""控制饮食摄入,增加有氧运动..."
"手机坏了怎么办?""设备故障排除指南:重启..."
  • 问题用疑问句,答案用陈述句
  • 问题用口语,答案用专业术语
  • 问题说目标,答案说方法

HyDE 的做法

让 LLM 生成一个假设答案,把问题翻译成答案的风格:

问题:"怎么减肥?"
        ↓
   HyDE 翻译成答案风格:
   "减肥需要控制饮食摄入,增加有氧运动..."
        ↓
   用这个去搜,就能找到写"控制饮食"的文档了!

原因 2:利用 LLM 的世界知识

LLM 在预训练时读过大量文本,它知道:

  • 答案通常长什么样
  • 答案会用哪些关键词
  • 答案的结构是什么

即使 LLM 生成的假设答案内容不对,它的向量表示仍然能和真实答案对齐。

原因 3:缓解"词汇不匹配"问题

传统检索的问题

用户搜:"手机坏了怎么办" 文档里写:"设备故障排除指南"

手机 vs 设备坏了 vs 故障 —— 字面不一样。

HyDE 的做法

LLM 生成假设答案:

"如果手机出现故障,可以尝试以下方法:1. 重启设备 2. 恢复出厂设置 3. 联系售后服务中心..."

这个假设答案会同时包含用户的词和文档的词,起到词汇桥接的作用。

原因 4:增加查询的信息密度

原始查询嵌入向量信息量
"python list"低(就两个词)
"Python 中列表的使用方法,包括创建、访问、修改列表元素的示例代码"

HyDE 生成的假设答案更长、更具体,包含更多可嵌入的语义信息


3.4 一个反直觉的事实

HyDE 的假设答案不需要正确!

实验表明,即使假设答案内容是错的,只要:

  • 语言风格像答案
  • 关键词覆盖到位
  • 语义方向正确

就能有效提升检索效果。

这是因为嵌入空间里,相似主题的文档聚在一起,假设答案只需要落在正确的"语义区域"即可。


3.5 适用场景

适合不适合
问答型查询("什么是 X")导航型查询("某某官网")
开放性问题事实性查询("珠穆朗玛峰多高")
需要解释的问题简单检索("python 官网")

3.6 与 Query Rewriting 对比

方法做法比喻
Query Rewriting把问题说得更清楚翻译官
HyDE编一个答案去找答案美食家

两者都是让检索更准确,但方法不同!


3.7 常见追问及回答

Q: HyDE 和 Query Rewriting 有什么区别?

"两者目标相似但方法不同:

维度Query RewritingHyDE
做法改写问题生成答案
嵌入对象改写后的问题假设答案
核心优势让问题更清晰桥接问题 - 答案空间
延迟低(一次 LLM)中(一次 LLM+ 嵌入)

实际项目里可以一起用:先重写查询,再用 HyDE 检索。"

Q: 假设答案如果错了怎么办?

"这是 HyDE 反直觉的地方——假设答案不需要正确

因为我们要的不是答案内容,而是它的向量表示。只要:

  • 语言风格像答案
  • 关键词覆盖到位
  • 语义方向正确

就能找到正确的文档。实验表明,即使假设答案有事实错误,检索效果依然提升。"

Q: 怎么评估 HyDE 的效果?

"看检索阶段的指标:

  • MRR:第一个正确答案的排名
  • NDCG:整体排序质量
  • Recall@K:前 K 个结果里有多少正确答案

也可以看最终答案质量,用人工评估或 LLM-as-a-judge。

我在项目里对比过,HyDE 对简短查询的 MRR 提升约 10-15%。"


3.8 一张图总结

┌──────────────────────────────────────────────────────────┐
│                     HyDE 工作流程                         │
├──────────────────────────────────────────────────────────┤
│                                                          │
│  用户问题                    HyDE                        │
│  ┌─────────┐              ┌─────────────┐               │
│  │ "如何    │              │  假设答案:   │               │
│  │  减肥?"  │ ────────────→│  控制饮食、   │               │
│  └─────────┘   生成假设    │  增加运动... │               │
│                            └─────────────┘               │
│                                  ↓                       │
│  传统检索:问题 → 文档        用假设答案嵌入检索            │
│  鸿沟大 ❌                    鸿沟小 ✅                    │
│                                                          │
│  结果:找到"科学减重指南"等真实文档                        │
│                                                          │
└──────────────────────────────────────────────────────────┘

3.9 核心要点总结

HyDE 关键点

  • 核心思想:用答案搜答案
  • 三步流程:生成假设答案 → 嵌入 → 检索
  • 反直觉:假设答案不需要正确

为什么有效

  1. 填补问题 - 答案语义鸿沟
  2. 利用 LLM 预训练知识
  3. 缓解词汇不匹配
  4. 增加信息密度

面试关键词

  • Hypothetical Document Embeddings
  • 用答案搜答案
  • 语义鸿沟
  • 向量表示对齐

================================================================================

第 4 章 Multi-Query(多查询检索)

4.1 通俗理解(12 岁能听懂)

你有一次提问的机会

想象你在玩一个寻宝游戏,面前有一个神秘的宝箱,里面装着你要找的答案。

游戏规则是:你只能对宝箱管理员说一句话,然后他帮你从仓库里找宝物。

第一次尝试

你问:

"怎么变强?"

管理员想了想,给你拿了一本《健身入门》。但你心里想的是:"我是想变编程高手啊!"

问题出在哪里?

你的问题太模糊了!"变强"可以有很多种意思:

  • 💪 身体变强(健身)
  • 🧠 大脑变强(学习)
  • 💻 编程变强(写代码)
  • 🎮 游戏变强(打游戏)

Multi-Query 就像一个"聪明的分身术" 🔄

Multi-Query 的做法

你不是只说一句话,而是同时说好几句不同的话

原始问题:"怎么变强?"
        ↓
   ┌─────────────────────────────┐
   │  Multi-Query 分身术          │
   └─────────────────────────────┘
        ↓
   ┌─────────────────────────────────────┐
   │  "如何通过健身让身体变强?"           │
   │  "如何提高编程能力?"                │
   │  "如何在游戏中变强?"                │
   └─────────────────────────────────────┘
        ↓
   用这 3 个问题分别去搜索
        ↓
   把找到的所有结果合并在一起
        ↓
   去掉重复的,选出最好的
        ↓
   给用户一个完整的答案!

一个比喻

方法比喻结果
单次查询派 1 个人去找东西可能找错
Multi-Query派 3 个人从不同角度去找更可能找到对的

为什么这样更好?

就像你问朋友问题:

  • 问 1 个朋友,可能他只想到一个角度
  • 问 3 个朋友,能得到 3 种不同的想法,最后综合起来更全面!

4.2 核心概念拆解

什么是 Multi-Query?

Multi-Query 是一种检索优化技术,它的核心思想是:

用多个不同角度的查询变体并行检索,然后合并结果

工作流程

  1. 生成变体:用 LLM 把原始查询改写成 3-5 个不同的版本
  2. 并行检索:每个变体同时去检索
  3. 结果融合:合并所有结果,去掉重复的,重新排序
  4. 返回答案:给用户一个更全面的结果

举个例子

用户问:"python list 怎么用?"

Multi-Query 生成的变体:

  1. "Python 列表的基本语法"
  2. "Python list 创建和访问方法"
  3. "Python 列表操作示例代码"
  4. "如何在 Python 中使用列表存储数据"

每个查询都能找到一些不同的文档,合并起来就更全面了!


4.3 与 Query Rewriting 的对比

维度Query RewritingMulti-Query
目标把问题说清楚从多个角度问问题
生成数量1 个改写后的问题3-5 个变体问题
检索次数1 次多次(并行)
比喻翻译官分身术
延迟中(但并行可以加速)
覆盖率单一角度多角度覆盖

形象比喻

  • Query Rewriting:你说的不清楚,我帮你翻译成清楚的一句话
  • Multi-Query:你可能想问多个角度,我帮你同时问好几个问题

4.4 面试回答指南(2 分钟版本)

1️⃣ 先给定义(20 秒)

"Multi-Query 是一种检索优化技术,核心思想是生成多个查询变体并行检索,然后合并结果

简单说,就是用'分身术'从多个角度问同一个问题,找到更全面的答案。"

2️⃣ 说明为什么需要(30 秒)

"用户查询有两个问题:

① 歧义性

  • 比如'怎么变强',可能是健身、编程、学习
  • 单次查询只能命中一个角度

② 覆盖不全

  • 即使用户问题清楚,单次检索也可能漏掉相关文档
  • 不同表述的文档可能只被某些变体命中

Multi-Query 通过多个变体来解决这两个问题。"

3️⃣ 讲工作原理(40 秒)

"Multi-Query 分三步:

第一步:生成变体 用 LLM 根据用户查询生成 3-5 个不同角度的变体。

第二步:并行检索 每个变体同时去检索(可以并行执行,延迟不增加太多)。

第三步:结果融合 合并所有结果,去掉重复的,然后用 RRF(Reciprocal Rank Fusion)或其他方法重新排序。

关键是:不同变体可能命中不同但相关的文档,合并后覆盖率更高。"

4️⃣ 结合实际应用(20 秒)

"在 RAG 系统里,Multi-Query 通常和 Query Rewriting 一起用:

用户查询 → [Query Rewriting][Multi-Query 生成变体][并行检索][结果融合][生成]

我在项目里试过,对于开放型问题和歧义查询,效果提升明显。"


4.5 优势与成本分析

核心优势

优势说明数据
召回率提升不同变体命中不同但相关的文档Recall@10 +30%~80%
歧义处理同时覆盖多个可能的含义歧义查询提升 81%
多角度覆盖每个变体找到不同角度的文档答案更全面
鲁棒性强某个变体不好,其他可以弥补容错率高

成本分析:为什么是 6-8 倍?

详细成本拆解(基于典型云 API 价格估算)

组件单次查询Multi-Query (3 变体)Multi-Query (5 变体)
LLM 调用(生成变体)0 次 × $0.0021 次 × 0.002=0.002 = 0.0021 次 × 0.002=0.002 = 0.002
嵌入(Embedding)1 次 × $0.00013 次 × 0.0001=0.0001 = 0.00035 次 × 0.0001=0.0001 = 0.0005
向量检索1 次 × $0.00053 次 × 0.0005=0.0005 = 0.00155 次 × 0.0005=0.0005 = 0.0025
总计$0.0006$0.0038$0.0050
倍数1x6.3x8.3x

倍数计算过程

单次查询总成本:$0.0001 + $0.0005 = $0.0006

Multi-Query (3 变体) 总成本:$0.002 + $0.0003 + $0.0015 = $0.0038
倍数 = $0.0038 ÷ $0.0006 = 6.33 倍

Multi-Query (5 变体) 总成本:$0.002 + $0.0005 + $0.0025 = $0.0050
倍数 = $0.0050 ÷ $0.0006 = 8.33 倍

成本构成分析

┌─────────────────────────────────────────────────────────────┐
│              Multi-Query 成本构成(3 变体)                   │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  单次查询:$0.0006                                          │
│  ├── 嵌入:$0.0001 (16.7%)                                  │
│  └── 检索:$0.0005 (83.3%)                                  │
│                                                             │
│  Multi-Query:$0.0038                                       │
│  ├── LLM 生成变体:$0.002 (52.6%)  ← 新增                   │
│  ├── 嵌入:$0.0003 (7.9%)        ← 3 倍                     │
│  └── 检索:$0.0015 (39.5%)       ← 3 倍                     │
│                                                             │
│  倍数 = $0.0038 / $0.0006 = 6.33 倍                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

关键点说明

  1. LLM 调用是主要成本增量

    • LLM 生成变体:$0.002,占总成本 52.6%
    • 这是纯新增的成本,单次查询没有这一步
  2. 嵌入和检索成本按变体数量线性增长

    变体数嵌入成本检索成本总成本倍数
    1 次(单次)$0.0001$0.0005$0.00061x
    3 次$0.0003$0.0015$0.00386.3x
    5 次$0.0005$0.0025$0.00508.3x
  3. 实际倍数取决于变体数量

    • 3 个变体 → 约 6 倍
    • 4 个变体 → 约 7 倍
    • 5 个变体 → 约 8 倍

⚠️ 注意:以上价格是基于典型云 API 的示例估算,实际成本取决于:

  • 使用的 LLM 模型(GPT-4 比 GPT-3.5 贵)
  • 嵌入模型(商业 API vs 本地部署)
  • 向量数据库(云服务 vs 自建)
  • 查询长度(tokens 数量)

如果是本地部署模型,边际成本接近零,但前期投入大,成本倍数仍然适用(6-8 倍的资源消耗)。


4.6 优化策略:如何降低成本

策略 1:条件触发

def should_use_multi_query(query):
    """只对特定查询使用 Multi-Query"""
  
    # 查询太短(< 5 词)→ 用 Multi-Query
    if len(query.split()) < 5:
        return True
  
    # 查询有歧义(包含泛化词)→ 用 Multi-Query
    ambiguous_words = ["怎么", "如何", "什么", "为什么"]
    if any(word in query for word in ambiguous_words):
        return True
  
    # 事实性查询 → 不用 Multi-Query
    if query.endswith("吗") or "?" in query:
        return False
  
    # 默认不用
    return False

策略 2:动态调整变体数量

查询类型变体数量延迟成本
简短模糊5 个
一般查询3 个
明确查询2 个

策略 3:并行化优化

# 串行(慢)❌
results1 = retriever.search(query1)
results2 = retriever.search(query2)
results3 = retriever.search(query3)

# 并行(快)✅
import asyncio
results1, results2, results3 = await asyncio.gather(
    retriever.search(query1),
    retriever.search(query2),
    retriever.search(query3)
)

策略 4:缓存变体生成

# 常见查询的变体可以缓存
cache = {
    "python 教程": ["Python 入门教程", "Python 基础语法", "Python 学习路径"],
    "怎么减肥": ["如何科学减肥", "减肥饮食指南", "减肥运动方法"],
}

def get_variants(query):
    if query in cache:
        return cache[query]  # 直接返回,省去 LLM 调用
    else:
        variants = llm.generate_variants(query)
        cache[query] = variants
        return variants

4.7 一张图总结

┌─────────────────────────────────────────────────────────┐
│                  Multi-Query 工作流程                    │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  用户问:"怎么变强?"                                    │
│         ↓                                               │
│  ┌──────────────────────────┐                           │
│  │  LLM 生成 3-5 个变体问题   │                           │
│  └──────────────────────────┘                           │
│         ↓                                               │
│  ┌───────────┐  ┌───────────┐  ┌───────────┐           │
│  │ 健身变强   │  │ 编程变强   │  │ 学习变强   │           │
│  │ [搜索]    │  │ [搜索]    │  │ [搜索]    │           │
│  └───────────┘  └───────────┘  └───────────┘           │
│         ↓              ↓              ↓                  │
│  ┌───────────────────────────────────────────┐          │
│  │         合并结果 + 去重 + 排序             │          │
│  └───────────────────────────────────────────┘          │
│         ↓                                               │
│  最终答案(更全面、更准确)                              │
│                                                         │
└─────────────────────────────────────────────────────────┘

4.8 核心要点总结

Multi-Query 关键点

  • 核心思想:多角度问问题,找到更全面的答案
  • 四步流程:生成变体 → 并行检索 → 结果融合 → 返回答案
  • 成本:6-8 倍基准成本

优势

  1. 召回率提升 30%~80%
  2. 歧义处理能力强
  3. 答案更全面
  4. 鲁棒性强

优化策略

  1. 条件触发(不是所有查询都用)
  2. 动态调整变体数量
  3. 并行化检索
  4. 缓存常见查询变体

面试关键词

  • 分身术比喻
  • 多角度覆盖
  • RRF 结果融合
  • 成本 6-8 倍