RAG 超级教程:从原理到实战,用向量+重排模型搭出又准又省钱的 AI 问答

公開日: 2026-07-10 12:50 3633文字 19 min read ... アクセス数

この投稿は「日本語」では表示できません。元の投稿を表示しています。
一篇讲透 RAG 的长文:什么是 RAG、为什么需要它、工作流程、核心组件、与微调的区别、如何搭建与优化、常见开源方案、真实应用场景与误区,并以本博客「就这篇文章问 AI」为例走完一次完整问答。配套硅基流动两个免费模型 BAAI/bge-m3(嵌入)与 BAAI/bge-reranker-v2-m3(重排)。
朗读本文
0:00 / --:--

你有没有过这种冲动:网站有几百篇文章,想做一个「站内 AI 助手」,于是把全部文章正文拼进 system prompt,再问问题?

我最初也是这么干的。直到账单出来、回答开始胡说八道、长文章直接超出上下文窗口——才意识到这是条弯路。

这篇教程把 RAG(Retrieval-Augmented Generation,检索增强生成)讲透:为什么不要「全塞进 prompt」,正确的姿势是什么,怎么用硅基流动免费的两个模型(嵌入 BAAI/bge-m3 + 重排 BAAI/bge-reranker-v2-m3)搭出又准又省钱的问答系统。

想白嫖这两个免费模型,可以用这个注册链接:https://cloud.siliconflow.cn/i/MBwLMSrY


一、什么是 RAG(Why)

RAG = Retrieval-Augmented Generation(检索增强生成):在让大模型生成答案之前,先从外部知识库里检索出最相关的资料,把这些资料连同问题一起交给大模型,让它「带着资料」回答。

它的核心思想一句话:让模型「现查现答」,而不是指望它把全世界的 knowledge 都背在参数里。

为什么会出现 RAG?

大模型本身有几个天生的天花板:

  • 知识有截止日期:模型只在训练数据时间点之前「懂」,之后的事一概不知。
  • 看不到你的私有数据:公司文档、你的博客、客户聊天记录,模型训练时根本没见过。
  • 上下文窗口有限:哪怕有 200K 上下文,也装不下整个知识库。
  • 会一本正经地胡说(幻觉 / Hallucination):资料里没有的内容,它也会编得头头是道。

2020 年 Meta 等提出的 Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks 论文,就是为了让模型在回答时「先查资料」,从而缓解上述问题。后来随着向量数据库和 embedding 模型成熟,RAG 成了落地 LLM 应用最主流的范式。

它解决了什么问题 / 与传统大模型回答的区别

传统大模型回答RAG 增强回答
知识来源训练时「背」进去的参数实时检索的外部资料
时效性停在训练截止日资料更新即生效
私有数据看不到能检索到
可溯源无法引用出处能给出资料来源
幻觉容易编造有资料约束,显著降低

一句话:传统大模型是「凭记忆考试」,RAG 是「开卷考试」。


二、为什么需要 RAG

重点说痛点,这恰恰是 RAG 存在的理由:

  1. 大模型知识会过时:2024 年的模型答不了 2026 年的新政策、新 API。
  2. 容易产生幻觉(Hallucination):没有资料时,模型会自信地编造事实、链接、数字。
  3. 无法直接访问企业私有数据:内部 Wiki、合同、工单,模型根本不知道。
  4. Prompt 太长,Token 成本高:把全站文章塞进 prompt,每次提问都重发几百万 token。
  5. 无法引用资料来源:用户无法核实「这句话到底出自哪里」,不信任。

RAG 把「记忆」和「查资料」解耦——模型负责推理和表达,知识存放在外面随时可更新。


三、RAG 的工作流程

一张流程图就能说清:

flowchart LR
  Q[用户问题] --> E[Embedding 向量化]
  E --> V[(Vector Database 向量库)]
  V --> R[Retriever 检索 Top-K]
  R --> RR[Reranker 重排 可选]
  RR --> L[LLM 生成答案]

放到文字里就是:

用户问题

Embedding(向量化:把问题变成向量)

Vector Database(向量数据库里存着所有资料的向量)

Retriever(检索:找出和问题向量最相似的若干段)

Reranker(重排,可选:对召回结果按真实相关性重新打分)

LLM(带着最相关的资料生成答案)

每一步的作用:

  • Embedding:把自然语言变成一串数字(向量),让「语义相似」可以被「数学距离」衡量。
  • Vector Database:存放所有资料的向量,支持「按向量找最近邻」的高效检索。
  • Retriever:用问题的向量去库里做最近邻搜索,粗筛出候选(如 15 段)。
  • Reranker:把「问题 + 每个候选」拼起来重新打分,精排出真正最相关的(如 5 段)。这是质量的关键一步。
  • LLM:只消费 top-N 资料,生成带出处的答案。

四、RAG 的核心组件

1. Embedding(嵌入模型)

把文本映射成固定维度的稠密向量。维度常见的有 768 / 1024 / 1536。中文场景首选 BAAI/bge-m3(1024 维,中英文都强),在硅基流动上免费

那「向量」到底是什么?

一句话:向量就是一串数字,代表一段文本在「语义空间」里的坐标。

想象一张地图:每篇文章、每句话都是一个点,语义相近的句子在地图上离得近,不相关的离得远。但文字本身没法直接算「距离」,所以嵌入模型把它变成一串定长的数字,比如 1024 维的 [0.12, -0.03, 0.87, …]。这串数字就是那句话的「坐标」。

  • 维度越高,能表达的语义越细腻(1024 维比 384 维装得下更多细微差别)。
  • 「语义相似」≈「向量距离近」:用余弦相似度(两个向量夹角的余弦)衡量,越接近 1 越相关,越接近 0 越不相关。

大模型「读」的是向量吗?——这是个常见误解

不是。要把两件事分清楚:

  1. 向量只用来「检索」:检索阶段,系统把问题也变成向量,去向量库里找「离得最近」的几个文本片段。这一步全是数学计算(算距离、排序),大模型不参与。
  2. 真正喂给大模型的是「原文」:检索完成后,系统把对应的原始文本片段(注意,不是那串数字)拼进 prompt,大模型读的是这些文字,再据此生成答案。

所以更准确的说法是:向量负责「找得准」,大模型负责「读得懂」。 向量是给检索器用的「地址」,不是给大模型读的「内容」。也是因为这个分工,RAG 才能用很便宜的模型就答得准——大模型看到的只是精挑细选出来的几段文字。

2. Chunk(文本切分)

把长文档切成小段(chunk)。RAG 的检索粒度是 chunk,不是整篇文档。切得太粗→召回不精准;太细→语义被切碎。常见甜区是 300~500 字

3. Vector Database(向量数据库)

专门存向量、支持 ANN(近似最近邻)检索的数据库。可选 Qdrant / Milvus / Chroma / FAISS,或直接在 Postgres 里用 pgvector 扩展(本博客用的就是它)。

4. Retriever(检索器)

负责「问题向量 → 候选 chunk」的粗筛。核心是余弦相似度 / 内积 / 欧氏距离。

5. Reranker(重排模型)

Cross-Encoder 结构,比单纯余弦准得多。把 query + 候选 一起喂进去打分。BAAI/bge-reranker-v2-m3 在硅基流动上同样免费

6. LLM(生成模型)

最后消费 top-N 资料生成答案。因为只看到几段,所以可以用更便宜的模型,成本骤降。

它们如何配合:嵌入模型负责「入库」和「查」时的向量化;向量库+检索器负责粗筛;重排模型负责精排;LLM 负责表达。前三者决定「找得准」,最后一个决定「答得好」。


五、RAG 的优势

  • 回答更准确:带着真实资料回答,而不是凭空编。
  • 降低幻觉:有资料约束,编造空间被压缩。
  • 可引用来源:每条答案能附上出处段落,用户可核实。
  • 知识实时更新:往库里加新文档即可,不用动模型。
  • 降低 Token 消耗:只送 top-N 段(几千 token),不是全库。
  • 可使用更便宜的生成模型:因为上下文短而精,小模型也答得不错。
  • 企业数据无需重新训练模型:知识在外面,模型参数不动。

六、RAG 与微调(Fine-tuning)的区别

这是高频搜索话题,一张表说清:

维度RAG微调(Fine-tuning)
知识更新快(加文档即生效)慢(需重新训练)
是否修改模型不改参数修改模型权重
实时更新知识支持不支持,需重训
成本低(主要是检索+少量生成)高(训练算力+数据标注)
适合场景知识库 / 检索问答让模型学会某种「能力 / 风格」

重点:很多企业实际采用 「RAG + 微调」组合——用 RAG 提供最新、可溯源的知识,用微调让模型掌握特定的表达风格或任务格式。不是二选一。


七、如何搭建一个 RAG

完整流程:

  1. 准备文档:博客文章、PDF、Wiki、工单等原始资料。
  2. 文本切分(Chunk):按语义切成 300~500 字的小段。
  3. Embedding:用 bge-m3 把每段变成向量。
  4. 写入向量数据库chunk + 向量 + 元数据 入库。
  5. 用户提问:问题进来。
  6. 检索:问题向量化后,在库里召回 Top-15。
  7. 重排(可选但推荐):用 bge-reranker 重排,取 Top-5。
  8. 交给 LLM 回答:把 Top-5 拼进 prompt,生成答案并附来源。

八、常见开源方案(生态一览)

框架

  • LangChain(最流行,组件多)
  • LlamaIndex(数据接入与索引见长)
  • Haystack(企业级 pipeline)

Embedding 模型

  • BGE(BAAI/bge-m3 等,中英文强,硅基流动免费)
  • Jina Embeddings
  • Nomic Embed

向量数据库

  • Qdrant(Go 写,性能好,易部署)
  • Milvus(大规模分布式)
  • Chroma(轻量,开发友好)
  • FAISS(Meta 的向量检索库,常作底层引擎)

Reranker

  • BGE Reranker(BAAI/bge-reranker-v2-m3,免费)
  • Jina Reranker

九、如何优化 RAG(最容易忽略、却最有价值)

  1. Chunk 大小怎么选:300~500 字是常见甜区;超长文档可先按标题/段落结构切。
  2. Chunk 是否需要重叠(Overlap):建议留 10%~20% 重叠,避免一句话被切断导致语义丢失。
  3. Hybrid Search(混合检索):向量检索(语义)+ 关键词检索(BM25 / 全文索引)融合(RRF),召回率明显更高。本博客资源站就是「向量 + ilike 词法」双路 RRF 融合。
  4. Metadata Filter(元数据过滤):先按时间、分类、作者过滤,再检索,能大幅降噪(比如只搜「2026 年的教程」)。
  5. Top-K 如何设置:召回 15~20、重排后取 5,是稳妥起点;太长反而引入噪声。
  6. 是否需要 Reranker:几乎总是「需要」——它能把余弦召回的误排纠正回来,质量提升肉眼可见。
  7. 如何降低 Token 成本:只送重排后的 Top-5;生成模型选便宜的;嵌入/重排用免费模型。
  8. 如何提高召回率:混合检索 + 元数据过滤 + 合理 chunk + overlap + 重排,四管齐下。

十、RAG 的应用场景(适合什么场景)

  • 企业知识库:员工问制度、流程、产品文档。
  • AI 客服:检索历史工单与 FAQ,给出准确答复。
  • PDF 问答:上传合同 / 论文 / 手册,直接问内容。
  • API 文档助手:开发者问「这个接口怎么调」,定位到对应段落。
  • 法律咨询:检索法条与判例(须人工复核,不可直接采信)。
  • 医疗知识助手:检索指南与文献(同理,辅助而非替代专业判断)。
  • 教育平台:按教材章节答疑、出练习题。
  • 博客问答:就像本博客的「就这篇文章问 AI」——读者对某一篇提问,模型只基于该文作答。

十一、常见误区

  • RAG ≠ 微调:一个补知识,一个学能力,别混为一谈。
  • RAG 不会让模型变聪明:它只是给资料,模型本身能力不变。
  • RAG 不是数据库:它是「检索 + 生成」的范式,底层才用数据库。
  • RAG 不是搜索引擎:它最终要生成自然语言答案,不是返回链接列表。
  • RAG 不一定比微调更适合所有场景:要模型「学会新能力/新风格」还是得微调。
  • Reranker 不是必须的:但加了通常显著更好,属于「可选但强烈推荐」。
  • Chunk 越大不一定越好:过大反而稀释相关性、浪费 token。

十二、实战案例:本博客的「就这篇文章问 AI」

以这个博客为例,真实架构是:

Markdown 文章(知识库)
   ↓ 自动切分(按段落 / 标题)
   ↓ bge-m3 生成 Embedding
   ↓ 存入向量库(本博客用 Postgres + pgvector;你也可以用 Qdrant)

用户提问
   ↓ bge-m3 向量化问题
   ↓ 向量库召回相关文章片段(Top-15)
   ↓ bge-reranker-v2-m3 重排(Top-5)
   ↓ 调用硅基流动的 DeepSeek(或更便宜的免费模型)生成答案

一次完整的问答流程(伪代码,可直接落地):

// ① 索引阶段(写文章时跑一次)
const chunks = splitByHeading(markdownText);          // 自动切分
const vectors = await embed(chunks);                  // bge-m3 向量化
await db.insert(chunks.map((c, i) => ({ content: c, embedding: vectors[i] })));

// ② 提问阶段
const queryVec = (await embed([question]))[0];        // 问题向量化
const candidates = await db.search(queryVec, 15);     // 向量库召回 Top-15
const ranked = await rerank(question, candidates, 5); // bge-reranker 重排取 Top-5
const context = ranked.map(r => candidates[r.index]).join('\n\n');

// ③ 生成(只送 5 段,便宜又准)
const answer = await chatWithLLM(`
请根据以下资料回答,并标注来源:
${context}

问题:${question}
`);

嵌入与重排调用硅基流动的免费模型:

const SF_KEY = process.env.SILICONFLOW_API_KEY!;

// 嵌入:BAAI/bge-m3(免费,1024 维)
async function embed(texts: string[]): Promise<number[][]> {
  const r = await fetch('https://api.siliconflow.cn/v1/embeddings', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${SF_KEY}` },
    body: JSON.stringify({ model: 'BAAI/bge-m3', input: texts, encoding_format: 'float' }),
  });
  const j = await r.json();
  return j.data.map((d: any) => d.embedding as number[]);
}

// 重排:BAAI/bge-reranker-v2-m3(免费)
async function rerank(query: string, documents: string[], topN = 5) {
  const r = await fetch('https://api.siliconflow.cn/v1/rerank', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${SF_KEY}` },
    body: JSON.stringify({ model: 'BAAI/bge-reranker-v2-m3', query, documents, top_n: topN }),
  });
  return (await r.json()).results; // [{ index, relevance_score }] 已按分数排序
}

完整 SQL(pgvector 建表 + 余弦召回)和成本对比,见我另一篇短文;核心结论:嵌入 + 重排都免费,生成模型只看 Top-5(约 3000 token),比「全塞 prompt」省 99%+。


小结

RAG 的精髓就一句话:知识放向量库,提问时只送最相关的几段给大模型。

  • 嵌入用 BAAI/bge-m3(免费)
  • 重排用 BAAI/bge-reranker-v2-m3(免费)
  • 向量库用 pgvector / Qdrant
  • 生成模型只看 Top-5

照这个结构搭,你的 AI 问答会更准、更快、便宜一个数量级。想白嫖这两个免费模型,注册链接:https://cloud.siliconflow.cn/i/MBwLMSrY

本文代码可直接复用——事实上这个博客自己的「就这篇文章问 AI」功能,跑的就是同一套管线。