소스 검색

refactor: reviewer 只查事实、审查只跑一轮,AI 味收敛到润色阶段

针对 #106 审查-修复循环 token 优化,采用 reviewer 与润色拆分职责的方案:

- reviewer 改为纯事实审查(设定/时间线/连贯/角色/逻辑 5 维),移除 AI 味检测;
  新增强制逐维度结论 dimension_results,提升单轮覆盖面
- 写章 Step 3 审查只跑一轮:blocking 问题定点修复后直接进润色,不再重审;
  修不动则用 AskUserQuestion 由用户裁决(allowed-tools 补 AskUserQuestion)
- AI 味检测与改写全部由 Step 4 润色承担(polish-guide 7 层 Anti-AI +
  anti_ai_force_check 门禁,原已存在,未改)
- 清理 review SKILL / 参考文档 / 两个评测集中失效的 ai_flavor 引用
- review_schema.py 保留 ai_flavor 类别与回流函数(向后兼容,审查不再触发)

Refs #106
lingfengQAQ 2 주 전
부모
커밋
20925cb8e7

+ 4 - 6
webnovel-writer/agents/evals/evals.json

@@ -4,7 +4,7 @@
     {
       "id": 1,
       "prompt": "审查第4章正文。chapter=4, chapter_file='正文/第0004章-迦南学院的考验.md', project_root='agents/evals/files/test-project', scripts_dir 为本插件的 scripts 目录。",
-      "expected_output": "输出结构化 JSON 问题清单,包含多个 ai_flavor 类型的 issue,识别出密集的 AI 写作痕迹",
+      "expected_output": "输出结构化 JSON 问题清单,并对 5 个维度逐项给出结论(dimension_results)",
       "files": [
         "agents/evals/files/test-project/正文/第0004章-迦南学院的考验.md",
         "agents/evals/files/test-project/.webnovel/state.json",
@@ -13,11 +13,9 @@
       ],
       "expectations": [
         "输出是合法 JSON,包含 issues 数组和 summary 字符串",
-        "至少有 1 个 ai_flavor 类型的 issue 识别了'缓缓'或'淡淡'等万能副词",
-        "至少有 1 个 ai_flavor 类型的 issue 识别了'首先/其次/最后'三段式",
-        "至少有 1 个 ai_flavor 类型的 issue 识别了'眸中闪过'或'瞳孔微缩'等神态模板",
-        "至少有 1 个 ai_flavor 类型的 issue 识别了情绪标签化('他非常紧张'或'他感到欣慰')",
-        "至少有 1 个 ai_flavor 类型的 issue 识别了章末总结句('总而言之')",
+        "包含 dimension_results,逐项覆盖 setting/timeline/continuity/character/logic 五个维度",
+        "每个维度的 conclusion 非空(无问题时为 pass)",
+        "每个 issue 的 category 属于 setting/timeline/continuity/character/logic/pacing/other 之一",
         "每个 issue 都有 severity、category、location、description 字段",
         "每个 issue 都有 evidence 字段且非空",
         "没有输出 overall_score(reviewer 不评分)",

+ 20 - 41
webnovel-writer/agents/reviewer.md

@@ -1,6 +1,6 @@
 ---
 name: reviewer
-description: 统一审查 agent。检查正文的设定一致性、叙事连贯性、角色一致性、时间线、AI味,输出结构化问题清单。
+description: 统一审查 agent。逐维度检查正文的设定一致性、时间线、叙事连贯、角色一致性、逻辑,输出结构化问题清单。
 tools: Read, Grep, Bash
 model: inherit
 ---
@@ -9,7 +9,9 @@ model: inherit
 
 ## 1. 身份与目标
 
-你是章节审查员。你的职责是读完正文后,找出所有可验证的问题,输出结构化问题清单。
+你是章节**事实审查员**。你的职责是读完正文后,找出所有可验证的事实/逻辑/一致性问题,逐维度输出结构化问题清单。
+
+你只查 5 个维度:设定一致性、时间线、叙事连贯、角色一致性、逻辑。
 
 你不评分、不给建议、不写摘要性评价。你只找问题、给证据、给修复方向。
 
@@ -19,8 +21,6 @@ model: inherit
 - `Grep`:在正文中搜索关键词
 - `Bash`:调用记忆模块查询
 
-若用户明确提供或指定项目级文风/反 AI 味规则文件,必须先读取并把其中的私有规则纳入检查;输出 issue 时不暴露文件路径。
-
 ```bash
 # 查询角色当前状态
 python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" state get-entity --id "{entity_id}"
@@ -71,42 +71,13 @@ python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" ind
 - 角色决策是否有合理动机
 - 战斗/冲突结果是否符合已建立的力量对比
 
-### 6. AI味(category: ai_flavor)
-
-按 5 个子维度逐一检查:
-
-#### 6.1 词汇层
-- 高频 AI 词汇是否密集(参见 polish-guide K/L/M/N 类)
-- "缓缓/淡淡/微微"+动词 结构是否在 500 字内出现 3 次以上
-- 是否大量使用"眸中闪过""瞳孔微缩"等神态模板
-- severity: 个别命中 `medium`,密集命中 `high`
-
-#### 6.2 句式层
-- 是否存在"起因→经过→结果→感悟"四段闭环
-- 是否存在连续同构句(≥3 句主谓宾结构一致)
-- 是否每段都以总结句收尾("他终于明白了""由此可见")
-- 是否存在同一信息用不同句式重复说 2-3 遍
-- 是否存在比较状语或抽象判断先行,随后用正文补解释,导致句子像在替读者下结论
-- severity: `high`
-
-#### 6.3 叙事层
-- 节奏是否匀速(段落信息密度是否过于均匀,无快慢之分)
-- 是否存在"他不知道的是……""殊不知……"戏剧性反讽提示
-- 章末是否"安全着陆"(冲突完美解决,无遗留不安感或未闭合问题)
-- 是否存在展示后紧跟解释(先用动作展示,紧接着一句话解释刚才动作的含义)
-- severity: `medium`
-
-#### 6.4 情感层
-- 情绪描写是否标签化("他感到愤怒""她非常紧张"而非行为暗示)
-- 是否存在情绪即时切换(上句愤怒,下句就平静了,无过渡)
-- 所有角色是否用同一套反应模板(全员"瞳孔微缩""心中一凛")
-- severity: 标签化 `high`,其他 `medium`
-
-#### 6.5 对话层
-- 对话是否为信息宣讲(解释背景而非推进冲突)
-- 是否全员书面语、无口语特征、无个人口癖
-- 对白后是否跟解释性叙述("他这么说是因为……")
-- severity: 信息宣讲 `high`,其他 `medium`
+### 强制逐项结论
+
+完成上述 5 个维度检查后,必须为**每个维度**输出一行结论;无问题也要显式输出 `pass`。
+
+- 每个维度的结论写入输出 JSON 的 `dimension_results` 字段(见第 8 节)。
+- 结论格式:无问题 → `"conclusion": "pass"`;有问题 → `"conclusion": "发现N个问题:简述"`,同时在 `issues` 中给出每条问题的完整结构。
+- `dimension_results` 必须且只能覆盖这 5 个维度:setting / timeline / continuity / character / logic。
 
 ## 6. 边界与禁区
 
@@ -124,6 +95,7 @@ python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" ind
 - [ ] severity 分级合理(critical 仅用于确定的事实矛盾)
 - [ ] category 归类正确
 - [ ] blocking 字段只在 critical 或确认阻断时为 true
+- [ ] `dimension_results` 覆盖全部 5 个维度(无问题也输出 pass)
 
 ## 8. 输出格式
 
@@ -134,7 +106,7 @@ python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" ind
   "issues": [
     {
       "severity": "critical | high | medium | low",
-      "category": "continuity | setting | character | timeline | ai_flavor | logic | pacing | other",
+      "category": "continuity | setting | character | timeline | logic | pacing | other",
       "location": "第N段 或 具体引用",
       "description": "问题描述",
       "evidence": "原文引用 vs 数据记录",
@@ -142,6 +114,13 @@ python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" ind
       "blocking": true
     }
   ],
+  "dimension_results": [
+    {"dimension": "setting", "conclusion": "pass"},
+    {"dimension": "timeline", "conclusion": "发现1个问题:上章黄昏→本章晨光,无时间流逝交代"},
+    {"dimension": "continuity", "conclusion": "pass"},
+    {"dimension": "character", "conclusion": "pass"},
+    {"dimension": "logic", "conclusion": "pass"}
+  ],
   "summary": "N个问题:X个阻断,Y个高优"
 }
 ```

+ 0 - 1
webnovel-writer/references/index/reference-loading-map.md

@@ -40,7 +40,6 @@
 | webnovel-review | Step 2 | always | `references/review-schema.md` |
 | webnovel-review | Step 2 | 审查涉及爽点或钩子分析 | `references/shared/cool-points-guide.md` |
 | webnovel-review | Step 2 | 审查涉及多线交织 | `references/shared/strand-weave-pattern.md` |
-| webnovel-review | Step 2 | ai_flavor issue >= 3 | `skills/webnovel-write/references/anti-ai-guide.md` |
 | webnovel-review | Step 6 | blocking issue 需用户决策 | `references/review/blocking-override-guidelines.md` |
 | webnovel-query | 查询识别后 | 所有查询 | `skills/webnovel-query/references/system-data-flow.md` |
 | webnovel-query | 查询识别后 | 伏笔分析 | `skills/webnovel-query/references/advanced/foreshadowing.md` |

+ 0 - 1
webnovel-writer/references/reading-power-taxonomy.md

@@ -348,7 +348,6 @@
 |---------------------|----------------|
 | continuity | Hard-001 (可读性底线)、Hard-002 (结构完整) |
 | pacing | Hard-003 (节奏灾难)、爽点模式、微兑现 |
-| ai_flavor | 钩子类型、钩子强度 |
 
 ### 5.2 输出字段映射
 

+ 2 - 2
webnovel-writer/references/review/blocking-override-guidelines.md

@@ -29,7 +29,7 @@ purpose: review Step 6 blocking issue 用户裁决参考
 以下情况**可以考虑 override**(但仍需用户确认):
 
 - issue 是**节奏偏差**(本章偏慢/偏快,但不影响剧情正确性)
-- issue 是**风格建议**(对话过于书面化、描写密度偏高等
+- issue 是**角色风格软偏差**(如对话偏书面,但与人设相符
 - issue 是**结构化节点未完全覆盖**(可选节点未落地,但必须节点已覆盖)
 
 ## 知识补充层
@@ -37,7 +37,7 @@ purpose: review Step 6 blocking issue 用户裁决参考
 ### 可 override 的典型场景
 
 1. **过渡章节奏偏慢**:reviewer 报告 pacing_score 低,但本章是故意铺垫,用户确认后 override
-2. **对话风格偏书面**:reviewer 标记 ai_flavor,但角色设定就是学者/官员,书面语合理
+2. **对话风格偏书面**:reviewer 标记 character(对话风格偏离),但角色设定就是学者/官员,书面语合理
 3. **可选节点未覆盖**:CPN 中某个可选推进节点在正文中隐含但未显式展开
 
 ### 不可 override 的典型场景

+ 0 - 2
webnovel-writer/skills/webnovel-review/SKILL.md

@@ -61,7 +61,6 @@ python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${WORKSPACE_ROOT}" \
 - `PROJECT_ROOT` 必须包含 `.webnovel/state.json`
 - 任一关键目录不存在时立即阻断
 - `CHAPTER_GOAL` 必须来自详细大纲真实目标;若 `chapter_brief.meta.query` 仍是 `{章纲目标}` / `第N章章纲目标`,按系统问题记录。
-- 中高严重度 `ai_flavor` issue 会由 review-pipeline 回流到 `.story-system/anti_patterns.json`,作为后续写章避雷模式。
 
 ### Step 2:按需加载参考资料
 
@@ -78,7 +77,6 @@ python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${WORKSPACE_ROOT}" \
 |---------|-----------|
 | 审查涉及爽点或钩子分析 | `../../references/shared/cool-points-guide.md` |
 | 审查涉及多线交织 | `../../references/shared/strand-weave-pattern.md` |
-| ai_flavor issue ≥ 3 | `../../skills/webnovel-write/references/anti-ai-guide.md` |
 | blocking issue 需用户决策 (Step 6) | `../../references/review/blocking-override-guidelines.md` |
 
 ### Step 3:加载项目投影状态与待审正文

+ 1 - 2
webnovel-writer/skills/webnovel-review/evals/evals.json

@@ -4,7 +4,7 @@
     {
       "id": 1,
       "prompt": "使用 /webnovel-review 审查第4章(agents/evals/files/test-project/正文/第0004章-迦南学院的考验.md)。项目在 agents/evals/files/test-project/。",
-      "expected_output": "生成审查报告,包含 AI 味问题和时间线问题,并将审查指标写入 index.db",
+      "expected_output": "生成审查报告,识别时间线等事实/一致性问题,并将审查指标写入 index.db",
       "files": [
         "agents/evals/files/test-project/正文/第0004章-迦南学院的考验.md",
         "agents/evals/files/test-project/.webnovel/state.json",
@@ -12,7 +12,6 @@
       ],
       "expectations": [
         "审查报告被生成",
-        "报告中识别了至少 3 个 ai_flavor 问题",
         "报告中识别了时间跳跃问题(上章黄昏→本章晨光)",
         "审查指标被写入(review_metrics)",
         "报告中的每个 issue 都有 evidence"

+ 4 - 4
webnovel-writer/skills/webnovel-write/SKILL.md

@@ -1,7 +1,7 @@
 ---
 name: webnovel-write
 description: 产出可发布章节,完整执行上下文→起草→审查→润色→提交→备份。
-allowed-tools: Read Write Edit Grep Bash Agent
+allowed-tools: Read Write Edit Grep Bash Agent AskUserQuestion
 ---
 
 # 写章流程
@@ -22,7 +22,7 @@ allowed-tools: Read Write Edit Grep Bash Agent
 
 - 禁止并步、跳步、伪造审查
 - 必须使用 `Agent` 工具调用指定 subagent;不得用主流程口头代替 subagent 输出
-- blocking issue 未解决不进 Step 4/5
+- 审查只跑一轮;blocking issue 定点修复或经用户裁决后才进 Step 4/5
 - 失败只补跑失败步骤,不回退
 - 参考资料按步骤按需加载
 
@@ -112,7 +112,7 @@ python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" rev
   --save-metrics
 ```
 
-blocking=true → 修复后重审,不进 Step 4。`--fast` 只检查 setting/timeline/continuity。`--minimal` 跳过。
+审查只跑一轮,reviewer 只调用一次。`blocking=true` 的问题在不改剧情、不破设定的前提下定点修复后直接进 Step 4,不重新调用 reviewer;确实无法修复的 blocking 问题用 `AskUserQuestion` 让用户裁决(接受当前版本 / 手动修复 / 放弃)。非 blocking issue 交给 Step 4 处理。`--fast` 只检查 setting/timeline/continuity。`--minimal` 跳过。
 
 ### Step 4:润色
 
@@ -174,7 +174,7 @@ python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" bac
 
 1. 正文文件存在且非空
 2. 审查已落库(`--minimal` 除外)
-3. blocking=true 必须在 Step 3
+3. blocking=true 必须在 Step 3 定点修复或经用户裁决
 4. anti_ai_force_check=pass(`--minimal` 除外)
 5. accepted CHAPTER_COMMIT,projection 五项 done/skipped
 6. chapter_status=committed(projection 自动推进)