2. 工程合同文本的数字化预处理
在把工程合同交给大模型或规则引擎做条款审查之前,必须先完成一件事:把"人看的合同"变成"机器能算的合同"。这一步统称为数字化预处理。它决定了后续所有审查结论的上限——如果OCR把"发包人"识别成"发包入",把"3.5%"识别成"3.5%",再强的模型也会给出错误判断。本节按真实处理链路,讲清四个环节:PDF/扫描件解析、OCR纠错、段落与条款切分、元数据标注。
一、先判断合同是"电子版"还是"扫描版"
工程合同常见的来源有三类:一是Word/PDF导出的原生电子文档,文字层可直接提取;二是纸质合同扫描或手机拍照生成的图片型PDF,只有像素没有文字;三是混合型,正文是电子文字,但盖章页、附件、图纸是扫描图片。处理前必须先分类,否则会做无用功或漏掉关键页。
判断方法很直接:用解析库尝试提取文字,若某页提取出的字符数极少(例如少于20个字符)而页面尺寸正常,基本可判定为图片页。以Python为例:
import fitz # PyMuPDF
doc = fitz.open("contract.pdf")
for i, page in enumerate(doc):
text = page.get_text("text").strip()
imgs = page.get_images(full=True)
print(f"第{i+1}页 字符数={len(text)} 图片数={len(imgs)}")
# 字符数少且图片数≥1 → 该页需走OCR
实际工程合同中,专用合同条款、协议书、中标通知书通常是电子版,而盖章页、手写补充条款、附件清单常是扫描件。因此解析策略应是"逐页判定、混合处理",而不是整份文档一刀切。
二、OCR纠错:不是识别完就结束
OCR(光学字符识别)把图片转成文字后,错误集中在几类:形近字("己/已/巳"、"未/末")、数字与单位("1"与"l"、"0"与"O"、"m²"识别成"m2")、表格线干扰导致的串行、以及印章覆盖区域的缺字。工程合同里最致命的是金额、日期、比例、工期天数这几类数字错误。
纠错不能只靠通用词典,要建立领域纠错规则。例如:
- 金额字段:识别结果若出现"壹拾贰万"与阿拉伯数字"120000"不一致,标记为待人工复核;
- 日期字段:用正则约束为"YYYY年MM月DD日"格式,非法日期(如2024年13月)直接拦截;
- 比例字段:百分号前后必须是数字,"3.5%"不能变成"3.5%"以外的形态;
- 术语表替换:维护"发包人/承包人/监理人/暂列金额/缺陷责任期"等术语白名单,对编辑距离为1的疑似错词做候选替换并记录日志。
三、段落与条款切分:让机器找到"第X条"
合同审查的最小单位是条款,而不是整篇文档。切分要做两级:先按版面切段落,再按编号体系切条款。
工程合同普遍采用"第X条 → X.1 → X.1.1"的层级编号。切分时用正则识别编号模式,并记录层级深度。例如:
import re
# 匹配 "第3条"、"3.1"、"3.1.2" 等编号
pat = re.compile(r'^(第[一二三四五六七八九十百]+条|\d+(\.\d+){0,3})\s*')
for line in lines:
m = pat.match(line.strip())
if m:
level = m.group(1).count('.') + 1
# level=1 为条,level=2 为款,level=3 为项
难点在于:扫描件的编号可能被识别成"第3条"或"第 3 条"或"第三条",需要归一化;跨页条款要合并;表格内的条款不能按行切碎。切分完成后,每条条款应带上条款号、层级、起止位置、所属章节,形成结构化条款列表。
四、元数据标注:给每条条款贴"标签"
元数据是后续检索和审查的索引。工程合同至少应标注以下字段:
| 元数据字段 | 示例值 | 用途 |
|---|---|---|
| 合同类型 | 施工合同/监理合同/分包合同 | 选择对应审查规则集 |
| 条款类别 | 价款/工期/质量/违约/争议解决 | 分类审查 |
| 风险关键词 | 无限责任、单方解除、垫资 | 风险预警 |
| 金额/比例 | 合同价 12,000,000 元;质保金 3% | 数值合规校验 |
| 来源页/坐标 | P7, (120,340)-(480,410) | 定位原文、高亮回显 |
标注方式建议"规则+模型"结合:先用关键词和正则打底(如出现"违约金"即归入违约类),再用小模型对条款做类别补全。标注结果以JSON存储,每条条款一个对象,便于后续按类别批量审查。
五、把四步串成可复现的流水线
实际落地时,建议把上述四步封装成一条可重复执行的流水线,每一步都输出中间产物并记录日志:解析阶段输出"页级文字/图片标记表",OCR阶段输出"原文—修正—置信度"记录,切分阶段输出"条款层级树",标注阶段输出"条款JSON库"。这样一旦最终审查结论异常,可以逐级回溯定位是解析漏页、OCR错字,还是切分把两条条款合并了。
完成预处理后,合同就从一份不可计算的文档,变成了带编号、带类别、带坐标、可检索可审查的结构化条款集合。这是后续所有条款分析、风险识别与合规校验的数据基础。