
OpenClaw 文档 i18n 翻译流水线防抖、增量翻译与聚合提交的完整设计【免费下载链接】openclawThe AI that really does things. Any OS. Any Platform. The lobster way. 项目地址: https://gitcode.com/GitHub_Trending/cl/openclawOpenClaw 的文档体系采用「英文源文档 独立发布仓库」的架构英文文档在源码仓库中随每次推送快速发布而 20 种语言译本则通过一套带防抖debounce和增量incremental机制的自动化翻译流水线生成。读完本文你将理解这套流水线的 11 步事件流、防抖冷却策略、基于x-i18n.source_hash的增量翻译判定、跨 job 的 artifact 契约与聚合提交机制并能对照本仓库中的同步 Workflow、发布触发器和 Go 翻译工具源码掌握每个设计决策背后的实现证据。架构背景为什么源仓库与译本仓库要分离翻译工作流文档位于 docs/.i18n/translation-workflow.md它明确自身是「docs 发布流水线的内部说明」且docs/.i18n目录会被文档站点构建忽略、不对外发布。同一目录下的 docs/.i18n/README.md 解释了整体拆分逻辑英文文档以openclaw/openclaw即本仓库中的docs/为唯一事实来源生成产物各语言 locale 树与实时翻译记忆 translation memory存放在发布仓库openclaw/docs源仓库不再提交docs/zh-CN/**、docs/ja-JP/**等生成目录拆分的目的把生成产物挡在主产品仓库外、让 Mintlify 保持单一发布文档树、保留内置语言切换器并且即使某些 locale如th、fa暂不被 Mintlify 的navigation.languages接受其译本与翻译记忆仍会被持续生成和保留。翻译资产本身保留在源仓库的docs/.i18n/下每个语言一份术语表如 glossary.zh-CN.json另有glossary.ja-JP.json、glossary.de.json等 20 份和导航文件zh-Hans-navigation.json、ja-navigation.json等。术语表在 Go 翻译工具中按极简结构解析type GlossaryEntry struct { Source string json:source Target string json:target }见 scripts/docs-i18n/glossary.go这一拆分直接决定了后文的部署策略英文可以「每笔提交即部署」而翻译只能低频、聚合地部署。流水线设计目标工作流文档开头列出了六条硬性目标它们是整个流水线所有机制的出发点英文文档在每次源文档同步后快速部署locale 翻译不因main上的每一个热点提交而运行翻译任务带防抖一批密集的文档提交只触发一轮one translation wave翻译locale job 只翻译「自上次成功的 locale 输出以来源 hash 发生变化」的页面成功的 locale 输出被一次性聚合提交——即使部分 locale job 失败每周一次的对账reconciliation重跑所有 locale/页面路径修复漏译或不稳定的翻译。完整事件流从文档同步到线上冒烟工作流定义了 11 步事件流下面逐步展开并补充仓库内可验证的实现证据同步英文文档openclaw/openclaw将英文文档同步进openclaw/docs。本仓库侧的入口是 docs-sync-publish.yml当main分支的docs/**及相关脚本变更时触发checkout 源仓库与openclaw/clawhub文档源克隆发布仓库然后调用node scripts/docs-sync-publish.mjs --target ... --source-repo ... --source-sha ...执行镜像。英文立即部署GitHub Pages 直接从同步提交部署英文/源变更。触发 Translate All由同步提交、release dispatch、手动 dispatch 或每周定时任务触发。发布侧的触发脚本在源仓库有明确对应——docs-translate-trigger-release.yml 在release: published事件时通过gh api repos/openclaw/docs/dispatches向发布仓库发送event_typetranslate-all-releaseclient_payload携带modeincremental、release_tag、source_repository与source_sha。协调器coordinator冷却等待开始翻译前先等待一个冷却窗口见下节。读取源元数据冷却结束后协调器读取当前origin/main的源元数据即发布仓库中的.openclaw-sync/source.json。该文件由同步脚本写入scripts/docs-sync-publish.mjs 第 857 行执行writeJson(path.join(targetRoot, .openclaw-sync, source.json), metadata)。采用更新状态若冷却期间到达更新一版文档同步协调器改用更新的源状态。并行 locale job逐语言翻译 job 以fail-fast: false并行运行——单个 locale 失败不阻塞其他语言。上传 artifact每个 locale job 为其请求的源 SHA 上传一个 artifact契约见下文。finalizer 聚合finalizer 下载可用 artifact、忽略过期或失败载荷推送唯一一次聚合 i18n 提交。触发 Pages 部署聚合提交落地后finalizer 只 dispatch 一次 Pages 部署。线上冒烟Pages workflow 在部署完成后再 dispatch live smoke保证冒烟测试检查的是已部署站点而不是与部署过程赛跑。补充一点实现细节docs-sync-publish.yml 的concurrency配置特意采用「排队而非取消」cancel-in-progress: false提交注释解释了原因——cancel-in-progress会饿死镜像仓库每次main推送都取消在途同步而取消的运行没有后继者持续高合并速率下openclaw/docs永远无法前进配合脚本内的skip_stale_source通过git merge-base --is-ancestor判断远端已包含当前源 SHA 时跳过完成了幂等保证。防抖策略把提交风暴收敛成一轮翻译防抖debounce是这套流水线的核心成本控制点规则如下协调器在文档同步或 release dispatch 之后等待 1 小时再重新读取origin/main默认冷却时长由发布仓库的仓库变量OPENCLAW_DOCS_TRANSLATION_COOLDOWN_SECONDS控制默认值3600仓库 dispatch 调用方可通过client_payload.cooldown_seconds覆盖它手动运行可设置cooldown_seconds输入如果等待期间.openclaw-sync/source.json发生了变化协调器会从更新的状态重新计时如果main持续移动等待上限由OPENCLAW_DOCS_TRANSLATION_MAX_WAIT_SECONDS封顶默认等于冷却值达到上限后翻译「最新观测到的状态」手动运行与每周运行默认不等待直接进入翻译。这套「滑动冷却 上限封顶」的组合解决了两个矛盾既不会在文档提交密集期每笔都跑全量翻译也不会因为main一直有提交而让翻译无限顺延。增量翻译以x-i18n.source_hash为判定依据每个被翻译的页面都在 front matter 中存储x-i18n.source_hashlocale job 将当前英文页 hash 与已存储的 locale hash 对比。这一机制的写入端在 Go 翻译工具中可以直接看到——scripts/docs-i18n/process.go 的encodeFrontMatter为每个译文页面生成完整的x-i18n元数据块frontData[x-i18n] map[string]any{ source_path: relPath, source_hash: hashBytes(source), provider: docsI18nProvider(), model: docsI18nModel(), workflow: workflowVersion, prompt_version: promptVersion, generated_at: time.Now().UTC().Format(time.RFC3339), postprocess_version: localizedLinkPostprocessPending, }除了source_hash该块还记录了 provider、model、workflow 版本、prompt 版本与生成时间——这意味着当 prompt 或工作流升级时流水线有能力识别「哪些译文是用旧 prompt 生成的」。正常incremental运行只翻译三类页面缺失的 locale 页面源页面存在但该语言尚无译文x-i18n.source_hash过期的页面英文源已修改受源删除/裁剪影响的页面英文页被删对应译文需同步清除。两条边界规则docs/.i18n/**下的内部文件不是翻译输入仅变更内部 i18n 文件的 push 触发运行会在进入 locale 矩阵之前直接跳过某个 locale job 失败时其 artifact 被标记为失败且不携带载荷。finalizer 仍然提交成功的 locale失败的 locale 保持「过期」状态——因为它的源 hash 仍然不匹配会在下一次增量运行中被自动捡起重翻。这是「失败自愈」的关键不需要重试队列hash 不匹配本身就是待办列表。翻译记忆translation memory以 JSONL 格式维护在docs/.i18n/locale.tm.jsonl。scripts/docs-i18n/tm.go 逐行解码该文件只收录CacheKey非空且Translated非空白的条目——缓存键到译文片段的映射让重复出现的术语和句子在后续翻译中无需重新调用 LLM。Artifact 契约locale job 与 finalizer 之间的接口locale job 与 finalizer 之间通过 artifact 解耦命名格式为「语言 源 SHA」i18n-zh-cn-source-sha每个 artifact 的内容结构固定metadata.json changed-files.txt deleted-files.txt payload/docs/locale/** payload/docs/.i18n/locale.tm.jsonl其中metadata.json包含locale、locale slug、源 SHA、pending 数量、changed 数量以及任何失败原因。finalizer 会拒绝source_sha与当前.openclaw-sync/source.json不匹配的 artifact——这保证了即使一次旧触发的 artifact 迟到也不会把过期译文写进当前源状态之上。关于触发事件的兼容性源仓库的 release workflow 只 dispatch 一个translate-all-release事件见 docs-translate-trigger-release.yml协调器仍接受旧版按 locale 分发的 release 事件以保持兼容但这些事件只是兜底路径。聚合提交正常路径上唯一一次 locale pushfinalizer 拥有正常路径上唯一的 locale push 权限提交信息固定为chore(i18n): refresh translations该提交可能只包含部分 locale 集合——失败的语言缺席不影响其余语言落地job summary 会列出已应用的语言、无变化的语言、缺失或失败的语言、过期 artifact、无效 artifact。这个「部分成功可提交、失败者下轮补齐」的语义与增量翻译的 hash 判定形成闭环失败 locale 的页面 hash 不匹配天然进入下一轮待翻集合。每周对账修复 LLM 不稳定性的兜底机制每周运行使用full模式强制对所有 locale、所有源页面做一次全量对账而不是只依赖变化的源 hash。此外术语表变更也会强制全量对账——因为 glossary 指引可能影响源 hash 并未变化的页面同一个英文句子在新术语表下应翻译成不同的表达。术语表正是 scripts/docs-i18n/glossary.go 加载的glossary.locale.json源/目标词条对其变更等价于翻译指引变更所以必须全量重校。每周运行的预期行为重新生成或校验每个 locale 页面裁剪过期的 locale 页面按需刷新翻译记忆仍然使用并行 locale job仍然只提交一个聚合结果仍然容忍单个 locale 失败。工作流文档对此的定位很明确每周运行是LLM 输出不稳定、部分失败和漏掉的增量更新的修复机制repair mechanism。增量路径追求成本最低full 路径保证最终一致两者互补。部署策略英文高频译本低频部署侧的规则是整条流水线的收口英文从源同步提交部署——每笔文档提交都是一次快速英文部署译文在聚合 i18n 提交之后部署。finalizer 之所以手动 dispatch GitHub Pages 一次是因为GitHub 会抑制来自GITHUB_TOKEN提交的常规 push 触发 workflow 运行——GITHUB_TOKEN推送无法自触发 Pages 工作流必须显式 dispatchPages workflow 在部署之后再 dispatch live smoke让冒烟测试检查已部署站点而非与部署过程赛跑预期效果一个「热点文档日」应该产生大量快速的英文部署但只有少量 locale 部署如果 Mintlify 这类外部部署提供方监听每一次 push聚合 i18n 提交就是「负载削减器」load reducer。文档特别警告不要恢复按 locale 向main的 push否则会击穿这套低频部署设计。关键文件索引文件作用docs/.i18n/translation-workflow.md翻译流水线权威说明本文主体来源docs/.i18n/README.mdi18n 资产总览、源/发布仓库拆分缘由与 locale 清单docs/.i18n/glossary.zh-CN.json 等各语言术语表glossary翻译约束输入.github/workflows/docs-sync-publish.yml英文文档镜像到发布仓库的同步 workflow含幂等跳过与重试.github/workflows/docs-translate-trigger-release.ymlrelease 发布时向发布仓库 dispatchtranslate-all-releasescripts/docs-sync-publish.mjs同步脚本写入.openclaw-sync/source.json源元数据L857scripts/docs-i18n/process.go译文页面x-i18nfront matter含source_hash生成scripts/docs-i18n/tm.go翻译记忆 JSONL 的加载与缓存键匹配scripts/docs-i18n/glossary.go术语表解析source/target 词条对小结这套设计值得借鉴的三个模式从本仓库的实现看OpenClaw 文档翻译流水线展示了 LLM 驱动的内容生成在 CI 中的三个通用工程模式以内容 hash 为增量基线不维护「待翻队列」source_hash不匹配即待办——失败、遗漏、新增页面全部收敛到同一判定逻辑天然幂等且可自愈防抖 上限封顶的批处理滑动冷却合并提交风暴MAX_WAIT封顶防止无限顺延手动/定时任务旁路冷却兼顾成本与时效并行部分成功 聚合提交 定期全量对账fail-fast: false让单语言故障不阻塞整体finalizer 单点持有 push 权weekly full 模式兜住 LLM 的不稳定性——增量路径求快对账路径求对。对任何需要为多语言文档站点接入 LLM 翻译的团队「英文高频部署 译文聚合低频部署 hash 增量 每周全量对账」这套组合是一个经过本仓库 workflow 与 Go 工具源码双重佐证的完整参考实现。【免费下载链接】openclawThe AI that really does things. Any OS. Any Platform. The lobster way. 项目地址: https://gitcode.com/GitHub_Trending/cl/openclaw创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考