目 录CONTENT

文章目录

RAG学习笔记

~梓
2026-06-29 / 0 评论 / 0 点赞 / 0 阅读 / 0 字
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

RAG 学习笔记

记录 RAG(Retrieval-Augmented Generation,检索增强生成)的完整流程、三种范式、以及生产级 RAG 的优化手段(query 改写、多路检索、rerank)。配带数字的完整例子,便于理解每一步"谁和谁比、比出什么"。


一、为什么需要 RAG

LLM 的知识有两个局限:

  1. 静态:训练完成后不知道新信息(今天的新闻、当前时间)
  2. 不私有:不知道你的内部文档、业务数据

RAG 的思路:检索相关文档 → 喂给 LLM → LLM 基于文档回答。这样 LLM 就能回答它本来不知道的问题,且答案有据可查(可溯源到文档)。


二、基础 RAG 流程(4 步)

1. 切片(chunking):  把文档切成小块
2. 入库(indexing):   每块文本 → embedding → 向量存入向量库
3. 检索(retrieval):  用户问题 → embedding → 和库里向量比相似度 → 取最相似的 k 块
4. 生成(generation): 把检索到的文本块拼进 prompt → LLM 生成回答

下面逐步拆解。


三、切片(Chunking)

把长文档切成小块,因为:

  • embedding 对短文本效果更好(长文本语义被稀释)
  • 检索要精准(返回整篇文档不如返回最相关的一段)
  • LLM context 有限

常见切法

方法 说明
固定长度 每 N 字符切一块,带 overlap(相邻块重叠,保证上下文不断裂)
递归字符切分 按段落 → 句子 → 字符递归切,尽量在自然边界切
按标题切分 Markdown 按 # ## 标题切,保留语义结构

典型参数

  • chunk_size:每块字符数(如 800~1600)
  • chunk_overlap:相邻块重叠字符数(如 100),避免切断上下文
  • 小块合并:太小的块合并到上一块,避免碎片

四、Embedding 与向量库

Embedding

把文本转成定长向量(如 1024 维),让语义相近的文本向量也相近。

"禅院飞鸟介绍" → [0.12, -0.34, 0.56, ..., 0.78]  (1024个数)
"禅院飞鸟的背景" → [0.11, -0.32, 0.55, ..., 0.77]  (向量很接近)
"CPU排查方法"   → [-0.45, 0.23, -0.11, ..., 0.02] (向量差很远)

向量库

存文档向量,支持高效相似度检索。常见:Milvus、Faiss、Chroma、Pinecone。

入库时文档向量预先算好存着,检索时只算 query 向量,和库里现成的比,所以快。

相似度度量

  • 余弦相似度:算两个向量夹角,越接近 1 越像
  • L2 距离(欧氏距离):算向量直线距离,越小越像

五、向量检索

流程

query → embed → query向量
              ↓
         和库里所有文档向量算相似度
              ↓
         取相似度最高的 top-k 个文档

top-k vs top-p(易混)

含义 用在哪
top-k 取相似度最高的 k 个文档 检索阶段(RAG 用这个)
top-p 从累积概率达 p 的词里采样(nucleus sampling) 生成阶段(LLM 采样,和检索无关)

RAG 检索用 top-k(如 top-3),取最相似的 3 个文档。


六、三种 RAG 范式

范式 流程 检索时机 适用
Naive RAG(经典) 问题 → 检索 → 拼 prompt → 生成 每次必检索 简单 QA,问题明确
Agentic RAG LLM 决定调不调检索工具、用什么 query LLM 自己判断 问题多样,有时不需要检索
Advanced RAG query改写 + 多路检索 + rerank + 拼 prompt 优化检索质量 生产级,追求准确率

Agentic RAG vs 传统 RAG 的关键区别

传统 RAG Agentic RAG
检索时机 每次必检索 LLM 决定调不调
检索词 用户原话 / 改写 LLM 自定(作为工具参数)
检索结果去哪 拼进 prompt context 作为 ToolMessage 在 ReAct 循环里给 LLM

Agentic RAG 把检索做成 Agent 的一个工具,LLM 自己决定何时检索、用什么词检索。灵活,但检索结果走 ToolMessage,LLM 可能不如"直接拼 context"那样充分使用文档。


七、Advanced RAG 的优化手段

7.1 Query 改写

用户原话未必是好的检索词。用 LLM 把问题改写成更适合检索的词。

用户原话: "我想了解禅院飞鸟,还有禅院业是什么"
  ↓ LLM 改写
q1: "禅院飞鸟 介绍"
q2: "禅院飞鸟 出处 背景"
q3: "禅院业 含义"

多查询(Multi-Query)

生成多个不同角度的检索词,每个都去检索一遍,合并结果(不是选最好的 query)。

q1 → 检索 → 文档 A, B, C
q2 → 检索 → 文档 B, D, E
q3 → 检索 → 文档 F, G
合并去重: A, B, C, D, E, F, G

为什么要多个:单个 query 召回不全,多角度检索覆盖更广。合并的是文档,不是 query

HyDE(假设文档检索)

让 LLM 先生成一个"假设性答案文档",用这个假设文档的向量去检索。思路:答案和答案更像(比"问题和答案"更接近)。

7.2 多路检索(混合检索)

向量检索(语义匹配)+ 关键词检索(BM25,精确匹配)结合。向量擅长语义,关键词擅长精确词匹配,混合更稳。

7.3 Rerank(重排序)

向量检索召回的 top-N 文档,用 cross-encoder 重新打分排序,取最相关的 top-k。

为什么叫"重"排序:向量检索已经按相似度排过一次,rerank 是用更准的模型再排一次。


八、Bi-encoder vs Cross-encoder(核心区分)

这是理解 rerank 的关键。两种打分方式:

Bi-encoder(双编码器)—— 向量检索用

query → 编码 → query向量
doc   → 编码 → doc向量
分数 = 余弦相似度(query向量, doc向量)
  • query 和 doc 分别编码,各得向量,再算距离
  • doc 向量可预先算好存库,检索时只算 query 向量
  • ,但 query 和 doc 没有交互,精度有限

Cross-encoder(交叉编码器)—— rerank 用

[query + doc] 一起输入模型 → 一个相关性分数
  • query 和 doc 拼一起过模型,直接输出分数
  • 不能预计算,每个 query-doc 对都要现跑一次
  • ,但准——query 和 doc 在模型内部做 attention 交互,能捕捉细粒度匹配

对比

Bi-encoder Cross-encoder
输入 单条文本 (query, doc) 对
输出 向量 分数
能否预计算 能(doc 向量存库) 不能
速度
精度 一般
用途 初筛(从海量文档召回 N 个) 精排(从 N 个挑 k 个)

类比

  • Bi-encoder = 给 query 和 doc 各拍张照片,比两张照片像不像(快但粗)
  • Cross-encoder = 把 query 和 doc 摆一起仔细通读,判断多相关(准但慢)

九、完整 Advanced RAG 例子(带数字)

设定:知识库有 5 个文档(入库时已向量化)

D1: 禅院飞鸟介绍
D2: 禅院飞鸟出处
D3: 禅院飞鸟内容
D4: CPU排查方法(无关)
D5: 长尾效应(无关)

用户问题

"我想了解禅院飞鸟,还有禅院业是什么"

步骤 1:LLM 改写出 3 个检索词

q1: "禅院飞鸟 介绍"
q2: "禅院飞鸟 出处 背景"
q3: "禅院业 含义"

步骤 2:每个 query 各自向量化,各自和 5 个文档比相似度

q1 向量 vs D1~D5:

文档 相似度
D1 0.92 最像
D3 0.80
D2 0.71
D4 0.12
D5 0.08

取 top-2 → 挑出 D1, D3

q2 向量 vs D1~D5: 挑出 D2, D1

q3 向量 vs D1~D5: 挑出 D1, D2

步骤 3:合并挑出的文档(去重)

{D1,D3} ∪ {D2,D1} ∪ {D1,D2} = {D1, D2, D3}

候选文档池:D1, D2, D3

步骤 4:rerank(cross-encoder 打分)

原问题 + 每个候选文档一起输入 cross-encoder,输出分数:

cross-encoder(原问题, D1) → 0.95
cross-encoder(原问题, D3) → 0.88
cross-encoder(原问题, D2) → 0.72

排序:D1(0.95) > D3(0.88) > D2(0.72),取 top-2 → D1, D3

步骤 5:拼进 prompt,LLM 生成回答

prompt:
  系统: 基于以下资料回答
  资料: [D1] 禅院飞鸟是... [D3] 禅院飞鸟讲述...
  用户: 我想了解禅院飞鸟,还有禅院业是什么

LLM → 基于D1、D3生成回答

流程图

用户问题
  ↓ LLM 改写
q1, q2, q3
  ↓ 每个各自向量化,各自和知识库比相似度
q1 → 挑出 D1,D3
q2 → 挑出 D2,D1
q3 → 挑出 D1,D2
  ↓ 合并文档去重
候选池: D1, D2, D3
  ↓ rerank(原问题+文档 一起输入cross-encoder打分)
D1(0.95) > D3(0.88) > D2(0.72)
  ↓ 取top-2
D1, D3
  ↓ 拼进prompt
LLM 生成回答

十、三个模型协作

完整 RAG 系统用到三个独立模型,各司其职:

模型 职责 怎么工作
embedding 模型(bi-encoder) 文本 → 向量,用于检索 单条文本输入,输出向量
rerank 模型(cross-encoder) 给 query-doc 对打分,用于精排 query+doc 一起输入,输出分数
LLM 生成最终回答 对话生成

不能合并成一个,因为训练数据、模型结构、优化目标都不同:

  • embedding 模型擅长"把文本压成向量"
  • rerank 模型擅长"判断两段文本相不相关"
  • LLM 擅长"生成自然语言"

十一、关键认知清单

  1. RAG 解决 LLM 的静态和不私有问题:检索外部文档喂给 LLM,让它回答原本不知道的问题。
  2. 基础流程四步:切片 → embedding 入库 → 向量检索 → 拼 prompt 生成。
  3. 切片带 overlap:相邻块重叠,保证上下文不断裂。
  4. 向量检索是 query 向量 vs 文档向量:对比一次,挑出最相似的文档。检索结果是挑出的文档,不是再拿去对比的输入。
  5. top-k 是检索参数,top-p 是生成参数,两者无关。
  6. 三种范式:Naive(每次检索)、Agentic(LLM 决定检索)、Advanced(加改写+rerank)。
  7. Agentic RAG 把检索做成工具:LLM 自定 query,结果走 ToolMessage。灵活但未必充分使用文档。
  8. query 改写不是选最好的 query:多 query 各自检索,合并的是文档。
  9. rerank = 重排序:向量检索排过一次,cross-encoder 用更准的模型再排一次。
  10. bi-encoder vs cross-encoder:前者分别编码比向量(快,初筛),后者一起编码出分数(准,精排)。
  11. 完整 RAG 用三个模型:embedding + rerank + LLM,职责不同不能合并。
  12. 性能与精度平衡:先用快的 bi-encoder 筛掉绝大多数(海量→N),再用准的 cross-encoder 精排少数(N→k)。

附:简化版对照

学习项目通常是简化版 RAG(Agentic RAG,无改写无 rerank):

简化版:  embedding → 向量检索 top-k → (ToolMessage) → LLM
完整版:  query改写 → 多路检索 → 合并 → rerank → (拼prompt) → LLM

简化版省了:多 query 改写、多路检索、rerank 精排。代价是检索精度有限。理解了完整版,就知道简化版省了什么、为什么、代价是什么。

0

评论区