# 开发者避坑指南 (Developer's Survival Guide) 这份文档总结了 EPUB 翻译器开发过程中的血泪教训。在修改代码前,**务必阅读此文档**。 ## 🔴 核心原则 (Core Principles) ### 1. 奥卡姆剃刀原则 (KISS) **不要自作聪明。** * **错误案例**:为了“美观”或“规范”,给 ID 加上方括号 `[p_001]`,甚至试图让 LLM 返回 JSON 结构。 * **后果**:LLM 经常搞错括号的全角/半角,或者漏掉闭合括号,导致正则解析极其痛苦,甚至产生 `SyntaxError`。 * **最佳实践**:**ID 就用纯文本 `p_xxxxx`。** 解析就用 `find()` 和字符串切片。越简单越不容易出错。 ### 2. 单一真理源 (Single Source of Truth) **不要在模块间传递散乱的数据。** * **错误案例**:`TextProcessor` 返回一个 list,`Translator` 拿去翻译,`Builder` 又重新解析一遍 HTML 试图匹配。 * **后果**:一旦提取逻辑微调(比如过滤了短句),Builder 就再也对不齐了,导致严重的错位(翻译张冠李戴)。 * **最佳实践**:**Manifest (清单) 是唯一的真理。** 提取时生成 Manifest,翻译时更新 Manifest,构建时只读 Manifest。 --- ## 🚫 常见陷阱 (Pitfalls) ### 1. Prompt Engineering * **不要指望 LLM 完美遵守复杂的格式指令。** * *Bad Prompt*: "请返回 JSON,key 是 ID,value 是译文..." (JSON 语法错误率高,Token 消耗大) * *Bad Prompt*: "请用 `[ID]` 包裹编号..." (括号混乱) * *Good Prompt*: "每行开头必须是 `p_xxxxx`,后接译文。严禁修改 ID。" * **不要让 LLM "解释" 它的翻译。** * 它一旦开始解释,解析器就很难把正文抠出来。必须在 System Prompt 中严令禁止。 ### 2. 正则表达式 (Regex) * **慎用 `re.sub` 处理未知输入。** * LLM 返回的文本可能包含各种奇怪的 unicode 字符或未转义的特殊符号。 * 在 f-string 中拼接正则(如 `rf'\[{id}\]'`)极易引发 Python 的 `SyntaxError`,尤其是涉及引号嵌套时。 * **解决方案**:如果能用字符串 `find()` + 切片解决的问题,**绝对不要用正则**。 ### 3. EPUB 结构处理 * **不要随意丢弃 Item。** * 之前的逻辑是“只处理 Document,其他的忽略”。结果导致封面图片、css、字体文件全部丢失。 * **正确逻辑**:默认复制所有非 Document 资源。对于 Document,要么替换为双语版,要么原样保留。 * **不要重建 Spine 顺序。** * 不要试图自己去猜页面顺序。严格按照 `original_book.spine` 的顺序来构建新书。 * **不要依赖 `min_length` 过滤。** * "Chapter 1" 只有 9 个字符,但它很重要。任何长度过滤都会导致漏译。 ### 4. Metadata 处理 * **不要假设 Metadata 总是规范的字符串。** * `ebooklib` 解析出来的 metadata 有时是对象,有时是 `None`。调用 `.lower()` 前必须做类型检查 (`if name and isinstance(name, str)...`)。 --- ## ✅ 推荐工作流 (Workflow) 1. **修改提取逻辑时** -> 必须同时检查 `get_valid_text_elements` 是否被 `Builder` 复用。 2. **修改 Prompt 时** -> 必须同步更新 `LLMClient` 的解析逻辑。 3. **遇到对齐问题时** -> 不要去改 `Builder` 的匹配算法,而是去检查 Manifest 中的 ID 序列是否正确。 --- *Last Updated: v0.03*