Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

文档与翻译

ZeroClaw 拥有两个独立的翻译层:

格式涵盖内容
应用字符串Mozilla Fluent (.ftl)CLI 帮助文本、命令描述、运行时消息
文档gettext(.pomdBook 中的所有文件

有关这些流程背后的事实来源、存储、加载、回退和发布边界,请参阅本地化目录生命周期。为文档提取提供输入的生成英文参考内容在生成文档流水线中映射。

它们分别填充并分别存储。两者都使用共享的、与提供商无关的运行时路径:在 providers.models.<kind>.<alias> 下配置模型提供商,并将 --model-provider <alias> 传递给填充命令。任何已配置的别名都可以选择:裸别名(--model-provider <alias>),或者当同一别名存在于多个 kind 下时使用 kind.alias 限定符(--model-provider anthropic.<alias>)。解析器要求匹配的条目指定一个模型,然后将端点默认值、身份验证、线路协议以及可选的自定义 uri 处理委托给运行时提供商栈。

通过 Ollama 使用本地模型是首选方案:无需 API 密钥,无按次调用费用。若需发布级质量,使用托管服务提供商也可以。翻译是本地操作。运行 cargo mdbook sync 来生成专门的翻译缓存 PR、发布翻译流程以及新增语言环境;常规英文文档 PR 可将大范围生成的 .po 变更推迟到专门的后续处理中。

提供程序配置

Ollama 是当前文档的规范来源。请确保已安装 Ollama 并已拉取 qwen3:30b-a3b,然后配置一个 Ollama 提供方条目。uri 是完整的端点 URL,且为可选项:将其留空以使用该提供方系列的默认端点(由运行时提供方栈解析)。仅在需要指向自托管网关或代理时才设置它。任何已配置的系列均可使用(Anthropic、OpenAI、OpenRouter、Ollama……);翻译工具会构建真正的运行时提供方,因此每个系列的端点、认证头和传输协议都会为你处理:无需 OpenAI 兼容性要求。

在本地构建文档

翻译目录(git submodule)

已翻译的 .po 目录位于挂载在 docs/book/pozeroclaw-labs/zeroclaw-docs-translations 子模块中。Rust 开发循环(cargo build, cargo test, cargo clippy)不需要它,但构建或同步文档时需要。初始化一次:

sh

git clone --recurse-submodules https://github.com/zeroclaw-labs/zeroclaw   # 新克隆
git submodule update --init docs/book/po                                   # 现有克隆

如果没有检出子模块,英文仍然可以构建(英文源位于 docs/book/src/),但翻译后的区域会渲染为空。

一键快速启动

sh

cargo mdbook serve                       # 在 http://localhost:3000/en/ 提供所有语言环境
cargo mdbook serve --locale ja           # 针对日语源码的实时重载
cargo mdbook build                       # 将所有语言环境的静态构建放入 docs/book/book/
cargo mdbook refs                        # 重新生成自动生成的参考页面
cargo mdbook sync                        # 翻译缓存流程:重新提取 + 合并 .po 文件
cargo mdbook sync --locale ja            # 仅同步一个区域设置
cargo mdbook sync --force                # 强制重新翻译所有内容(质量检查)
cargo mdbook sync --locale ja --force    # 强制重新翻译某个区域设置
cargo mdbook stats                       # 按语言环境显示已翻译/模糊/未翻译的内容
cargo mdbook check                       # 验证 .po 文件格式(在翻译 PR 之前运行)

始终使用 cargo mdbook … 包装器。直接在 docs/book/ 中运行 mdbook build 会跳过 xtask 步骤,而该步骤负责从 locales.toml 渲染 theme/lang-switcher.js,这会导致构建失败并报错 failed to open theme/lang-switcher.js for hashing

必需的工具

cargo mdbook 会快速失败并告知你缺少什么,但作为参考:

工具安装
mdbookcargo install mdbook --version 0.5.4 --locked
mdbook-mermaidcargo install mdbook-mermaid --version 0.17.1
mdbook-i18n-helperscargo install mdbook-i18n-helpers --locked
cargohttps://rustup.rs
gettext(msgfmt、msgmerge)apt install gettext / brew install gettext

mdbook-mermaid 的版本已固定,但其发布的锁定文件仍选择 mdBook 0.5.0 的预处理器。对该工具不要使用 --locked,以便 Cargo 解析 mdBook 0.5.4 所使用的兼容 0.5.x 预处理器。

构建产物及其位置

输出由…生成
docs/book/src/**/*.md(手动编写)docs/book/book/<locale>/mdbook build
docs/book/src/reference/cli.md(相同路径;已忽略 gitcargo mdbook refs
docs/book/src/reference/config.md(相同路径;已忽略 gitcargo mdbook refs
target/doc/(rustdoc)docs/book/book/api/cargo doc --no-deps --workspace --exclude zeroclaw-desktop

这两个 reference/*.md 文件是从代码中实际的 clap 派生和 JSON schema 生成的,请勿手动编辑。应改为编辑相关 Rust 类型上的 /// 文档注释。

cargo mdbookcargo run -p xtask --bin mdbook -- 的别名(在 cargo 配置中定义)。如需面向贡献者的精简版本,请参阅在本地构建文档

[!NOTE] 全文搜索仅为主要语言区域(英语,locales.toml 中的第一项)构建。翻译后的语言区域在构建时不包含搜索索引或搜索框。每个语言区域的搜索索引体积很大(每个约 6-7 MB),会显著增加 gh-pages 克隆的大小;将搜索限制为英语可使克隆保持精简。若要为翻译后的语言区域重新添加搜索框,需在 build_localesxtask/src/cmd/mdbook/build.rs)中为该构建重新启用 output.html.search.enable

如何保持翻译的时效性

当英文源文件发生变化时,cargo mdbook sync 会执行两个阶段:

  1. 提取mdbook-xgettext 会根据当前的英文源文件重新生成 po/messages.pot
  2. 合并msgmerge --no-fuzzy-matching 更新每个语言环境的 .po 文件,为新增或已更改的源字符串赋予空的 msgstr "",并移除过时的条目。只有在合并之前已存在的模糊条目,才可在后续审查或填充接受时继续使用。

然后该命令会统计模糊 + 未翻译的条目,并在指定 --model-provider 时只填充这些条目。未更改的字符串不会产生任何开销:.po 缓存意味着针对未更改的源重新运行是空操作。如果不指定 --model-provider,同步仍会执行提取 + 合并并报告差异;没有 msgstr 的字符串会在渲染时回退为英文。

Sync 使用稳定的输出规则(msgcat --sort-output --no-wrap --add-location=file)来规范化 catalog,因此 diff 仅聚焦于真实的源代码变更。无法避免的变动包括:header 元数据(如 POT-Creation-Date 等)、字符串在文件间移动时的引用位置更新,以及实际的源字符串编辑。

常规英文文档 PR 可将大范围的 .po 变更推迟到专门的后续跟进中处理。仅在以下情况包含 .po 更新:PR 是翻译缓存更新、发布翻译更新、新增语言区域,或产生的差异较小且便于审查时。

填充应用字符串(Fluent)

应用字符串位于 crates/zeroclaw-runtime/locales/ 中。英语是事实来源,并在编译时嵌入。

运行时加载边界。

  • 嵌入式资源: 英语版 cli.ftltools.ftl 已嵌入。builtin_cli_ftl_source() 枚举由运行时嵌入的非英语 CLI 目录;zeroclaw-tools 单独嵌入英语工具字符串,以保持 crate 依赖方向。
  • 磁盘覆盖层: <config-dir>/data/ftl/<locale>/ 处的目录可覆盖嵌入的 CLI 值并提供已翻译的运行时/工具值。zeroclaw locales fetch 用于填充此共享目录。
  • 使用注意事项: 填写并提交 .ftl 文件会更新已跟踪的目录源,但只有当消费者的加载器嵌入该目录,或该文件安装在加载器可读取的位置时,消费者才会使用它。

apps/zerocode TUI 维护着一份独立的 Fluent 目录(apps/zerocode/locales/),请参阅下方的 zerocode stringscargo fluent 会遍历两个目录根(runtime + zerocode),因此下面的每个子命令默认都会同时涵盖这两者。

sh

cargo fluent stats                                                   # 各语言环境、各目录的覆盖率
cargo fluent check                                                   # 校验两个语言目录的 .ftl 语法
cargo fluent fill --locale ja --model-provider anthropic.<alias>             # fill missing keys (default batch 50)
cargo fluent fill --locale ja --model-provider anthropic.<alias> --batch 10  # 更小批次:每个请求处理更少条目(缓解速率限制/截断问题)
cargo fluent fill --locale ja --model-provider anthropic.<alias> --force     # 重新翻译所有内容
cargo fluent scan                                                    # 查找与 Rust 源码相比过期或缺失的密钥

限定到单个目录:每个子命令都接受 --catalog <runtime|zerocode>(默认:两者)。若仅翻译 TUI:

sh

cargo fluent fill --locale ja --model-provider anthropic.<alias> --catalog zerocode
cargo fluent check --catalog zerocode                                # 仅语法检查 zerocode

未知的 --catalog 值会报错并列出有效的选项。

fill 会为每个具有 en/ 目录的选定目录树根生成 <locale>/<domain>.ftl:包括运行时的 cli.ftl/tools.ftl 以及 zerocode 的 zerocode.ftl

提供方解析与运行时共享。 --model-provider 接受在 [providers.models.<kind>.<alias>] 下配置的任何别名:可以是裸别名(<alias>),在存在歧义时也可使用 kind.alias 限定符(anthropic.<alias>)。该工具会构建实际的运行时提供方,因此端点、认证标头和传输协议会按家族分别解析(Anthropic 的 /v1/messages + x-api-key、OpenAI 兼容的 /v1/chat/completions + Bearer 等等):不做任何假定。加密的 api_key 值会通过规范的 SecretStore 解密。使用 --config-dir <dir>(与 zeroclaw --config-dir 相对应)可从非默认位置读取配置和 .secret-key;默认位置为 ~/.zeroclaw,其次为 ~/.config/zeroclaw

批处理: fill 每个批次发送一个请求(将所有 N 个条目作为单个 JSON 对象);--batch 可降低 N 值,以缓解服务商的速率限制或长条目的响应截断问题。每个批次在发送下一个请求之前都会写入磁盘,因此运行中途失败只会丢失正在处理的那个批次。重新运行时会跳过目标 .ftl 中已存在的键,因此可自动续传:无需使用 --force

zerocode 字符串(Fluent,独立)

apps/zerocode 带有自己独立的 Fluent 配置,与上述运行时目录分离。该 TUI 有意与工作区的其余部分解耦:它不依赖 zeroclaw-* crate,并且其字符串与源代码放在一起,而非位于 zeroclaw-runtime/locales/ 之下。

在哪里什么
apps/zerocode/locales/en/zerocode.ftl编译时嵌入的可信源
apps/zerocode/locales/<locale>/zerocode.ftl纳入版本控制的翻译目录源,用于 fill/fetch 和发布工作流;不会自动嵌入
$ZEROCODE_LOCALE_DIR/<locale>/zerocode.ftl显式覆盖,用于测试翻译
<config-dir>/data/ftl/<locale>/zerocode.ftlzeroclaw locales fetch 写入并由 zerocode 加载的共享的每用户目录

密钥命名空间

所有 zerocode 键都以 zc- 为前缀,绝不会与运行时的 cli-channel-tool- 命名空间发生冲突。zc- 内部的命名约定为 zc-<pane>-<purpose>

  • zc-pane-<name>:顶级模式栏标签
  • zc-app-<purpose>:由 app.rs 拥有的字符串(对话框、帮助、状态)
  • zc-<pane>-<purpose>:特定窗格本地的字符串(zc-dashboard-*zc-chat-*……)

和弦字面量不会被翻译

Ctrl+CEscShift+Up 这样的组合键字形属于协议,而非自然语言。HelpEntryHelpNode 构造函数将组合键向量作为 &'static str 接收,将描述作为 String 接收,因此组合键字面量保持硬编码,而描述则通过 t() 传递。当文本中内嵌组合键时,请使用 { $keys } Fluent 占位符,并在渲染时传入组合键,而不是在字面量周围拼接翻译后的文本。

区域设置解析

Locale 来自 zerocode 配置中的顶层 locale 字段。未设置时,i18n::detect_locale() 会读取按以下顺序解析的配置目录:--config-dir,然后是 ZEROCLAW_CONFIG_DIR,再是 ~/.zeroclaw,否则回退到 en。zerocode 独立于其自身配置解析 locale;它不共享守护进程的查找逻辑。

添加字符串

  1. 将键 + 英文值添加到 apps/zerocode/locales/en/zerocode.ftl。按源文件对键进行分组,并添加分区注释,使目录保持易于浏览。
  2. 将源代码中的字面量替换为 crate::i18n::t("zc-…")。对于枚举→标签的 match 分支,请从 fluent_key() 方法返回键常量(&'static str),并在渲染处调用 t(),切勿对字符串进行 match
  3. cargo check -p zerocodei18n 单元测试(cargo test -p zerocode i18n)会在编译/测试时捕获缺失的键。运行时缺失的键会渲染为 {zc-key-name} 并发出一次性的 stderr 警告。

正在填充翻译

cargo fluent 会同时遍历 zerocode 目录和运行时目录,因此无需单独的填充命令。运行 cargo fluent fill --locale <code> --model-provider <alias> 会在填充运行时目录的同一过程中生成 apps/zerocode/locales/<code>/zerocode.ftlcargo fluent checkcargo fluent stats 同样会报告 zerocode;scan 会为 apps/ 建立索引,因此 zc- 键引用可以针对 zerocode 的源文件解析。要在 zerocode 中体验翻译,请通过 zeroclaw locales fetch 安装它,或将其放在上述两个磁盘搜索根目录之一中。

填充文档翻译(gettext)

文档翻译位于 docs/book/po/cargo mdbook sync 会一步运行 extract → merge → strip obsolete → AI-fill。如果不带 --model-provider,sync 仍会运行 extract + merge 并报告有多少字符串需要翻译:部分翻译在渲染时会回退到英文。

sh

cargo mdbook sync --model-provider anthropic.<alias>              # delta fill
cargo mdbook sync --model-provider anthropic.<alias> --force      # 质量检查:重新翻译所有条目
cargo mdbook sync --model-provider anthropic.<alias> --batch 1    # 每条记录后写入(最安全的恢复方式)
cargo mdbook sync --locale ja --model-provider anthropic.<alias>  # single locale
cargo mdbook sync --model-provider anthropic.<alias> --config-dir ~/.zeroclaw  # 限定别名 + 显式配置目录

--model-provider 通过与 cargo fluent 相同的共享运行时提供方路径进行解析(任何已配置的系列/别名、按系列设置的端点 + 身份验证 + 线路协议、SecretStore 解密、--config-dir 支持)。与将整个批次作为单个 JSON 对象发送的 cargo fluent 不同,gettext 填充器对每个源字符串发出一次请求,以保持 msgid → msgstr 映射的明确性,因此 --batch 控制的是 .po 刷新到磁盘的频率(检查点间隔),而非请求大小。完整目录的语言区域意味着数千次连续请求;对于日常增量填充,廉价的本地 Ollama 别名是经济之选。

该流水线具有内置的弹性:

  • 泄漏检测:如果模型返回自身的指令而非翻译结果,工具会检测该模式(通过响应长度比例和项目符号列表结构),尝试从响应末尾恢复真实的翻译内容,若恢复失败则清空该条目以便重新翻译。
  • 受保护字面量检查cargo mdbook check 同样会拒绝生成的 .po 文件中高置信度的字面量损坏。诸如 ZeroClaw Maturity Framework 之类的产品名称、zeroclaw daemon 之类的命令字面量,以及围栏 TOML 段/键字面量,在译文中必须逐字节保持完整。请翻译周围的叙述文字,而非面向机器的文本。
  • 路径泄漏检查:生成的译文不得引入英文源文本中不存在的机器本地绝对路径;这些条目会被清空以重新翻译,并被 cargo mdbook check 拒绝。
  • 增量写入:每批处理完成后,都会重写 .po 文件。运行过程中按下 Ctrl-C 不会丢失此前的处理进度。
  • 过时条目清理msgmerge + msgattrib --no-obsolete 可防止已移除的源字符串作为 #~ 条目堆积。

维护者应接受 Building the docs locally 中记录的常规英文文档例外情况。仅当 PR 本身是翻译缓存更新、发布翻译更新、新语言区域变更,或生成的差异足够小可供审查时,才要求更新 .po 文件。

添加新的区域设置

  1. 编辑仓库根目录下的 locales.toml,这是你唯一需要修改的文件:

  2. 翻译应用字符串:

    sh

    cargo fluent fill --locale <code> --model-provider ollama
    
  3. 引导并填充文档 .po 文件:

    sh

    cargo mdbook sync --locale <code> --model-provider ollama
    
  4. 步骤 2 中运行的 cargo fluent fill 会在同一遍处理中生成 apps/zerocode/locales/<code>/zerocode.ftl,因为 cargo fluent 会同时遍历运行时和 zerocode 两个目录。无需手动执行 zerocode 步骤;可使用 cargo fluent stats 验证覆盖情况。

其他所有内容,包括 lang-switcher.js、CI 部署目标列表以及 cargo mdbook locales 的输出,都会自动从 locales.toml 读取。

翻译目录子模块

翻译后的 .po 目录不在此仓库的主树中。它们位于专用的 zeroclaw-labs/zeroclaw-docs-translations 仓库中,并作为 git 子模块挂载在 docs/book/po(默认分支 main)。该挂载点对路径是透明的:book.toml 的 gettext 预处理器、cargo mdbook synccargo mdbook build 都会像之前一样精确读取 po/

Rust crate 开发循环从不需要该子模块。只有文档构建以及 docs-deploy / release 作业需要它;这些检出都会传递 submodules: recursive。其他所有内容都保持不包含子模块。

每次发布时,scripts/release/refresh-translations.sh 会将变更的目录发布到子模块的 main 分支,将该提交标记为 v{version},检出该标签,并暂存主仓库的 gitlink。bump-version.sh 会有意将翻译固定留给该辅助脚本处理。messages.pot*.failures.log 是重新生成的构建产物,在两个仓库中都被 Git 忽略,而不是受跟踪的文件。

发布翻译工作流

发布时的刷新、验证、打标签、推送和 gitlink 固定流程是发布运行手册中的第 2 步的一部分。本页面介绍翻译系统;准备发布时,请以运行手册作为操作依据。

模型质量说明

翻译质量因语言和模型的不同而有显著差异。

区域设置得到充分支持的备注
ja, zh-CNqwen3 系列,任何前沿托管模型Qwen 以中文为首选;日语能力也很强
es, frqwen3、mistral、gemma3、托管罗曼语族在广泛范围内训练良好
低资源语言环境仅限托管的前沿模型本地模型经常会出现幻觉

对于发布级别的传递,建议通过 --force 使用托管的前沿模型。在开发过程中进行持续的增量填充时,使用本地的 Ollama 模型即可,且免费。