Initial commit

This commit is contained in:
谭凯
2026-01-19 09:51:07 +08:00
commit 9ef82393be
174 changed files with 22285 additions and 0 deletions
+60
View File
@@ -0,0 +1,60 @@
# 开发者避坑指南 (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*: "请返回 JSONkey 是 IDvalue 是译文..." (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*