跳到正文
OpenRouter Announcements·· 9 小时前AI 评分58

OpenRouter 如何搭建自校正本地化系统

How We Built a Self-Correcting Localization System for OpenRouter

AI 导读

OpenRouter 上线简体中文、西班牙语、葡萄牙语(巴西)、德语、法语、日语和韩语共 7 种语言,本地化处于 beta 阶段。其流水线每天扫描变更字符串,用 GPT-6.1 Sol 分批翻译,再由代码校验占位符与术语、同一模型二次核验语义,失败则带原因重试,最终以 pull request 形式由人合并。

正文 · AI 翻译

The OpenRouter homepage in Japanese.

OpenRouter 现已支持简体中文、Español、Português (Brasil)、Deutsch、Français、日本語和한국어,以及英语。本地化从今天开始进入 beta 阶段。要切换语言,请从账户菜单中选择一种语言,或直接访问类似 openrouter.ai/ja 或 openrouter.ai/ko/models 的地址。

The OpenRouter models page in Korean, with filters, tabs, and model metadata translated.

翻译一个网站并让译文保持最新很难,对我们来说尤其如此。OpenRouter 的网站有 16,918 条英文字符串,而且我们每天都会改动其中一些,所以一次性翻译不到一周就会过时。我们搭建了一个循环来帮助大规模完成这件事。每天,它会找出发生变化的字符串,翻译它们,在代码中检查它们,并让第二个模型对照英文核验含义。当某个译文未通过检查,或核验器拒绝它时,循环会附上原因将其送回并重试。这个重试循环就是系统中自我纠正的部分。

仍有一些错误会漏过去,人们会把这些抓出来。当审校者和读者报告错误时,我们会把它转化为术语表规则、风格说明或覆盖项,而每日审校发现的错误也会成为测试用例,未来每个模型都必须通过。整条流水线都运行在 OpenRouter 上。

译文与代码一起存放在 Git 中

在任何模型参与之前,译文需要一个存放之处。我们使用开源的 General Translation 运行时来包裹 React 代码中的字符串。我们将译文作为 JSON 目录与代码一起提交,并在运行时本地加载,因此请求路径中不会有翻译服务。字符串在合并后一天内就会被纳入翻译。在此之前,页面显示英文原文。每个译文条目还会存储其来源英文的指纹。当有人编辑英文时,指纹不再匹配,该条目就会回到队列中。这条规则让每日运行能够找出所有过期条目,而无需重新翻译整个目录。

流水线

队列中的每个字符串在到达网站之前都要经过五个阶段。

How a string gets translated: new text goes to a translator model, then code checks, then a verifier model, then review, then live. Failed checks and verifier rejections go back to the translator, and fixes flagged by reviewers or readers go into the glossary.

一个脚本扫描前端,并将每个被包裹的英文字符串写入源目录。每个条目记录其文件和 UI 角色,例如按钮、标题或表头。角色很重要,因为同一个英文单词在不同位置可能需要不同的译法。按钮上的“Queue”是一条指令,而本文后面提到的一个缺陷就是模型把它当作名词来翻译。

2. 翻译

我们将新增和变更的字符串分批发送给 GPT-6.1 Sol,每批最多 40 条,并使用 Structured Outputs 让回复遵循严格的 JSON schema。每个请求都携带我们的全局和按语言区分的风格说明、批次中任何产品术语的术语表规则,以及每个字符串的 UI 角色。

下面是一个简化示例,展示针对一个日语批次的翻译器请求,其中风格说明和术语表规则已截短。

{
  "model": "openai/gpt-6.1-sol",
  "messages": [
    {
      "role": "system",
      "content": "Translate OpenRouter UI strings into Japanese. ..."
    },
    {
      "role": "user",
      "content": "[{\"id\":\"q1\",\"role\":\"button\",\"text\":\"Queue\"}]"
    }
  ],
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "name": "translations",
      "strict": true,
      "schema": {
        "type": "object",
        "properties": {
          "translations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": { "type": "string" },
                "text": { "type": "string" }
              },
              "required": ["id", "text"],
              "additionalProperties": false
            }
          }
        },
        "required": ["translations"],
        "additionalProperties": false
      }
    }
  }
}

由于 OpenRouter 上的每个模型都接受相同的请求,尝试不同的翻译器只需更改模型 slug。我们就是这样运行本文后面的模型对比的。

3. 检查

代码会拒绝以下回复:破坏 ICU 占位符、复数分支、富文本标签,或首尾空白,或以术语表禁止的形式呈现产品术语。我们会将拒绝的批次拆成更小的片段重新发送,并说明失败原因,默认最多进行 4 轮。该上限是一个可设置项,最高可设为 20。在最后一轮后仍失败的字符串将保留英文,并在拉取请求中标记。

4. 验证

对同一模型的第二次调用充当验证器,对照英文阅读每一条译文,并按严重程度列出错误。任何严重或重大错误,例如遗漏从句或含义颠倒,都会将字符串退回给翻译器,并附上迄今为止的所有异议。翻译器在首次尝试后最多可重试 3 次,最后一次重试会使用更多的推理投入。每个字符串的花费没有单独上限,因为重试限制已经对其形成了约束。算上检查重发,一个字符串最多可经历四次翻译尝试,每次最多四轮检查,外加每次尝试后的一次验证器调用。这样最坏情况下,每个字符串每种语言约需 20 次模型调用。如果验证器宕机,流水线不会写入任何内容,字符串保持英文。读者看到一天英文,总比看到未经检查的译文要好。

5. 审查

每个每日批次都会以一个拉取请求的形式提交。AI 审查员阅读差异并发布发现,由人工合并拉取请求。

我们如何衡量

本文的其余部分依赖三个评估套件,因此在数字开始之前,了解每个套件测试什么会有所帮助。

  • 模型比较(254 个案例)使用不同的翻译器模型运行流水线,并用生产验证器为每条回复评分。我们用它来选择翻译器。
  • 流水线比较(454 个案例)对同一个模型运行两次,一次通过完整流水线,一次使用仅两行的简单提示。代码检查、验证器、来自另外三个模型家族的评判者以及回译检查都会为其评分。
  • 缺陷套件(22 个案例)包含每日审查在验证器放行后发现的真实错误。每个案例都禁止已发布的那个错误。

我们尝试过又放弃的方案

流水线现在看起来很简单,因为我们在评估衡量了最初设计的三个部分后将其移除。

更便宜的翻译器

我们首先测试了一个更小、更便宜的模型 GPT-6 Luna(openai/gpt-6-luna)。在模型比较中,它首次尝试通过了 91.7% 的案例,而 GPT-6.1 Sol 为 99.2%。它最弱的语言是韩语和日语。它最难的失败是我们的翻译框架 General Translation 无法编译的回复,例如它对“Legacy alias of {value}”的翻译。这些失败在每次重试中都持续存在。

更重的模型成本约为其 3.4 倍,在这 254 个案例中为 1.94 美元对 0.57 美元。我们支付这个差价,因为一个永远无法收敛的错误字符串,修复起来比一开始就做对要花费更多时间和精力。

单独的评判模型

在验证器出现之前,一个单独的评判模型会为每个译文打分,我们会重新翻译它标记或标记为不确定的任何内容。为了了解它的效果如何,我们用一个基准测试标注了三种字符串:已知错误、修正后的译文(早期错误的手工修正版本,应当通过)以及一个干净样本。评判模型确实发现了真正的问题。在一次基准测试运行中,它将那次运行中 91% 的真实缺陷标记为不确定。它还标记了 14 个修正译文中的 11 个,以及 150 个干净译文中的 42 个,因此它把大量优质工作退回重新翻译。

在验证器就位的情况下,关闭评判模型使首轮准确率从 99.2% 降至 98.8%,最终结果保持不变。评判模型此前会将约 45% 的初稿退回重新翻译。我们现在默认将其关闭。

将困难字符串留给人处理

起初,验证器在每次重试时都拒绝的字符串会保持未翻译状态,直到有人手工修复。对目录进行完整重译——16,274 个字符串译为 7 种语言——留下了 97 个这样的字符串(0.09%)。现在,流水线会根据验证器的发现对被拒绝的草稿进行排序,提交错误最少的一个,并在拉取请求中标记以供审查。循环总是以译文结束,即使该译文仍带有被标记的错误,而该标记会将其呈现在合并拉取请求的人面前。

流水线相比裸模型增加了什么

流水线增加的大部分是更少的明显错误。为了衡量这一点,我们的评估在 454 个案例上对同一模型运行两次,一次通过完整流水线,一次使用两行提示且没有风格说明、术语表或重试。裸模型返回了一个格式错误的回复,剩下 453 对可供比较。

指标裸模型完整流水线
未通过术语表或人工编写检查453 个中的 147 个454 个中的 4 个
首轮通过验证器通过检查的 306 个中的 263 个(85.9%)全部 454 个中的 448 个(98.7%)
关键错误,汇总自其他模型系列的三个评判模型203109
双方在总体偏好上各自获胜的对数117139
含义在回译后得以保留90.8%89.3%

人工编写检查是针对一个评估案例的手写规则。例如,中文的“Queue”不得翻译为 队列,即已发布的那个名词形式。检查失败从 147 降至 4,这是术语表和重试在发挥作用。

验证器的首轮数据使用不同的基数。对于裸模型,是通过代码检查的 306 个字符串,而对于流水线,是全部 454 个。验证器与翻译器来自同一模型系列,因此其通过率告诉我们模型与自身一致的程度。我们使用 GPT-6.1 Sol 来完成这两项工作,因为它是我们测试的两个翻译器中更准确的一个。为了获得外部视角,评估还将每一对译文不加标签地发送给来自其他模型系列的三个评判模型:Claude Opus 5.5、Gemini 4 Argon 和 DeepSeek V4 Pro。在三个评判模型之间,他们在流水线输出中发现了 109 个关键错误,在裸模型输出中发现了 203 个。每个评判模型的错误单独计数,因此三个评判模型都标记的字符串会在总数中增加三个。

在 453 对的总体偏好上,评判模型选择流水线的有 139 对,选择裸模型的有 117 对,61 对平局,136 对的两个译文完全相同。这一差距远小于检查失败和关键错误所显示的差距,因此流水线的价值主要在于它消除的具体错误。

最后一行会把每条回复回译成英文,并判断原意是否保留。裸模型得分 90.8%,流水线得分 89.3%。回译无法看出术语或语域,而这正是流水线改动的大部分内容,因此我们把这一结果视为持平。

反馈闭环

验证器在发布前拦截了大部分错误,读者则能发现其余错误中的一部分。

Highlighted text on the Japanese homepage with the popover for sending feedback on it.

在“语言”对话框中开启“选中即报告”,然后高亮任意译文,添加备注并发送。每份报告都会附带语言、页面和确切文本。模型会先对其进行分类,从四种修复方案中选择一种,并在几分钟内上线修复。我们的 AI 审核员会检查修复,最后由人工完成最终合并。

  • 含义错误。 该字符串当天回退为英文,随后获得修正后的译文。
  • 术语错误。 我们将该术语以可接受形式和该语言应拒绝的形式加入术语表。我们会固定 HIPAA、SOC 2、OAuth 和 SAML 等合规与协议名称,使流水线将其保留为英文。
  • 语气或标点错误。 该规则会写入该语言的风格说明。
  • 单个字符串错误。 精确覆盖会固定已批准的措辞,后续任何运行都无法更改。

验证器放行、但每日审核发现的错误会进入缺陷套件。目前已有 22 个用例。其中包括将按钮上的“Queue”误译为名词(此处应为动词)、将“shadow traffic”误译为道路交通,以及一个含义被颠倒的 HIPAA 设置。每个用例都会禁止已发布的错误,因此未来任何模型、提示词或术语表变更若使其重现,评估就会失败。

成本

我们最初定价时,将全部 16,274 个字符串完整重译为 7 种语言,共 113,918 条译文,包含翻译和验证在内,总成本约为 430 美元。我们通过对每种语言的生产规模批次定价并放大规模得出该数字。折算下来,每个字符串每种语言不到半美分。验证略高于一半,约为 228 美元,即每个字符串每种语言 0.002 美元。此后目录已增长至 16,918 个字符串,如今完整重译约需 460 美元。每日循环只发送变更内容,一天有 677 个变更字符串、涉及 7 种语言时,成本约为 18 美元。

这两个数字仅涵盖翻译和验证调用。它们不包括构建流水线的工程时间、AI 审核员和分类模型发起的调用,以及合并每日拉取请求的人员。

如今的 16,918 个字符串包含 136,429 个英文单词,因此 7 种语言合计 955,003 个单词,使我们的成本约为每词 0.0005 美元。以下是按 Smartling 和 Gengo 公布的每词起价(截至 2026 年 11 月 10 日)计算的同样完整重译成本。

选项费率全站,7 种语言
我们的流水线,翻译与验证约每词 0.0005 美元约 460 美元
Smartling 机器翻译每词 0.0075 美元约 7,200 美元
Smartling AI 翻译每词 0.06 美元约 57,300 美元
Gengo 标准每词 0.09 美元约 86,000 美元
Smartling AI 人工翻译每词 0.12 美元约 114,600 美元
Gengo 高级每词 0.18 美元约 171,900 美元
Smartling 人工翻译每词 0.20 美元约 191,000 美元

以上为标价;企业合同需协商,且上述机器翻译的每一行都包含人工审核或项目管理,而我们的数字未计入这些。最接近的同类选项是 Smartling 的机器翻译,我们的流水线成本约为其 6%。

你可以复用的部分

如果你正在为自己的产品做本地化,这个设计中有四个部分可以直接沿用。

  • 将每条译文与其英文原文进行指纹比对,这样过时的条目就会自动重新排队。
  • 让代码在任何模型审查含义之前,先拒绝损坏的占位符、复数分支、标签和禁用词。
  • 使用一个能指出每个错误及其严重程度的验证器,并将这些异议发回给翻译器。
  • 把人们发现的每一个错误转化为术语表规则、风格说明、覆盖设置或评估用例。

向我们发送反馈

在测试阶段,部分措辞可能不够准确,最快的修复方式是在语言对话框中使用“选择并报告”功能进行报告。我们会审查每一份报告,并将其转化为术语表规则、风格说明或覆盖设置。

常见问题

OpenRouter 支持哪些语言?

OpenRouter 提供英语、简体中文、西班牙语、巴西葡萄牙语、德语、法语、日语和韩语版本。本地化功能处于测试阶段。

如何在 OpenRouter 上更改语言?

从账户菜单中选择一种语言,或打开本地化地址,例如 openrouter.ai/ja。

哪些模型负责翻译 OpenRouter?

GPT-6.1 Sol(openai/gpt-6.1-sol)负责翻译每个字符串,然后对同一模型发起第二次调用,对照英文原文进行验证。两者都通过 OpenRouter API 运行。

翻译整个网站需要多少费用?

将目前 16,918 个字符串完整重新翻译成 7 种语言,费用约为 460 美元,包含翻译和验证,即每个字符串每种语言不到半美分。同样的工作在 Smartling 公布的机器翻译费率下约为 7,200 美元,在公布的 AI 和人工翻译费率下约为 57,300 美元至 191,000 美元。

如何报告糟糕的翻译?

在语言对话框中开启“选择并报告”,高亮显示读起来有问题的文本,添加备注并提交。

来源:OpenRouter Announcements · openrouter.ai