genre-taxonomy-convergence-plan-2026-06-04.md 8.4 KB

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 方案:

都市 玄幻 仙侠 奇幻 科幻
历史 悬疑 游戏 古言 现言
幻言 年代 种田 快穿 衍生

这些值用于:

  • 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

例子:

template_name,canonical_genre,template_type,route_tags,trope_tags,format_tags,aliases
都市异能,都市,route,都市异能,,,"异能|现代异能"
规则怪谈,悬疑,route,规则怪谈,,,"规则动物园|规则类"
系统流,玄幻,trope,,系统流,,"系统|系统文"
知乎短篇,现言,format,,,知乎短篇,"知乎体|盐选|小程序短篇"
西幻,奇幻,route,西幻,,,"西方奇幻"

3. 用户输入解析结果

用户输入不直接等于硬题材。解析结果应该是结构化对象:

{
  "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。

不改运行逻辑。

验证:

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。
  • 新增兼容字段:

    {
    "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: 可选目录重构

只有前四阶段稳定后再做。

目标结构:

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_labelgenre_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 通过。