RAG学习笔记

RAG,全称 Retrieval Augmented Generation(检索增强生成)

大致分为两个阶段:

  1. 离线阶段:数据入库
  2. 在线阶段:检索生成

离线阶段主要做:

1
文档解析 → 数据清洗 → 文档分块 → 向量化 → 建索引

在线阶段主要做:

1
用户提问 → 查询改写 / 知识库选择 → 召回 → 重排 → Top K 过滤 → 拼接上下文 → 大模型生成回答

文档解析与数据清洗

文档解析

  • 多格式适配: 兼容各种文件格式,如 PDF、Word、Markdown、HTML、JSON、TXT 甚至 Excel
  • 内容提取: 从原始文件中剥离出“净文本”。
    • 如果是 PDF,需要解析文字层;如果是扫描件,则需要 OCR。
    • 如果是 HTML,需要剔除脚本、样式表,只保留正文。
  • 元数据(Metadata)提取: 在提取文本的同时,记录文档的属性,如:文件名、页码、标题、作者、创建时间、章节层级等。
  • 数据清洗: 去除文档中的冗余信息,如乱码、过多的空格、特殊的非打印字符、邮箱、版权声明、水印文案等。

经验与问题

1.PDF 多栏排版解析错乱

传统 PDF 解析工具(比如 PyPDF2)是按行从上往下读的,对多栏解析存在问题。

正确做法是引入版面分析(Layout Analysis)技术。 先识别出文档的物理布局——哪些区域是左栏、哪些是右栏、哪些是表格、哪些是页眉页脚——然后按逻辑结构而非文本顺序提取内容。推荐使用 MinerU 或 Marker 这类专门做文档解析的工具,它们内置了版面分析能力,能正确处理多栏、表格等复杂布局。

2.OCR 把表格和代码全毁了

对表格区域做专门的表格识别,按单元格顺序输出并保留结构化格式;对代码块设置 OCR 保持换行和空格格式。整体建议使用 PaddleOCR 配合版面分析,先检测区域类型(文字/表格/代码/图片),再分别用针对性策略处理。

3.PPT 里的图片信息直接丢了

python-pptx 能提取文本框里的文字,但对嵌在图片里的文字完全无能为力

解决办法: 对 PPT 中的图片元素,先提取出来做 OCR 识别,把图片中的文字也纳入知识库。同理,视频类文档需要先做语音识别(ASR)得到字幕文本,再按内容语义分段入库。

文档分块

文档分块(Chunking)本质上是在尽量保持语义完整的前提下,把长文档拆成适合 Embedding 和 RAG 检索的小块。按照复杂度和智能程度,大致可以分为下面几类:

分块方式 核心思想 优点 缺点 适用场景
按 Token 数分块 固定长度切分(如 512 Token),一般带 Overlap 10%~20% 简单、高效 容易截断语义 大规模数据预处理
递归字符切分 按段落 → 句子 → 单词逐层拆分 保持文本结构 仍是规则驱动 通用 RAG 默认方案
基于结构切分 利用 Markdown、HTML、JSON 等文档结构 保留逻辑层级 依赖格式规范 API 文档、技术文档
按语义分块 根据句子语义相似度决定边界 语义完整,检索效果好 计算成本高 长文档、知识库
Meta-Chunking(语义+逻辑增强) 利用 LLM 的 PPL 感知逻辑边界,并进行语义补全 最符合人类理解方式 成本最高,实现复杂 高质量 RAG、复杂知识库

固定长度切块 → 结构切块 → 语义切块 → Meta-Chunking(逻辑感知 + 语义补全 + 全局摘要)

向量化

Embedding 原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
输入文本    苹果手机很好用


Tokenization [苹果, 手机, 很, 好用]


添加特殊Token(CLS/SEP) [CLS, 苹果, 手机, 很, 好用, SEP]


Token ID [101,512,678,321,789,102]


Token Embedding + Position Embedding 查阅embedding模型中预定义的表格,每个ID拿到一个例如1536维的初始向量


┌───────────────────────────────────────────────────────────────┐
│ Transformer Encoder │
│ │
│ Input X │
│ │ │
│ ├──► Q = XWQ │
│ ├──► K = XWK │
│ ├──► V = XWV │
│ │ │
│ ├──► Self-Attention │
│ ├──► Add & Norm │
│ ├──► Feed Forward Network (FFN) │
│ ├──► Add & Norm │
│ │ │
│ └──► 重复 12~24 层 │
└───────────────────────────────────────────────────────────────┘


Contextual Token Embeddings


Pooling(Mean / CLS / Max)


L2 Normalization 将池化后生成的向量进行归一化,即使其模长(长度)等于 1


Sentence Embedding

模型选型

在 Embedding Leaderboard 选择:https://huggingface.co/spaces/mteb/leaderboard

主要考虑如下点:

  • 模型参数大小
  • 支持维度
  • 语言能力(支持哪些语言)
  • clustering 聚类
  • Retrieval 检索能力
  • Classification 文本分类
  • STS 语义相似度
  • Summarization 摘要匹配
  • Instruction Retrieval 指令检索
  • Reranking 重排序

检索

Query 改写

解决的问题:

  • 指代消解(Coreference Resolution): 处理多轮对话。例如用户问“它的价格是多少?”,改写器会根据上下文将其改写为“华为 Mate 60 Pro 的价格是多少?”。
  • 纠错与去噪: 修正错别字,剔除无意义的口语助词(如“那个…我想问一下…”)。
  • 术语对齐: 将口语化的表达转化为专业术语。例如将“肚子疼怎么办”改写为“腹痛的治疗建议”。
  • 结构转换: 将复杂的长难句拆解或简化,提取出核心语义特征。

检索通常方案为混合检索,主要方案为稠密向量+稀疏向量,稠密向量+BM25。

稠密向量:通常是低维向量(例如 384、768 或 1024 维),其中大部分值非零
稀疏向量:高维向量(例如 30,000+ 维),其中大部分值为零。通常,稀疏嵌入中的每个活动维度(即具有非零值的维度)对应于模型词汇表中的特定标记,从而具有可解释性。
BM25:BM25 通过计算查询中的每个词在文档中的重要性,然后加权求和,得到一个相关性分数。分数越高,表示文档与查询越相关。

稀疏向量

为什么使用稀疏嵌入模型?

解决的是词汇匹配角度问题

稀疏嵌入模型在传统的词汇方法(如 BM25)和稠密嵌入模型之间占据了一个有价值的细分市场。它们具有以下优点:

  • 混合潜力:与稠密模型结合效果非常好,稠密模型可能在词汇匹配很重要的搜寻中遇到困难。
  • 可解释性:你可以确切地看到哪些标记对匹配做出了贡献。
  • 效能:在许多检索任务中,效能可与稠密模型媲美甚至更好。

关于更多稀疏嵌入模型,可参考文档:https://huggingface.tw/blog/train-sparse-encoder

rerank

在重排序阶段,利用交叉编码器(Cross-Encoder),把问题(Query)和“候选文档”拼在一起,作为一个长句子塞进模型(比如:gte-rerank)。模型可以同时看到问题和文档的每一个字。通过自注意力机制(Self-Attention),在 Transformer 的每一层中,Query 中的每一个 token 都可以直接通过 Attention 机制观察到文档中的每一个词。

生成答案

提升回答能力

  1. 可以明确在提示词中要求不要瞎猜,例如:你必须严格基于提供的知识内容回答,不允许猜测。 如果知识未覆盖,请回答:“知识库暂无相关内容”。
  2. 可以让大模型给出引用的 chunk 内容。
  3. 可以让大模型回答两次,然后做一致性校验。当然对于内部客服智能体来说,必要性不高。

评估

ragas

可以采用开源框架,ragas来评测 rag 效果。ragas 评测主要是依赖于大模型判断。

ragas 从四个指标方面来衡量:

  • generation 生成
    • faithfulness(忠实性):用于衡量生成的回答与检索到的上下文在事实逻辑上的一致性。
    • answer relevancy(回答相关性):用于衡量生成的回答与用户输入之间的相关程度
  • retrieval 检索
    • context precision(上下文精度):衡量的是检索出的内容中,相关文本块被放置在排序列表顶部的程度。
    • context recall(上下文召回率):衡量的是在所有相关的文档中,有多少被成功检索了出来。

自研

可以选择三个核心指标:

  • Recall Score(检索召回率)
  • Correctness(答案正确度)
  • Groundedness(基于知识库程度)
指标 衡量什么 反映什么
RecallScore 检索是否找到正确知识 RAG 是否准确
Correctness 回答是否正确 大模型对问题理解与表达是否准确
Groundedness 回答是否基于知识 大模型是否存在幻觉
  • retrieved_context:即 RAG 知识库召回的内容,用作后续给大模型提示的上下文,以下会简称 context
  • answer:即大模型根据提示输出给用户所见的答案
  • ground_truth:三个值中唯一由人类编写的基准问题答案

计算方法如下:

  • 召回率(recall_score):context 与 ground_truth 的余弦相似度对比
  • 正确度(correctness):answer 与 ground_truth 的余弦相似度对比
  • 是否基于知识(groundedness):context 与 answer 的余弦相似度对比

面试问题

离线解析模块是怎么做的”或者”知识库是怎么建的?

先讲挑战。 我们项目有 5000 份多格式文档,包含 PDF(多栏排版、扫描版)、PPT、纯文本甚至视频。主要挑战是多格式统一解析、OCR 对表格和代码的还原、以及分块时保持语义完整性。

再讲方案。 解析层面,我们针对不同格式做了针对性处理——PDF 用版面分析技术处理多栏和表格,扫描件用 PaddleOCR 配合区域检测,PPT 对图片元素做 OCR 补充提取,视频走 ASR 转字幕。分块层面,采用规则+语义融合的三层切分策略,配合 chunk overlap 保持连续性。同时给每个 chunk 打上层级标签、内容类型和来源元数据,支持在线阶段的精准过滤。

最后讲效果和联动。 chunk 大小通过实验配合 LLM 上下文窗口调优,元数据标签在检索阶段支持按时间、来源、类型等维度过滤,整体提升了召回的准确率。我们用解析失败率、平均 chunk 长度等指标监控离线流程质量,持续迭代优化。

参考

  1. RAG 全链路技术详解
  2. 阿里面试官冷笑:”5000 份文档扔进去就算建好知识库了?难怪你的 RAG 答非所问。” 我无言以对…
  3. RAG 深度解析:分块、向量化、召回、重排,才是“蒸馏同事 skill”的关键
  4. RAG—Chunking 策略实战|得物技术
  5. 从评估到改进:RAG 知识库质量优化探索
  6. 如何构建一个更“好”的知识库?