dsh-calibre-ebook-translator
English | 中文
Calibre Ebook 翻译插件在现代化 Agents 工作流中的适配。
这是我的博客提示词(2023 年版)转换成 Agents 工作流的版本。经过 74 块真实书籍翻译的迭代打磨,从一个简单的翻译提示词演化为完整的分块整书翻译工作流系统。
- 博客地址:https://www.yayaus.com/2025/02/11/calibre%E6%8F%92%E4%BB%B6ebook-translator%E6%8F%92%E4%BB%B6%E7%9A%84%E6%8F%90%E7%A4%BA%E8%AF%8D%E5%88%86%E4%BA%AB.html
- GitHub:https://github.com/riverai/dsh-calibre-ebook-translator
Calibre 的 Ebook 翻译插件至今没有 MCP 支持,所以早期只能手动复制。相关功能请求此前已提交到 Ebook 项目,目前尚未被采纳。本插件现在通过配套 MCP 直接读写 chunk,不再需要手动粘贴。
配套 MCP(必装)
本插件依赖一个配套的 MCP 服务器来直接读写 Calibre 的翻译缓存:
安装时必须将 MCP 服务器命名为 calibre-ebook-trans(与协议中硬编码的工具前缀 mcp__calibre-ebook-trans__ 一致)。如果用了别的名字,协议里的所有 MCP 工具调用都会找不到目标。
MCP 文件管线:防幻觉 + 省 token 的核心设计
这是本工作流最重要的工程决策之一。传统的 MCP 调用方式是 get_original(把原文读进对话)→ agent 翻译 → write_chunk(把译文从对话写回 MCP)——文本经过模型上下文两次,每次都有截断、变形、幻觉的风险,且大块文本会消耗大量 token。
本插件采用文件管线替代:
| 环节 | 传统方式 | 文件管线(本插件) |
|---|---|---|
| 读取原文 | get_original → 文本进入对话 → agent 再写入 .txt |
get_original_to_file → MCP 直接导出到本地 .txt,文本不经过对话 |
| 写回译文 | agent 从对话输出译文 → write_chunk 传入字符串 |
write_chunk_from_file → 传入 .txt 文件路径,MCP 自己读取,文本不经过对话 |
| 导出返工 | get_translation → 文本进入对话 |
get_translation_to_file → 导出到本地 .txt,文本不经过对话 |
效果:零 content token 消耗(大块文本不经过模型上下文)、零截断风险、零生成式写入幻觉。write_chunk_from_file 还内置了回读校验(verify_mismatch 标志),写入后自动比对存储内容与文件内容是否一致。CRLF 自动归一化为 LF,UTF-8 BOM 自动剥离。
如果不想用 MCP,也可以使用手动模式(用户手动粘贴 chunk 原文),但会失去文件管线的防幻觉能力和自动读写能力。
这是什么
一个 DeepSeek Harness (dsh 0.2.x) 的自定义 Agent 模式:分块整书翻译,带跨会话持久术语表与记忆胶囊、独立审校子代理、一致性扫描、脚本化校验。适合配合 Calibre 切块逐段输入的长篇翻译。
前置准备(Calibre + 切块)
- 安装 Calibre。
- 安装 Calibre 的 Ebook Translator 插件(在 Calibre 插件市场搜索"Ebook Translator")。
- 用 Calibre 打开你想翻译的书,点击 Ebook Translator 插件的翻译按钮——不需要等它翻译完,只需让它把书切分成 chunk。个人推荐按 6000 个 token 左右切块(插件设置里可调 merge length)。
- 切块完成后,可以关闭插件和 Calibre——后续翻译由本工作流通过 MCP 直接读写缓存,不需要 Calibre 运行。
安装
第一步:安装配套 MCP(参考 https://github.com/riverai/MCP-for-Calibre-Ebook-Translator 的说明),确保服务器命名为 calibre-ebook-trans。
第二步:安装本插件
dsh plugin --profile web add github:riverai/dsh-calibre-ebook-translator
或本地安装:
dsh plugin --profile web add file:<本目录的完整路径>
第三步:安装后重启 dsh web,模式选择器里会出现"书籍翻译模式"。
脚本自动部署
本插件包内置 scripts/ 子目录,包含五个 Python 工具:
verify-chunk.py、apply-edits.py、glossary-append.py、scan-consistency.py、export-full.py。
翻译 Agent 在首次处理新工作区时会自动从包安装路径复制这些脚本到工作区根目录(即 books/ 所在目录)。无需手动操作。
如需手动部署:把 scripts/*.py 复制到你的工作区根目录即可。
实用脚本体系
本插件不只是一个提示词——它附带了一套经过真实翻译事故打磨的 Python 工具链,每一项都对应一个真实发生过的问题。
verify-chunk.py — 结构/标点/格式校验(每块三跑)
每块译文的强制安全网,在三个节点各跑一次:草稿后(-t draft)、审校编辑后(-t review)、复制为成品后(默认)。16 项检查,FAIL/WARN 分级:
- 结构对齐:行数、非空块数、逐行空行模式——源文第 i 行必须是译文第 i 行(这是 MCP 对齐和一致性扫描的硬不变量)
- en dash 检查(分级):源文有 dash 但译文没有 = FAIL(漏译原文标点);译文多了 dash = WARN(可能合理使用,需人工裁定)——不一刀切禁止,也不放过漏译
- 格式卫生:无 ASCII 直引号(必须是中文全角)、无全角斜杠、无字面
\n、无 markdown 标记(**粗体等——实际运行中曾连续 4 块触发)、无 BOM、无 tab、无行尾空格 - 引号检查:嵌套引号内层必须用全角单引号
''、引号方向异常检测("旅人"方向全反——实际事故) - 草稿→成品改动行数、审校稿→成品逐字一致(防止成品被意外编辑)
- 断言:
-a "应存在串"/-x "应已删串"
WARN 不计入 FAIL、不改退出码,但必须逐条人工裁定后放行——不得无视或过滤掉。例外可登记到 .verify-exceptions 文件(格式 NNN:L reason),但只能用于已批准的翻译体例(如文学名句采用通行译本),绝不能用来掩盖真正的错误。
apply-edits.py — 精准批量编辑工具(唯一批准的编辑途径)
所有对译文的批量编辑必须通过此工具,禁止另写一次性脚本。它的设计每一项都对应一次真实事故:
- 唯一性断言:每条
old_string在目标文件中必须恰好出现一次,否则整批回滚("FATAL: BATCH ROLLED BACK")——防止误伤 - occurrence 列(第 4 列,可选):处理重复字符串的三种方式——空 = 严格唯一(默认);
all= 替换全部(仅限 whole-line 锚点,短串+all 是事故不是功能);k= 替换第 k 个 - 批内冲突预检:同一批里两条编辑的
old_string相同(或一个是另一个的子串)会被拒绝——这源于一次真实事故:两条编辑共享一个 old_string,都通过了唯一性预检,但按顺序应用时第二条成了静默空操作(str.replace返回原文),仍然打印 "applied",一条术语修正就这么消失了,很久之后才被全书扫描发现 - 引号形态陷阱防护:ASCII
"(U+0022) 与全角""(U+201C/U+201D) 肉眼相同但字节不同,手打 old_string 必然出错。脚本自动剥离 BOM 和 CR,但引号形态须从文件实读或按码位构造 --fix-quotes:ASCII 双引号按开/关方向交替转为全角(只动双引号,保留英文撇号如Swann's Way)
输入为 TSV 文件(old_string<TAB>new_string<TAB>note<TAB>occurrence),用完即删。
glossary-append.py — 术语表维护工具
术语表不只是"记录翻译"——它是全书一致性的地基。此工具管理它的追加和订正:
- 四种模式:
append(追加新行)、edit(修改已有行的译文,旧值自动移入备注勿用:X)、edit-note(修改备注列)、add-row(交互式单行追加) - 管道符消毒:单元格内不得出现半角
|(会拆行导致备注尾部被解析器静默丢弃——一次事故吹了 15 行的备注)。脚本自动将|替换为/ - 解析器反解:两个解析器(glossary-append.py 和 scan-consistency.py)都只按非转义管道符拆分,当一行超过 5 列时把多余的拼回备注——所以遗留的破损行不会静默丢失备注尾部
- 备注微语法:
候选:X(可选译法,位置检查视为合规)、勿用:X(废弃译法,出现即报错)、订正:DATE ...(订正记录)、源文:...(源文缺陷)、自由文字(最后)。标记用半角冒号,不用 markdown,不包括号 - lint / normalize:
lint是只读报告(检查格式问题),normalize是格式修复(无语义变更)
scan-consistency.py — 跨块一致性扫描器
这是工作流中最强大的质量保障工具。它不是简单的"禁词扫描"——早期版本曾退化成几个内置禁词的检查器,看起来很绿但真实漂移在积累。现在重写为六项检查:
A. 术语位置对位(主检查)——读取全书术语表,对源文中每个术语的每次出现,检查译文同一行是否有批准译法或候选译法。依赖硬不变量:源文第 i 行 = 译文第 i 行(由 verify-chunk.py 保证)。分两级报告(不可拉平):
- Tier 1 位置漂移(必须处理):高特异性术语(多词短语、专有名词)在某处合规、另一处不合规——这是漂移,不是单纯的"不合规"
- Tier 2 术语表口径与正文不符(须调和术语表):某术语的译法在任何地方都不匹配——这是术语表与正文的分歧,不是位置 bug
B. 勿用残留——废弃译法在译文中任何地方出现。保留此检查的原因:位置检查有包含关系盲区(批准译法是"莫"时,错误的"莫乌"也包含"莫"且通过),只有勿用列表能抓到这一类。A 和 B 是互补的,不是替代关系。
C. 提醒词(默认关闭)——没有内置提醒词表(故意的):通用列表会把整个扫描退化成"查几个词",毫无价值。用 --watch-words 传入书特定的列表。命中是提示,不是判定。
D. 术语发现(--discover)——发现源文中反复出现但不在术语表里的英文短语。漂移往往是因为一个术语从未入表,所以从未被检查。
E. 审校稿/成品分歧(--stage both)
F. 候选/包含关系冲突(--collisions)——报告四个分桶:A 自相矛盾(候选与勿用互相包含,必修)/ B 跨行遮蔽(一行批准译法是另一行译法的子串,漂移藏身处)/ C 同行长短共存(通常没问题)/ D 勿用超串(信息性)
退出码:0 = 干净,2 = 有发现待裁定,1 = 错误。Tier 2 不影响退出码(它是调和清单),只有 Tier 1 漂移、勿用残留、审校/成品分歧、A 类冲突才影响。--strict-all 让 Tier 2 也影响;--exit-zero 强制返回 0。
四项已知限制(不假装它们不存在):(1) 包含盲区——批准译法是错误译法的子串时位置检查看不到(由 B 和 --collisions 兜底);(2) 同字符串两个指代——一条术语行无法区分;(3) 同词日常义——既是锁定术语又是日常词汇的词无法逐位置裁定(留在 Tier 2);(4) 覆盖依赖——扫描的上限是术语表的覆盖率,用 --discover 突破。
例外:.scan-exceptions 文件,三种粒度加多词形式(NNN:L 原文 理由 / NNN 原文 理由 / * 原文 理由 / NNN:L | 原文含空格时 | 理由)。只能登记已裁定的合法偏差,不能用来掩盖错误。
export-full.py — 全书导出
按块号顺序拼接所有 translations/chunk-NNN.txt 为 translations/_full.txt。导出时报告回改汇总和待裁定条目。
使用方法
默认翻译风格
如果你不额外指定翻译风格,工作流会使用内置的默认风格——该风格重点保证准确性:忠实保留原文内容、结构、标点;使用现代标准书面语;禁止自行升格文雅(不添加源文没有的文言腔),但保留源文本有的文学性;禁止陈词滥调(意义透支 + 语义偏移);专业术语首次出现括注英文原文。
如果你想指定风格,在开新书时一并说明即可——用户指定的风格优先级高于内置默认风格,会立即写入记忆文件。
开始翻译
输入:
开新书 某个名字 你的其他想法,比如这本书应该用什么风格,如果不写就用内置的风格决策和探测自动决定
工作流会新建手动制定格式的术语表、进度、记忆 markdown 文件。
先跑一轮测试(AI 会主动推荐)
AI 在会话开场就会主动提示:建议先手动跑一块校准流程,再切换到 goal 模式。强烈建议遵循这个顺序——先手动跑一块,观察 AI 是否合理使用了各种流程(文件管线读取原文、脚本校验、审校子代理、裁定上屏、成品写入 MCP)。如果流程正常,再进入 goal 模式自动完成整本书。
Goal 模式(AI 唤醒,自动完成整本书)
确认第一块流程正常后,AI 会主动提示是否进入 goal 模式(也可手动输入 /goal)。Goal 模式下:
- 大部分决策由 AI 自主完成(术语选择、翻译策略、审校修订、一致性修正)。
- 重要问题(影响全书的术语重决定、风格转向、改变含义的歧义)会写入记忆文件的
## 待裁定段,AI 先按最佳判断继续,用户在 goal 结束后统一裁定。 - 所有质量规则(管线、记忆契约、编辑纪律、校验)在 goal 模式下照常生效——goal 只移除逐块人工检查点,不放松任何质量要求。
定期检查(推荐每 30 块)
AI 在长任务中可能偷偷偏离标准流程。建议每 30 块左右回到对话检查一下:
- AI 是否仍在按 14 步管线走(读记忆 → 取原文 → 术语扫描 → 草稿 → 校验 → 审校 → 裁定上屏 → 编辑 → 复制成品 → 写回 MCP → 更新术语表 → 更新记忆/进度/报告)?
- 审校裁定是否仍在主屏幕逐条输出?
- 脚本是否仍在每块三跑(draft / review / final)?
如果发现偏离,在对话中直接修正——你的指令会写入记忆文件,后续块会遵循。
在对话中说的话都会被记住
你有什么想说的、想做的、想调整的,都在对话中解决——这些内容会写入记忆文件,优先于 AI 的自主判断。比如:
- "这个词统一用 X" → 写入
## 用户指令,全书后续遵循 - "语气再口语点" → 更新风格笔记,立即生效
- "这块的审校意见我不同意第 3 条" → AI 重新裁定
记忆与术语表
- 每次主 agent 进行翻译之前都会主动读取三个文件(memory.md、glossary.md、progress.md),防止轮次过多之后忘记了自己要做什么。
- 每次你手动输入的新指令,都会记录在记忆文件中,与之前的设计完成闭环。
- 术语表包含原文、译文、类别、首次出现块位置、备注与备选,允许相同词汇出现不同翻译(候选 + 勿用标记)。
翻译流程
- 主 agent 在翻译时已经包含框架提供的大量上下文,不需要额外的读入上下文。
- 草稿写入临时文件 → 审校 → 精准编辑 → 复制为成品 → 写回 MCP(文件管线,文本不经对话,零幻觉风险)。
- 最后翻译成品会写入成品稿件
.txt。 - 同时,在用户对话主界面不会输出完整译文,但是会输出新的术语决策、翻译要点、翻译难点、审校逐条裁定、遗留问题等其他信息。
- 所有上屏信息都会完整复制到 reports.md 文件中——即使对话被压缩折叠,上屏的历史记录也不会丢失,随时可在文件中查阅。
审校
- 审校 subagent 因为是白纸,会在调用时直接使用 read 工具读取原文 chunk、中间译文、术语表、前面两期左右的译文成品 chunk。
- 同时主 agent 还会向审校 subagent 直接传入大量的本次翻译细节,包括有哪些翻译思路和难点。
- 在审校 agent 拿到足够信息之后,会直接返回固定格式的评审意见,主 agent 自主决定接受还是拒绝。
- 审校裁定必须先在主屏幕逐条输出(七列表格:编号 / 目标(含行号) / 原文 / 原始译文 / 审校文 / 结果 / 理由),再应用修改。
- 审校如果触及术语翻译建议(哪怕只提了一次),必须捕获入术语表——新词加行,已有词加候选或触发回改。
回改
- 在合适的时候如果翻译主 agent 发现过往翻译有误,会调用搜索和阅读工具回改以前的部分(可能需要用户对话框授权)。
- 一旦发生了回改,该次回改会立即记录在记忆文件中,最后导出的时候会重新在主屏幕打印这次的信息。
- 回改会触发联动警告:一本书是紧耦合系统,改一处往往意味着他处也要改,扫描工具会定位受影响的块。
完成 🎉
当所有 chunk 翻译完成、## 待裁定 条目全部搞定、回改全部落地后,工作流会报告全书完成。此时回到 Calibre,打开 Ebook Translator 插件——所有译文已经通过 MCP 写回了翻译缓存——直接点击导出本书:
- 选择你喜欢的文件格式(EPUB、PDF、AZW3 等)
- 选择双语对照或单语言
- 选择各种显示样式
导出的就是你的完整译本。享受你的书。
许可证
MIT License — 见 LICENSE。
No comments yet. Be the first to write one.