乐于分享
好东西不私藏

RAG文档解析与清洗:先把脏文本变成可检索知识

RAG文档解析与清洗:先把脏文本变成可检索知识

这是《从零搭建企业RAG知识库》第05期。

前几期我们已经启动Qdrant,并把中文文本转换成Embedding向量。但真实企业资料不会整齐地躺在一个数组里:有Markdown说明、TXT制度、PDF合同,还有页眉页脚、空行、目录和重复内容。

如果不先处理,后面的Chunk切分和向量检索都会被污染。本期只做一件事:把不同格式的文件转换成统一、可追踪的文档记录。

一、为什么解析和清洗比换模型更重要

用户问题最终要匹配的是知识块。如果PDF正文被页眉打断,Markdown代码块混进产品说明,或者同一份制度重复入库,检索返回的内容就可能不完整、重复甚至互相矛盾。

清洗阶段的目标不是“把文本变漂亮”,而是保留事实、去掉噪声、补齐来源。任何会改变原意的改写,都应该留给后续的生成阶段,并保留原文用于核对。

二、先定义统一数据结构

本期每个文档单元使用以下字段:doc_id用于稳定标识;source记录文件路径;title保存标题;text保存清洗后的正文;page记录PDF页码;version记录文档版本。

后续切分时,还会增加chunk_id、chunk_index和content_hash。不要等向量入库后才补这些字段,因为那时已经很难追溯某条答案来自哪一页原文。

三、准备项目

将本期project目录复制到工作区,在其中创建data文件夹,把需要处理的.md、.txt和.pdf文件放进去。

Windows PowerShell:

```powershell

python -m venv .venv

.\.venv\Scripts\Activate.ps1

python -m pip install -r requirements.txt

```

macOS或Linux:

```bash

python3 -m venv .venv

source .venv/bin/activate

python -m pip install -r requirements.txt

```

本期使用PyMuPDF读取PDF文本,使用BeautifulSoup为后续HTML类文档预留扩展位置。解析库只负责读取,不负责替你判断业务内容是否正确。

四、清洗文本的四条规则

第一,统一换行符,把Windows和Linux换行统一为\n。第二,把不换行空格替换为普通空格。第三,合并连续空格,但不要删除段落边界。第四,把超过两行的空行压缩,避免向量中出现大量无意义空白。

不要使用“删除所有标点”“每行拼成一行”这类激进规则。标点和段落经常承载条件、范围和例外,删掉后可能改变制度原意。

五、处理TXT和Markdown

TXT通常直接读取即可,但必须明确编码。示例使用UTF-8;如果遇到乱码,先确认原文件编码,不要直接用错误编码强行替换。

Markdown需要保留标题层级,因为标题可以成为后续Chunk的上下文。代码块、表格和链接是否保留,要根据知识库用途决定:产品参数通常保留表格内容,示例代码可以单独进入代码知识库。

本期示例会去掉代码块正文,目的是演示“说明文档”的清洗路径。若你的知识库需要检索代码,请为代码块设计单独解析器,不要照搬这一条规则。

六、按页解析PDF

PDF不是天然的“文本文件”。有些PDF是数字文本,有些只是扫描图片;本期PyMuPDF只能稳定读取数字文本。扫描件需要OCR流程,且必须额外检查识别错误。

示例按页生成Document记录,并把page写入元数据。这样检索命中后,可以回到原始PDF的准确页码,而不是只知道文件名。

如果PDF有页眉和页脚,应根据固定模式删除;如果页眉内容会随章节变化,不要使用全局字符串替换。最安全的做法是先统计重复行,再人工确认删除规则。

七、运行清洗脚本

```bash

python clean_documents.py

```

脚本会递归读取data目录,并输出:

```text

output/documents.jsonl

```

JSONL每一行是一条独立记录,适合流式处理和后续批量切分。打开文件检查三件事:正文是否完整;来源和页码是否存在;同一段内容是否被重复读入。

八、为什么输出JSONL而不是直接写入Qdrant

此时还没有进行Chunk切分,也没有生成Embedding。先落地中间结果,便于检查和重跑。如果解析规则有误,可以从documents.jsonl重新切分,不需要重新读取所有原始文件。

这也是RAG工程中很重要的边界:原始文件是输入,中间文档记录是可审计产物,向量库是检索索引。三者不要混成一个不可回滚的脚本。

九、本期验收清单

确认data目录中的文件都被识别;Markdown标题没有丢失;TXT没有乱码;数字型PDF能提取正文;扫描PDF被标记为需要OCR;每条记录都有doc_id和source;PDF记录有page;清洗没有删除业务条件;output/documents.jsonl可以重复生成;output目录没有提交敏感原文到公开仓库。

下一期我们进入RAG最关键的参数之一:Chunk切分。会比较固定长度、按标题切分和带重叠切分,并用同一组问题观察召回差异。

到这里,你的RAG输入已经从“杂乱文件”变成了可追踪的标准文档记录。