文档加载与解析:让RAG系统读懂你的文件
做RAG系统,第一步就是要把文档喂给机器。但机器不是人,它看不懂PDF里的排版,也读不懂Word里的表格。说白了,我们需要一个“翻译官”——把各种格式的文件,转成机器能理解的纯文本。
我个人习惯把这一步叫做“文档的预处理”。你想想看,如果这一步没做好,后面检索再牛,也是垃圾进垃圾出。我在项目中遇到过太多次了,因为PDF解析漏了一行关键数据,整个问答系统就答非所问。
常见文档格式:PDF、Word、HTML
现实世界里,文档格式五花八门。但RAG系统最常打交道的,就这三种:
- PDF:最头疼的格式。它本质上是“打印出来的图片”,文字可能被切割、乱序。尤其是扫描件,简直就是噩梦。
- Word:相对友好。结构清晰,有段落、标题、表格。但要注意,有些Word文档里嵌了图片,图片里的文字是读不出来的。
- HTML:网页的骨架。标签嵌套复杂,但只要你懂点前端,用BeautifulSoup就能轻松提取正文。
嗯,这里要注意:不要以为所有PDF都能完美解析。我曾经处理过一份政府红头文件,PDF里用了特殊字体,结果解析出来全是乱码。后来我换了个工具才搞定。
文档解析工具:三剑客
工欲善其事,必先利其器。我常用的三把刀:
1. PyMuPDF(fitz)—— PDF解析首选
为什么推荐它?因为它快,而且能处理复杂的PDF布局。我习惯用它来提取文本、表格,甚至图片。
import fitz # PyMuPDF
doc = fitz.open("report.pdf")
for page_num, page in enumerate(doc):
text = page.get_text()
print(f"第{page_num+1}页内容:\n{text}")
你看,代码就这么几行。但有个坑:get_text()默认是按阅读顺序提取的,如果PDF里有多栏布局,它可能会把两栏的文字混在一起。我曾经因为这个,把一份双栏论文解析得乱七八糟。后来我改用page.get_text("blocks"),按块提取,再手动排序,才解决了问题。
2. python-docx —— Word文档的瑞士军刀
Word文档相对规整。python-docx可以读取段落、表格、标题样式。我一般这样用:
from docx import Document
doc = Document("report.docx")
for para in doc.paragraphs:
print(para.text, para.style.name) # 文本内容和样式名
这里有个细节:Word里的表格,需要用doc.tables来遍历。我建议把表格转成Markdown格式,这样既保留了结构,又方便后续分块。
3. BeautifulSoup —— HTML解析利器
HTML文档,说白了就是一堆标签。BeautifulSoup能帮你快速定位到正文区域,去掉广告、导航栏这些噪音。
from bs4 import BeautifulSoup
with open("page.html", "r", encoding="utf-8") as f:
soup = BeautifulSoup(f, "html.parser")
# 提取所有段落文本
for p in soup.find_all("p"):
print(p.get_text())
嗯,这里要注意:有些网页的正文藏在<article>或<div class="content">里。我习惯先查看网页结构,再写选择器。别偷懒,直接find_all("p")可能会把页脚也抓进来。
文档分块策略:切得对,才能找得准
文档解析完了,得到一大段文本。但你不能直接把整篇文档扔给RAG系统。为什么?因为大模型的上下文窗口有限,而且检索时,粒度太粗会导致命中率低。
我总结了几种分块策略,你可以根据场景选:
| 策略 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 固定长度分块 | 通用场景,快速原型 | 实现简单,速度最快 | 可能切断语义完整的段落 |
| 段落分块 | 结构清晰的文档(如论文、报告) | 保留语义完整性 | 段落长度不一,可能过长或过短 |
| 语义分块 | 需要高精度检索的场景 | 块内语义连贯,检索效果好 | 实现复杂,需要额外模型 |
| 递归分块 | 长文档,需要多级粒度 | 灵活,可适应不同查询 | 存储成本高,管理复杂 |
我个人最常用的是“段落分块+固定长度兜底”。具体做法是:先按段落切,如果某个段落太长(比如超过500字),再按句子或固定长度切。这样既保证了语义完整,又控制了块的大小。
知识体系总览
下面这张图,是我对本章知识体系的总结。你可以看到,从原始文档到可检索的文本块,中间经历了三个关键步骤:格式解析、文本提取、分块策略。每一步都有对应的工具和注意事项。
你看,整个流程其实不复杂。但每个环节都有细节要注意。我刚开始做RAG时,总想着一步到位,结果在解析这一步就栽了跟头。后来我养成了一个习惯:每处理一种新文档,先手动检查几页,看看解析效果。嗯,这个习惯帮我避免了很多线上事故。
核心要点总结:
- PDF用PyMuPDF,注意多栏布局和扫描件
- Word用python-docx,表格要单独处理
- HTML用BeautifulSoup,先定位正文区域
- 分块策略没有银弹,根据文档内容灵活选择
- 永远先做小规模验证,再批量处理
好了,文档加载与解析就聊到这里。记住一句话:解析的质量,决定了RAG系统的上限。这一步花再多时间都值得。