没有不值得去解决的问题,也没有不值得去学习的技术!

A Tour of Go de-DE 上线复盘:第三门语言用了约 16 小时,下一门如何压到 8 小时?

图 1:A Tour of Go 德语版 de-DE 已正式运行在生产环境

作者:

A Tour of Go 多语言翻译项目

图3:访问过去的 Go Tour 简体中文站 tour.go-zh.org 时,当前已经无法正常建立连接。

(1) 从「A Tour of Go 中文版」这个搜索词开始:我决定做一个持续维护的 Go Tour 中文版

本地运行的 A Tour of Go「Methods continued」课程页面,左侧为课程说明,右侧为 Go 代码编辑器及运行结果。

(2) A Tour of Go 中文版项目设计冻结:从 101 页到 103 页,从 Gin 转向 Cobra CLI

A Tour of Go 中文版开发实战:英文基线、在线运行与 101 页上游同步体系

(3) A Tour of Go 中文版开发实战:英文基线、在线运行与 101 页上游同步体系

go-tour-i18n 项目完成首个简体中文课程页面 welcome/1 的整页翻译、结构校验和本地预览。

(4) A Tour of Go 多语言翻译项目实录:完成首个 zh-CN 页面翻译闭环

图 1:DeepSeek 官方更新日志显示,本次只更新 DeepSeek-V4-Flash,DeepSeek-V4-Pro API 与 APP、Web 模型均未更新

(5) A Tour of Go 中文翻译项目进展:完成前 8 页、修复 present 语法,并暂缓 DeepSeek 对比

图 1:generics/1 简体中文页面本地预览

(6) 一个页面重试五次:使用 GLM-5.2 翻译 A Tour of Go 时遇到的 Token 与 Present 结构问题

图 1:methods/16 简体中文页面浏览器预览

(7) A Tour of Go 中文翻译实录:如何只翻译教学代码注释,而不破坏 Go 代码

图 2:A Tour of Go methods/20「练习:错误」中文候选页面最终渲染效果

(8) A Tour of Go 多语言翻译:当正确的中文语序被受保护标记顺序校验误判

图 3:methods/24 中文页面,静态代码、Bounds 行内代码和链接内的 image.Rectangle 均正确渲染

(9) A Tour of Go 中文翻译完成 7 个代表页校准:最后 3 页又发现了哪些真实问题

图 2:首批 10 个普通页面经过试跑与流程校准后全部进入 ready

(10) A Tour of Go 多语言翻译项目:首批 10 个普通页面试跑,从 2 个 blocked 到全部 ready

图 2:flowcontrol/6 最终中文页面,return 与 v 为适应自然中文语序发生整体换位

(11) A Tour of Go 中文翻译第二批实跑:从 Inline Code 顺序误判到历史响应重新验证

图 1:flowcontrol/6 首次原始输入实验直接通过统一自动校验

(12) A Tour of Go 多语言翻译项目:从 swap 问题重新审视 Token 保护,原始输入与最小保护的一次真实实验

图 7:moretypes/1 最终中文页面预览。左侧课程正文、静态代码块、行内代码和教学注释均正常渲染,右侧官方 Go 示例继续保持原样。

(13) A Tour of Go 多语言翻译实战:第三批 10 页全部 Ready,继续校准 Protected Token 的结构角色

图 4:上游源码确认共有 103 个课程页面,zh-CN 最终达到 ready=103、pending=0、blocked=0

(14) A Tour of Go 多语言翻译项目:zh-CN 103 个课程页面全部 ready,课程正文翻译阶段完成

图 4:GitHub 与 ChatGPT 已成功连接

(15) ChatGPT 连接 GitHub 实测:让 AI 直接读取 go-tour-i18n 仓库参与译文审核

图 3:中文 Go 术语校准完成后,将确定的译法写入 zh-CN glossary

(16) 为什么 channel 最终选择“通道”:A Tour of Go 中文术语统一的一次实践

图 1:技术含义基本正确,但“返回一个返回……”已经明显影响阅读,因此仍被列入 C 类修订

(17) 103 页逐页审核后,只返修 16 页:A Tour of Go 中文正文发布前质量审计

图 2:中文课程页面以及已经完成本地化的编辑器控制区

(18) A Tour of Go 多语言翻译项目:公共 UI 本地化完成,从课程译文走向完整中文界面

图 2:完整 zh-CN 正式投影成功生成,103 个课程页面被重新组装为 7 个 .article

(19) 从 103/103 ready 到完整站点验收:A Tour of Go 中文版补齐正式投影与课程元数据本地化

图 3:从 production bundle 独立启动的 A Tour of Go 简体中文页面,课程正文、公共 UI 和官方 Go 示例均已进入最终发布形态。

(20) A Tour of Go 多语言翻译项目:103 页全部完成后,我终于生成了可独立部署的 zh-CN Production Bundle

图 1:A Tour of Go 简体中文版正式生产页面,远程运行已经成功输出“Hello, 世界”。

(21) A Tour of Go 多语言翻译项目:zh-CN 正式上线,从生产发布到 go.dev Playground 的完整部署记录

图 1:新生产域名 go-dev.shuijingwanwq.com 已正常访问,Go 示例远程运行成功

(22) A Tour of Go 多语言翻译项目:从 go-tour 到 go-dev,完成 EdgeOne、Nginx 与 HTTPS 生产域名迁移

图 1:A Tour of Go 多语言翻译项目正式生产首页

(23) A Tour of Go 多语言翻译项目正式上线:从项目首页、公共 Footer 到生产发布元数据的完整收尾

图 3:GA4 g/collect 请求返回 HTTP 204,并携带当前课程页面地址,确认 Google Analytics 已产生真实事件上报

(24) A Tour of Go 多语言翻译项目:接入 Google Analytics 与百度统计,从 systemd 注入到 EdgeOne 与真实上报验证

图 1:生产环境 robots.txt 与 sitemap.xml 已正确对外提供,Sitemap 共包含 104 个规范 URL。

(25) A Tour of Go 中文站上线后:补齐 robots.txt、Sitemap,并完成五大搜索引擎提交

图 4:发布生产并刷新 EdgeOne 缓存后,再次通过真实手机访问,顶栏项目名称已经完整保持在一行,最终移动端验收通过。

(26) A Tour of Go 多语言翻译项目:修复手机端首页顶栏标题换行,并完成真机验证

图 3:生产自动部署脚本第一次真实运行时,systemd 已经显示 active,但首次 localhost 探测仍然得到 HTTP 000;随后连续 3 次同时满足 active + HTTP 200 后,脚本才判定部署成功,并继续完成公网 HTTP 200 验收。这次真实运行验证了连续应用层健康检查的必要性。

(27) A Tour of Go 多语言翻译项目:从一次 203/EXEC 故障到生产自动部署脚本落地

图 1:阿里云生产环境访问 go.dev Playground 时出现 TLS 握手超时

(28) A Tour of Go 多语言翻译项目:为 Playground 搭建独立的 ZgoCloud 执行代理

图 3:清除 /tour/script.js 缓存后,Run 已直接请求 ZgoCloud /compile 并返回 HTTP 200

(29) A Tour of Go 多语言翻译项目:将生产 Run / Format 切换到 ZgoCloud 执行节点

【图 1:微信中运行 Go 示例时出现 Error communicating with remote server.】

(30) A Tour of Go 中文版手机端运行与格式化偶发失败排查:从间歇性报错到补强 Nginx 可观测性

【图 4:向 golang-dev 公开邮件列表发送 Playground 使用告知邮件并投递成功】

(31) A Tour of Go 多语言项目:为 Playground 代理增加唯一 User-Agent,并主动告知 Go 官方

【图 3:百度剩余 9 个核心 URL 提交成功,remain 归零】

(32) A Tour of Go 搜索引擎收录实测:从 Google 自然索引到百度主动提交与 Bing IndexNow

【图 1:当前正式中文 methods/24 页面,右侧示例代码运行成功】

(33) A Tour of Go 中文翻译完成后,我为什么重新评估 minimal-protect 翻译模式

【图 3:5 个页面 Request SHA256 完全一致,但 Response SHA256 全部不同】

(34) A Tour of Go 翻译实验:更多原始上下文为什么没有更好?从 157 个保护标记到 30 次重复盲评

图 3:3 个代表页 × 4 个评审模型,共 12 次匿名评审的完整排名与第一名票数。

(35) A Tour of Go 翻译质量再评估:minimal-protect 未达预期后,我开始比较 ChatGPT、Codex 与 GLM-5.2

图 2:GitHub 中的 chatgpt-zh-CN-008 重译批次。一个 Batch 同时保存 inputs、raw-responses、candidates、validation 和 retry 记录,GitHub 成为 ChatGPT 与本地翻译流水线之间的数据交接层。

(36) 没有 OpenAI API,我如何用 ChatGPT + GitHub 完成 A Tour of Go 103 页全量重译

图 1:103 个正式课程页面完成最终语义质量审核,结果为 A=103、B/C/D=0,同时不存在缺失、重复或额外页面。A/B/C/D 是本轮项目内部语义质量分级,并不是自动结构 validator 的结果。

(37) 103 页翻完还不能发布:A Tour of Go ChatGPT 译文的语义审核与 Canonical Promotion

图 3:7 个 article endpoint 的 production origin 与 EdgeOne 公网响应全部 exact match,同时新的 ChatGPT 译文标记存在,旧版译文标记已经消失。

(38) 103/103 与 7/7 Exact Match:A Tour of Go ChatGPT 新译文的最终线上验收

【图 2:upstream source preview】

(39) A Tour of Go 多语言翻译项目首次实现 upstream 同步机制:从一次性翻译到长期维护

图 2:A/B/C/D 质量评级规则,展示正式质量 rubric 与 Promotion gate。

(40) A Tour of Go 多语言翻译项目引入 Translation Quality Review:从自动验证到 AI 翻译质量控制

图 4:翻译后 Playground Example,展示中文注释与保持不变的 Go 代码结构。

(41) A Tour of Go 多语言翻译项目实现 Playground Example 本地化:从代码注释翻译到完整学习体验

图 5:公网页面验证广告脚本输出

(42) A Tour of Go 多语言翻译项目接入广告系统:从 AdSense 专用配置到通用 HTML 注入架构

图 3:百度统计单页应用设置

(43) go-dev 单页网站接入统计与 Google AdSense Auto Ads 验证记录

图 1:GitHub 仓库中的多语言翻译项目结构

(44) A Tour of Go 多语言翻译项目:选择日语作为第二语言并启动翻译验证

图 5:模型身份描述不一致

(45) A Tour of Go 多语言翻译项目中的 AI 协作异常排查:一次长期工程会话失效分析

【图 1:ChatGPT GitHub 写入流程调整说明截图】

(46) go-tour-i18n 翻译流程调整:从 ChatGPT GitHub 写入到本地 artifact 导入

图 4 展示了本次异常状态。

(47) go-tour-i18n 翻译自动化流程复盘:已验证的 ChatGPT 翻译能力在新任务中的稳定性问题

【图 6:全部评审结束以后才读取 secret key,完成最终揭盲】

(48) A Tour of Go 翻译质量再评估:Codex High 已接近 ChatGPT High,我决定调整默认翻译引擎

图 4:ja-JP 生产课程页实际运行 Go 示例

(49) A Tour of Go 日语版正式上线:第二门语言 ja-JP 完成生产发布

图 1:ja-JP 上线以后,先提交“新增语言标准化流程”

(50) A Tour of Go 多语言扩展复盘:为第三门语言建立标准化流程

图 1:课程正文结束以后,页面左侧仍然存在大块视觉空白,但 AdSense 并没有在这里插入展示广告。

(51) A Tour of Go 明明有大片空白,为什么 AdSense 就是不显示展示广告?

图 2:golang/website 当前的 _content/tour/。课程内容、静态资源和模板都在这个上游目录中持续维护。

(52) 为了 AdSense,要不要放弃 SPA?A Tour of Go 页面架构的一次取舍

图 4:最终的手动课程广告真实展示在课程内容区域内,而不是 footer 之后。

(53) 保留 SPA 以后,广告应该放在哪里?从 AdSense 预览到方案 B

图 1:Google Search Console 中,多个不同的 A Tour of Go 课程 URL 被判断为“重复网页,用户未选定规范网页”。

(54) SPA 的 SEO 老问题:为什么最后还是给 103 个 A Tour of Go 课程页生成了 Prerender HTML

图 2:方案 B 生产环境中,源码已经正常,但课程主体高度异常缩短,footer 提前进入第一屏。

(55) 从源码空白到 AdSense 高度污染:A Tour of Go 方案 B 的生产收尾

图 1:A Tour of Go 德语版 de-DE 已正式运行在生产环境

(56) A Tour of Go de-DE 上线复盘:第三门语言用了约 16 小时,下一门如何压到 8 小时?

A Tour of Go 的第三门社区语言 de-DE 已经正式上线。

生产地址:

https://de-go-dev.shuijingwanwq.com

至此,目前项目已经有简体中文、日语和德语三个实际运行的社区语言版本。

这一次德语版仍然不是“翻译完成就上线”。

103 个课程 Page、19 个 eligible Example,共 122 个 TranslationUnit,仍然完整经过 automatic validation、Quality Check、Final Review、promotion、Locale Surface Review、production 部署和真实浏览器验收。

第一次 Quality Check 中,122 个 TranslationUnit 里有 119 个达到 A,另外 3 个被判定为 B,没有直接放行,而是重新进入 revision。修订完成以后,最终 122 个 TranslationUnit 全部达到 A。

Final Review 又重新独立审核了一遍,最终同样是 122 个 A + approved。

也就是说,这次并没有因为已经是第三门语言,就降低原来的质量门槛。

图 1:A Tour of Go 德语版 de-DE 已正式运行在生产环境
图 1:A Tour of Go 德语版 de-DE 已正式运行在生产环境

先说明:这 16 小时并不是从零开始

这篇文章的标题里有一个很醒目的数字:

约 16 小时。

按每天 8 小时计算,大约就是两个工作人日。

这个数字如果脱离整个项目的前期投入,很容易产生误解。

它并不是说:

“从零开始完整翻译、审核、开发并上线一门 A Tour of Go 语言,只需要 16 个小时。”

实际上完全不是这样。

我大约从 2026 年 7 月 28 日开始形成比较明确的 A Tour of Go 多语言计划。

真正开始集中推进第一门简体中文,大约是从 8 月 1 日开始。

一直到 8 月 22 日左右,第一门语言的完整翻译、质量审核、工具、生产环境和上线流程才真正走完整。

仅仅从 8 月 1 日到 8 月 22 日这一阶段,我基本上没有完整休息过,每天投入时间通常都超过 10 个小时。

即使只按照每天 10 个小时进行非常保守的计算:

22 天 × 10 小时 = 220 小时

也已经超过 220 个小时。

而这还只是第一门语言最集中的一个阶段。

中文完成以后,第二门语言 ja-JP 又继续承担了一项很重要的任务:验证此前为中文构建的能力到底能不能真正扩展到另一个 locale。

也是在日语完成以后,我才进一步把新增 locale 的完整生命周期、Locale Surface Review、生产服务器基线、首次部署与日常部署等内容固化成正式 Runbook。

所以,当 de-DE 开始的时候,很多非常昂贵的问题已经不需要重新解决了。

TranslationUnit 怎样定义,不需要重新研究。

Quality Check 和 Final Review 怎样执行,不需要重新设计。

glossary 怎样约束全站,不需要重新决定。

服务器使用什么目录结构、systemd 怎么管理、Nginx 怎么接入、Playground 怎么复用,也不需要重新探索。

广告、共享静态资源、生产部署和 CDN 同样已经有现成基线。

因此,更准确的理解应该是:前面用了数百个小时逐渐把“增加一门语言”做成了一套系统,而 de-DE 第一次比较清晰地展示了,在这套基础已经存在以后,再增加一门语言的边际人工成本可以下降到约 16 个小时。

这也是为什么我认为这个 16 小时值得记录。

它不是用来说明翻译工作本身有多轻松。

恰恰相反,它说明的是:

大量工作其实已经提前完成了。


上一轮解决“流程怎么走”,这一轮开始回答“流程到底有多快”

ja-JP 完成以后,我没有直接开始第三门语言,而是先整理了一轮新增 locale 标准化。

当时最重要的问题是:

如果增加第三门语言,还要不要重新理解一遍整个项目?

现在 de-DE 真正走完以后,这个问题已经基本得到回答。

至少从架构层面来看,答案是:

不需要。

de-DE 没有重新设计 TranslationUnit。

没有重新设计 Quality Check。

没有重新设计 Final Review。

没有重新设计共享广告架构。

也没有重新设计 SPA 生命周期和 Playground。

整个过程基本按照已有 Runbook 往前走。

但新的问题也很快出现了:

即使路线已经知道,真正走完这条路线仍然需要不少人工时间。

这就成为第三门语言和第二门语言最大的区别。

第二门语言以后,我主要在解决:

有没有一条正式流程?

第三门语言完成以后,我开始更关心:

这条正式流程中,还有多少时间其实花在了重复操作、历史遗留问题和人工搬运上?


de-DE 的 16 小时,并不全是“正常新增语言成本”

如果这 16 个小时全部都是:

翻译 → 审核 → 发布

那么下一门语言想压缩到 8 小时,难度其实会很大。

但实际执行以后我发现,其中相当一部分时间并不是德语本身必然需要的。

而是在第三次完整执行时,又发现了一批以前没有完全暴露出来的历史问题。

例如 status.tsv

第一门、第二门语言时已经有状态文件和相关流程,但到了第三门语言,某些生成和同步边界才真正被完整验证。

再例如翻译文件末尾空行和 EOF normalization。

单独看只是非常小的格式问题,但当 TranslationUnit 数量达到 122 个,而且还涉及 candidate、promotion、diff 和 validation 时,一个很小的不一致就可能不断产生额外确认成本。

除此之外,这一轮还遇到了旧 upstream commit/time fixture。

有 4 个测试仍然期待以前的 upstream baseline:

645042eb

而当前正式 FrozenUpstreamCommit 已经更新。

最终确认以后发现,这和 de-DE 本身、SHA-256、language selector 都没有关系,只是测试中的历史 fixture 没有同步。

问题很小,但如果不把根因确认清楚,就很容易在完全错误的方向上浪费时间。

生产部署阶段还出现过一个首次 deployment 特有的问题。

已有 locale 部署时始终存在 old release,但 de-DE 是真正的首次部署,没有 old release。

原来的 SSH 参数传递在这种情况下会丢失一个空 positional argument,最终触发:

unbound variable

后来专门改成显式 sentinel,才彻底区分“没有旧 release”和“参数丢失”。

这些事情都不是“每新增一种语言理应重新处理一次”的工作。

所以我的处理原则基本都是:

这次既然已经发现,就尽量不要让下一门语言重新支付同样的成本。

图 2:de-DE 上线过程中持续修复流程问题,并把部署与生产验收进一步自动化
图 2:de-DE 上线过程中持续修复流程问题,并把部署与生产验收进一步自动化

从图里的提交记录也可以看到,这次 de-DE 并不是只有翻译内容的变化。

上线过程中不断有测试、部署脚本、生产验收、shared-assets、语言列表规则以及历史问题被继续收紧。


一些“看起来很小”的问题,其实很消耗人工时间

这次有一个感受变得越来越明显:

真正影响效率的,往往不是一个需要两小时开发的大功能,而是连续出现十几个需要人判断十分钟的小问题。

比如一个测试为什么失败。

一个目录到底是不是 production profile。

一个广告环境变量名称在文档里是不是已经过期。

shared-assets 是否真的需要重新部署。

Cloudflare 缓存到底应该强制要求 MISS -> HIT,还是只需要确认缓存状态正常。

新增 de-DE 后,是否必须马上重新部署中文和日语,让旧站首页立即出现 Deutsch。

单独一个问题可能并不复杂。

但每一次都需要:

查看代码 → 找文档 → 判断现状 → 执行命令 → 看结果 → 再决定下一步。

这些操作累计起来,时间很快就上去了。

所以 de-DE 这一轮除了“完成第三门语言”,另一项很重要的结果就是:

继续把这些需要临时分析的问题,尽可能变成代码里的明确行为和仓库里的正式规则。


语言列表最终也选择了“最终一致”,而不是每次全站同步

de-DE 上线以后,还有一个很典型的问题。

新的 language registry 已经包含德语。

因此新构建的 de-DE 自然可以看到:

简体中文、English、Deutsch、日语。

但已经运行在 production 的 zh-CN 和 ja-JP,使用的是它们之前构建好的 release。

旧 release 不会因为 Git 仓库里增加了一个语言,就自动获得新的语言列表。

最开始很容易把这理解为:

新增 de-DE 后,是不是应该马上重新 publish 中文和日语?

这次实际上也额外同步了一次 zh-CN 和 ja-JP,并确认两个站点都正确显示了 Deutsch。

但在继续分析以后,我最终决定:

以后不把这种反向同步作为新增 locale 的上线 gate。

首页的 language registry 是 build-time 数据。

因此已有 locale 的语言列表正式采用 eventual consistency。

新语言上线时,必须确认:

新 locale 自己能够正确看到已有语言。

但是已有的旧 locale,不要求在新语言上线当天立即反向显示它。

它们等下一次正常 upstream sync、UI 更新或者日常 release 时,自然获得最新 registry 就可以。

这个决定看起来只是少部署两个站点。

但如果以后变成 10 门、20 门甚至更多语言,意义就完全不同了。

如果每增加一门语言,都必须立即重新构建、部署和清理其他所有 locale 的缓存,那么成本会随着语言数量不断放大。

而 eventual consistency 可以把这部分成本基本消掉。


production 验收开始真正收敛成一个命令

de-DE 这一轮,我认为最有实际效率价值的改进之一,是:

scripts/verify-production.sh

以前 production 部署完成以后,需要继续手动确认很多事情。

例如:

release identity 是否正确。

服务器上的 current 是否真的是目标 release。

localhost 是否正常。

公网几个关键路由是不是 200。

sitemap 到底有多少 URL。

里面有没有错误 hostname。

有没有 HTTP failure。

/socket 是否仍然保持预期边界。

CDN 有没有真正返回缓存状态。

这些检查单独执行都不复杂。

问题是需要不断复制命令、看输出,再人工记住哪些已经检查过。

现在这部分被正式压缩成:

Plaintext
scripts/verify-production.sh <release-dir>

de-DE 的最终结果是:

Plaintext
release identity: PASS
remote identity: PASS
source routes: 7/7 PASS
public routes: 7/7 PASS
html identity: PASS
sitemap: 105/105 PASS
socket boundary: PASS
CDN: PASS

PRODUCTION MACHINE ACCEPTANCE: PASS
图 3:verify-production.sh 将 de-DE 的生产机器验收收敛为一次执行,并最终全部 PASS
图 3:verify-production.sh 将 de-DE 的生产机器验收收敛为一次执行,并最终全部 PASS

这里我很在意的一点是:

自动化并没有减少验收项目。

不是为了快,就少检查几个 URL。

也不是为了快,就不检查 sitemap。

实际上恰恰相反。

把检查变成脚本以后,可以更稳定地每次都执行完整范围。

所以效率提升和质量降低,并不是一回事。

很多时候,自动化以后反而更容易维持严格标准。


最终验收仍然保留人工 HUMAN GATE

当然,也不是所有事情都适合交给脚本。

机器可以判断:

HTTP 是不是 200。

hostname 是否正确。

sitemap 是不是 105/105。

release SHA 是否一致。

但是机器很难完全替代:

页面到底看起来正不正常。

德语标题有没有溢出。

移动端 header 是否被裁切。

按钮宽度是否够用。

footer 有没有和内容重叠。

点击 Weiter 以后 SPA 是否仍然自然。

Run / Format / Reset 是否真的能正常交互。

广告加载机会是否会破坏课程布局。

所以 de-DE 在机器验收 PASS 后,仍然完整进行了真实浏览器验收。

这一轮实际还发现并修复过一些只有 rendered surface 才比较容易暴露的问题。

包括移动端标题、按钮宽度、课程列表 footer、分页居中和页面之间的视觉细节。

这也是为什么项目现在会明确区分:

machine acceptance

和:

browser HUMAN GATE

我的目标不是把 HUMAN GATE 去掉。

而是尽量让人只判断真正需要人看的东西。


de-DE 最终不是“翻译完成”,而是完整 production gate 通过

最终 de-DE 的 Locale Surface Review 得到:

Plaintext
decision = passed

并且不是只有 TranslationUnit 通过。

最终 evidence 中记录的是:

Plaintext
A language quality review: passed
preview rendered acceptance: passed
production machine acceptance: passed
production browser acceptance: passed
lightweight ads confirmation: passed

同时:

Plaintext
unresolved language blocker: none
unresolved rendered blocker: none
unresolved production blocker: none
图 4:de-DE Locale Surface Review 最终通过,语言质量、预览、生产机器、浏览器与广告验收全部完成
图 4:de-DE Locale Surface Review 最终通过,语言质量、预览、生产机器、浏览器与广告验收全部完成

这也是我比较看重的一点。

无论译文最初通过什么方式产生,最终决定它能不能进入 production 的,不应该只是“生成完成”。

真正重要的是后面的:

结构验证、完整 source ↔ target 审核、A-only Quality Check、独立 Final Review、Surface Review 和 production acceptance。

这也是为什么我不准备为了把下一门语言压缩到 8 个小时,就删掉这些 gate。


到了第三门语言,最大的瓶颈已经开始变成人工操作

de-DE 做完以后,我现在觉得整个项目的瓶颈已经发生了一次比较明显的变化。

最开始最大的瓶颈是:

能力不存在。

需要先写工具、做架构、建立 workflow。

后来最大的瓶颈变成:

流程不够明确。

所以 ja-JP 完成以后,我专门建立 Runbook 和 Locale Surface Review。

现在到了 de-DE,越来越明显的瓶颈已经变成:

人工审核与人工操作。

特别是 Quality Check 和 Final Review。

正式规则要求每一个 TranslationUnit 都必须单独审核。

这一点我目前并不打算改变。

122 个 TranslationUnit 就应该有 122 个明确的质量结论。

不能因为前面 20 个都很好,就推测后面的也没问题。

不能用 automatic validation 替代语言质量判断。

也不能因为某种翻译方式过去表现不错,就跳过审核。

真正可以优化的是另外一层。

现在人工审核过程中,人不只是在“判断译文”。

还需要做很多辅助操作:

找当前 TranslationUnit。

读取 source。

读取 candidate。

确认 glossary。

确认 validation evidence。

组织审核上下文。

记录结果。

切换到下一个 TranslationUnit。

如果出现 B,再整理 revision unit。

然后重新进入下一轮。

这里真正有质量价值的,是:

判断这个 TranslationUnit 是否达到 A。

其他相当多动作,其实只是信息搬运。


下一步真正应该优化的,是“让人只负责判断”

所以如果下一门语言还要继续提速,我现在最想优化的不是翻译速度。

而是:

减少一个完整 locale 生命周期里人工需要操作多少次。

比如 Quality Check。

理想状态应该逐渐变成:

Plaintext
生成 Candidate Snapshot
→ 自动准备完整 review packet
→ 连续执行逐 TranslationUnit 审核
→ 自动记录每个 A/B/C/D
→ 自动汇总
→ B/C/D 自动形成 revision unit list

这里仍然是逐 TranslationUnit 审核。

标准一点都没有降低。

只是把:

122 次找文件和组织上下文

变成:

少数几次启动审核任务。

Final Review 也一样。

仍然独立重新读取:

source、candidate、glossary、validation evidence、TranslationUnit identity。

但是这些材料应该尽可能自动准备。

最终只让人关注:

这个结果是否可以 approved。

生产流程其实已经开始朝这个方向走了。

目前机器部分越来越接近:

Plaintext
deploy
→ CDN purge HUMAN GATE
→ verify-production.sh
→ browser HUMAN GATE

我希望 TranslationUnit 审核以后也能逐渐达到类似状态。


下一门语言为什么目标是 8 小时

如果 de-DE 大约花了 16 个小时,那么下一门直接要求 4 小时,我觉得暂时还是有些激进。

因为语言本身可能出现更多 revision。

不同 locale 的 UI 长度也可能暴露新布局问题。

production 同样可能出现真实异常。

这些事情没有必要为了追求一个漂亮数字而忽略。

所以目前比较现实的下一阶段目标是:

完整新增一门语言控制在 8 小时以内。

这里的“8 小时”同样不是指传统意义上的纯翻译工时。

它仍然指:

在已有生产体系基础上的新增 locale 增量执行时间。

而且前提是不降低现在的质量标准。

122 个 TranslationUnit 仍然逐个 Quality Check。

Final Review 仍然 A-only。

Locale Surface Review 仍然执行。

production machine acceptance 和 browser acceptance 仍然保留。

我要减少的是:

重复复制命令。

重复找文件。

重复确认已经有正式答案的问题。

重复执行可以被脚本稳定完成的机器检查。

以及下一门语言再次踩到这一门语言已经修过的坑。


4 小时可以作为更后面的“无异常路径”目标

如果 8 小时以后也能够稳定达到,我觉得才适合继续看 4 小时。

4 小时更适合被理解成:

基础设施稳定、翻译质量较高、没有明显 revision 风暴、没有生产异常时的一条理想 happy path。

而不是给所有语言设置硬指标。

因为如果一个 locale 在 Quality Check 中真的发现十几个 B,那么就应该老老实实 revision。

质量问题不应该因为“4 小时预算已经到了”而被放过去。

所以从长期来看,我更关心的可能不只是:

Plaintext
一门语言用了多少小时

还应该开始记录:

Plaintext
需要多少次人工介入
需要多少次异常回流
需要多少个 HUMAN GATE
多少时间真正花在语言判断
多少时间花在操作和等待

只有这样,后面的效率优化才会越来越清楚。


第三门语言真正留下的,不只是 de-DE

从最终 Git 记录来看,de-DE 上线以后,这一轮又留下了不少可以继续复用的东西。

首次 production deployment 对新 locale 的支持已经更完整。

production machine acceptance 已经有正式的一键入口。

shared-assets 的生产验收也进一步自动化。

旧 upstream fixture 已经清理。

retranslation batch 的默认命名也同步到了当前正式工作流。

language registry 的 eventual consistency 规则已经明确写进正式文档。

这些事情意味着:

第四门语言开始的时候,项目状态应该比 de-DE 开始的时候更加干净。

图 5:de-DE 上线后继续清理本轮发现的问题,让第四门语言不再重复支付相同的流程成本
图 5:de-DE 上线后继续清理本轮发现的问题,让第四门语言不再重复支付相同的流程成本

最终工作区重新回到 clean。

对我来说,这也是一次新增 locale 真正结束的重要标志。

不是:

“页面已经可以访问,所以先算完成。”

而是:

这轮发现的问题已经尽量回收到代码、测试、脚本和文档里。


小结

A Tour of Go de-DE 已经正式上线。

如果只看这一轮新增语言本身,从开始集中推进到最终 production,大约花了 16 个小时。

但是这个数字不能脱离前面的长期投入理解。

从 7 月 28 日左右开始形成明确计划,到 8 月初集中推进第一门中文,再到 8 月 22 日左右完成第一门语言完整上线,仅中文最密集的阶段就已经投入超过 220 个小时。

随后 ja-JP 又继续验证第二门语言,并把很多经验变成正式 Runbook 和质量流程。

所以 de-DE 的 16 小时,不是整个项目的成本。

它更接近于:

当底层能力已经存在以后,新增第三门语言的边际成本。

而这一轮最重要的收获,也不仅仅是多了一个德语站点。

更重要的是,我开始能够比较清楚地看到:

哪些时间属于真正不可省略的语言质量判断。

哪些时间属于历史遗留问题。

哪些时间属于机械操作。

哪些操作已经可以交给脚本。

以及整个项目下一阶段真正的效率瓶颈在哪里。

目前看来,最大的瓶颈已经越来越不是“怎么部署一门语言”。

也不是“新增 locale 的架构应该怎么设计”。

而是:

怎样在不降低逐 TranslationUnit Quality Check、A-only Final Review、Locale Surface Review 和 production acceptance 标准的前提下,把大量没有判断价值的人工操作从流程中移出去。

所以第四门语言,我现在给自己的目标是:

8 小时以内。

如果后面能够稳定做到,再尝试把没有明显异常的理想路径进一步压到 4 小时左右。

从 200 多个小时建立第一套完整能力,到第三门语言开始出现大约 16 小时的边际成本,我觉得真正值得继续做的事情已经越来越清楚:

不是单纯追求“翻译得更快”,而是让此前投入的工程能力不断产生复利。

从源码空白到 AdSense 高度污染:A Tour of Go 方案 B 的生产收尾

A Tour of Go 多语言翻译项目

本系列完整记录 A Tour of Go 多语言翻译项目从架构设计、整页翻译、结构保护、自动校验,到生产发布与后续维护的实际开发过程。

项目入口:
✅ 在线学习:A Tour of Go 简体中文版
✅ 项目源码:GitHub:shuijingwan/go-tour-i18n

当前第一阶段已完成简体中文版本。项目属于非官方社区多语言翻译项目,与 Go 官方无隶属或授权关系。