> 参考文献是字母序的——所以抽取器的验收条件是"首条 A 开头、末条 Z 开头"
一个从 PDF 里抽参考文献的工具,在一批会议论文上基本不可用: 41 条参考文献只抽到 7 条,每一篇都只抽到个位数。 原因是那个模板用悬挂缩进排参考文献,而抽取规则是按字号判断条目边界的。
结论先行¶
一个从 PDF 里抽参考文献的工具,在一批会议论文上基本不可用: 41 条参考文献只抽到 7 条,每一篇都只抽到个位数。 原因是那个模板用悬挂缩进排参考文献,而抽取规则是按字号判断条目边界的。
重写成按 PDF 坐标判断:
条目起始 x ≈ 108
续行 x ≈ 118 ← 悬挂缩进的那 10pt,就是边界信号
页边行号 x ≈ 73 ← 要排除
附录标题 行首的粗体 sans 字体
终止条件 "内容像不像参考文献",而不是字号
但真正值得记住的不是这套规则,是验收办法:
参考文献是按字母序排的。所以抽出来的第一条应该 A 开头,最后一条应该 Z 开头。 一批 PDF 全部满足,才算抽对了。
为什么¶
PDF 抽取这类任务的困境是:没有 ground truth,而且人工核验很贵。 你不可能为了测一个抽取器去手抄 41 条参考文献 × 五篇。
于是通常的做法是看抽出来的条数"像不像对"——而这恰恰是最不可靠的信号: 抽到 7 条和抽到 41 条,在没有真值的情况下都"像"。
字母序端点这个检查的好处是:
- 它来自数据本身的性质,不来自抽取器的实现。 所以抽取器怎么改都不会把这个检查一起改坏。
- 它是端到端的。 首条和末条正确,意味着边界识别、起止判定、排序保持全都对了。 中间漏一条它抓不到,但首尾错了必然是系统性错误。
- 成本是零。 两个字符的比较。
- 它在一批文件上同时成立才通过,这把偶然蒙对排除掉了。
这是一类可以到处找的东西:从数据的已知不变量里,derive 一个廉价的端到端验收条件。 其他例子:
| 数据的不变量 | 可以当验收条件的 |
|---|---|
| 参考文献按字母序 | 首条 A、末条 Z |
| 表格每列加总等于合计行 | 逐列重算 |
| 章节编号连续 | 抽出的标题序列无跳号 |
| 页码递增 | 抽出的块的页码单调 |
| 双语文档两侧段数相等 | 段落计数相等 |
怎么用¶
- 写抽取器之前先找不变量。 问"这份数据有什么性质,是我不抽也知道的?" 那些性质就是你的测试集,而且不用标注。
- 把不变量写成断言,跑在一批真实文件上,不是一个样例上。 一批全部满足才算过。
- 终止条件用语义,不用排版。 "内容像不像参考文献"比"字号变了"稳健得多—— 排版会变,内容的形态不会。
- 按坐标而不是按字号判结构。 悬挂缩进、双栏、行号这些都是坐标上的规律;字号在同一块里经常是常量。
- 抽到的条数远少于预期时,先怀疑边界规则,不要先怀疑 PDF。 41 → 7 这个比例本身就是"边界信号选错了"的指纹。
出处¶
- 自己的参考文献抽取链在一批外部会议 PDF 上的实测,2026-10: 原抽取器在悬挂缩进模板上 41 条只抽到 7 条(每篇都是个位数); 按坐标重写的版本(条目 x≈108 / 续行 x≈118 / 行号 x≈73 / 粗体 sans 判附录标题) 配合"首条 A、末条 Z"的验收条件,一批文件全部通过
- 相关:一个写出来的界是可执行断言——拿它自己声明的参数范围去跑,我的界被我的反例推翻了、用 any() 写的回归测试是假保证——它只要求最容易过的那个夹具通过、 引用全真的时候,靠数值一致性区分论文——六个五分钟能做完的检查