浏览代码

docs(genres): plan taxonomy convergence

lingfengQAQ 2 周之前
父节点
当前提交
1ed73a5921
共有 1 个文件被更改,包括 290 次插入0 次删除
  1. 290 0
      docs/operations/genre-taxonomy-convergence-plan-2026-06-04.md

+ 290 - 0
docs/operations/genre-taxonomy-convergence-plan-2026-06-04.md

@@ -0,0 +1,290 @@
+# Genre Taxonomy Convergence Plan
+
+日期:2026-06-04
+
+## 目标
+
+把题材体系收敛到 CSV 已经采用的 15 个 `canonical_genre`,同时保留 37 个中文题材模板作为初始化阶段的可叠加预设。
+
+一句话原则:
+
+> CSV canonical 是主干;模板是预设;套路、形式、平台细分全部标签化。
+
+## 当前判断
+
+当前运行链路里,`templates/genres/*.md` 只被 `/webnovel-init` 使用:
+
+- `webnovel-init/SKILL.md` 要求用户选题材后按需读取 `templates/genres/`。
+- `init_project.py` 按用户传入的 `genre` 精确读取 `templates/genres/{genre}.md`,并写入新项目的 `设定集/世界观.md`。
+- `plan/write/query/review` 不直接读取这 37 个模板。
+
+CSV 层已经相对收敛:
+
+- 9 张 CSV 的 `适用题材` 只允许 15 个 canonical 或 `全部`。
+- `validate_csv.py` 当前可做到 0 errors / 0 warnings。
+
+主要漂移点:
+
+- `templates/genres/` 的 37 个文件名混合了 canonical、平台细分、legacy alias、套路标签和形式标签。
+- `reference_search.py` 不能解析所有模板名。
+- `webnovel-init/SKILL.md` 的题材集合仍是混合列表,容易把非 canonical 写进 `state.json.project.genre`。
+- `题材与调性推理.csv` 的 `题材/流派` 实际更像 `route_tag`,不全是 platform tag。
+
+## 目标模型
+
+### 1. 硬题材枚举
+
+唯一硬枚举继续使用 CSV 方案:
+
+```text
+都市 玄幻 仙侠 奇幻 科幻
+历史 悬疑 游戏 古言 现言
+幻言 年代 种田 快穿 衍生
+```
+
+这些值用于:
+
+- CSV `适用题材`
+- `裁决规则.csv` 的 `题材`
+- Story System 的 `canonical_genre`
+- `reference_search.py --genre`
+- 新项目 `state.json.project.genre`
+
+### 2. 模板预设
+
+37 个 `templates/genres/*.md` 不再被视为硬题材,而是 template preset。
+
+每个 preset 必须声明:
+
+- `template_name`
+- `canonical_genre`
+- `template_type`
+- `route_tags`
+- `trope_tags`
+- `format_tags`
+- `aliases`
+
+例子:
+
+```csv
+template_name,canonical_genre,template_type,route_tags,trope_tags,format_tags,aliases
+都市异能,都市,route,都市异能,,,"异能|现代异能"
+规则怪谈,悬疑,route,规则怪谈,,,"规则动物园|规则类"
+系统流,玄幻,trope,,系统流,,"系统|系统文"
+知乎短篇,现言,format,,,知乎短篇,"知乎体|盐选|小程序短篇"
+西幻,奇幻,route,西幻,,,"西方奇幻"
+```
+
+### 3. 用户输入解析结果
+
+用户输入不直接等于硬题材。解析结果应该是结构化对象:
+
+```json
+{
+  "user_genre_label": "知乎短篇风的规则怪谈",
+  "canonical_genre": "悬疑",
+  "route_tags": ["规则怪谈"],
+  "trope_tags": [],
+  "format_tags": ["知乎短篇"],
+  "template_presets": ["规则怪谈", "知乎短篇"]
+}
+```
+
+## 改动范围
+
+### 必改
+
+- `webnovel-writer/templates/genres/*.md`
+  - 标题中文化。
+  - 不第一阶段移动文件,先降低风险。
+- `webnovel-writer/templates/genres/index.csv`
+  - 新增模板索引,覆盖 37 个模板。
+- `webnovel-writer/scripts/reference_search.py`
+  - 接入模板名/别名到 canonical 的解析。
+- `webnovel-writer/scripts/init_project.py`
+  - init 时先 resolve genre。
+  - `state.json.project.genre` 写 canonical。
+  - 额外保存用户原始题材与 tags。
+  - 读取模板时按 index 加载 preset,而不是只按原始 `genre` 精确找文件。
+- `webnovel-writer/skills/webnovel-init/SKILL.md`
+  - 题材集合改为 15 个 canonical。
+  - 说明可输入模板预设/套路/形式,但必须映射到 canonical。
+- `webnovel-writer/scripts/validate_csv.py`
+  - 增加模板索引覆盖校验。
+  - 校验所有 template preset 都能映射到 canonical。
+
+### 应改
+
+- `webnovel-writer/references/csv/genre-canonical.md`
+  - 明确 `题材与调性推理.csv` 的 `题材/流派` 是 `route_tag`,不是纯 platform tag。
+- `webnovel-writer/references/csv/README.md`
+  - 补充 template preset 与 canonical 的关系。
+- `webnovel-writer/references/index/reference-loading-map.md`
+  - 更新 init 阶段题材模板加载规则。
+- 相关 tests
+  - `reference_search` genre resolve 测试。
+  - `init_project` 模板加载测试。
+  - template index 覆盖测试。
+
+### 暂不改
+
+- 不大规模重写 9 张 CSV 内容。
+- 不删除 37 个模板。
+- 不立即把 `templates/genres/` 拆成 `canonical/` 和 `presets/` 子目录。
+- 不改变老项目读取逻辑的兼容路径。
+- 不把 `genre-profiles.md` 作为主真源,只保留 fallback 定位。
+
+## 分阶段计划
+
+### Phase 1: 建立模板索引和校验
+
+范围:
+
+- 新增 `templates/genres/index.csv`。
+- 覆盖现有 37 个模板。
+- 所有模板 H1 中文化,去掉英文括号。
+- 新增校验:每个 `templates/genres/*.md` 必须在 index 里有一行。
+- 新增校验:每行 `canonical_genre` 必须属于 15 个 canonical。
+
+不改运行逻辑。
+
+验证:
+
+```powershell
+python -X utf8 webnovel-writer\scripts\validate_csv.py
+$env:PYTHONUTF8='1'; python -m pytest webnovel-writer\scripts\data_modules\tests\test_prompt_integrity.py -q --no-cov
+```
+
+### Phase 2: 接入 genre resolve
+
+范围:
+
+- 在 `reference_search.py` 中增加模板索引加载。
+- `resolve_genre()` 支持:
+  - canonical
+  - platform tag
+  - legacy value
+  - template name
+  - aliases
+- 未识别输入保持原行为,但返回 warning 或可诊断状态。
+
+验证:
+
+- 增加测试覆盖以下输入:
+  - `都市异能 -> 都市`
+  - `规则怪谈 -> 悬疑`
+  - `知乎短篇 -> 现言` 或按 index 配置值
+  - `西幻 -> 奇幻`
+  - `系统流 -> 玄幻` 默认映射
+
+### Phase 3: 改 init 写入与模板加载
+
+范围:
+
+- `init_project.py` 接收用户原始题材。
+- 解析为 `canonical_genre` 与 tags。
+- `state.json.project.genre` 写 canonical。
+- 新增兼容字段:
+
+```json
+{
+  "project": {
+    "genre": "悬疑",
+    "genre_label": "知乎短篇风的规则怪谈",
+    "genre_tags": {
+      "route": ["规则怪谈"],
+      "trope": [],
+      "format": ["知乎短篇"],
+      "templates": ["规则怪谈", "知乎短篇"]
+    }
+  }
+}
+```
+
+- 生成世界观时加载:
+  - canonical 对应模板(如存在)
+  - template preset 对应模板
+
+兼容策略:
+
+- 老项目如果 `project.genre` 是非 canonical,运行时通过 resolver 兼容。
+- 新项目只写 canonical。
+
+验证:
+
+- init 项目测试。
+- Story System route 测试。
+- prompt integrity。
+- 全量 pytest。
+
+### Phase 4: 更新 skill 与文档
+
+范围:
+
+- `webnovel-init/SKILL.md`
+  - 主体题材只展示 15 个 canonical。
+  - 说明模板预设/套路/形式的输入会被映射。
+- `references/csv/genre-canonical.md`
+  - 改清楚 route_tag / trope_tag / format_tag。
+- `references/csv/README.md`
+  - 写明 CSV 只接受 canonical,模板 index 负责用户输入层。
+
+验证:
+
+- prompt integrity。
+- 文档关键字断链搜索。
+
+### Phase 5: 可选目录重构
+
+只有前四阶段稳定后再做。
+
+目标结构:
+
+```text
+templates/genres/
+  index.csv
+  canonical/
+    都市.md
+    玄幻.md
+    ...
+  presets/
+    都市异能.md
+    规则怪谈.md
+    知乎短篇.md
+    系统流.md
+```
+
+这一步改动范围大,建议单独 PR/commit。
+
+## 建议提交拆分
+
+1. `docs(genres): document taxonomy convergence plan`
+2. `chore(genres): add template index and normalize headings`
+3. `feat(genres): resolve template presets to canonical genres`
+4. `feat(init): persist canonical genre and genre tags`
+5. `docs(genres): update init and csv taxonomy guidance`
+6. 可选:`refactor(genres): split canonical and preset templates`
+
+## 风险与控制
+
+- 风险:`state.json.project.genre` 从细分名改为 canonical 后,用户肉眼看到的信息变少。  
+  控制:保留 `genre_label` 和 `genre_tags`。
+
+- 风险:`系统流`、`知乎短篇` 等默认映射可能有争议。  
+  控制:index 中标注 `template_type`,并允许 init 交互时让用户确认 canonical。
+
+- 风险:一次性移动模板会造成路径断裂。  
+  控制:第一阶段只加 index,不移动文件。
+
+- 风险:CSV route 表的 `题材/流派` 命名与语义不一致。  
+  控制:先文档改名为 route_tag 语义,代码字段兼容不动,后续再考虑列名迁移。
+
+## 完成标准
+
+- 37 个模板全部有 index 映射。
+- 所有模板标题纯中文。
+- `validate_csv.py` 同时校验 CSV 与模板 index。
+- `reference_search.py` 能解析所有模板名到 canonical。
+- 新 init 项目写入 canonical `project.genre`。
+- 旧项目非 canonical genre 不崩,能 fallback resolve。
+- prompt integrity 与全量 pytest 通过。