Advanced-RAG原理:RAG-Fusion 检索增强生成的多查询融合实战
在构建AI问答系统时,很多Web开发者会直接采用“用户输入 → 向量检索 → LLM生成”的经典RAG(Retrieval-Augmented Generation)流程。这就像我们在电商网站实现一个商品搜索框:用户输入“轻薄笔记本”,系统返回匹配的商品列表。但问题来了:用户的问题往往模糊、简略甚至带有歧义。比如:“怎么处理合同违约?”“推荐适合初学者的Python框架”传统RAG只用原始问题做一
图片来源网络,侵权联系删。

文章目录
引言
在构建AI问答系统时,很多Web开发者会直接采用“用户输入 → 向量检索 → LLM生成”的经典RAG(Retrieval-Augmented Generation)流程。这就像我们在电商网站实现一个商品搜索框:用户输入“轻薄笔记本”,系统返回匹配的商品列表。
但问题来了:用户的问题往往模糊、简略甚至带有歧义。比如:
- “怎么处理合同违约?”
- “推荐适合初学者的Python框架”
传统RAG只用原始问题做一次向量检索,很容易漏掉关键文档——就像只用“违约”搜法律条款,却忽略了“解除合同”“赔偿标准”等同义表述。
RAG-Fusion 正是为解决这一问题而生:它通过生成多个视角的查询,再融合检索结果,大幅提升召回率与相关性。对Web开发者而言,这相当于在搜索前先做“关键词扩展 + 意图识别 + 多路召回”,是搜索工程的自然演进。
本文将从Web技术视角,深入解析RAG-Fusion原理,并提供基于Node.js + LangChain.js 的可运行实战代码。

1. RAG-Fusion核心思想:用LLM生成多视角查询,再融合排序
1.1 传统RAG的局限
问题:单次检索依赖原始问题的表达质量,若问题不完整或术语不标准,召回效果差。
1.2 RAG-Fusion 的三步走
RAG-Fusion 由 Vespa 团队 提出,核心流程如下:
-
Query Generation(查询生成)
用LLM将原始问题改写为多个语义等价但表述不同的子查询。 -
Parallel Retrieval(并行检索)
对每个子查询独立执行向量检索,得到多组候选文档。 -
Reciprocal Rank Fusion(RRF 融合排序)
使用无监督算法融合多路结果,按综合相关性重排序。
1.3 Web类比:多路召回 + 排序融合
这与现代推荐系统/搜索引擎的架构高度一致:
- 多路召回:协同过滤、内容匹配、热门榜单
- 融合排序:加权打分、Learning-to-Rank、RRF
RAG-Fusion 本质上是将“搜索策略”交给了LLM来智能生成,而非人工规则。

2. 核心原理详解:从Query Generation到RRF
2.1 Query Generation:让LLM帮你“换说法”
提示词模板示例:
你是一个搜索专家。请根据以下原始问题,生成3个不同但语义相关的搜索查询,用于从知识库中检索相关信息。
原始问题:{question}
输出格式(每行一个查询):
1. ...
2. ...
3. ...
例如,输入“如何申请专利?”,可能输出:
- 专利申请流程和所需材料
- 个人如何提交发明专利
- 专利注册的官方步骤和费用
💡 Web开发者注意:这里LLM充当了“意图扩展器”,类似SEO中的关键词挖掘工具。
2.2 Reciprocal Rank Fusion(RRF)原理
RRF 是一种无需训练的融合算法,公式如下:
[
\text{Score}(d) = \sum_{q \in Q} \frac{1}{k + \text{rank}_q(d)}
]
其中:
- ( d ):文档
- ( q ):某个子查询
- ( \text{rank}_q(d) ):文档 ( d ) 在查询 ( q ) 结果中的排名(从1开始)
- ( k ):常数(通常取60),避免排名为1时分数过高
优势:
- 不依赖具体检索模型的打分(兼容不同向量库)
- 对排名靠前的文档给予更高权重
- 实现简单,计算高效
🌰 举例:某文档在查询1中排第2,在查询2中排第1,则得分为 ( \frac{1}{60+2} + \frac{1}{60+1} \approx 0.032 )

3. 实战:用Node.js + LangChain.js实现RAG-Fusion
我们将构建一个支持RAG-Fusion的问答API,使用Chroma作为向量数据库。
3.1 项目依赖
npm install langchain @langchain/chroma openai
3.2 实现RAG-Fusion链
// rag-fusion.js
import { ChatOpenAI } from "@langchain/openai";
import { PromptTemplate } from "@langchain/core/prompts";
import { RunnableSequence } from "@langchain/core/runnables";
import { reciprocalRankFusion } from "langchain/rerank/reciprocal_rank_fusion";
// Step 1: 生成多查询
const queryGenPrompt = PromptTemplate.fromTemplate(`
你是一个搜索专家。请根据以下原始问题,生成3个不同但语义相关的搜索查询。
原始问题:{question}
输出格式(每行一个查询):
`);
const llm = new ChatOpenAI({ model: "gpt-4o-mini", temperature: 0 });
const queryGenChain = RunnableSequence.from([
{
question: (input) => input.question,
},
queryGenPrompt,
llm,
(output) => output.content.split('\n').filter(q => q.trim() !== '').map(q => q.replace(/^\d+\.\s*/, ''))
]);
// Step 2: 并行检索(假设已有 retriever)
async function retrieveFromQueries(queries, retriever) {
const allResults = [];
for (const query of queries) {
const docs = await retriever.invoke(query);
allResults.push(docs);
}
return allResults;
}
// Step 3: RRF 融合
function fuseResults(allResults) {
return reciprocalRankFusion(allResults);
}
// 主流程
export async function ragFusion(question, retriever) {
// 1. 生成查询
const queries = await queryGenChain.invoke({ question });
console.log("Generated queries:", queries);
// 2. 并行检索
const allResults = await retrieveFromQueries(queries, retriever);
// 3. 融合排序
const fusedDocs = fuseResults(allResults);
// 4. 取 Top 4 作为上下文
return fusedDocs.slice(0, 4);
}
3.3 集成到Express API
// routes/qa.js
import express from 'express';
import { Chroma } from "@langchain/chroma";
import { OpenAIEmbeddings } from "@langchain/openai";
import { ragFusion } from '../rag-fusion.js';
const router = express.Router();
// 初始化向量检索器(需提前加载数据)
const vectorStore = await Chroma.fromExistingCollection(
new OpenAIEmbeddings(),
{ collectionName: "my_docs" }
);
const retriever = vectorStore.asRetriever({ k: 5 });
router.post('/ask', async (req, res) => {
const { question } = req.body;
try {
const contextDocs = await ragFusion(question, retriever);
// 构建最终回答(此处简化,实际可用另一个LLM链)
const answer = `基于以下信息回答:\n${contextDocs.map(d => d.pageContent).join('\n---\n')}`;
res.json({ answer, sources: contextDocs.map(d => d.metadata.source) });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
3.4 效果对比
| 方法 | 原始问题 | 召回关键文档数 |
|---|---|---|
| 传统RAG | “怎么注销公司?” | 2 |
| RAG-Fusion | 生成:“公司注销流程”、“企业吊销与注销区别”、“工商注销所需材料” | 5 |
结论:RAG-Fusion显著提升长尾问题的覆盖能力。

4. 常见问题与优化建议(Web开发者视角)
4.1 性能瓶颈:多查询导致延迟增加
- 问题:生成3个查询 + 3次检索 ≈ 3倍耗时
- 优化:
- 并行执行检索(
Promise.all) - 缓存高频问题的查询扩展结果
- 限制最大查询数(通常3~5个足够)
- 并行执行检索(
4.2 查询质量不稳定
- 问题:LLM可能生成无关或重复查询
- 优化:
- 在提示词中强调“不同角度”“避免重复”
- 后处理去重(基于向量相似度)
- 设置最低置信度过滤
4.3 与HyDE、Step-Back等方法的关系
- HyDE:生成假设答案再检索 → 适合事实型问题
- Step-Back:先抽象问题再检索 → 适合推理型问题
- RAG-Fusion:多角度查询 → 通用性强,适合模糊问题
✅ 建议:将RAG-Fusion作为默认策略,复杂场景可组合使用。
5. 总结与进阶方向
RAG-Fusion 是Advanced RAG体系中的关键一环,它用极低的工程成本(仅增加一个LLM调用)换取显著的检索质量提升。对于Web开发者而言,理解其原理有助于:
- 设计更鲁棒的AI问答系统
- 构建企业级知识库应用
- 优化搜索型产品的用户体验
进阶学习路径:
- 掌握LangChain.js的Reranker模块
- 尝试与HyDE、Parent Document等策略组合
- 构建评估 pipeline(使用RAGAS等工具)
- 部署到Serverless平台(如Vercel Edge Functions)
推荐资源:
- 📄 论文:RAG-Fusion: Improved Retrieval Augmented Language Models
- 🧪 LangChain.js RAG-Fusion 示例:官方GitHub
- 🛠️ 工具:LlamaIndex 的 Query Fusion Retriever
- 🎓 课程:《Advanced RAG Techniques for Developers》(DeepLearning.AI)
AI搜索不是终点,而是智能交互的起点。用好RAG-Fusion,让你的知识库真正“懂”用户。

更多推荐


所有评论(0)