这次做本地 Word 标书自动填报,我越来越清楚地感觉到,一个系统一旦需要用户不断截图、不断指出“这里没填”“那里识别错了”,它就还没有真正理解自己在处理什么问题。

表面上看,需求很简单:给我一份 Excel 或结构化数据,把里面的内容填进一批 Word 文档里。

但只要文档开始异构,这件事就会迅速变形。
同一个业务字段,可能出现在段落、表格、括号、签章区、声明段、附件页、身份证图片区、法定代表人承诺书、联合体协议里。它们在文本形式上完全不同,在版面位置上也没有统一模板,但在业务语义上却指向同一类信息。

所以这个问题真正困难的地方,从来不是“写 Word”,而是:系统能不能理解文档里哪些区域本质上是在索取什么信息。

这类任务真正处理的,不是字符串替换,而是语义槽位识别

如果文档完全标准化,自动填充其实不难。你知道每个字段对应哪个书签、哪个表格单元格、哪个占位符,剩下的工作只是做映射和回填。

但在真实场景里,特别是标书、合同、申报材料、资质文件这类文档中,问题往往不是缺少写入能力,而是缺少统一的槽位定义。

同一个“供应商名称”,可能表现为:

  • 供应商名称:____
  • 乙方(成交供应商):
  • 单位名称(盖章):
  • 本人___系___法定代表人
  • 牵头人名称:

从文本表面看,这些位置彼此差异巨大。

但从填写意图看,它们都在要求系统识别某种组织主体信息。

这说明一个很关键的问题:
自动填充 Word 并不是一个简单的文本替换任务,而是一个文档中的语义槽位识别任务。只有先识别“这个位置要什么”,后面的填充才有意义。否则系统永远只能停留在“看见一个标签、匹配一个值”的低层次自动化上。

当前方案为什么会显得像“头痛医头”

你之前的批评非常准确。
如果一个系统需要用户持续指出漏填案例,再由开发者补正则、补别名、补表格规则,它虽然能工作,但还没有形成真正的泛化能力。

这种方案的典型特征是:

  • 对少量样本文档适配得越来越好。
  • 每遇到一种新模板,又要补一层规则。
  • 规则越来越多,但系统对“为什么这里该填”仍然缺乏统一解释。

它的优点当然也很现实:

  • 落地快。
  • 对局部样本见效快。
  • 能快速验证项目是否可做。

但问题同样明显:

  • 维护成本会持续上升。
  • 规则之间会互相碰撞。
  • 新文档一进来,系统又回到“先看哪里坏了再修哪里”的模式。

这就是为什么很多文档自动化项目一开始看起来进展很快,后面却越来越像在修补裂缝。因为它们真正缺的,不是更多规则,而是更高一层的文档理解能力。

这次方案核心上并不是 CV,而是结构解析加规则匹配

严格说,这次的主路径几乎不是计算机视觉。

核心做法还是:

  • 解析 .docx 的 XML 结构。
  • 读取段落、表格、run、页眉页脚。
  • 基于标签别名、正则、上下文和局部表格结构做匹配。
  • 再把结果写回 Word,并尽量保持格式。

这是一条非常自然的路线,因为 .docx 本身就是结构化文档。
既然能直接拿到段落和表格,第一反应当然应该是从结构层处理,而不是先渲染页面再做视觉识别。

但这里有一个关键边界:
结构化不等于足够理解。

你之所以会强烈感觉“这里其实应该有 CV”,不是因为 OCR 更高级,而是因为你的任务已经超出了 XML 结构本身能够清晰表达的范围。你真正关心的是:

  • 页面上哪里看起来像一个待填区。
  • 哪些视觉上属于同一块内容。
  • 哪些区域虽然文本相似,但其实是签章、附件、图片占位。
  • 哪些字段虽然写法不同,却在语义和版式上属于同一类位置。

这些判断,结构解析只能提供部分线索,无法单独完成。

为什么只靠规则最终会失效

规则不是没有价值。事实上,在文档自动化的早期阶段,规则通常是最现实、最高性价比的切入方式。

问题在于,规则系统能否长期成立,取决于文档世界是否足够稳定。

一旦文档开始表现出下面这些特征,规则就会越来越脆:

  • 同一字段在不同模板里写法差异很大。
  • 表格结构并不固定。
  • 待填区并不总是文本标签加空格线。
  • 某些信息以图片、签章框、附件页形式出现。
  • 段落中存在多层嵌套条件和可选条款。

这时,规则还能起作用,但它的角色应该开始变化。
它不再适合作为唯一引擎,而更适合作为高置信度的局部判断器。真正的主引擎,需要逐步升级成一种“结构 + 视觉 + 语义”的联合理解系统。

也就是说,规则可以负责:

  • 明确标签的快速定位。
  • 已知模板的高效填充。
  • 某些稳定表格结构的直接映射。

而更高层的系统,则需要负责:

  • 判断一块区域是什么类型。
  • 判断一个槽位和哪个业务字段最相关。
  • 判断某个位置是否应该填文字、图片、盖章或保持空白。

真正可扩展的方案,应该把 Word 看成版面理解问题

如果目标是处理少量固定模板,现有方案已经足够有价值。

但如果目标是:

  • 面向 1000+ 异构文档,
  • 尽量少依赖人工纠错,
  • 支持持续扩展到更多文书类型,

那系统就不能继续只把自己理解成“Word 填写器”。

更合理的架构应该至少分成几层:

第一层是结构解析层。
继续读取 .docx 的段落、表格、run、图片占位、页眉页脚,因为这些信息仍然是最便宜、最稳定的基础材料。

第二层是版面理解层。
必要时把页面渲染出来,识别视觉块、空白区、签章区、附件图片区、复选条款区和表格区域,让系统知道一页纸在视觉上是怎么组织的。

第三层是语义映射层。
把“供应商名称”“法定代表人”“项目名称”“投标总价”“身份证号”这类业务字段,映射到文档中的潜在槽位,而不是只做字符串近似匹配。

第四层是回填与验证层。
不仅负责写回,还要负责检查:哪些字段已经填了,哪些有多个候选位置,哪些位置置信度过低,哪些需要人工确认。

一旦这样分层,系统才会从“局部自动化脚本”升级成真正的文档填报引擎。

对后来者更重要的,不是先选技术,而是先承认问题本质

我觉得这类项目里最容易犯的错误,不是用错某个库,而是把问题定义得太窄。

如果你把它定义成“批量改 Word”,那自然会优先想到 Office 自动化、书签替换、正则匹配和 XML 写回。

但如果你把它定义成“在复杂文书里寻找可被填写的语义槽位,并将结构化业务数据稳定落回去”,那你对系统的期待就会完全不同。

这时你会更自然地接受:

  • 规则不是终点,只是起点。
  • .docx 结构解析很重要,但不是全部。
  • CV 不是为了炫技,而是为了补足结构层看不到的版面信息。
  • 人工确认不是失败,而应该是低置信度路径里的正式节点。

这其实就是文档自动化走向成熟的标志。
不是要求系统一次性全自动,而是先把问题拆成它真实存在的那几层。

写在最后

自动填充 Word 文档,真正困难的地方,从来不是“把值写进文件”,而是如何在高度异构的文档世界里识别出稳定的填写意图。

你真正要管理的,不只是段落、表格和 run,而是字段语义、版面结构、附件类型、填写动作和回填置信度之间的关系。

所以这类系统最值得升级的方向,不是继续堆更多补丁规则,而是逐步从“规则驱动的 Word 修改器”走向“结构、视觉、语义联合驱动的文档理解系统”。只有到了这一步,自动填报才会真正从能用,变成可扩展。