墨墨墨墨墨宝の宝藏之地
首页项目归档照片墙音乐灵境说说杂谈友链关于
封面

PDF 文件解析到底应该怎么做?从文本提取到企业级文档理解

写作时间:2026-09-09 22:28:33
# 知识库
# PDF

很多人第一次接触 PDF 解析时,会觉得这个问题应该很简单:

不就是把 PDF 里的文字提取出来吗?

如果只是为了读取一份普通 PDF,确实很简单。

用 PyMuPDF、pdfplumber,几行代码就能把文本拿出来。

但如果需求变成:

  • 解析企业内部几万份 PDF;
  • 同时支持电子 PDF 和扫描件;
  • 识别标题、正文、表格、图片;
  • 保留章节层级和上下文;
  • 最终还要进入 RAG 知识库;
  • 并且要求解析结果尽可能稳定;

问题就完全不一样了。

真正的企业级 PDF 解析,本质上不是一个 Text Extraction 问题,而是一个 Document Understanding(文档理解) 问题。

一个相对完整的处理链路,大致可以拆成:

PDF 输入
   │
   ▼
① PDF 基础解析
   │
   ▼
② 文本提取 / OCR
   │
   ▼
③ 页面布局理解
   │
   ▼
④ 表格 / 图片理解
   │
   ▼
⑤ 文档结构融合
   │
   ▼
⑥ Chunk 切片
   │
   ▼
RAG / 知识库

每一层解决的问题都不一样。

而真正影响最终效果的,往往并不是 OCR。


一、先理解一个事实:PDF 本质上不是“文档”

这是理解 PDF 解析最重要的一点。

我们平时看到的 Word 文档,本身具有明确的语义结构。

例如:

标题

正文

表格

图片

Word 知道这一段是标题,那一段是正文,某一块是表格。

但是 PDF 很多时候并不知道。

对于 PDF 来说,它保存的更接近:

在坐标 (100, 50) 绘制文字 A

在坐标 (200, 50) 绘制文字 B

在坐标 (100, 80) 画一条线

在坐标 (100, 120) 放一张图片

换句话说:

PDF 更接近一种页面绘制格式,而不是结构化文档格式。

这也是为什么一个 PDF 在人眼看来非常规整,但程序解析出来以后却可能完全乱掉。

因为人类看到的是:

第三章 系统设计

3. 1 数据库设计

系统数据库采用……

程序最开始看到的可能只是:

[
  {
    "text": "第三章",
    "x": 100,
    "y": 120,
    "font_size": 22
  },
  {
    "text": "系统设计",
    "x": 180,
    "y": 120,
    "font_size": 22
  }
]

至于它是不是标题、属于第几级标题、后面哪些内容属于它,这些都需要重新推断。

所以 PDF 智能解析的核心目标,其实可以总结成一句话:

把一个“页面绘制结果”,重新还原成一个“结构化文档”。


二、第一层:PDF 基础解析

整个流程首先需要解决的是:

PDF 文件本身能够提供哪些原始信息?

通常需要获取:

  • 文本;
  • 文本坐标;
  • 字体;
  • 字号;
  • 图片;
  • 页面尺寸;
  • 页码;
  • Drawing 信息;
  • Block 信息。

Python 生态里比较常见的是 PyMuPDF(fitz)。

例如:

page.get_text("dict")

可以拿到类似:

{
  "text": "系统架构",
  "bbox": [100, 200, 300, 250],
  "font": "宋体",
  "size": 18
}

这里非常重要的一点是:

我们不应该只拿:

系统架构

而应该把:

文本 + 坐标 + 字体 + 字号 + 页码

一起保留下来。

因为这些信息后面都会参与页面结构判断。

另外还有一些常见工具:

pdfplumber

比较适合:

  • 坐标分析;
  • 文本提取;
  • 简单表格分析。

Apache PDFBox

Java 项目中比较常见。

对于企业内部以 Java 为主的系统,PDFBox 也是一个很成熟的选择。

这一层本身技术难度并不算特别高。

真正的问题在于:

基础解析只能告诉你“页面上有什么”,不能告诉你“这些东西是什么意思”。


三、第二层:OCR——解决扫描件问题

不是所有 PDF 都真正包含文本。

企业内部经常会碰到:

  • 扫描合同;
  • 扫描发票;
  • 扫描档案;
  • 盖章文件;
  • 历史材料。

这种 PDF 本质上可能只是:

PDF
 └── 一张图片

你调用:

page.get_text()

可能什么都拿不到。

这个时候就必须走 OCR。

典型流程:

PDF Page
   │
   ▼
页面转图片
   │
   ▼
文本检测
   │
   ▼
文本识别
   │
   ▼
文本 + 坐标 + 置信度

最终得到类似:

{
  "text": "合同编号",
  "bbox": [100, 200, 300, 240],
  "confidence": 0.98
}

开源方案中,中文场景经常使用 PaddleOCR。

商业环境下也可能直接接:

  • Azure Document Intelligence;
  • AWS Textract;
  • 阿里云 OCR;
  • 腾讯云 OCR;
  • 企业内部 OCR 服务。

现在 OCR 对于正常印刷文字已经比较成熟。

真正容易出问题的是:

  • 手写文字;
  • 印章覆盖;
  • 低清扫描;
  • 倾斜;
  • 强噪声;
  • 模糊图片;
  • 特殊字体。

所以 OCR 是一个重要模块,但它往往不是现代 PDF 解析系统里最难的部分。

因为 OCR 解决的只是:

这里写了什么。

它并没有解决:

这段文字在整个文档里面是什么。


四、第三层:Layout Analysis,真正的核心

如果让我选 PDF 智能解析里面最关键的一层,我会选:

Layout Analysis——页面布局理解。

假设我们已经拿到了:

第一章 系统概述
系统主要用于……
1. 1 建设目标
……

接下来需要判断:

  • 哪一个是标题?
  • 哪一个是正文?
  • 哪一个是页眉?
  • 哪一个是页脚?
  • 哪一个是表格?
  • 哪一个是图片?
  • 哪几个 Block 属于同一段?
  • 阅读顺序是什么?

也就是把:

坐标 + 文本

变成:

语义 Block

例如:

{
  "type": "heading",
  "level": 1,
  "content": "第一章 系统概述"
}

或者:

{
  "type": "paragraph",
  "content": "系统主要用于……"
}

最简单的方案:规则

例如:

字号 > 18
→ 标题

页面顶部固定区域
→ 页眉

页面底部固定区域
→ 页脚

规则的优势非常明显:

  • 快;
  • 稳定;
  • 容易解释;
  • 成本低。

如果企业内部 PDF 模板高度统一,规则方案甚至可能非常好用。

问题在于:

泛化能力差。

一旦文件变成:

  • 合同;
  • 论文;
  • 财报;
  • 招标文件;
  • 规章制度;
  • 产品手册;

规则很快就会失效。

比如一个财报中的 18 号字体,可能只是表格标题。

而一个合同正文标题,可能只有 14 号字体。

因此工业系统一般不会完全依赖单一规则。


五、Layout 模型解决什么问题?

更进一步,可以引入文档理解模型。

例如 LayoutLM 系列的核心思想就是:

模型不只看:

“数据库设计”

还会看:

文字内容
+
文字所在位置
+
页面视觉信息

例如:

文字:数据库设计

位置:
x = 100
y = 200

字号:
18

视觉特征:
加粗、独占一行

模型最终判断:

Heading

类似的方向还有:

  • LayoutParser;
  • DocTR;
  • 各类 Document AI 模型;
  • 多模态文档模型。

这一层为什么难?

因为根本不存在一种统一的 PDF 排版方式。

论文的结构可能是:

Title
Abstract
1 Introduction
2 Related Work

合同可能是:

第一条
第二条
(一)
1.

招标文件又可能是:

第一章
1. 1
1. 1.1
一、
(一)
1.

财报还会夹杂大量:

  • 表格;
  • 图;
  • 注释;
  • 双栏排版。

所以 Layout Analysis 的本质其实是:

根据视觉信息、空间信息以及文本语义,重新推断文档的结构。

这也是 PDF 智能解析真正开始困难的地方。


六、第四层:表格解析,比 OCR 麻烦得多

表格通常是 PDF 解析里的第二个大坑。

一个人看到:

姓名年龄张三20

马上就知道:

张三的年龄 = 20

但 PDF 内部可能只是:

姓名
年龄
张三
20

然后每个文字分别有自己的坐标。

程序需要自己推断:

姓名 和 年龄
属于第一行

张三 和 20
属于第二行

张三 和 姓名
属于同一列

这就涉及:

  • 行识别;
  • 列识别;
  • 单元格识别;
  • 合并单元格;
  • 表头识别;
  • 跨页表格。

传统方案

例如 Camelot。

对于有明确线框的表格:

+--------+--------+
| 姓名   | 年龄   |
+--------+--------+
| 张三   | 20     |
+--------+--------+

处理效果通常不错。

Tabula 也是比较经典的方案。

AI 方案

例如 Table Transformer。

通常流程:

页面图片
   │
   ▼
Table Detection
   │
   ▼
Row / Column / Cell Detection
   │
   ▼
结构还原
   │
   ▼
HTML / Markdown / JSON

最终可能还原为:

<table>
  <tr>
    <td>姓名</td>
    <td>年龄</td>
  </tr>
  <tr>
    <td>张三</td>
    <td>20</td>
  </tr>
</table>

但实际企业文件远没有这么理想。

最麻烦的是:

  • 无边框表格;
  • 合并单元格;
  • 多级表头;
  • 跨页表格;
  • 单元格内部存在段落;
  • 表格中嵌套图片;
  • 同一页多个表格;
  • 表格和正文混排。

特别是跨页表格。

例如:

Page 10

姓名 | 部门 | 金额
张三 | 技术部 | 100
李四 | 技术部 | 200

--- Page Break ---

王五 | 财务部 | 300
赵六 | 财务部 | 400

第二页可能根本没有表头。

系统还要判断:

第二页这一块是不是上一页表格的延续?

这已经不是单纯 OCR 可以解决的问题了。


七、第五层:图片、图表和架构图

现代企业文档里还有大量非文本信息:

  • 系统架构图;
  • 流程图;
  • 柱状图;
  • 折线图;
  • 产品截图;
  • 示意图;
  • 网络拓扑图。

如果只是传统 PDF Parser,最多只能告诉你:

这里有一张图片。

但它不知道图片表达了什么。

因此可以考虑引入 Vision LLM。

例如让视觉模型分析:

PDF Page Screenshot
        │
        ▼
Vision Model
        │
        ▼
Image Description

比如一个系统架构图:

用户
 ↓
API Gateway
 ↓
订单服务
 ↓
数据库

视觉模型可能生成:

该架构采用网关统一接收请求,
下游包含订单服务,订单服务访问数据库。

这就可以进一步进入知识库。

但多模态模型也不是万能的。

简单截图通常问题不大。

真正困难的是类似:

30 个模块
+
100 条连接线
+
多种颜色
+
多个子系统

这类复杂架构图。

视觉模型非常容易:

  • 漏掉节点;
  • 看错箭头;
  • 搞反调用关系;
  • 合并不同模块;
  • 编造不存在的连接。

所以这里仍然要区分:

“能描述图片”和“能精确还原图片中的结构关系”是两个完全不同的能力。


八、第六层:Document Object Model

到了这里,我们会发现一个新的问题:

前面拿到了很多东西:

Text
OCR
Heading
Paragraph
Table
Image
Page
BBox

接下来怎么统一?

这就是一个非常典型的工程问题。

一个比较合理的做法是建立自己的:

Document Object Model。

可以把它理解为 PDF 世界里的 HTML DOM。

例如:

{
  "document_id": "xxx",
  "pages": [
    {
      "page": 10,
      "blocks": [
        {
          "id": "block_001",
          "type": "heading",
          "level": 1,
          "content": "数据库设计"
        },
        {
          "id": "block_002",
          "type": "paragraph",
          "content": "数据库采用……"
        },
        {
          "id": "block_003",
          "type": "table",
          "content": {}
        }
      ]
    }
  ]
}

如果做得更完整,还可以保留:

parent_id
previous_id
next_id
page_number
bbox
source
confidence
heading_path
image_id
table_id

最终形成:

Document
 ├── Chapter
 │    ├── Heading
 │    ├── Paragraph
 │    ├── Table
 │    └── Image
 └── Chapter

这一步的重要程度经常被低估。

因为如果没有统一的数据模型,前面的各个解析模块很容易变成:

OCR 输出一种 JSON

表格模型输出另一种 JSON

图片模型输出 Markdown

Layout 模型又输出一种格式

最后整个知识库系统会非常难维护。

所以企业级系统真正需要设计的不是一个:

PDF → Text

而是:

PDF → Structured Document

九、Chunk 并不是“500 Token 切一下”这么简单

PDF 终于解析完成之后,一般还要进入 RAG。

很多系统到了这里会直接:

500 Token 一个 Chunk

然后做 Embedding。

这当然可以跑。

但效果很容易出问题。

例如原始文档:

第三章 数据库设计

3. 1 数据库连接池

数据库最大连接数配置为 100。

如果切成:

Chunk A:

第三章 数据库设计

以及:

Chunk B:

数据库最大连接数配置为 100。

用户搜索:

数据库设计里的连接池最大连接数是多少?

Chunk B 虽然包含答案,但已经失去了:

第三章 数据库设计
3. 1 数据库连接池

这些上下文。

这也是为什么我一直认为:

RAG 的切片质量,本质上取决于前面的文档结构还原质量。

如果前面已经得到了:

第三章 数据库设计
   └── 3.1 数据库连接池
          └── 最大连接数配置为100

那么 Chunk 就可以保存:

{
  "content": "数据库最大连接数配置为100。",
  "heading_path": [
    "第三章 数据库设计",
    "3.1 数据库连接池"
  ]
}

最终进入 Embedding 的文本甚至可以是:

第三章 数据库设计
3. 1 数据库连接池

数据库最大连接数配置为100。

这样检索质量会明显更稳定。

所以相比单纯使用:

Fixed-size Chunking

我更倾向于:

Heading-aware Chunking
+
Semantic Chunking
+
Parent-Child Chunking

根据不同文档动态组合。


十、哪些环节最难?

如果按照企业实际落地时的效果保障难度,我个人会这样排序:

排名模块难度1Layout / 文档结构还原⭐⭐⭐⭐⭐2表格结构还原⭐⭐⭐⭐⭐3Chunk 与上下文保持⭐⭐⭐⭐4复杂图片 / 图表理解⭐⭐⭐⭐5Document Model 融合⭐⭐⭐6OCR⭐⭐7PDF 基础文本提取⭐

这里有一个比较反直觉的地方:

很多 PDF 解析项目一开始最关注 OCR。

但真正做到后面就会发现:

OCR 错几个字,影响的可能只是一句话。

而结构错了,影响的可能是一整篇文档。

比如:

标题识别错
→ 章节层级错
→ Chunk 切错
→ 上下文丢失
→ RAG 检索错
→ LLM 最终回答错

这是一个非常典型的误差传播链路。


十一、企业里真正现实的方案是什么?

如果真的要做一个企业级 PDF 解析系统,我并不认为应该一开始就追求:

任意 PDF
+
100% 自动解析
+
100% 准确

这个目标本身就不现实。

更务实的路线通常是:

PDF Parser
+
OCR
+
Layout Analysis
+
Table Parser
+
Vision Model
+
LLM Correction
+
Document Model

然后针对企业内部高频文档不断优化。

例如:

第一阶段
先覆盖 60%~70% 主流文件

↓

第二阶段
针对合同、制度、报告等高频模板优化

↓

第三阶段
补充特殊表格、跨页、图片等能力

↓

第四阶段
建立解析评估集持续回归测试

而不是:

为了一个非常特殊的 PDF
写 500 行特殊规则

企业知识库中的 PDF 类型往往非常杂。

今天是合同,明天是财报,后天又是 PPT 转出来的 PDF。

如果每一种文件都写一套特殊逻辑,最终系统一定会失控。

因此更加合理的思路应该是:

构建一套足够精细的底层文档模型和解析架构,再通过持续测试、模型升级和局部规则不断提高覆盖率。


十二、LLM 应该放在哪里?

现在还有一种很容易出现的思路:

既然大模型这么强,直接整页 PDF 截图丢给多模态模型不就好了?

小规模场景当然可以。

但是企业级系统很难全部这么做。

主要有几个原因:

1. 成本

几万、几十万份文件全部走视觉大模型,成本很高。

2. 稳定性

传统 Parser 对于:

文本
坐标
字体

这类信息是确定性的。

LLM 则存在概率性。

3. 可解释性

企业系统需要知道:

这一段内容来自第几页?
原始坐标在哪里?
解析置信度是多少?

不能只拿到模型生成的一段 Markdown。

4. 幻觉

特别是复杂表格和架构图,大模型可能生成原文不存在的信息。

所以我更倾向于把 LLM 放在:

传统解析解决 80%
+
LLM 处理复杂语义和修正

而不是:

LLM 替代整个 Document Parser

例如可以让 LLM 帮忙:

  • 判断两个 Block 是否属于同一段;
  • 修正异常阅读顺序;
  • 判断标题层级;
  • 判断跨页表格;
  • 对图片生成描述;
  • 修复 OCR 明显错误;
  • 对解析结果进行一致性检查。

这样会更加符合企业系统的工程要求。


十三、最后:PDF 解析其实是一个“小型文档智能系统”

如果只是:

pdf_to_text()

PDF 解析非常简单。

但当目标变成:

“让 AI 真正理解企业 PDF,并把它变成可靠知识。”

整个问题就会从一个 Python 工具调用,逐渐演变成:

Document Parser
+
OCR
+
Computer Vision
+
Layout Understanding
+
Table Recognition
+
Multimodal LLM
+
Data Modeling
+
RAG

这也是为什么很多知识库系统:

Demo 看起来效果非常好。

但是一进入真实企业数据,马上就开始出现:

表格错乱
标题丢失
章节关系丢失
图片无法理解
跨页内容断裂
检索上下文不足

因为真正决定知识库效果的,往往不是最后用了哪个 Embedding 模型。

而是更早的一步:

你到底有没有把原始文档解析成“正确的知识结构”。

所以如果让我总结企业级 PDF 智能解析最重要的设计原则,我会归纳成三点:

第一,不要把 PDF 当成纯文本。

它首先是一个具有二维空间关系的页面。

第二,不要把 PDF 解析等同于 OCR。

OCR 解决的是“写了什么”,Document Understanding 解决的是“它是什么意思、它属于哪里”。

第三,不要只关注解析准确率,要关注结构是否能够一直传递到 RAG。

最终真正有价值的链路应该是:

PDF

↓

页面元素

↓

结构化 Document

↓

章节 / 段落 / 表格 / 图片关系

↓

语义 Chunk

↓

检索

↓

完整上下文

↓

LLM

当这条链路真正打通之后,PDF 才不再只是一份“可以搜索的文本”。

而真正变成了一份:

机器可以理解、检索、引用和推理的知识。

avatar

墨墨墨墨墨宝

在 AI 的浪潮里写代码,也顺便研究怎么别被浪拍死。

RECOMMENDED

企业级模型调用问题归档

2026-09-07 22:38:29

FDE 不是更高级的驻场开发,而是一种高成本的公司运行机制

2026-09-08 17:47:56

当 100k Token 预算只剩 60k:AI 系统应该如何做资源优化?

2026-09-10 13:02:35

Table of Contents