Skip to content

Tutorial 5 Localization zh

James Morris edited this page Jul 29, 2026 · 1 revision

教程 5 · 本地化(i18n)

🌎 语言: 简体中文查看全部 33 种语言

目标: 理解 LockedIn CLI 如何支持 33 种语言,并练习指导智能体再添加一种。 本地化非常适合智能体:工作足够机械,便于委派;同时又有测试门禁、布局规则和语法审查等 真实约束,可以训练你的审查能力。

← 上一章:教程 4:提示与审查 · 返回 首页


这里的“已本地化”是什么意思

用西班牙语、印地语、日语、简体中文或任何内置语言运行 CLI,所有内容都会变化: 启动画面、帮助表、每个命令的输出、聊天会话,甚至法律细则。不只是笑话,而是整个可见界面。

lockedin --lang zh post
LOCKEDIN_LANG=hi lockedin
lockedin --lang zh aura

语言在启动时自动检测,优先级如下:

  1. --lang 标志(--lang zh--lang=fr-l ja
  2. LOCKEDIN_LANG 环境变量
  3. 区域设置(LC_ALL / LC_MESSAGES / LANG,然后是操作系统 / 运行时区域设置)
  4. 英语后备

normalizeLang() 通常使用区域设置的主子标签。因此 de-DE 选择 de,但 tlh 不会误选 tl;真实别名 filtgl 会映射到他加禄语 tl,挪威语 nbnn 映射到 no,旧印尼语代码 in 映射到 id,旧希伯来语代码 iw 映射到 he。 两个区域代码会原样保留,而不折叠到主子标签:pt-BR / pt_BR 选择规范区域代码, 通用 pt 保持向后兼容的巴西葡萄牙语包(两者共享 pools/UI);en-SG / en_SG 保留新加坡英语,通用 en 仍为英语。香港繁体中文也是同类例外: zh-HKzh_HK.UTF-8zh-Hant-HK 选择 zh-HK,通用 zh 与中国大陆标签 选择简体中文 zh

会话中切换——/language 面板。 CLI 一直可以用 --langLOCKEDIN_LANG 以其他语言启动,现在也能在会话途中切换。输入 /language(别名 /lang/languages) 会按代码列出全部 33 种语言,并以各自文字显示;/language el 会切换本会话余下部分。 重点是逃生出口:切换后,面板先以新语言重绘,再用刚离开的语言打印确切返回方法—— 当前输入 /language en,下次运行 lockedin --lang en。这样即使误入 日本語ಕನ್ನಡ 也不会被困住。连续切换两次时,还会提供 LOCKEDIN_LANG 指定的语言。 --langLOCKEDIN_LANG 的行为不变。与 /a11y 一样,它是真实工具,不是讽刺内容。

核心思想:语言包

所有可翻译文本都位于语言包中,每种语言一个,结构如下:

{ meta: { lang: 'zh', name: '简体中文', dir: 'ltr' },
  pools: { HOOKS: [ /* 约 25 项 */ ], LESSONS: [ /* ... */ ], /* ... */ },
  ui:    { buzzwordDensity: '黑话密度:', /* 标签、标题 */ } }
  • pools 是第 2 章介绍的内容数组。
  • ui 是界面文字:标签、标题和小模板。

英语参考包位于 src/lockedin.js;其余 32 个模块位于 src/content/*.jsarbnbodeelen-SGeseufafifrhehiidisitjaknmsnlnoplptpt-BRrusvtltrukurzhzh-HKpt-BR 重用 pt 的 pools/UI,但单独注册)。 每个包都注册到 BUNDLESSUPPORTED_LANGS 由这些键生成,renderHelp() 打印生成的代码列表, 任何 UI 包都不会硬编码该列表。

setLang('fr');       // 让活动语言指向法语包
// L = 活动 pools,U = 活动 ui
pick(L.HOOKS)        // 法语开场
U.buzzwordDensity    // "Densité de jargon : "

每个渲染器都读取 LU,绝不硬编码文本,因此仅调用 setLang 就能切换整个体验。

安全网:键一致性

添加语言之所以安全,依靠这条不变量:

每个语言包都必须暴露与英语完全相同的 poolsui 键。

测试会对全部 33 个语言包强制执行。如果在英语中新增 UI 字符串,却忘记翻译到乌克兰语, npm test 会变红并指出缺失键,因此不可能静默交付半翻译语言。

难点:终端布局

不同语言会以不同方式考验终端布局:

  • 日语、简体中文和香港繁体中文使用东亚宽字符 / 全宽字符。vw() 将它们计为两列, wrap() 会硬拆没有空格的长标记,使 CJK 文本留在卡片和框内。
  • 印地语和卡纳达语使用非间距 / 包围组合标记(Mn / Me),例如元音符号和辅音抑制符。 vw() 将其计为零列,不会虚增宽度。
  • box() 会先包装正文行再填充,因此长翻译横幅不会冲破边框。
  • 每个语言包设置 sentenceEndlistSep,例如 . / , / , 让生成器组合的句子自然。

新增语言时,卡片头字符串 cardSubtitlecardMetacardFooter 必须保持 ≤ 60 个可见列。阿拉伯语、波斯语、希伯来语和乌尔都语设置 meta.dir: 'rtl'。 默认输出不含双向文本控制符,因为部分终端会把它们显示成方框标签。只有明确设置 LOCKEDIN_BIDI=on,才会在换行后启用平衡隔离符,同时保留 ANSI、ASCII 命令和逻辑复制顺序。 无障碍输出始终移除控制符。没有明确启用时,混合 RTL/LTR 排列可能较简单;绝不能探测或推断支持。

隐蔽难点:原始用户输入周围的语法

一些 UI 模板会用 {cap} 等占位符插入用户原句。不要逐槽机械翻译;占位符可能是一整句用户文字, 而不是整齐的名词,最终句子仍须符合语法。

真实案例:日语模板若直接在 {cap} 后加 ,当 {cap} 是完整从句时会很别扭。 解决方案不是“更努力地直译”,而是重构模板,例如加入名词化结构或移动占位符,让任意用户输入都适配。

✅ 和你的智能体一起试试——添加一种语言

选择你能校对的语言,并先写规格:

添加丹麦语(da)。 创建 src/content/da.js,作为 { meta, pools, ui } 语言包,键与英语完全相同,翻译每个条目(每个内容池约 25 项,以及全部 UI 字符串)。 在 src/lockedin.jsBUNDLES 中注册 da--lang dada-* 区域设置都应选中它。 卡片头字符串不得超过宽度限制。npm test 必须保持绿色,并添加与现有本地化测试相仿的 丹麦语不变量和检测测试。

然后运行第 3–4 章的循环:

  1. 先规划。 “写代码前,说明会改哪些文件,以及怎样保持英语键一致性。”
  2. 测试优先。 “先添加失败测试:da 检测、da 键一致性,以及丹麦语 reflect/connect 不变量。暂时不要创建语言包。”
  3. 实现。 “把现有语言包逐键翻译为 src/content/da.js,注册它并让测试通过。 随机性只能使用 pick / shuffle。”
  4. 门禁与审查。 运行 npm testlockedin --lang da post,再阅读差异: 是否每个键都翻译?卡片边框是否对齐?带 {cap} 的模板能否容纳原始用户从句?

较小的热身练习:

  • “为全部 33 个语言包各添加一个 TAGLINE,保持数量相同。”
  • “检查卡纳达语 cardFooter 是否 ≤ 60 可见列,并说明如何测量组合标记。”
  • “指出删除 ja.js 中一个 ui 键时会失败的测试。”

接下来

  • 浏览 src/content/es.js,它仍是创建新语言包的友好模板。
  • 重读 docs/HANDOFF.md 中的“Adding a language”。
  • 欣赏 命令参考 中的多语言笑话。

完整教程到此结束。你现在可以在测试门禁后指导 AI 智能体构建功能并进行本地化, 支持 33 种语言,也随时可以继续扩展。同意吗?👇

📘 LockedIn CLI wiki

Tutorial

Reference


Satire · Sátira · 風刺. Not affiliated with LinkedIn. GPL-3.0-or-later.

Clone this wiki locally