# Agent Note: 基于简报的最小化翻译更新

Status: implemented

[English](2026-07-26-briefed-minimal-translation-updates.md) | 中文

## 问题

[双语配对约定](2026-07-02-bilingual-docs-and-pairing-gate.md)早已规定对侧文件按最小幅度更新：把被改的一侧与其上次确认状态做 diff，据此修补对侧文件，绝不整篇重译；但仓库内置的工作流让每次更新都付出整篇文档级别的开销。负责翻译的 subagent 在动手处理一个两行的 diff 之前，要先加载完整的指导语料（guidance corpus），即 skill（技能）、配对约定、翻译规则、192 行的术语表、语体样例与行文标准；要通过 `git cat-file` 手工重新推导上次确认状态以来的 diff；每轮迭代还要重跑全语料配对门禁，而该门禁为校验一个配对要解析整棵树里的每一个配对。一次小的英文行文修改，动辄花掉数十倍于其应得份额的 token 用量与分钟数，被惩罚的恰恰是约定想要的行为：在同一个 PR（Pull Request）里把对侧文件一并带上。

## 决策

扩展的手动工作流使用生成的简报（briefing）而非指导语料来更新配对；该工作流中的新配对仍采用保持不变的整篇文档路径。常规 agent 工作采用由[轻量翻译决策](2026-08-08-lightweight-routine-documentation-translation.md)定义的直接路径。

- **`pnpm run gen-translation-brief [--apply] [pair...]`**（[scripts/gen-translation-brief.ts](../../../../scripts/gen-translation-brief.ts)，组装逻辑在 [scripts/translation-brief.ts](../../../../scripts/translation-brief.ts)）针对每个失去同步的配对，打印被改一侧从其记录在案的上次确认 blob 到当前工作区的 diff，并附上以能安全对齐的最窄粒度映射的这次改动，映射失败时粒度确定性地逐级放宽：仅落在配对中逐字节一致的围栏代码块内的改动会直接算出（`--apply` 会把它拼接进对侧文件，并在写入前用配对门禁的结构签名校验所得结果）；否则，每个有改动的 Markdown 单元（标题、段落、表格行、列表项、围栏代码块、块引用、HTML 块、分隔线、链接定义；匹配依据是以容器为作用域的种类序列）都带上各自的上次确认源文、当前源文与当前对侧文本及行号；无法对齐的单元回退到按深度匹配的标题章节；当章节也无法对齐或两侧同时漂移时，简报会明说这一点并省略映射，而不是靠猜。术语表行只与改动块匹配（英文术语按词边界匹配，含复数变形）；当目标侧是中文时，简报还会跟踪每个相关术语在整篇文档中的首次出现：一旦某次编辑使其移位，腾出的与接收的两处区间就会附一条解释性说明加入简报，因为「首次出现」括注必须随之移动。单元映射、代码拼接与首次出现机制采纳了增量提示词流水线工作的规划器设计；该项工作中接入提供方的对比评测，已为自动流水线独立验证了同一套范围阶梯。简报就是译者的全部工作集；简报回答不了的决策，仍以完整的真源文档作为升级求证路径。
- **显式调用时，[dsh-translate-docs](../../../skills/dsh-translate-docs/SKILL.md) 中的更新路径**消费这份简报：机械类改动（只涉及围栏代码块）用 `--apply` 应用，不动用 subagent；行文类 diff 交给 subagent，其提示词就是简报本身，而非指导语料；核验只对改动块逐句进行，不覆盖整篇文档。
- **配对门禁接受配对参数。**`verify-translation-pairing [pair...]` 只检查被点名的配对（配对三个文件中的任意一个，或其裸词干，都能指代该配对）；全语料扫描仍是 `doc-sync`（文档同步门禁）与 CI 运行的无参数形式。`--write` 现在要求点名已确认的配对：裸 `--write` 会拒绝执行，重新记录全部配对必须显式写 `--write --all`；原因是旧的裸形式会默默为树中每一个漂移的配对背书，包括调用者从未看过的那些，纯行文层面的漂移于是可以永远保持绿灯。每份记录的注释都写明针对该配对自身的按对命令。写下记录之前，`--write` 用 `git hash-object -w --stdin` 存入每一侧的精确字节，并在内容寻址的本地 `refs/dsh/translation-pairing/snapshots/` ref 下固定该 blob；未提交的上次确认快照因此能被简报生成器之后的 `git cat-file` 取回，而不只是留下一个 Git 无法解析的 hash 名称或暴露于垃圾回收。

## 基准测试

该决策来自对本仓库历史上十次真实配对更新的受控回放（2026 年 7 月；每例改动 1 到 64 行英文，涵盖 README、RFC、Agent Note 与用户文档）。每个样例都在临时仓库中重建到其真实的上次确认状态，英文改动保持未提交，再用全新的 subagent 分别跑过相互竞争的各条工作流：维持现状的语料加载路径、简报路径、无指导对照组、整篇重译、小模型上的简报路径，以及每个 agent（智能体）一次处理三对文档的批量方案。产出先经机械门禁把关，再由评委盲评打分；评委还同时收到真实的历史更新与原样未动的陈旧对侧文件作为对照。

- 简报路径在盲评的忠实性、保留度与流畅度上与现状路径打平（两者都达到或超过真实历史更新的水平），而在未发生停滞的样例上只花费约三分之一的 token 用量与墙钟时间（全部十例的中位数：相对 token 成本单位 276k 对 595k，轮次数 14 对 32）。
- 整篇重译被证实有害，而不只是浪费：它丢弃经评审的措辞，盲评保留度因此崩塌（4.4/10 对 9.8）；它还使各更新组保持住的既定术语发生漂移（既定译法本就写在对侧文件自身的正文里）；而且它是成本最高的一组。
- 无指导对照组的质量同样立得住（对一次更新有约束力的上下文，是 diff 加上对侧文件自身经评审的正文，而非指导语料），但简报以几乎可忽略的额外成本，换来固定的工作集、内联的术语，以及两侧同时漂移的警告。
- 以简报为输入，小模型的表现与大模型持平，因此更新路径不再假定翻译必须由前沿模型完成。
- 把三对文档合并给同一个 subagent，相比三次各自带简报的运行没有可靠的节省，还把互不相关的失败耦合在一起；该方案被否决。

在同样这十个样例上进行的第二次正面对比回放，把本文最终交付的简报与其早前仅按章节的形态（没有单元层级、没有直接算出的机械路径、上下文只含对侧文件、不跟踪首次出现）相对照。行文质量与成本两相持平（两两盲评裁定各有胜负，差距仅在文风），而最终交付的形态在两项客观结果上胜出：两个只涉及围栏代码块的样例在一秒之内完成且不消耗任何模型 token，产出与经人工评审的历史更新逐字节一致；而在那个编辑使某术语在整篇文档中的首次出现发生移位的样例上，最终交付的简报所标记的移位复现了经人工评审的括注迁移，仅按章节的形态则留下一处「首次出现」违例，留待评审去捕捉。

## 曾考虑的替代方案

- **保留原工作流，只让门禁支持按对检查**：门禁扫描本是较小的开销，大头在语料加载与翻查历史。只收窄检查范围，约 3 倍的开销仍会原地保留。
- **把整篇重译作为更新路径**（朴素流水线的做法）：依据基准测试证据否决，理由是保留度崩塌、术语漂移、成本最高。约定的最小更新规则得以延续，且从此有数据支撑。
- **每个 subagent 批量处理多对文档**：否决。没有实测出节省（简报本身已对固定内容做了去重），而且一对文档停滞或陷入混乱会把其余配对一并拖住。
- **在伴随记录中保存逐段的翻译记忆条目**（用分段 hash 取代整文件 hash）：否决。配对两侧的段落边界可以合理地不同，任一侧都可能先撰写，这类条目还会不断膨胀并在合并时产生冲突。基于现有整文件 hash 按需计算的区间映射，在对齐可信时能恢复同样的对齐关系，不可信时会明确说明。
- **给自动提示词流水线加一个更新模式（prompt-v5）**：推迟，本文不做设计。今天没有任何调用方在驱动 [scripts/translation-prompt.ts](../../../../scripts/translation-prompt.ts)，实际的成本中心是 agent 路径。流水线在拥有消费方之前，维持其整篇文档的 v4 约定。

## 后果

- 在显式调用的扩展工作流中，一次小的行文修改，其对侧文件更新只需生成一份简报，外加一个小而聚焦的任务（不读指导语料、不翻查历史、循环内不做全语料扫描），同一 PR 内完成更新的义务保持不变。
- 简报生成器成为一致性记录的第二个消费方：记录的 blob hash 如今还驱动 diff 还原与章节映射，这进一步强化了如实维护记录的动机。
- 每个不同的已确认快照都会保留一个内容寻址的本地 ref 和对象。因此，中途放弃的重新记录可能留下额外的持久固定项，但它不会改变任何分支或提交历史；这种本地保留正是防止垃圾回收让已接受配对记录失效所付出的代价。
- 不带参数的 `--write` 不再可用；靠肌肉记忆的调用者必须点名配对或传 `--all`。这正是目的所在：批量背书如今是一个可见的、有意为之的动作。
- 按对检查意味着一个更新循环可以在别处某个无关配对处于红灯时自己保持绿灯；`doc-sync`/CI 中的全语料检查仍然承载树级不变式。
- 区间映射只在上次确认源文、当前源文与当前对侧文本三方的种类序列一致时才信任一处对齐；映射失败时粒度确定性地逐级放宽（单元 → 章节 → 整篇文档）而不是靠猜，因此被重构过的文档拿到的是一份明确写着「请自行定位相关区域」的简报，绝不会是一张错误的地图。
- 「首次出现」的一次移位可能让简报扩大到直接改动块之外；这一成本是「首次出现」约定的明确后果，而非对齐启发式。

## 测试

[scripts/translation-brief.spec.ts](../../../../scripts/translation-brief.spec.ts) 固定单元与章节的区间提取（以容器为作用域的种类、只按深度对齐章节从而让已翻译的标题文字仍能映射、首个标题前的序言）、对齐与改动索引检测、机械代码拼接及其每一个拒绝条件、带词边界与复数变形约束的双向术语行匹配、首次出现移位跟踪、围栏升级，以及渲染后简报的约定（带三方上下文的单元条目、机械／章节／整篇文档三种范围、分方向的规则摘要、按对的收尾命令）。[scripts/translation-pairing.spec.ts](../../../../scripts/translation-pairing.spec.ts) 固定未提交快照的精确字节持久化与取回、在不可用对象进入伴随记录前失败、参数归一化（配对的任一文件或裸词干都归一到锚点），以及 CLI（命令行界面）用例矩阵：按对检查、裸 `--write` 拒绝执行、`--write <pair>`、`--write --all`、`--list` 的互斥性、未知标志。
