OpenCode 日语区域术语表 ja.md:从 WSL 用词之争看自动翻译管线中的 Glossary 机制
本文以 OpenCode 仓库中 ja.md 这份日语区域术语表为核心,讲解它作为“社区评审沉淀”如何约束产品本地化的用词选择(WSL連携 而非 WSL統合)、哪些标识符禁止翻译,以及它如何被 translate:app 脚本 自动注入到 AI 翻译会话中,最终落实到 packages/app、packages/ui、packages/desktop 三套 i18n 词典里。读完后你能理解一份 Glossary 文件在整个国际化流水线中的完整生命周期,并掌握如何为某个语言区域新增或修订术语规则。
一、ja.md 是什么:一个语言区域专属的翻译约束文件
.opencode/glossary/ja.md 是 OpenCode 仓库按语言拆分的本地化术语表之一。同目录下的 README 说明了该目录的定位:每个 locale 一个文件,文件名使用小写区域 slug(例如 zh-cn.md、zh-tw.md),文件内容记录“社区学习到的措辞与术语偏好”,用于补充共享的翻译指导;当仓库使用了别名 slug(例如 br 对应巴西葡语 / pt-BR)时,应在文件的 Guidance 一节中注明。目录当前收录了 ar、br、bs、da、de、es、fr、ja、ko、no、pl、ru、th、tr、zh-cn、zh-tw 共 16 份语言文件。
ja.md 全文遵循 README 给出的标准模板(Sources → Do Not Translate → Preferred Terms → Guidance → Avoid),内容完整继承如下。
1. 术语依据来源(Sources)
ja.md 开头声明了规则来源:
- PR #9821:
https://github.com/anomalyco/opencode/pull/9821 - PR #13160:
https://github.com/anomalyco/opencode/pull/13160
这体现了 README 贡献规范中的一条硬性要求——“每次新增或更新规则时都要补充 Sources 一节”,即每条用词偏好都必须能追溯到具体的 PR 评审,而不是凭空发明术语映射(Prefer PR-backed guidance over invented term mappings)。
2. 不可翻译项(Do Not Translate, Locale Additions)
ja.md 规定以下条目在日语翻译中保持原样:
| 条目 | 规则说明 |
|---|---|
OpenCode |
正文中保持大小写;仅在命令、包名、路径或代码中使用小写 opencode |
OpenCode CLI |
作为产品称谓整体不翻译 |
CLI、TUI、MCP、OAuth |
保留英文缩写 |
| 命令、标志(flags)、文件路径、代码字面量 | 完全按原样保留 |
3. 推荐术语(Preferred Terms)
ja.md 的核心增量是一条被 PR 评审确认过的用词偏好,原表格完整保留:
| 英文 / 上下文 | 推荐译法 | 备注 |
|---|---|---|
| WSL integration(UI 标签) | WSL連携 |
PR #13160 偏好此写法,而非 WSL統合 |
| WSL integration description | WindowsのWSL環境で... |
PR #13160 的自然日语措辞改进 |
表格上方特别注明:“这些是 PR 支撑的用词偏好,可能会演化”——这正是 README 建议的“将可能演化的条目标记为 preferred”的做法。
4. 指导原则(Guidance)与禁用项(Avoid)
- 优先自然的日语表达,而非逐字翻译;
- 技术产物必须精确保留:命令、标志、代码、URL、模型 ID、文件路径;
- WSL 集成相关文案遵循 PR #13160 的用词方向,追求更自然的日语;
- 在 WSL 集成 UI 上下文中,
WSL連携是已评审的措辞,避免使用WSL統合; - 避免翻译产品名与协议名等固定标识符。
二、ja.md 如何进入自动翻译管线
Glossary 文件不是孤立的文档——它是翻译管线的运行时输入。从 script/translate-app.ts 的源码结构看,存在一条清晰的“词典漂移检测 → 注入术语表 → 受控执行 → 复核”链路。
1. locale 到 glossary 文件的映射
脚本中 glossaryFile() 函数(script/translate-app.ts#L125-L129)把产品内 locale 码映射到术语表路径:
export function glossaryFile(locale: Locale) {
if (locale === "zh") return ".opencode/glossary/zh-cn.md"
if (locale === "zht") return ".opencode/glossary/zh-tw.md"
return `.opencode/glossary/${locale}.md`
}
也就是说 ja 会解析为 .opencode/glossary/ja.md。这一映射由 script/translate-app.test.ts 中的测试用例“maps product locale codes to their glossaries”直接验证(fr → fr.md、zh → zh-cn.md、zht → zh-tw.md)。
2. 术语表被注入翻译提示词
translate() 函数(script/translate-app.ts#L396-L416)在执行翻译会话前会读取该 locale 的术语表全文,并将其作为 glossary 字段(含 file 与 content)拼进发给 OpenCode 的请求 JSON。请求模板是 script/translate-app.md,其中明确要求:
- “Apply the locale glossary included in the request.”(应用请求中附带的 locale 术语表)
- “Preserve technical terms and artifacts exactly: OpenCode, API names, identifiers, code, commands, flags, paths, URLs, versions, error messages, config keys, and placeholder tokens.”——与 ja.md 的 Do Not Translate 一节形成双重约束
- 只允许使用 read、glob、grep、webfetch、websearch、edit 工具,不得执行命令或转委托
从源码看,翻译会话还通过 translationConfig() 生成了严格的权限边界:share: "disabled"、关闭 formatter/LSP/snapshot,edit 权限默认 deny、仅放行本 locale 的目标文件(见 translationConfig 与测试用例 “disables side effects and scopes edits for the translation agent”)。这保证 AI 翻译者只能修改声明过的 i18n 目标文件,术语表约束因此能在一个“写权限最小化”的环境中生效。
3. 翻译目标文件与漂移检测
每个 locale 的翻译目标固定为三个域(targetFiles):
packages/app/src/i18n/<locale>.tspackages/ui/src/i18n/<locale>.tspackages/desktop/src/renderer/i18n/<locale>.ts(仅桌面原生 locale)
findDrift() 会对比英文源词典与目标词典,输出 missing(缺键)、extra(多余键)、placeholders({{token}} 占位符不匹配)三类漂移,并支持 CLDR 复数变体(如阿拉伯语的 two/few/many 分类)。执行完毕后,脚本用 git 工作区快照比对(unexpectedChanges())确认没有越界改动,并导出会话记录核验实际使用的模型与 variant。
除了 translate:app(应用词典),文档翻译命令 .opencode/command/translate.md 同样要求“当 .opencode/glossary/<locale>.md 存在时应用其中的 locale 专属指导”,说明术语表是贯穿应用界面与文档两套翻译流程的共同规范。
三、在日语词典中验证 ja.md 的落实
packages/app/src/i18n/ja.ts 中的实际字符串是 ja.md 规则生效的直接证据:
"settings.desktop.section.wsl": "WSL",
"settings.desktop.wsl.title": "WSL連携",
"settings.desktop.wsl.description": "WindowsのWSL環境でOpenCodeサーバーを実行します。",
三条规则逐条对应:
- UI 标签使用了评审确认的
WSL連携,而非被 Avoid 一节禁用的WSL統合; - 描述文案正是 PR #13160 指向的
WindowsのWSL環境で...句式(“在 Windows 的 WSL 环境中运行 OpenCode 服务器”); OpenCode在正文中保留了大小写,未翻译成罗马字或其他变体。
同样的“技术产物精确保留”原则也体现在 WSL 错误文案中(packages/app/src/i18n/ja.ts#L75-L96):占位符 {{distro}}、{{code}}、{{signal}}、{{timeout}} 原样保留且必须与英文源一致——这正是 findDrift() 会拦截的 placeholders 漂移类型。若某条译文把 {{code}} 写成 {{code}} 之外的任何形式,或漏掉了某个键,脚本会在报告中列出该键并要求修复。
四、如何为其他语言区域新增或修订术语规则
依据 README 的贡献规范,为任意 locale 维护术语表的标准流程是:
- 在
.opencode/glossary/下按小写 slug 命名文件(语言级指导用语言码,如fr.md;区域级用完整 slug,如zh-cn.md); - 按模板分节组织:
Sources(列出驱动该规则的 PR/issue)、Do Not Translate (Locale Additions)、Preferred Terms(表格:英文 | 推荐译法 | 备注)、Guidance、可选的Avoid; - 新增规则时同步补充
Sources;用词可能演化时标记为 preferred; - 优先收录“跨多个文档/界面反复出现、可一致应用、且有社区贡献或评审讨论支撑”的条目;若尚无术语级修正,先给通用指导。
ja.md 就是一份合格的范本:两条推荐术语都能落到具体 PR,规则与 zh-cn.md 等其他语言文件在结构上完全对齐,且能被 glossaryFile() 直接寻址、被两套翻译流程(应用词典与文档)共同引用。
五、适用前提与限制
- 术语表的约束力来自翻译管线与评审流程,而非运行时强制:
translate:app会把术语表全文注入提示词,但最终质量仍依赖模型遵循度与 PR 评审; - 仓库 locale slug 与 BCP47 存在有意偏差(如
br表示巴西葡语pt-BR),新增文件时若使用别名 slug,必须在 Guidance 中记录; - Preferred Terms 明确标注“may evolve”,引用其中术语时应以最新 PR 评审为准;
- 本文所述管线基于当前仓库快照,默认模型、variant 与并发参数(如 translate-app.ts#L86-L115 中的
--concurrency、--model、--variant)可能随版本变化,执行前建议先跑--dry-run查看漂移报告。
参考路径汇总:术语表 ja.md、目录规范 glossary/README.md、管线实现 script/translate-app.ts、提示词模板 script/translate-app.md、管线测试 script/translate-app.test.ts、文档翻译命令 .opencode/command/translate.md、实际字典 packages/app/src/i18n/ja.ts。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00