- Refactor codebase into src/ (preprocessing, translation, assembly) - Add pipeline/ scripts for individual stages - Externalize configuration to config/config.yaml - Fix Cover Image preservation - Update documentation and manuals
51 lines
2.6 KiB
Markdown
51 lines
2.6 KiB
Markdown
# 开发者避坑指南 (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)
|
||
**不要在模块间传递散乱的数据。**
|
||
* **最佳实践**:**Manifest (清单) 是唯一的真理。** Profile, Glossary, Winner Model 都应该直接存储在 Manifest 的 metadata 中,而不是依赖外部临时文件。
|
||
|
||
---
|
||
|
||
## 🚫 常见陷阱 (Pitfalls)
|
||
|
||
### 1. Python 语法陷阱
|
||
* **f-string 中的正则**:
|
||
* *Bad*: `rf'\[{id}\]'` 或 `rf"[{id}]"`。在 f-string 中使用反斜杠转义非常容易出错,尤其是涉及引号嵌套时。
|
||
* *Good*: 使用字符串拼接 `r'\[' + id + r'\]'`。虽然丑一点,但绝对安全。
|
||
* **Unhashable Dict**:
|
||
* *Bad*: `glossary = profile.get('glossary', {{}})`。双花括号 `{{}}` 在 Python 中会被解释为集合 `{dict()}`,而 dict 是不可哈希的,导致 `TypeError`。
|
||
* *Good*: `glossary = profile.get('glossary', {})`。
|
||
|
||
### 2. Prompt Engineering
|
||
* **不要让 LLM "解释" 它的翻译。**
|
||
* 它一旦开始解释,解析器就很难把正文抠出来。必须在 System Prompt 中严令禁止。
|
||
* **Context Injection**:
|
||
* 注入 Glossary 时,格式越简单越好(如 `Term -> Translation`),不要用复杂的 JSON 结构,这会消耗 Token 且容易被模型忽略。
|
||
|
||
### 3. EPUB 结构处理
|
||
* **不要随意丢弃 Item。**
|
||
* 默认复制所有非 Document 资源。对于 Document,要么替换为双语版,要么原样保留。
|
||
* **不要重建 Spine 顺序。**
|
||
* 不要试图自己去猜页面顺序。严格按照 `original_book.spine` 的顺序来构建新书。
|
||
|
||
---
|
||
|
||
## ✅ 推荐工作流 (Workflow)
|
||
|
||
1. **修改提取逻辑时** -> 必须同时检查 `get_valid_text_elements` 是否被 `Builder` 复用。
|
||
2. **修改 Prompt 时** -> 必须同步更新 `LLMClient` 的解析逻辑。
|
||
3. **调试 LLM 输出时** -> 使用 `raw_chat_completion` 接口进行单元测试。
|
||
|
||
---
|
||
|
||
*Last Updated: v0.05* |