RAG学习笔记
RAG,全称 Retrieval Augmented Generation(检索增强生成)
大致分为两个阶段:
- 离线阶段:数据入库
- 在线阶段:检索生成
离线阶段主要做:
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 | 输入文本 苹果手机很好用 |
模型选型
在 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 机制观察到文档中的每一个词。
生成答案
提升回答能力
- 可以明确在提示词中要求不要瞎猜,例如:你必须严格基于提供的知识内容回答,不允许猜测。 如果知识未覆盖,请回答:“知识库暂无相关内容”。
- 可以让大模型给出引用的 chunk 内容。
- 可以让大模型回答两次,然后做一致性校验。当然对于内部客服智能体来说,必要性不高。
评估
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 长度等指标监控离线流程质量,持续迭代优化。