我们卖的是翻译基础设施,自己的营销站点也提供五个 locale。审查实际线上使用的 JSON 时,第一个问题并不是语气,而是一个德语复合词里的一个错误字符,乍看几乎没问题:本该是拉丁字母的位置上,是一个西里尔字母。这个词读起来像一条术语表条目,直到你去看它的码点。如果连我们自己的翻译都有问题,凭什么让别人信任这个产品?


本不该上线的五个故障

德语界面文案里混进西里尔字母。 一条术语表条目曾混用了不同文字:后缀看起来像拉丁字母的 “ar”,其实有一个字母不是。母语读者一眼就能看出来,拼写检查却看不出来。

**The string:** …"Übersetzungsglossар"… (Cyrillic "р" in the compound)
**What it should be:** "Übersetzungsglossar"
**Why it matters:** It reads as corrupted text. It signals automated output nobody proofread in the target language.

德语和法语的语体用反了。 这是一个开发者工具,语气应该贴近工程师在产品界面里实际的写法。但我们在 de 和 fr 里处处用了正式称呼。这不是吹毛求疵:它意味着默认的翻译路径为整个界面选错了语体,而不只是几条边缘字符串。

**The string:** "… wie Sie …" / "vous pouvez …"
**What it should be:** informal "du" / "tu" voice for product and FAQ
**Why it matters:** Every screen sounded like enterprise procurement, not like the product we sell to vibe coders.

凭空出现的货币。 英文写的是美元,德语却显示成欧元,还带着按月计费的标签。我们并不按国家定不同的价格,JSON 却暗示了这一点。

**The string:** "20 €/Monat" (and similar) next to "$20/mo" elsewhere
**What it should be:** one USD amount, formatted per locale via code (e.g. Intl), not hand-invented symbols in JSON
**Why it matters:** Pricing trust. Mixed symbols read as either a bug or a hidden price change.

“coding” 的假朋友词。 在三种语言里,“coding environment” 被译成了“编码(encoding)环境”的词。FAQ 告诉用户可以留在他们的“编码环境”里。无论怎么理解这个产品,这都是错的。

**The string:** Spanish "codificación", Italian "codifica", German "Codierung" in the wrong sense
**What it should be:** development environment wording (e.g. entorno de desarrollo / ambiente di sviluppo / Entwicklungsumgebung)
**Why it matters:** It is a semantic bug. It reads like we do not understand our own domain.

“Ship” 被当成邮寄发货。 德语和意大利语的字符串用了人们和包裹联系在一起的动词,而不是发布软件的意思。同一个英文源文,用词领域却错了。这源于未经修正的机器建议,而不是有意的风格选择。

**The string:** parcel-shipping verbs applied to "ship your app"
**What it should be:** release / deploy / deliver software wording
**Why it matters:** Developer trust. One wrong verb tells the reader the copy was never read by a developer in that language.

自动生成的翻译为什么会漂移

这不是在指责译者。站点的大部分内容从来没有人工逐条过一遍。通用模型默认使用正式语体,因为开放网络上的批量双语文本大多是这个样子。当目标是“看起来合理的字符”而不是“正确的文字系统”时,它们还会混用跨文字系统的近形字。没有术语表,相邻键之间的用词就会漂移;没有货币规则,模型就会编造看似合理的本地符号;没有领域检查,encoding 和 coding 就会撞车。这正是我们要解决的故障模式,而我们自己的站点在像客户一样审查之前,也照样中招了。


清理之后我们做了什么

一次性的文案修改不构成体系。能长久起作用的,是一份小小的规范文件,全团队(以及将来任何自动翻译批次)都把它当作铁律,再加一个能在合并前运行的校验脚本。

规范。 i18n/LOCALIZATION_POLICY.md 记录了各 locale 的语体、JSON 中仅使用美元定价、外来词的取舍(例如保留 vibe coders 的英文写法)、coding 与 encoding 的假朋友词规则,以及行内字面量的排版。它刻意写得很短。没有写下来的规则,模型不会稳定地推断出来。

## Currency
- USD only in all locales. Use {monthlyPrice} and {overageRate} placeholders…
## False friends
- Coding environment is not encoding: Spanish desarrollo / Italian sviluppo / German Entwicklung…

校验。 scripts/verify-translations.sh 会检查拉丁语系 locale 文件里的西里尔字母、欧元符号、旧的假朋友词子串,以及定价占位符与 messages/en.json 的一致性。安装了 ripgrep 时还会启用可选检查。这个脚本是底线,不是上限。有了它,“我们修过一次了”就不会在下一次批量编辑中悄悄失效。

用代码解决,而不是再去猜 JSON。 我们把对外展示的美元金额集中到 lib/pricing.ts,并把 formatUsdPerMonth 和 formatUsdOveragePer1k 接入首页和 FAQ,让 locale 文件不再自己编造数字。问题不只在于字符串译错了,还在于规模化之前,规范和格式化器都没就位。


AI 辅助 i18n,你可以直接照搬的做法

如果你用模型生成翻译,语体是波动最大的变量。在增加更多语言之前,先按 locale 锁定它。货币锁在代码里,不要锁在文案里。锁定品牌词和开发者行话。运行自动检查,让不合格的批次直接失败,而不是“回头再人工扫一眼”。回头再看的时候,质量标准永远比第一遍低。

想了解这次审查背后的架构思路,请读如何本地化 AI 生成的应用,工具对比见 globalize.now vs Lokalise vs Crowdin。如果你正在自己的仓库里接入 i18n,想要同样的防护,在 globalize.now 连接仓库,转换会在应用里一次完成;npx skills add globalize-now/globalize-skills 是我们为安装在代码旁边的 Skill 提供的入口文档。最后说句实话:我们自己用了自己的产品,发现了难看的 bug,写了规范,又加了一道关卡。这就是我们希望每一次多语言发布都达到的标准。

globalize.now 把硬编码的应用文案转换为可直接翻译的语言文件,并在你持续发布时保持同步更新。

免费试用 globalize.now