码上拾光

无书签 PDF 的大纲从哪里来:三级容错的解析链路

· #架构#文档解析#AI应用

去年接的第一个活,做到现在终于稳定了。问题很具体:客户给的技术文档是 PDF,大多没有书签,几百页,要按章节结构切成条目给下游系统用。核心难点只有一个——大纲从哪来

三个来源,没有一个够

书签。 有书签的 PDF 直接读书签树,准确、快。但客户的文档里有书签的不到三成,而且不少书签是错的(扫描件用工具补的)。

多模态模型。 把页面图片喂给视觉语言模型,让它标出标题和层级。效果比想象中好,但两个问题:一是贵、慢,几百页要跑很久;二是它给的坐标不准,后面单独写一篇。

启发式规则。 按字体大小、加粗、编号模式(1.、1.1、1.1.1)判断标题。快、免费,但遇到排版不规范的文档就乱。

三个来源单独用都不行。

链路

最后做成了三级容错:

PDF ──► 有可信书签? ──是──► 书签树 ────────────────┐
         │否                                        │
         ▼                                          │
       版面解析(MinerU)出文本块与坐标               │
         │                                          ▼
         ▼                                     大纲树
       多模态模型标注标题 ──► 坐标回锚 ──► 层级推断 ─┘
         │失败/超预算

       启发式规则(字体特征 + 编号)

每一级的判断标准:

层级推断为什么单独一步

模型标出来的标题带层级,但经常错——它会把”3.1”标成一级,把”3”标成二级。所以层级不信模型,单独推:

  1. 先看编号:点号数量决定层级(3 一级,3.1 二级)。OCR 噪点要容错,3 .13.1 都得认成 3.1
  2. 没编号的标题,用模型标注的层级,但要经过”单调性检查”:前一个标题是二级,下一个不能直接跳到四级。
  3. 两个来源冲突,编号优先。

这一步修掉了最烦人的一类错误:阶梯式嵌套——每个标题都比上一个深一级,整棵树歪成一条斜线。

切片

大纲树有了,切片就是按标题的坐标范围截页面。300 DPI 渲染,跨页的章节拼接。这部分没什么难的,难的是坐标要准,而坐标准不准取决于回锚那一步。

验收口径

客户验收时看的是”大纲对了多少、切片对了多少”,目前稳定在 94% 以上。剩下的 6% 集中在两类文档:扫描质量差的,和排版完全不规范的(标题不加粗不编号,纯靠空行分隔)。这两类靠链路解决不了,得靠人工复核,系统里留了复核入口。

一句话

模型不可靠,规则不聪明,书签不齐全。三个不完美的来源按可信度排队,每一级只接自己能确定的,剩下的往下传。这个结构后面在别的项目里又用了几次。


← 回到文章列表