文档清洗
2276 字约 8 分钟
domain/aiai/rag
2026-07-24
文档清洗(Document Cleaning)是 RAG 数据管道中连接"文档解析"和"文档切分"的关键环节,负责去除解析后文本中的噪声、冗余和不规范内容,将"原始文本"转化为"可索引的高质量文本"。清洗质量直接影响 Embedding 质量、检索精度和最终生成效果。
一句话解释
把文档解析出来的"脏文本"变成"干净文本"——去掉页眉页脚、广告、乱码、重复内容,统一格式,让后续的 Embedding 和检索都更准确。
核心问题
为什么文档清洗如此重要?
- Garbage in, garbage out:噪声文本生成的 Embedding 向量质量差,直接降低检索精度
- 上下文窗口浪费:页眉页脚、广告等噪声占用 LLM 的上下文窗口,挤压有效信息空间
- 重复内容导致偏差:同一内容在多个文档中重复出现,会在检索结果中被过度加权
- 格式混乱影响切分:不规范的文本导致 Chunk 切分质量下降
四大清洗策略
1. 去重(Deduplication)
目标:检测和删除重复或高度相似的内容。
去重层级:
| 层级 | 方法 | 适用场景 |
|---|---|---|
| 文档级去重 | 文件哈希(MD5/SHA256)比较 | 完全相同的文档 |
| 段落级去重 | 段落文本的 MinHash/SimHash 相似度 | 不同文档中的重复段落 |
| 句子级去重 | 句子精确匹配或 n-gram 重叠 | 模板化文档中的重复句子 |
MinHash 去重流程:
- 对文本做 n-gram 分词
- 用多个哈希函数计算 MinHash 签名
- 比较两个文档的 MinHash 签名相似度(Jaccard 相似度近似)
- 相似度 > 阈值(通常 0.8-0.9)的文档对标记为重复
2. 去噪(Noise Removal)
目标:删除与文档核心内容无关的噪声信息。
常见噪声类型:
| 噪声类型 | 来源 | 清洗方法 |
|---|---|---|
| 页眉页脚 | PDF 解析 | 正则匹配 + 位置检测(页面顶部/底部的重复文本) |
| 页码 | PDF 解析 | 正则匹配数字模式 + 位置检测 |
| 广告/导航 | 网页解析 | 基于 DOM 结构移除(<nav>, <aside>, <footer>) |
| 水印文字 | PDF/图片 | OCR 后处理,基于位置和透明度过滤 |
| 乱码/编码错误 | 多来源 | 字符编码检测 + 非法字符过滤 |
| 表格分隔符 | PDF 解析 | 移除 ---, ===, *** 等装饰线 |
| 空白行/多余空格 | 多来源 | 压缩连续空白为单个空格 |
3. 标准化(Normalization)
目标:统一文本的格式和表达规范。
标准化操作:
| 操作 | 说明 | 示例 |
|---|---|---|
| 编码统一 | 全部转为 UTF-8 | 避免 GBK/UTF-16 混用 |
| 标点统一 | 中文标点 vs 英文标点统一 | , → , 或反之 |
| 大小写 | 英文术语大小写统一 | api → API |
| 日期格式 | 统一日期表达 | 2024/1/1, 2024-01-01, Jan 1, 2024 → 统一格式 |
| 数字格式 | 统一数字表达 | 1,000 vs 1000 |
| 特殊字符 | 替换或移除特殊字符 | → → ->, © → 移除 |
4. 格式化(Formatting)
目标:将文本转化为结构化的、利于切分和检索的格式。
格式化操作:
- Markdown 规范化:统一标题层级、列表格式、代码块标记
- 表格结构化:将解析出的表格文本还原为 Markdown 表格或 HTML 表格
- 链接处理:保留有意义的链接,移除跟踪参数
- 图片处理:提取图片 alt text 或 caption,移除无法解析的图片引用
- 章节结构恢复:为丢失结构的 PDF 文本恢复章节层级
清洗 Pipeline 设计
一个完整的文档清洗 Pipeline 分为三个阶段:
Stage 1: 预处理(Pre-processing)
├─ 编码检测与转换(→ UTF-8)
├─ 语言检测
├─ 文档类型识别(PDF/Word/HTML/代码)
└─ 基础格式修复(损坏文件处理)
Stage 2: 规则过滤(Rule-based Filtering)
├─ 正则表达式匹配噪声模式
│ ├─ 页眉页脚模式
│ ├─ 页码模式
│ ├─ URL/邮箱(按需保留或移除)
│ └─ 特殊字符/控制字符
├─ 基于位置的过滤
│ ├─ 页面顶部/底部 N% 区域
│ └─ 表格前后的装饰线
└─ 基于频率的过滤
├─ 跨页面重复文本(页眉页脚)
└─ 高频但低信息量的文本片段
Stage 3: LLM 清洗(可选,用于复杂场景)
├─ 结构化信息提取(从非结构化文本中提取结构化数据)
├─ 语义去重(检测表述不同但语义相同的内容)
├─ 文本修复(修复 OCR 错误、断句错误)
└─ 内容分类(标记每个段落的内容类型)成本考量:规则过滤是零成本/低成本的,应该处理 90% 的清洗任务。LLM 清洗成本高但能处理复杂语义问题,只在必要时使用。
多源清洗差异
不同来源的文档有不同的噪声特征和清洗重点:
| 数据来源 | 主要噪声 | 清洗重点 | 特殊处理 |
|---|---|---|---|
| 网页 | 广告、导航、侧边栏、Cookie 提示 | DOM 结构过滤 + 正文提取 | 使用 readability 算法 |
| 页眉页脚、页码、水印、双栏布局 | 位置检测 + 正则匹配 | 双栏 PDF 需要专门的列检测 | |
| Word | 批注、修订标记、隐藏文本 | 解析时过滤非正文内容 | 保留有意义的格式信息 |
| 代码 | 注释、import 语句、空行 | 按代码结构过滤 | 保留 docstring 和类型注解 |
| 数据库 | NULL 值、编码错误、格式不一致 | 数据清洗 + 标准化 | 字段级别的清洗规则 |
| 邮件 | 签名、引用链、HTML 格式 | 提取正文 + 去除引用 | 处理多层回复链 |
清洗质量对检索效果的量化影响
清洗质量直接影响 RAG 的检索效果,以下是典型的影响量化:
| 清洗维度 | 未清洗 vs 已清洗 | 影响机制 |
|---|---|---|
| 去重 | 检索精度提升 5-15% | 避免重复文档占据 Top-K 位置 |
| 去噪 | 检索精度提升 3-10% | 减少噪声对 Embedding 向量的干扰 |
| 标准化 | 检索精度提升 2-5% | 提升 BM25 的词汇匹配率 |
| 格式化 | 切分质量提升 10-20% | 结构化文本的 Chunk 语义更内聚 |
脏数据对 Embedding 质量的影响:
- 噪声文本(如页眉页脚)会改变 Chunk 的语义中心,导致 Embedding 向量偏移
- 重复内容导致某些语义区域过度密集,影响向量空间的分布均匀性
- 格式混乱导致 Chunk 边界不合理,语义被"平均化"
清洗过度 vs 清洗不足的平衡
| 问题 | 表现 | 后果 | 预防方法 |
|---|---|---|---|
| 清洗过度 | 有用信息被删除 | 召回率下降,关键信息丢失 | 保留清洗日志,抽样验证 |
| 清洗不足 | 噪声残留 | 检索精度下降,上下文窗口浪费 | 建立清洗质量检查点 |
平衡原则:
- 保守优先:宁可保留一些噪声,也不要删除可能有用的信息
- 分层清洗:先做确定性高的清洗(编码、空白),再做需要判断的清洗(语义去重)
- 可回溯:保留清洗前后的版本,便于对比和调试
- 领域适配:不同领域的"噪声"定义不同,需要领域专家参与定义清洗规则
与文档解析的衔接关系
原始文档 → [文档解析] → 原始文本 → [文档清洗] → 干净文本 → [文档切分] → Chunks衔接要点:
- 文档解析的输出质量决定了清洗的难度(解析质量高 → 清洗简单)
- 清洗的输出质量决定了切分的质量(清洗不彻底 → Chunk 语义不内聚)
- 清洗和解析可能需要迭代:清洗过程中发现解析问题 → 返回修复解析 → 重新清洗
常见误区
- 跳过清洗直接切分:噪声文本直接进入 Chunk,影响后续所有环节
- 只做规则清洗:复杂的语义重复和格式问题需要 LLM 辅助
- 清洗不可回溯:清洗后覆盖了原始数据,无法对比和调试
- 一套规则适用所有来源:PDF、网页、代码的噪声特征完全不同
- 忽视清洗的成本效益:LLM 清洗效果好但成本高,不是所有场景都需要
可继续补充的方向
- 清洗质量的自动化评估指标
- 基于 LLM 的自适应清洗策略
- 多语言文档的清洗特殊处理
- 清洗 Pipeline 的工程化部署(批处理 + 增量清洗)