翻译文件其实是填表,而不是翻译一份 PDF
把一份报关单交给通用翻译器,你会得到一整面准确的句子。把同一个文件交给必须核验它的海关关员,你会得到一次退单——因为第 4 栏不再是第 4 栏了。正式文件不是"碰巧排过版的文本":它是一张表格,某个数值的含义取决于它落在哪一栏,而读它的人会拿着原件逐行比对。
本文讲的是"翻译文件"和"填写表格"之间的区别:模板化翻译如何运作、成本是多少、在哪里失效,以及大多数文章会跳过的一点——只有真正跑上一段时间才会浮现的两种失效方式。
表格不是排过版的散文
把出生证明当文本读,你得到的是一串标签和数值:姓、名、出生日期、登记机关、证书字号。把它当表格读,得到的东西要严格得多:每个数值只有一个允许出现的位置,其中一部分具有法律效力,而字号本身正是使这张纸成为"文件"而非"对文件的描述"的那个东西。
按散文翻译保住了词,没保住位置。失败不在于输出是错的,而在于输出不再能与原件对照——而对认证翻译来说,可对照正是它存在的全部理由。
还有第二个更安静的问题:扫描件根本没有版式可保。拍下来的护照页就是像素。没有结构可以搬运,因为文件里本来就没有结构,结构只存在于看它的人眼里。任何建立在"保留原始格式"之上的方案,在这里都无物可保。
三种结局,由你上传的东西决定
实际上,文件翻译流水线只有三种可能的结局,而且在任何翻译发生之前就已经决定:
| 输入 | 输出 |
|---|---|
| 匹配到已知表格的扫描件或图片型 PDF | 逐字段填充该模板自带的表单 |
| 任何是或能变成 DOCX 的文件,且无匹配表格 | 译文直接写入原文件的 XML,版式得以保留 |
其余一切 —— .txt、.csv、.xlsx、.json、.po | 纯文本文件 |
这张表里有两点值得明说,因为它们经常被误读。
"没有模板"不等于"没有格式"。 没匹配到模板的 DOCX 返回时格式完好。模板增加的不是版式存活,而是字段级抽取和一张为该文件类型专门制作的表单。正是这一点让扫描件可用,而扫描件恰恰是别的办法都失灵的场景。
模板是给扫描件用的。 在我们的流水线里,只有当文件是图片型 PDF 时才会启用模板填充。带真实文本层的 PDF 或 DOCX 会走就地替换那条路,哪怕模板本可以匹配——因为只要有版式可替换,就地替换就是严格更优的。
模板到底由什么构成
模板由三样东西组成,值得分开来看,因为它们失效的方式不同。
带占位符的 DOCX 表单。 目标语言的文件,版式与原件一致,姓氏的位置写着 {{surname}}。填充是机械的。
字段模式。 这类文件有哪些数值、类型如何、哪些必填。抽取结果就是对着它评分的:声明了却没交付的字段会成为可见的缺口,而不是沉默的缺口。
抽取提示词。 把页面图像变成这些字段的那条指令。
我们提供 16 套这样的表单,覆盖三个语言对:十一套俄译英(户籍证书、护照、四种不动产登记摘要、法人登记摘要),四套韩译俄(出口报关单、原产地证、发票、装箱单),以及一套中国出口货物报关单。
机械的那部分比听上去更机械,也比你希望的更麻烦。占位符藏在合并单元格里、页眉页脚里,而且由于文字处理软件存储文本的方式,一个 {{exporter_address}} 经常被切成三段分散存放。任何要填充它的程序都必须先把占位符拼回去,任何要编辑它的程序还必须原样放回去。
在真实文件上的成本
这是一次完整的端到端实测,中国出口货物报关单译成俄语:
| 抽取字段 | 45 |
| 可翻译片段 | 44 |
| 输出 | 填好的 DOCX 表单,557 词 |
| 成本 | $0.0244 |
| 耗时 | 256 秒 |
| 数字保全 | 28 个中的 26 个 |
最后一行才是真正要紧的,也是通常不会被公布的。报关单基本上就是数字:HS 编码、数量、重量、金额、企业注册代码。原文 28 个数字中有 26 个原样出现在输出里。剩下两个中,一个是被有意改写的日期(20260702 → 02.07.2026),另一个是真正的丢失:表单里没有栏位可放的第二个企业代码。
第二个才是整套方法的诚实教训。抽取找到了这个值,表单没有地方安放它。模板只能交付它有栏位的东西,而缺失的栏位从外面看,和缺失的数值一模一样。
选对表格本身就是一道难题
有十六套表单,就必须有东西来判断一份文件属于哪一套。这个判断比人们以为的更便宜也更笨:加权关键词计分,每套表单一个阈值,外加一份排除词表。不调用任何模型,毫秒级完成,而且几乎总是对的。
几乎。
前不久我们把一份个体工商户登记摘要——六页,俄语——喂给自己的匹配器,它自信地选中了护照模板:0.367,阈值 0.3。这份文件里没有护照,没有"паспорт"这个词,没有签发机关那一行,没有任何一个能标识护照的词。
把它带到那里的是:登记摘要会引用经营者的身份证件,而那段的标题里写着"俄罗斯联邦公民"。两个各出现三次的通用短语,压过了一张连一个区分性关键词都没命中的表单。
眼下的修复是加排除词,我们也确实发了。真正的教训是结构性的:加权求和可以在一个区分性词条都没命中的情况下越过阈值。 如果你要造这样的东西,请给区分性词条的"是否出现"单独计分,而不只看总分。
没人会提醒你的那种失效
下面这个是我们没料到的,本节正是为它而写。
模板是这样做出来的:拿一份人工已经完成的真实译文,把里面的数值换成占位符。这是做表单最快的办法,做出来的表单也不错。但它有个陷阱:作者忘记替换的任何数值都会留在模板里,此后被断言到这张表单渲染的每一份文件上。
我们把自己的十六套表单全部扫了一遍,专找这个。十五套是干净的,一套不是——一份未成年人出境的公证同意书,它会打印出:
place of birth: Vladivostok——父母双方和随行成年人都是;- 按位置固定、而非从文件中读出的性别;
- 以及印章区里一位具名公证人和他的税号,而可用的公证人占位符就闲置在两段之下。
这张表单出具的每一份同意书都在这样断言——不管文件真正说的是谁。而且没有任何地方看起来是坏的。一张打印出合理城市名的表单,和一张真的读出了城市名的表单,看上去完全一样——这正是这类缺陷能挺过评审的原因。
如果你在用模板,这项检查值得自动化:把每套表单摊平成文本,抹掉占位符,看看还剩下哪些像具体事实的内容。你找到的大部分会是正当的印刷版式——"俄罗斯联邦公民护照"印在护照表单上是应该的。剩下的,就是某个人的出生地。
什么时候模板是错的工具
模板是有意做窄的,诚实的定位恰恰在这份窄:
- 它们只覆盖你有表单的文件类型。 十六套就是十六套。集合之外的文件走就地替换,保住版式,但拿不到字段级抽取。
- 文件必须真的是那个类型。 见匹配器一节:自信的错误答案比没有答案更糟,所以"没匹配到模板"必须是可接受的结局,而不是故障。
- 它们不重建版式。 让模型重新拼出一份连版式转换都没能还原的文件结构,是另一个问题,我们并不声称解决了它。
对合同、报告或信函,DOCX 就地替换才是正确答案,模板不会带来任何增益。对一张报关单的扫描件,它是唯一能产出对方可核验结果的答案。
要点
- 正式文件是表格,其含义是位置性的。 按散文翻译保住了词,丢掉了可核验性,而认证翻译要的就是可核验性。
- 模板是为扫描件而存在的。 文件本身有版式时,就地替换比任何表单都保得好。模板恰恰在无版式可保的地方发挥价值。
- 模板只能交付它有栏位的东西。 字段和占位符一起声明,并核查每个抽取到的值都有落点。
- 表单选择值得与抽取同等的审视。 加权计分可能在零个区分性词条命中的情况下选中一张表单;这要靠测量,不能靠假设。
- 审查表单里残留的数值。 从真实文件描摹出来的模板会继承那份文件的事实,直到有人去看——而从输出侧看不出问题。
FAQ
什么是模板化文件翻译?
它指的是:抽取标准文件的字段值,翻译这些值,再填充一张目标语言的专用表单——而不是把文件当作连续文本来翻译。适用于版式固定且具法律意义的文件:各类证书、报关单、登记摘要。
没匹配到模板的 DOCX 会丢格式吗?
不会。没匹配到模板的 DOCX 会在文件自身的 XML 内就地翻译,格式因此保留。模板增加的是字段级抽取和针对该文件类型的表单——这对扫描件最为关键,因为扫描件的文件里根本没有版式可保。
为什么不让 AI 重建版式?
因为"重建版式"和"保留版式"是两个不同的问题,失效方式也不同。文件里存在结构时,保留是可行的;而当转换未能还原结构时才需要重建,那是一个尚未解决的开放问题,而不是已交付的功能——对声称相反的供应商应当保持警惕。
怎么知道模板选对了文件类型?
拿真实文件去测,包括那些你预期会失败的。我们自己的匹配器曾自信地把一份工商登记摘要送去了护照表单,却没命中该表单任何一个标识性关键词——这个缺陷只有把语料跑一遍并阅读结果才看得见。
一次文件翻译能保住多少数字?
在我们实测的中国报关单上,原文 28 个数字中有 26 个原样输出,另有一个是被有意改写的日期。唯一真正的丢失是表单里没有对应字段的那个值。数字完整性是可测量的,也正是值得要求的指标——散文上的准确率分数说明不了 HS 编码是否幸存。
结语
"翻译文件"与"填写表格"的区别听起来像实现细节,实际上决定了产出能不能用。散文翻译面向阅读来优化;文件翻译必须面向核验来优化,因为总会有人把两份并排放好,一栏一栏地比。
也正因如此,这里有意思的工程并不在翻译那一步。它在于选对表单、让每个抽取到的值都有落点,以及确保表单本身没有在悄悄断言某个陌生人的事实。
如果你要翻译证书、报关单或登记摘要,想看看字段级抽取在你自己的文件上会产出什么,试试 KTTC——输出是一张可以逐行核验的填好表单,也只有这样的才值得要。
