113 lines
9.4 KiB
Markdown
113 lines
9.4 KiB
Markdown
# EPUB Bilingual Translator
|
||
|
||
大段翻译、全书术语表、严格占位符校验、agent 审校 skill 和无桌面 headless QA。
|
||
|
||
## 安装与使用
|
||
|
||
```bash
|
||
python3 -m venv .venv
|
||
.venv/bin/pip install -r requirements.txt
|
||
cp .env.example .env
|
||
# 在 .env 中填写 OPENAI_API_KEY;在 config/config.yaml 选择模型及服务地址。
|
||
.venv/bin/python main.py input/book.epub --bilingual
|
||
```
|
||
|
||
不带 `--bilingual` 输出中文版。支持 OpenAI-compatible Chat Completions 服务;保留项目现有模型配置,不自动更换服务商。`chunk_size` 是字符数,不是 token 数;按模型上下文及输出上限调整。默认每段请求约 24,000 字符,输出预算 16,000 token,超时 180 秒;输出截断不会被当作成功。不同供应商对 `max_completion_tokens` 的支持应在接入时确认。
|
||
|
||
指定该书的术语约定:
|
||
|
||
```bash
|
||
.venv/bin/python main.py input/book.epub --bilingual --glossary config/glossary.example.json
|
||
```
|
||
|
||
示例表用于说明格式,请按书籍内容编辑。未指定术语表时,程序先扫描全书,生成 `.work/书名/glossary.json`,然后所有并发翻译共用这份表。冲突建议保存在 `conflicts` 中,已确立译名不会被后续章节覆盖;别名碰撞会报错。人物别名应尽量采用完整名称,避免把同姓的其他人物当作主人公。支持 `aliases`、`notes`、`forbidden_targets` 和 `exclude_contexts`;单独姓氏之后的 family/clan/dynasty/surname 不适用人物译名,更长的明确术语优先匹配。
|
||
|
||
## 质量控制
|
||
|
||
- DOM 遍历保留行内标签,图片、数学公式和脚注作为完整对象保护;占位符须次数正确、嵌套合法,还原后须是合法 XHTML。
|
||
- 大段初译后,只重试未通过校验的条目。网络错误、重复输出 ID、缺失条目、截断和占位符错误保持待处理状态,不写入“错误译文”。正常运行有失败时终止,不静默生成不完整中文版。
|
||
- 在原 EPUB 容器上修改正文;保留 OPF、目录链接及层级、原 CSS 引用、图片、字体和其他资源。双语段落避免复制 ID,中文版保留原锚点;列表和表格不会插入无效兄弟节点。
|
||
- HTML5 修复处理不闭合标签和重复 ID,抽取不会重复处理嵌套列表/段落;支持裸 div、表格单元、图注和混合容器中的直接文本。
|
||
- 已翻译条目按原文、占位符、标题上下文、术语表、模型及风格指南指纹复用;每个 chunk 完成就保存。源文件变更会重新预处理。旧版本缓存会升级,无法安全复用的译文需要重新翻译。
|
||
|
||
`--skip-translation` 用于离线调试/部分样例,不代表全书已翻译。`--force-clean` 重新预处理;`--force-restore` 兼容旧用法,但现在每次回填前都会重新校验,旧的缓存 HTML 不再直接被信任。
|
||
|
||
## 可重复 QA
|
||
|
||
完整翻译使用 `--complete-book`,会纳入默认跳过的尾注、参考文献、索引、版权页及非 spine 文字资源。图片中的文字仍作为原图保留。NAV、NCX 和书内目录继续复用实际章节标题译文。
|
||
|
||
Zenmux 的 Sonnet 5.5 配置见 `config/zenmux.yaml`。凭据使用本地 `ZENMUX_API_KEY`,或通过 `--env-file` 指定 dotenv 文件;不把密钥写入 YAML 或提交到 Git。已有 Anthropic 兼容接口的 Zenmux token 可在本地映射到此变量:
|
||
|
||
```bash
|
||
export ZENMUX_API_KEY="$ANTHROPIC_AUTH_TOKEN"
|
||
.venv/bin/python main.py 'input/Gambling Man.epub' --complete-book --bilingual \
|
||
--config config/zenmux.yaml --output-dir output/sonnet55
|
||
```
|
||
|
||
`--config` 指定独立配置,不需要修改默认模型。全书术语扫描逐批保存;中断后运行相同命令会恢复扫描及已验证译文。自动术语冲突记录在 glossary.json 的 conflicts 中,并保留已有译名,仍需语言复核。
|
||
|
||
```bash
|
||
.venv/bin/pip install -r requirements-dev.txt
|
||
.venv/bin/python -m pytest -q
|
||
.venv/bin/python scripts/corpus_regression.py
|
||
```
|
||
|
||
### Skill + headless QA(推荐)
|
||
|
||
[epub-translate skill](skills/epub-translate/SKILL.md) 将全书术语审读、完整批次翻译、工程检查和截图/语义审校串成闭环。已安装到 Codex 时可用 `$epub-translate`。本轮模型默认 Luna agent;不把 Luna 猜成 API 模型名称,不自动启动旧 Sonnet 任务。原生阅读器是可选补充,桌面锁屏不妨碍本流程。
|
||
|
||
基础 QA 使用项目已有依赖,无需浏览器;可选渲染只增加 Playwright 与 Chromium headless shell:
|
||
|
||
```bash
|
||
.venv/bin/pip install -r requirements-qa.txt
|
||
export PLAYWRIGHT_BROWSERS_PATH="$PWD/.work/playwright"
|
||
.venv/bin/python -m playwright install chromium --only-shell
|
||
.venv/bin/python scripts/headless_qa.py input/book.epub output/translated_book.epub \
|
||
--manifest .work/book/manifest.json --render --out .work/book/headless-qa
|
||
```
|
||
|
||
不加 `--render` 即只做基础审计。Linux 系统运行库和 CJK 字体按部署环境提供。headless 服务仅绑定 loopback,从 EPUB ZIP 读取原样式及资源;书内脚本与外网请求禁用,不用 Calibre/Poppler。渲染器是 Chromium 连续 XHTML,不能代表所有阅读器的分页效果。
|
||
|
||
报告分别保留原书基线与新增问题;核对 OPF 相对路径、完整清单及源 SHA、实际回填文字、目录层级/目标、NAV 直接链接结构、NAV/NCX/书内目录标题和图片/字体摘要。采样截图检查两格缩进、部号字号、横向溢出与坏图,并实际点击注号及可用的返回链接。`visual_review` 和 `semantic_review` 仍为 pending,需由 agent 查看证据后记录验收。
|
||
|
||
尾注分成书内注释、外部入口和非注释目标。例如 House of Huawei 原 EPUB 的 1,099 个注号均跳作者按语,该页指向作者尾注网站;报告明确列为 external_notes_gateway,不能把有效作者按语链接说成书内尾注已验收,也不会误判为翻译新增坏链。
|
||
|
||
Luna agent 的完整测试不调用付费 API:`scripts/agent_book.py prepare/apply/build` 生成全书批次、校验结果摘要并拒绝不完整构建,同时生成中文和双语两版。不同模型使用独立工作目录。批次格式、术语审校及具体命令见 [skill 执行流程](skills/epub-translate/references/workflow.md)。
|
||
|
||
### 可选 Calibre 辅助 QA
|
||
|
||
安装 Calibre 和 Poppler,使 `ebook-convert`、`pdftoppm` 在 PATH 中。翻译主流程自动保存结构审计;加 `--visual-qa` 生成页面截图:
|
||
|
||
```bash
|
||
.venv/bin/python main.py input/book.epub --bilingual --visual-qa
|
||
# 对已有输出检查,默认抽样前 3 个已译章节:
|
||
.venv/bin/python scripts/visual_qa.py input/book.epub output/bilingual_book.epub \
|
||
--manifest .work/book/manifest.json --render --out .work/book/visual-qa
|
||
```
|
||
|
||
QA 输出包括 `report.json`、原文/译文 PNG、Calibre 日志及 `review.html`。`--chapter` 可重复指定 EPUB 内的章节 href;`--max-chapters 0` 检查所有章节,`--pages` 控制截图页数。输出保留源书已经存在的问题,并单独列出新增问题;这是工程审计,不替代 EPUBCheck 的完整标准验证。
|
||
|
||
打开 `review.html` 看对照图,再用 Calibre 阅读 EPUB 检查目录、脚注跳转和实际分页。发现问题后补充可复现测试、修改代码、重新构建并重渲染,记录检查页码和结果。**生成截图不等于视觉通过**,自动报告始终标明 `visual_review: pending`,实际视觉审核写入独立记录。PDF 是 Calibre 转换后的辅助视图,不能代替 EPUB 阅读器验证。
|
||
|
||
Mac 沙箱中 Calibre 的 Qt 渲染可能需要允许进程运行。QA 使用项目目录中的独立 Calibre 配置,参见 [Calibre 环境变量文档](https://manual.calibre-ebook.com/customize.html#environment-variables),避免影响日常书库配置。
|
||
|
||
用子 agent 生成的 Manifest 做离线翻译测试,无需外部 API:
|
||
|
||
```bash
|
||
.venv/bin/python scripts/build_sample.py input/book.epub path/to/agent-translations.json --out .work/sample
|
||
.venv/bin/python scripts/visual_qa.py input/book.epub .work/sample/bilingual-sample.epub \
|
||
--manifest .work/sample/manifest.json --allow-partial --render --out .work/sample/qa
|
||
```
|
||
|
||
`build_sample.py` 只接受与当前原文和占位符完全对应的条目,输出明确标为部分样例。完整架构见 `doc/architecture_flow.md`;本次测试记录见 `doc/QA_2026-10-08.md`。
|
||
|
||
### 中文正文与标题目录
|
||
|
||
中文正文(包括章首段)使用 `2em` 首行缩进;标题、图注、引用和注释保持各自布局。原文段落保留出版社样式。中文段落清除原内联 `text-indent`,以免 `!important` 覆盖中文规则。
|
||
|
||
预处理以目录的目标文件/锚点建立标题映射。每个实际章标题只翻译一次,NAV、NCX、书内目录及阅读器文档标题使用同一结果;目录 href、章节 ID、层级和顺序保留。章号、主标题、副标题分成多个块时,精确匹配相邻标题块并分别回填,不合并 DOM。中文模式把独立章号统一成“第一章”,Part 对应“第一部”;双语模式保留英文标题和目录标签。
|
||
|
||
无法可靠绑定的目录条目仅翻译标签,不改写猜测的章节正文;具体条目记录在 `book_structure.json` 的 `navigation_titles[].binding_note`。这类条目需要检查章节标题是否一致,不能视为全书标题同步已经通过。索引、版权、注释全文仍遵守原有跳过策略;导航中这些页面的名称可以翻译。
|
||
|
||
后续扫描 PDF/OCR 大版本的图文、结构与目录方案见 [路线图](doc/OCR_EPUB_ROADMAP.md)。
|