返回博客

给文档翻译流程装一条自动化流水线

需要把纸质证明文件翻成英文的场景并不罕见:出国签证、海外银行开户、学术申请……每次都是同样的几个动作——拍照、格式转换、识别文字、翻译、排版、导出 PDF。手动走一遍不难,但要是频繁遇到,重复操作的摩擦感会快速累积。

我把这个流程梳理了一遍,发现它完全可以自动化,而且值得仔细设计——因为输出是要交给官方机构审核的正式文件,容错空间很低。

流程的关键节点

整个管线拆开来看,有四个节点需要认真对待:

图像预处理:手机拍出来的照片通常是 HEIC 格式,且 EXIF 里带旋转信息——文件本身是横的,但查看器会按 EXIF 自动旋转,你以为是正的,实际写入 OCR 的却是歪的。所以第一步必须显式读取 EXIF 方向值,用 sips 或 Pillow 把旋转烘焙进像素,再转成 PNG 送给 OCR。跳过这一步,识别率会大幅下降。

OCR 引擎的降级策略:没有一个 OCR 引擎在所有环境下都可用。macOS 上的 Vision Framework 效果最好,但不可移植;EasyOCR 跨平台但需要提前装好依赖;Tesseract 是最后的保底选项。正确的设计是按优先级依次尝试,任意一个成功就停下来,而不是硬绑定到某一个实现上。这个「按序降级」的模式在工具脚本里非常实用,值得作为一个通用思路记下来。

翻译的格式约束:文档翻译不是普通的语义翻译,它有额外的格式要求:数字和金额必须原样保留(不能因为「更自然」而改写)、人名要转拼音并保留固定格式、机构名要加原文括注。这些约束应该写进 prompt 或函数的前置规则,而不是靠翻译引擎自己猜。

PDF 的版式设计:生成双语 PDF 的时候,第一页放原件图片、第二页放英文译文,是审核人员最习惯的阅读顺序。译文页要做到:标题居中加粗、正文左对齐、底部加「本文为原件的英文翻译」声明。reportlab 处理这些布局绰绰有余,但中英混排的字体选择要提前确认,否则中文字符会显示为方块。

「按序降级」比「选最好的」更健壮

设计这条流水线时,我遇到的最大诱惑是:直接用效果最好的那个 OCR 引擎,其他的都不考虑。

但「最好的」在本机开发环境里成立,在 CI、Docker 容器、或者别人的机器上就不一定了。Vision Framework 只有 macOS 有;EasyOCR 的模型文件首次运行要下载几百 MB;Tesseract 的中文语言包在精简镜像里默认不装。

更稳健的做法是把每个引擎包成一个独立的尝试单元,捕获异常后静默降级到下一个,最终无论哪个成功都走同样的后处理逻辑。这样写出来的代码,在任何环境下都能跑出「尽力而为」的最优结果,而不是在某个环境下直接崩掉。

这个思路不只适用于 OCR——凡是有多个实现可选、可用性不确定的外部依赖,都可以套用「有序降级链」的结构。

输出命名约定

生成的文件名用 <原始文件名>_Translated.pdf 格式,放在和原文件相同的目录下。这样不用记路径,翻译前后的文件一眼就能对应上,也方便批量处理时用 glob 扫描。

自动化的边界在哪里

自动化不是要取代人工判断,而是要把可以确定的部分固化下来,把真正需要判断的部分留给人。

在这条流水线里,机器可以可靠地完成:格式转换、旋转校正、文字识别、机械性翻译、版式生成。但有几件事仍然需要人工核查:机构名的官方英文名称是否准确、金额的货币单位是否正确、文件日期格式是否符合目标国家的惯例。

把这两类职责分清楚,自动化才是真正省力的,而不是把不确定性藏进脚本,最终在审核环节被打回来。

一句话心法

流水线的价值不在于消灭步骤,而在于让每个步骤只做一件事、做对一件事——让人的判断集中在机器无法确定的地方。