文档处理与分块策略:RAG 效果的第一道关
文档处理与分块策略:RAG 效果的第一道关
RAG 效果好不好,第一步的文档处理和分块策略影响巨大。文档清洗不干净、分块太大太小、语义被切断,都会导致检索不准、答案不完整。这篇讲文档解析、清洗、分块的各种策略,以及实际项目里怎么选。
大家好,我是黒漂技术佬。
很多人做 RAG,上来就搞向量库、搞大模型调优,结果效果一直不好。回头一看,最基础的文档分块就没做好——一块里塞了好几个主题,或者一句话被切成两半,检索能准才怪。
文档处理是 RAG 的第一道工序,基础不牢,地动山摇。
这篇讲文档解析、清洗、分块的各种策略,以及我做项目时的经验。
一、文档解析:从各种格式到纯文本
常见格式与工具
| 格式 | 推荐工具 | 特点 |
|---|---|---|
| Markdown / TXT | 直接读 | 最简单,格式干净 |
| PDF(文字版) | pdfplumber、PyMuPDF | 能提取排版信息 |
| PDF(扫描版) | OCR(PaddleOCR、Tesseract) | 先识别文字再处理 |
| Word (.docx) | python-docx、Unstructured | 保留标题层级 |
| HTML / 网页 | BeautifulSoup、Trafilatura | 去广告提取正文 |
| PPT | python-pptx | 提取文字和备注 |
| Excel / CSV | pandas | 表格数据特殊处理 |
解析不只是提取文字
好的解析不止是把文字抠出来,还要保留结构信息:
- 标题层级:H1/H2/H3,知道哪段属于哪个章节
- 列表:有序无序列表,不要挤成一坨
- 表格:表格转文字要保留行列关系
- 代码块:技术文档里的代码要完整
- 图片描述:有 alt 文本的提取出来
这些结构信息对分块和检索都很重要。
解析的坑
- PDF 排版错乱:双栏、页眉页脚、脚注,提取出来顺序乱
- 扫描版 PDF:纯图片,必须 OCR
- 网页噪声:广告、导航、推荐阅读,混进正文
- 格式乱码:特殊字符、编码问题
二、文档清洗:去掉噪声
原始文档里有很多没用的东西,混进去会影响检索质量。
常见清洗操作
1. 去重复
- 完全重复的段落删掉
- 页眉页脚每页都有,去掉
2. 去噪声
- 版权声明、免责声明
- 导航菜单、页脚链接
- 广告、推荐阅读
- 空白行、多余空格
3. 格式统一
- 统一换行符
- 多余空格合并
- 特殊字符处理
- 全角半角统一
4. 表格处理
表格直接转纯文本容易乱。几种处理方式:
- 简单表格:转 Markdown 表格格式
- 复杂表格:拆成行描述,每行一段文字
- 数值表格:保留结构化数据,单独处理
清洗的度
别洗太狠,把有用信息洗没了。比如技术文档里的代码、命令,不能当成噪声删了。
原则:影响理解的噪声去掉,有用的格式信息保留。
三、文本分块:RAG 最关键的一步
分块就是把长文档切成一段一段的,每段是一个检索单元。
为什么要分块?
- Embedding 模型有长度限制:比如 bge 最多 512 tokens,超长的效果差
- 检索精度:一整篇文档一个向量,太泛了,检索不准
- 上下文窗口有限:大模型上下文塞不下太多,只取相关的几段
分块大小怎么选?
太大太小都不好:
| 分块大小 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 小(100-256 tokens) | 检索精准,单块语义集中 | 上下文不完整,容易断章取义 | FAQ、短问答 |
| 中(512 tokens) | 平衡精度和完整度 | - | 通用场景,推荐 |
| 大(1024 tokens+) | 上下文完整,语义全 | 噪声多,检索不准 | 长文档、复杂主题 |
我的经验
- 通用知识库:512 tokens 左右,重叠 50-100 tokens
- 技术文档、代码:可以大一点,768 tokens
- FAQ、产品手册:小一点,256 tokens
- 先从 512 开始试,效果不好再调
重叠(Overlap)
两块之间留一部分重叠,防止语义被切断:
Chunk 1: [第1段 第2段 第3段] Chunk 2: [第3段 第4段 第5段] ↑ 重叠部分重叠大小一般是分块的 10-20%。比如 512 的块,重叠 50-100 tokens。
四、常见分块方法
方法 1:固定长度分块(最简单)
按字符数或 token 数切,到长度就切一刀。
fromlangchain.text_splitterimportCharacterTextSplitter splitter=CharacterTextSplitter(chunk_size=500,chunk_overlap=50,separator="\n")chunks=splitter.split_documents(documents)优点:简单快,稳定
缺点:可能从句子中间切开,语义断裂
适合:格式简单的纯文本。
方法 2:按语义分隔符分块(推荐)
优先在段落、句子边界切,尽量不切断完整语义。
fromlangchain.text_splitterimportRecursiveCharacterTextSplitter splitter=RecursiveCharacterTextSplitter(chunk_size=500,chunk_overlap=50,separators=["\n\n","\n","。","!","?"," ",""])分隔符按优先级排:先按段落切,太长再按行切,还长按句子切,最后按字切。
优点:尽量保持语义完整,效果好
缺点:块大小不均匀
这是最常用的分块方式,一般场景推荐这个。
方法 3:按标题/结构分块
利用文档的标题层级,按章节分块。
# 第一章 ## 1.1 功能介绍 这一段... ## 1.2 使用方法 这一段...每个二级标题下的内容作为一块,或者拆成几块。
优点:语义天然完整,自带标题上下文
缺点:依赖文档结构,格式乱的不行
适合:结构清晰的文档(Markdown、有标题的 Word)。
方法 4:语义分块(Semantic Chunking)
根据语义相似度分块,语义变了就切。用 embedding 算相邻句子的相似度,相似度骤降的地方切开。
优点:语义最准确
缺点:慢,要先 embedding,成本高
适合:对质量要求高、文档不太长的场景。
方法 5:父子分块(Parent-Child)
大块(父块)存完整语义,小块(子块)用来检索。
- 检索时匹配子块(精准)
- 返回给大模型用父块(完整)
父块(1024 tokens)→ 完整上下文 ├─ 子块1(256 tokens)→ 用于检索 ├─ 子块2(256 tokens)→ 用于检索 └─ 子块3(256 tokens)→ 用于检索优点:兼顾检索精度和上下文完整
缺点:实现复杂一点,存储量大
进阶方案,效果提升明显。
五、元数据:给每个块加标签
每个 chunk 不只是存文本,还要带元数据:
{"content":"这是分块的正文内容...","metadata":{"source":"产品手册v2.3.pdf","page":15,"chapter":"第三章 安装部署","category":"安装指南","update_time":"2026-06-01"}}元数据的作用
- 检索过滤:只搜某个分类、某个文档的内容
- 答案溯源:回答时引用来源,用户知道出自哪
- 权限控制:不同用户看不同级别的文档
- 更新管理:文档更新了,对应块重新索引
常用元数据字段
- source:来源文件名
- page/chapter:页码/章节
- category:分类
- update_time:更新时间
- author:作者
- tags:标签
六、分块策略选择指南
场景 1:FAQ / 问答库
- 分块方法:按问题分,每条 FAQ 一个块
- 块大小:100-256 tokens
- 特点:短而精准,检索直接命中
场景 2:产品手册 / 技术文档
- 分块方法:按标题 + 递归字符分块
- 块大小:512-768 tokens
- 特点:保留章节结构,语义完整
场景 3:代码文档 / API 文档
- 分块方法:按函数/接口分块
- 块大小:512-1024 tokens
- 特点:一个函数一个块,代码完整不切断
场景 4:长文章 / 研究报告
- 分块方法:父子分块 或 语义分块
- 块大小:父块 1024,子块 256
- 特点:兼顾精度和上下文
场景 5:对话记录 / 客服日志
- 分块方法:按会话分,多轮对话一个块
- 块大小:看对话长度
- 特点:上下文关联强,不能切断对话
七、实际项目经验
企业知识库项目的分块方案
我做的企业知识库,文档类型杂(手册、FAQ、技术文档、公告):
处理流程
- 各种格式解析成 Markdown(保留标题层级)
- 清洗:去页眉页脚、去重复、统一格式
- 按 H2 标题粗分,每个章节单独处理
- 章节内用 RecursiveCharacterTextSplitter 细分,512 tokens,重叠 10%
- 提取元数据(来源、章节、分类)
- 生成 Embedding,存入向量库
效果
- 检索召回率:比简单分块高 15% 左右
- 答案完整度:明显提升,很少出现断章取义
踩过的坑
坑 1:表格直接切碎了
表格被切成好几块,检索到一块也看不懂。
解决:表格整体作为一个块,或者转成结构化描述。
坑 2:代码块被切断
一段代码中间切开,上下文全乱了。
解决:检测代码块,整体保留,超长的再按函数切。
坑 3:重叠太少导致断句
两块刚好从一句话中间切开,检索到了也看不懂。
解决:重叠加到块大小的 15-20%。
坑 4:块大小一刀切
所有文档都用 512,FAQ 太大、长文档太小。
解决:按文档类型用不同的分块策略。
八、本篇小结
- 文档解析不止提取文字,结构信息(标题、列表、表格)很重要
- 清洗去噪声:重复、页眉页脚、广告、多余格式
- 分块是 RAG 的关键,直接影响检索质量
- 常用分块方法:固定长度 → 递归字符(推荐) → 按标题 → 语义分块 → 父子分块
- 块大小一般 512 tokens 起步,重叠 10-20%
- 元数据不能少:来源、分类、章节、时间,过滤溯源都靠它
- 不同场景用不同分块策略,不要一刀切
下一篇讲向量数据库选型与索引优化:各种向量库怎么选、索引怎么建、检索怎么加速。
我是黒漂技术佬。
