v0.5.2: dr-translator chunked translation protocol

Root cause: dr-translator was trying to write entire final_zh.md in one
write call, hitting Sonnet 4-6 output token limit for long reports
(~19k English words → ~27k Chinese chars → blown past 32k token cap).

Fix: explicit chunk-and-append protocol
- Split final_en.md by H1 (# ) then H2 (## ) boundaries
- Each chunk ≤ 2,500 English words
- First chunk uses write to create final_zh.md
- Subsequent chunks use edit or read+write to append
- Per-chunk Chinese output kept under ~5,000 characters (safe margin)
- Preserves glossary.json updates across chunks
This commit is contained in:
kai
2026-04-21 23:10:10 +08:00
parent 333b7bb8d5
commit 701bc1887e
18 changed files with 2769 additions and 66 deletions
+59 -18
View File
@@ -63,11 +63,58 @@ permission:
}
```
### Step 3: 分段翻译(遵循 en-zh-translation 规范
### Step 3: 分章切分(关键:防止单次输出超限
**按章翻译,不一次性翻译整篇**。每章翻译完写入 final_zh.md
**不能一次性翻译整篇,也不能一次性 write 整篇 final_zh.md。** 单次 write 的 content 如果超过约 8,000 个中文字(对应约 15k-20k output tokens),会触发 Claude Sonnet 的输出上限而失败
**切分规则**
1. 读取 final_en.md 全文,按 `# ` (H1) 行切成段。每个 H1 段是一个"翻译单元",例如:
- `# <Report Title>` + 前置元信息
- `## Disclaimer`
- `## Executive Summary`
- `## Abstract`
- `## Glossary`
- `# Chapter 1: ...`
- `# Chapter 2: ...`
- ...
- `## References`(占位符,留给 dr-reporter 回填,直接原样保留)
- `## Version History`
注意:`## ` 开头的章节也当作独立单元。Markdown 里通常前置件用 `##`(二级)、正文用 `# ``##`——以实际文件结构为准,**每个独立逻辑章节(元信息/免责/摘要/正文各章/参考/版本)都单独切分**。
2. 每个单元的**英文内容**不超过 ~2,500 words。如果某章超过这个长度,进一步按 `## ` 子节切分。
3. 切分完的每个块翻译后,中文字数通常 ≤ 3,500 字(英文 × 1.4)。单次 write 的 content 控制在 **5,000 个中文字**以内比较安全。
### Step 4: 逐块翻译 + 追加写入(核心流程)
**第一块(只有它用 write 创建文件)**
1. 翻译第 1 块(通常是标题 + 元信息 + 免责声明)
2. 调用 `write` 工具,创建 `final_zh.md`,内容 = 第 1 块的译文
3. 术语表同步到内存字典
**后续每一块(用 edit/append 追加)**
1. 翻译第 N 块(例如 Executive Summary
2. **追加到 final_zh.md**
- 读 final_zh.md 最后 200 字(确认当前尾部)
- 调用 `edit` 工具:`oldString` = 文件实际末尾的最后 1-2 行(确保能唯一匹配),`newString` = 原末尾 + `\n\n---\n\n` + 新译文块
- 或更稳妥:`read` 文件全文,在内存拼接,`write` 覆盖(但这样每次 write 的 content 会递增,接近 80% 时切换到"逐块 append via edit"模式)
3. 术语表持续更新
**边界情况**
- 如果某一块翻译后单独超过 5,000 个中文字,在翻译过程中就把它再拆两半翻译(按 `### ` 子小节)
- 如果 edit 的 oldString 无法唯一匹配(例如文件末尾是常见的"---"分隔符),先 read 取出末尾 300 字,带上更多上下文做 oldString
### Step 5: 术语表同步
翻译过程中遇到新术语:
- 决定中文译法(查行业惯例 > 权威文献 > 约定俗成)
- 加入 glossary.json
- 在首次出现处用"中文(English"格式
### Step 6: 翻译要点(每块翻译时遵守)
翻译要点:
- 专有名词首次出现用"中文(English)",之后一致使用一种
- 数字/日期/百分比完全保留原格式
- `[src_XXX]` 引用标注不动
@@ -76,14 +123,7 @@ permission:
- 主动语态优先于被动
- 删除英文冗余连词(furthermore / moreover / additionally
### Step 4: 术语表同步
翻译过程中遇到新术语:
- 决定中文译法(查行业惯例 > 权威文献 > 约定俗成)
- 加入 glossary.json
- 在首次出现处用"中文(English"格式
### Step 5: 自检(三轮)
### Step 7: 全文自检(所有块完成后)
**第 1 轮:准确性**
- 所有数字、日期、百分比、`[src_xxx]` 与原文一致?
@@ -94,15 +134,16 @@ permission:
- "的"字不过多(避免"X 的 Y 的 Z 的 W"链式)
- 没有翻译腔(如"...的话"、"对于...来说"、"在...方面"
- 句子长度有节奏变化
- 读一遍念出来自然?
**第 3 轮:humanizer-cn 禁用词**
扫描中文禁用词清单,逐一修正。
**第 3 轮:humanizer-cn 禁用词快速扫描**
```bash
grep -E "跃迁|赋能|落地|抓手|本质上|从根本上|随着.*不断|值得注意|综上所述" projects/<slug>/phase4/final_zh.md || echo "no hits"
```
命中的地方交给 dr-polisher 处理,不要现在大改。
### Step 6: 写入 final_zh.md
### Step 8: 统计字数
```bash
# 统计中文字数
python3 << 'EOF'
import re
with open('projects/<slug>/phase4/final_zh.md', encoding='utf-8') as f:
@@ -114,11 +155,11 @@ print(f'中文字数: {cn}, 英文词数: {en}, 总计: {cn+en}')
EOF
```
### Step 7: 保存术语表
### Step 9: 保存术语表
写回 `projects/<slug>/phase4/glossary.json`
### Step 8: 汇报
### Step 10: 汇报
向 dr-editor-in-chief 返回: