PDF导入RAG后乱码、空白或顺序错乱怎么办?文档解析完整排查
文章摘要
PDF导入知识库后出现乱码、空白、文字顺序错乱,是企业RAG项目最常见的数据源故障。根因可能是扫描件没有文本层、字体使用自定义编码、双栏版式阅读顺序错误、表格被拆散、OCR语言配置不正确,或者解析结果未经质量校验就直接分块。本文给出从PDF类型识别、文本层检测、字体与编码、OCR、版面恢复到入库质量门禁的完整排查流程。
一、先不要急着调整Embedding模型
典型现象:
上传PDF
→ 成功生成向量
→ 搜索不到正确内容
开发者常见的第一反应是:
- 换Embedding模型;
- 调高Top K;
- 调低相似度阈值;
- 更换向量数据库。
但如果解析出的原始文本已经错误,后续任何检索优化都无法补救。
第一步应该查看:
PDF解析后的原始文本
而不是直接查看最终问答结果。
二、先判断PDF属于哪种类型
1. 文字型PDF
可以在阅读器中选中文字并复制。
通常可以直接提取文本,但仍可能存在:
- 字体编码异常;
- 阅读顺序错误;
- 页眉页脚混入;
- 表格结构丢失。
2. 扫描型PDF
每一页本质上是一张图片。
特征:
- 无法选中文字;
- 文本提取结果为空;
- 文件来自扫描仪或拍照;
- 页面有明显阴影和倾斜。
必须使用OCR。
3. 混合型PDF
部分页面有文本层,部分页面是扫描图。
常见于:
- 合同附件;
- 盖章文件;
- 多来源合并文件;
- 旧档案数字化。
需要逐页判断,不能只根据第一页决定整个文件的解析方式。
三、文本为空怎么排查
检测每页字符数:
from pypdf import PdfReader
def inspect_pdf(path: str) -> list[dict]:
reader = PdfReader(path)
result = []
for index, page in enumerate(reader.pages):
text = page.extract_text() or ""
result.append({
"page": index + 1,
"char_count": len(text.strip()),
"preview": text[:100]
})
return result
判定规则可以是:
字符数大于100 → 可能是文字页
字符数1—100 → 需要人工检查
字符数为0 → 大概率需要OCR
阈值应根据文档类型调整。
四、为什么复制正常,程序却提取乱码
PDF存储的未必是Unicode文本。
它可能保存:
字形编号
+字体映射
+页面坐标
阅读器能够根据字体映射显示正确字符,但解析库可能无法恢复原始Unicode。
表现为:
□□□
乱码符号
不可见字符
字母顺序异常
处理方式:
- 更换PDF解析引擎;
- 检查是否存在ToUnicode映射;
- 对问题页进行OCR;
- 对解析结果做字符异常检测;
- 保留原页图片用于追溯。
五、建立乱码检测器
import re
def calculate_garbled_ratio(text: str) -> float:
if not text:
return 1.0
suspicious = re.findall(
r"[\uFFFD\x00-\x08\x0B\x0C\x0E-\x1F]",
text
)
return len(suspicious) / len(text)
还可以统计:
- 替换字符
�; - 连续方框;
- 控制字符;
- 中文文档中的异常拉丁字符比例;
- 单字重复;
- 无空格长串。
命中阈值后自动转OCR流程。
六、双栏和多栏版式为什么会错序
页面视觉顺序可能是:
左栏从上到下
→ 右栏从上到下
简单解析器可能按坐标输出:
左栏第一行
→ 右栏第一行
→ 左栏第二行
→ 右栏第二行
最终文本会像句子被交叉拼接。
解决方案需要版面分析:
检测文本块
→ 判断栏区域
→ 计算阅读顺序
→ 按区域合并
测试时应重点选择:
- 学术论文;
- 产品手册;
- 报纸;
- 双栏招标文件;
- 多栏参数表。
七、OCR不是简单开关
OCR需要配置:
- 语言;
- 分辨率;
- 页面旋转;
- 倾斜校正;
- 表格检测;
- 版面分析;
- 置信度阈值。
中文文件如果只启用英文识别,容易把:
0识别成O
1识别成l
金额小数点丢失
中文标点错位
高风险内容如合同金额、批号、日期和身份证号不能仅依赖OCR结果。
八、OCR质量如何评估
每个页面记录:
ocr_engine
ocr_language
ocr_confidence
rotation
image_dpi
char_count
processing_time
抽样检查:
- 标题是否正确;
- 数字是否正确;
- 条款编号是否连续;
- 页码是否混入正文;
- 表格字段是否对应;
- 专业术语是否错误。
可以建立字符级错误率:
CER = 错误字符数 / 真实字符数
九、页眉页脚会污染检索
如果每页都包含:
公司名称
保密文件
第12页/共80页
分块后这些文本会重复出现几十次,影响Embedding和关键词检索。
清理方法:
- 统计跨页重复行;
- 判断其坐标是否位于顶部或底部;
- 超过一定重复页数后标记为页眉页脚;
- 删除但保留页码Metadata。
不要直接删除所有短行,因为标题也可能很短。
十、表格不能当普通段落处理
错误结果:
产品A 100 20 产品B 200 30
模型无法判断:
- 哪个数字对应哪个产品;
- 100是库存还是价格;
- 表头是什么;
- 单位是什么。
建议输出为Markdown:
| 产品 | 库存 | 本月销量 |
|---|---:|---:|
| 产品A | 100 | 20 |
| 产品B | 200 | 30 |
并保存:
table_id
page
caption
headers
source_document
十一、公式和特殊符号怎么办
技术文档可能包含:
- 数学公式;
- 化学式;
- 上下标;
- 希腊字母;
- 工程单位;
- 流程图。
普通文本提取可能把:
m²
CO₂
α
变成错误字符。
处理策略:
- 保留原始公式表示;
- 使用支持公式识别的解析器;
- 保存页面截图;
- 对单位和数字做规则校验;
- 关键参数进入结构化数据表。
十二、解析结果必须经过质量门禁
不要采用:
解析成功
→ 直接分块
→ 直接入库
推荐:
解析
→ 页面级质量检查
→ 文档级质量检查
→ 异常页OCR或人工处理
→ 清洗
→ 分块
→ 入库
质量指标:
empty_page_ratio
garbled_ratio
ocr_page_ratio
duplicate_line_ratio
table_count
image_count
average_chars_per_page
language_confidence
十三、建议的失败状态
PARSE_PENDING
PARSE_SUCCEEDED
PARSE_PARTIAL
OCR_REQUIRED
MANUAL_REVIEW
REJECTED
INDEXED
不要把“部分页面失败”的文档标记为完全成功。
十四、最小排查清单
□ PDF是否有文本层
□ 是否存在扫描页
□ 原始文本是否为空
□ 是否出现乱码字符
□ 阅读顺序是否正确
□ 页眉页脚是否清理
□ 表格结构是否保留
□ OCR语言是否正确
□ 数字、日期、单位是否准确
□ 异常页是否阻止入库
总结
PDF进入RAG前,必须先完成:
类型识别
→ 文本或OCR解析
→ 版面恢复
→ 表格处理
→ 清洗
→ 质量检查
乱码、空白和顺序错乱属于数据工程问题,不是Embedding或大模型问题。只有解析结果可读、完整、可追溯,后续Chunk和检索优化才有意义。
延伸阅读
如果你正在关注企业级 AI 应用、RAG、Agent、MCP 与大模型工程化落地,欢迎访问 智元界:
https://www.zyentor.com/
智元界将持续分享可运行的技术实战、架构设计、问题排查与企业应用案例。