gwe-engine 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/README.md +265 -0
  2. package/README_EN.md +126 -0
  3. package/dist/cli.js +10444 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/index.d.ts +847 -0
  6. package/dist/index.js +10569 -0
  7. package/dist/index.js.map +1 -0
  8. package/package.json +1 -0
  9. package/src/kb/base-fillers.json +35 -0
  10. package/src/kb/base-prompt.ts +151 -0
  11. package/src/kb/base-vocab.json +87 -0
  12. package/src/kb/nodes/node_ai_continue_length/opt_ai_long.kb.json +36 -0
  13. package/src/kb/nodes/node_ai_continue_length/opt_ai_medium.kb.json +30 -0
  14. package/src/kb/nodes/node_ai_continue_length/opt_ai_short.kb.json +34 -0
  15. package/src/kb/nodes/node_ai_continue_length/opt_ai_xtra_long.kb.json +37 -0
  16. package/src/kb/nodes/node_ai_creativity/opt_ai_adventurous.kb.json +31 -0
  17. package/src/kb/nodes/node_ai_creativity/opt_ai_balanced.kb.json +31 -0
  18. package/src/kb/nodes/node_ai_creativity/opt_ai_conservative.kb.json +31 -0
  19. package/src/kb/nodes/node_anchor_density/opt_anchor_dense.kb.json +36 -0
  20. package/src/kb/nodes/node_anchor_density/opt_anchor_extreme.kb.json +37 -0
  21. package/src/kb/nodes/node_anchor_density/opt_anchor_sparse.kb.json +34 -0
  22. package/src/kb/nodes/node_anchor_density/opt_anchor_standard.kb.json +34 -0
  23. package/src/kb/nodes/node_battle_style/opt_battle_atmosphere.kb.json +32 -0
  24. package/src/kb/nodes/node_battle_style/opt_battle_detail.kb.json +36 -0
  25. package/src/kb/nodes/node_battle_style/opt_battle_psychological.kb.json +36 -0
  26. package/src/kb/nodes/node_battle_style/opt_battle_result.kb.json +37 -0
  27. package/src/kb/nodes/node_description_style/opt_desc_clinical.kb.json +36 -0
  28. package/src/kb/nodes/node_description_style/opt_desc_minimal.kb.json +37 -0
  29. package/src/kb/nodes/node_description_style/opt_desc_poetic.kb.json +35 -0
  30. package/src/kb/nodes/node_description_style/opt_desc_sensory.kb.json +39 -0
  31. package/src/kb/nodes/node_dialogue_style/opt_dialogue_concise.kb.json +34 -0
  32. package/src/kb/nodes/node_dialogue_style/opt_dialogue_natural.kb.json +32 -0
  33. package/src/kb/nodes/node_dialogue_style/opt_dialogue_stylized.kb.json +33 -0
  34. package/src/kb/nodes/node_dialogue_style/opt_dialogue_verbose.kb.json +34 -0
  35. package/src/kb/nodes/node_emotion_style/opt_emotion_both.kb.json +40 -0
  36. package/src/kb/nodes/node_emotion_style/opt_emotion_show.kb.json +41 -0
  37. package/src/kb/nodes/node_emotion_style/opt_emotion_tell.kb.json +40 -0
  38. package/src/kb/nodes/node_ending_hook/opt_hook_break.kb.json +54 -0
  39. package/src/kb/nodes/node_ending_hook/opt_hook_soft.kb.json +29 -0
  40. package/src/kb/nodes/node_ending_hook/opt_hook_suspense.kb.json +30 -0
  41. package/src/kb/nodes/node_info_density/opt_info_balanced.kb.json +37 -0
  42. package/src/kb/nodes/node_info_density/opt_info_fast.kb.json +37 -0
  43. package/src/kb/nodes/node_info_density/opt_info_leisurely.kb.json +41 -0
  44. package/src/kb/nodes/node_opening_impact/opt_opening_medium.kb.json +30 -0
  45. package/src/kb/nodes/node_opening_impact/opt_opening_strong.kb.json +46 -0
  46. package/src/kb/nodes/node_opening_impact/opt_opening_weak.kb.json +29 -0
  47. package/src/kb/nodes/node_paragraph_density/opt_dense_high.kb.json +36 -0
  48. package/src/kb/nodes/node_paragraph_density/opt_dense_low.kb.json +37 -0
  49. package/src/kb/nodes/node_paragraph_density/opt_dense_medium.kb.json +28 -0
  50. package/src/kb/nodes/node_payoff_frequency/opt_payoff_every_3.kb.json +31 -0
  51. package/src/kb/nodes/node_payoff_frequency/opt_payoff_every_chapter.kb.json +35 -0
  52. package/src/kb/nodes/node_payoff_frequency/opt_payoff_sparse.kb.json +37 -0
  53. package/src/kb/nodes/node_platform/opt_platform_feilu.kb.json +44 -0
  54. package/src/kb/nodes/node_platform/opt_platform_generic.kb.json +31 -0
  55. package/src/kb/nodes/node_platform/opt_platform_jinjiang.kb.json +42 -0
  56. package/src/kb/nodes/node_platform/opt_platform_newmedia.kb.json +43 -0
  57. package/src/kb/nodes/node_platform/opt_platform_qidian.kb.json +39 -0
  58. package/src/kb/nodes/node_platform/opt_platform_qimao.kb.json +43 -0
  59. package/src/kb/nodes/node_platform/opt_platform_tomato.kb.json +51 -0
  60. package/src/kb/nodes/node_pov/opt_pov_first_past.kb.json +34 -0
  61. package/src/kb/nodes/node_pov/opt_pov_first_present.kb.json +37 -0
  62. package/src/kb/nodes/node_pov/opt_pov_limited_third_past.kb.json +31 -0
  63. package/src/kb/nodes/node_pov/opt_pov_limited_third_present.kb.json +35 -0
  64. package/src/kb/nodes/node_pov/opt_pov_omniscient_third_past.kb.json +37 -0
  65. package/src/kb/nodes/node_pov/opt_pov_omniscient_third_present.kb.json +36 -0
  66. package/src/kb/nodes/node_rhetoric/opt_rhetoric_metaphor.kb.json +35 -0
  67. package/src/kb/nodes/node_rhetoric/opt_rhetoric_ornate.kb.json +37 -0
  68. package/src/kb/nodes/node_rhetoric/opt_rhetoric_plain.kb.json +25 -0
  69. package/src/kb/nodes/node_rhetoric/opt_rhetoric_sketch.kb.json +37 -0
  70. package/src/kb/nodes/node_sentence_rhythm/opt_rhythm_long.kb.json +42 -0
  71. package/src/kb/nodes/node_sentence_rhythm/opt_rhythm_medium.kb.json +40 -0
  72. package/src/kb/nodes/node_sentence_rhythm/opt_rhythm_mixed.kb.json +40 -0
  73. package/src/kb/nodes/node_sentence_rhythm/opt_rhythm_short.kb.json +41 -0
  74. package/src/kb/nodes/node_strictness/opt_strict_lenient.kb.json +50 -0
  75. package/src/kb/nodes/node_strictness/opt_strict_standard.kb.json +30 -0
  76. package/src/kb/nodes/node_strictness/opt_strict_strict.kb.json +52 -0
  77. package/src/kb/nodes/node_target_length/opt_length_1500.kb.json +39 -0
  78. package/src/kb/nodes/node_target_length/opt_length_2200.kb.json +39 -0
  79. package/src/kb/nodes/node_target_length/opt_length_3000.kb.json +39 -0
  80. package/src/kb/nodes/node_target_length/opt_length_4000.kb.json +39 -0
  81. package/src/kb/nodes/node_target_length/opt_length_custom.kb.json +31 -0
  82. package/src/kb/nodes/node_tone/opt_tone_badass.kb.json +45 -0
  83. package/src/kb/nodes/node_tone/opt_tone_classical.kb.json +41 -0
  84. package/src/kb/nodes/node_tone/opt_tone_cold.kb.json +42 -0
  85. package/src/kb/nodes/node_tone/opt_tone_colloquial.kb.json +33 -0
  86. package/src/kb/nodes/node_tone/opt_tone_folksy.kb.json +40 -0
  87. package/src/kb/nodes/node_tone/opt_tone_playful.kb.json +42 -0
  88. package/src/kb/nodes/node_tone/opt_tone_serious.kb.json +42 -0
  89. package/src/kb/nodes/node_twist_frequency/opt_twist_dense.kb.json +36 -0
  90. package/src/kb/nodes/node_twist_frequency/opt_twist_sparse.kb.json +26 -0
  91. package/src/kb/nodes/node_twist_frequency/opt_twist_standard.kb.json +32 -0
  92. package/src/kb/nodes/node_vocab_filler/opt_filler_relaxed.kb.json +45 -0
  93. package/src/kb/nodes/node_vocab_filler/opt_filler_standard.kb.json +46 -0
  94. package/src/kb/nodes/node_vocab_filler/opt_filler_strict.kb.json +56 -0
  95. package/src/kb/nodes/node_vocab_filler/opt_filler_webnovel.kb.json +56 -0
  96. package/src/kb/nodes/node_vocab_sensory/opt_vocab_daily.kb.json +46 -0
  97. package/src/kb/nodes/node_vocab_sensory/opt_vocab_esports.kb.json +45 -0
  98. package/src/kb/nodes/node_vocab_sensory/opt_vocab_fantasy.kb.json +40 -0
  99. package/src/kb/nodes/node_vocab_sensory/opt_vocab_generic.kb.json +32 -0
  100. package/src/kb/nodes/node_vocab_sensory/opt_vocab_historical.kb.json +43 -0
  101. package/src/kb/nodes/node_vocab_sensory/opt_vocab_horror.kb.json +48 -0
  102. package/src/kb/nodes/node_vocab_sensory/opt_vocab_military.kb.json +46 -0
  103. package/src/kb/nodes/node_vocab_sensory/opt_vocab_mystery.kb.json +43 -0
  104. package/src/kb/nodes/node_vocab_sensory/opt_vocab_scifi.kb.json +40 -0
  105. package/src/kb/nodes/node_vocab_sensory/opt_vocab_urban.kb.json +40 -0
  106. package/src/kb/nodes/node_vocab_sensory/opt_vocab_xianxia.kb.json +40 -0
  107. package/src/kb/presets/preset_daily.json +42 -0
  108. package/src/kb/presets/preset_esports.json +42 -0
  109. package/src/kb/presets/preset_fantasy.json +40 -0
  110. package/src/kb/presets/preset_historical.json +41 -0
  111. package/src/kb/presets/preset_horror.json +67 -0
  112. package/src/kb/presets/preset_miner.json +123 -0
  113. package/src/kb/presets/preset_mystery.json +55 -0
  114. package/src/kb/presets/preset_scifi_hardcore.json +55 -0
  115. package/src/kb/presets/preset_urban_jinjiang.json +42 -0
  116. package/src/kb/presets/preset_urban_tomato.json +66 -0
  117. package/src/kb/presets/preset_xianxia_qidian.json +50 -0
  118. package/src/kb/presets/preset_xianxia_tomato.json +66 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli.ts","../src/node-registry.ts","../src/types.ts","../src/config-merger.ts","../src/validator.ts","../src/anchor-detector.ts","../src/filler-words.ts","../src/radar.ts","../src/checker.ts","../src/prompt-builder.ts","../src/llm-provider.ts","../src/gwe-engine.ts","../src/kb/base-prompt.ts","../src/kb/base-vocab.json","../src/kb/nodes/node_ai_continue_length/opt_ai_short.kb.json","../src/kb/nodes/node_ai_continue_length/opt_ai_medium.kb.json","../src/kb/nodes/node_ai_continue_length/opt_ai_long.kb.json","../src/kb/nodes/node_ai_continue_length/opt_ai_xtra_long.kb.json","../src/kb/nodes/node_ai_creativity/opt_ai_conservative.kb.json","../src/kb/nodes/node_ai_creativity/opt_ai_balanced.kb.json","../src/kb/nodes/node_ai_creativity/opt_ai_adventurous.kb.json","../src/kb/nodes/node_anchor_density/opt_anchor_sparse.kb.json","../src/kb/nodes/node_anchor_density/opt_anchor_standard.kb.json","../src/kb/nodes/node_anchor_density/opt_anchor_dense.kb.json","../src/kb/nodes/node_anchor_density/opt_anchor_extreme.kb.json","../src/kb/nodes/node_battle_style/opt_battle_atmosphere.kb.json","../src/kb/nodes/node_battle_style/opt_battle_detail.kb.json","../src/kb/nodes/node_battle_style/opt_battle_psychological.kb.json","../src/kb/nodes/node_battle_style/opt_battle_result.kb.json","../src/kb/nodes/node_description_style/opt_desc_clinical.kb.json","../src/kb/nodes/node_description_style/opt_desc_minimal.kb.json","../src/kb/nodes/node_description_style/opt_desc_poetic.kb.json","../src/kb/nodes/node_description_style/opt_desc_sensory.kb.json","../src/kb/nodes/node_dialogue_style/opt_dialogue_concise.kb.json","../src/kb/nodes/node_dialogue_style/opt_dialogue_natural.kb.json","../src/kb/nodes/node_dialogue_style/opt_dialogue_stylized.kb.json","../src/kb/nodes/node_dialogue_style/opt_dialogue_verbose.kb.json","../src/kb/nodes/node_emotion_style/opt_emotion_show.kb.json","../src/kb/nodes/node_emotion_style/opt_emotion_tell.kb.json","../src/kb/nodes/node_emotion_style/opt_emotion_both.kb.json","../src/kb/nodes/node_ending_hook/opt_hook_soft.kb.json","../src/kb/nodes/node_ending_hook/opt_hook_suspense.kb.json","../src/kb/nodes/node_ending_hook/opt_hook_break.kb.json","../src/kb/nodes/node_info_density/opt_info_fast.kb.json","../src/kb/nodes/node_info_density/opt_info_balanced.kb.json","../src/kb/nodes/node_info_density/opt_info_leisurely.kb.json","../src/kb/nodes/node_opening_impact/opt_opening_medium.kb.json","../src/kb/nodes/node_opening_impact/opt_opening_strong.kb.json","../src/kb/nodes/node_opening_impact/opt_opening_weak.kb.json","../src/kb/nodes/node_paragraph_density/opt_dense_low.kb.json","../src/kb/nodes/node_paragraph_density/opt_dense_medium.kb.json","../src/kb/nodes/node_paragraph_density/opt_dense_high.kb.json","../src/kb/nodes/node_payoff_frequency/opt_payoff_every_3.kb.json","../src/kb/nodes/node_payoff_frequency/opt_payoff_every_chapter.kb.json","../src/kb/nodes/node_payoff_frequency/opt_payoff_sparse.kb.json","../src/kb/nodes/node_platform/opt_platform_generic.kb.json","../src/kb/nodes/node_platform/opt_platform_qidian.kb.json","../src/kb/nodes/node_platform/opt_platform_tomato.kb.json","../src/kb/nodes/node_platform/opt_platform_qimao.kb.json","../src/kb/nodes/node_platform/opt_platform_feilu.kb.json","../src/kb/nodes/node_platform/opt_platform_jinjiang.kb.json","../src/kb/nodes/node_platform/opt_platform_newmedia.kb.json","../src/kb/nodes/node_pov/opt_pov_first_past.kb.json","../src/kb/nodes/node_pov/opt_pov_first_present.kb.json","../src/kb/nodes/node_pov/opt_pov_limited_third_past.kb.json","../src/kb/nodes/node_pov/opt_pov_limited_third_present.kb.json","../src/kb/nodes/node_pov/opt_pov_omniscient_third_past.kb.json","../src/kb/nodes/node_pov/opt_pov_omniscient_third_present.kb.json","../src/kb/nodes/node_rhetoric/opt_rhetoric_plain.kb.json","../src/kb/nodes/node_rhetoric/opt_rhetoric_metaphor.kb.json","../src/kb/nodes/node_rhetoric/opt_rhetoric_ornate.kb.json","../src/kb/nodes/node_rhetoric/opt_rhetoric_sketch.kb.json","../src/kb/nodes/node_sentence_rhythm/opt_rhythm_short.kb.json","../src/kb/nodes/node_sentence_rhythm/opt_rhythm_medium.kb.json","../src/kb/nodes/node_sentence_rhythm/opt_rhythm_mixed.kb.json","../src/kb/nodes/node_sentence_rhythm/opt_rhythm_long.kb.json","../src/kb/nodes/node_strictness/opt_strict_lenient.kb.json","../src/kb/nodes/node_strictness/opt_strict_standard.kb.json","../src/kb/nodes/node_strictness/opt_strict_strict.kb.json","../src/kb/nodes/node_target_length/opt_length_1500.kb.json","../src/kb/nodes/node_target_length/opt_length_2200.kb.json","../src/kb/nodes/node_target_length/opt_length_3000.kb.json","../src/kb/nodes/node_target_length/opt_length_4000.kb.json","../src/kb/nodes/node_target_length/opt_length_custom.kb.json","../src/kb/nodes/node_tone/opt_tone_badass.kb.json","../src/kb/nodes/node_tone/opt_tone_classical.kb.json","../src/kb/nodes/node_tone/opt_tone_cold.kb.json","../src/kb/nodes/node_tone/opt_tone_colloquial.kb.json","../src/kb/nodes/node_tone/opt_tone_folksy.kb.json","../src/kb/nodes/node_tone/opt_tone_playful.kb.json","../src/kb/nodes/node_tone/opt_tone_serious.kb.json","../src/kb/nodes/node_twist_frequency/opt_twist_sparse.kb.json","../src/kb/nodes/node_twist_frequency/opt_twist_standard.kb.json","../src/kb/nodes/node_twist_frequency/opt_twist_dense.kb.json","../src/kb/nodes/node_vocab_filler/opt_filler_relaxed.kb.json","../src/kb/nodes/node_vocab_filler/opt_filler_standard.kb.json","../src/kb/nodes/node_vocab_filler/opt_filler_strict.kb.json","../src/kb/nodes/node_vocab_filler/opt_filler_webnovel.kb.json","../src/kb/nodes/node_vocab_sensory/opt_vocab_daily.kb.json","../src/kb/nodes/node_vocab_sensory/opt_vocab_esports.kb.json","../src/kb/nodes/node_vocab_sensory/opt_vocab_fantasy.kb.json","../src/kb/nodes/node_vocab_sensory/opt_vocab_generic.kb.json","../src/kb/nodes/node_vocab_sensory/opt_vocab_historical.kb.json","../src/kb/nodes/node_vocab_sensory/opt_vocab_horror.kb.json","../src/kb/nodes/node_vocab_sensory/opt_vocab_military.kb.json","../src/kb/nodes/node_vocab_sensory/opt_vocab_mystery.kb.json","../src/kb/nodes/node_vocab_sensory/opt_vocab_scifi.kb.json","../src/kb/nodes/node_vocab_sensory/opt_vocab_urban.kb.json","../src/kb/nodes/node_vocab_sensory/opt_vocab_xianxia.kb.json","../src/kb/presets/preset_daily.json","../src/kb/presets/preset_esports.json","../src/kb/presets/preset_fantasy.json","../src/kb/presets/preset_historical.json","../src/kb/presets/preset_horror.json","../src/kb/presets/preset_miner.json","../src/kb/presets/preset_mystery.json","../src/kb/presets/preset_scifi_hardcore.json","../src/kb/presets/preset_urban_jinjiang.json","../src/kb/presets/preset_urban_tomato.json","../src/kb/presets/preset_xianxia_qidian.json","../src/kb/presets/preset_xianxia_tomato.json","../src/kb-loader.ts"],"sourcesContent":["// ============================================================\n// GWE V3.2 - CLI 命令行工具\n// 用法: gwe check <file> | gwe - | gwe --json <file>\n// ============================================================\nimport fs from 'fs';\nimport path from 'path';\nimport { createEngineWithKB } from './kb-loader';\nimport { MockProvider } from './llm-provider';\nimport type { CheckResult } from './types';\n\nconst VERSION = '3.2.0';\n\n// 颜色\nconst colors = {\n reset: '\\x1b[0m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n magenta: '\\x1b[35m',\n cyan: '\\x1b[36m',\n gray: '\\x1b[90m',\n bold: '\\x1b[1m',\n};\n\nfunction colorize(text: string, color: keyof typeof colors): string {\n return `${colors[color]}${text}${colors.reset}`;\n}\n\nfunction printHelp(): void {\n console.log(`\n${colorize('GWE - Generic Web-novel Engine 网文追读力引擎', 'bold')} v${VERSION}\n\n${colorize('用法:', 'cyan')}\n gwe check <file> 检测一个网文章节文件\n gwe - 从标准输入读取文本并检测\n gwe --json <file> 输出JSON格式结果(用于程序集成)\n gwe --help, -h 显示帮助\n gwe --version, -v 显示版本\n\n${colorize('示例:', 'cyan')}\n gwe check chapter.txt\n cat chapter.txt | gwe -\n gwe --json chapter.txt > report.json\n echo \"疼。凿尖砸进指骨...\" | gwe -\n\n${colorize('评分说明:', 'cyan')}\n ≥90分 🏆 优秀,对标一线热门网文\n ≥85分 ✅ 良好,达到发布标准\n ≥75分 ⚠ 及格,需要修改\n ≥60分 ⚠ 较多问题,建议重写\n <60分 ✗ 质量不达标\n\n${colorize('评分维度:', 'cyan')}\n 身体反应 感官信号 动作推进 情绪张力\n 信息推进 转折密度 章末钩子\n`);\n}\n\nfunction printVersion(): void {\n console.log(`GWE v${VERSION}`);\n}\n\n// 全局引擎实例\nlet _engine: ReturnType<typeof createEngineWithKB>['engine'] | null = null;\nfunction getEngine() {\n if (_engine) return _engine;\n const { engine, result } = createEngineWithKB(new MockProvider());\n if (result.errors.length > 0) {\n console.error(colorize(`KB加载警告: ${result.errors.length}个错误`, 'yellow'));\n for (const err of result.errors) console.error(colorize(` - ${err}`, 'gray'));\n }\n _engine = engine;\n return engine;\n}\n\nfunction runCheck(text: string, filePath?: string, outputJson = false): void {\n const engine = getEngine();\n const result: CheckResult = engine.check(text, null);\n\n if (outputJson) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n // 标题\n console.log('');\n if (filePath) {\n console.log(colorize(` GWE V${VERSION} 网文追读力检测`, 'bold') + colorize(` ${filePath}`, 'gray'));\n } else {\n console.log(colorize(` GWE V${VERSION} 网文追读力检测`, 'bold'));\n }\n console.log('');\n\n // 分数\n const scoreColor = result.score >= 90 ? 'green' : result.score >= 80 ? 'cyan' : result.score >= 70 ? 'yellow' : 'red';\n const passed = result.passed ? colorize('通过', 'green') : colorize('未通过', 'red');\n let grade = '';\n if (result.score >= 90) grade = colorize('🏆 优秀', 'green');\n else if (result.score >= 85) grade = colorize('✅ 良好', 'green');\n else if (result.score >= 75) grade = colorize('⚠ 及格', 'yellow');\n else if (result.score >= 60) grade = colorize('⚠ 较差', 'yellow');\n else grade = colorize('✗ 不达标', 'red');\n \n console.log(` 综合得分: ${colorize(`${result.score}分`, scoreColor)} (${passed}) 字数: ${result.stats.totalChars}字 ${grade}`);\n console.log('');\n\n // 雷达图\n console.log(colorize(' ─── 7维雷达评分 ───', 'cyan'));\n const radarLabels: Record<string, string> = {\n bodyReaction: '身体反应',\n sensorySignal: '感官信号',\n action: '动作推进',\n emotion: '情绪张力',\n infoAdvance: '信息推进',\n twistFrequency: '转折密度',\n hookStrength: '章末钩子',\n };\n for (const [key, label] of Object.entries(radarLabels)) {\n const score = result.radarScores[key as keyof typeof result.radarScores];\n const barLen = Math.floor(score / 5);\n const bar = colorize('█'.repeat(barLen), score >= 90 ? 'green' : score >= 75 ? 'cyan' : score >= 60 ? 'yellow' : 'red') + colorize('░'.repeat(20 - barLen), 'gray');\n const scoreStr = score === 100 ? colorize('100', 'green') : colorize(String(score).padStart(3), score >= 90 ? 'green' : score >= 75 ? 'cyan' : score >= 60 ? 'yellow' : 'red');\n console.log(` ${label.padEnd(6)} ${bar} ${scoreStr}`);\n }\n console.log('');\n\n // 违规项\n if (result.violations.length > 0) {\n const order = { error: 0, warning: 1, info: 2 };\n const sorted = [...result.violations].sort((a, b) => \n (order[a.severity] ?? 3) - (order[b.severity] ?? 3)\n );\n const errorCount = sorted.filter(v => v.severity === 'error').length;\n const warnCount = sorted.filter(v => v.severity === 'warning').length;\n const infoCount = sorted.filter(v => v.severity === 'info').length;\n \n console.log(colorize(` ─── 违规项 (${colorize(`${errorCount} error`, 'red')}, ${colorize(`${warnCount} warning`, 'yellow')}, ${colorize(`${infoCount} info`, 'gray')}) ───`, 'cyan'));\n console.log('');\n for (const v of sorted) {\n const icon = v.severity === 'error' ? colorize(' ✗', 'red') : v.severity === 'warning' ? colorize(' ⚠', 'yellow') : colorize(' ℹ', 'gray');\n const name = colorize(`[${v.ruleName}]`, v.severity === 'error' ? 'red' : v.severity === 'warning' ? 'yellow' : 'gray');\n console.log(`${icon} ${name} ${v.message}`);\n if (v.suggestion) {\n const sugLines = v.suggestion.split('\\n');\n for (const line of sugLines) {\n if (line.trim()) console.log(colorize(` → ${line}`, 'gray'));\n }\n }\n console.log('');\n }\n } else {\n console.log(colorize(' ✓ 无违规项,章节质量优秀!', 'green'));\n console.log('');\n }\n\n // 统计\n console.log(colorize(' ─── 文本统计 ───', 'cyan'));\n console.log(` 段落数: ${result.stats.paragraphCount} 平均段长: ${result.stats.avgParagraphLength.toFixed(1)}字`);\n const anchorDensity = result.stats.totalChars > 0 ? ((result.stats.anchorCount / result.stats.totalChars) * 1000).toFixed(1) : '0';\n console.log(` 身体锚点: ${result.stats.anchorCount}个 (千字${anchorDensity}个)`);\n console.log(` 填充词: ${result.stats.fillerCount}个 对话占比: ${(result.stats.dialogueRatio * 100).toFixed(0)}%`);\n console.log('');\n}\n\n// 主逻辑\nconst args = process.argv.slice(2);\n\nif (args.length === 0 || args.includes('-h') || args.includes('--help')) {\n printHelp();\n process.exit(0);\n}\n\nif (args.includes('-v') || args.includes('--version')) {\n printVersion();\n process.exit(0);\n}\n\nconst outputJson = args.includes('--json');\nconst cleanArgs = args.filter(a => a !== '--json');\n\n// 从stdin读取\nif (cleanArgs[0] === '-' || cleanArgs[0] === '--stdin') {\n let data = '';\n process.stdin.setEncoding('utf-8');\n process.stdin.on('data', (chunk) => { data += chunk; });\n process.stdin.on('end', () => {\n if (!data.trim()) {\n console.error(colorize('错误: 标准输入为空', 'red'));\n process.exit(1);\n }\n runCheck(data, undefined, outputJson);\n });\n} else if (cleanArgs[0] === 'check') {\n const filePath = cleanArgs[1];\n if (!filePath) {\n console.error(colorize('错误: 请指定要检测的文件路径', 'red'));\n console.log('用法: gwe check <file.txt>');\n process.exit(1);\n }\n const resolvedPath = path.resolve(process.cwd(), filePath);\n if (!fs.existsSync(resolvedPath)) {\n console.error(colorize(`错误: 文件不存在: ${resolvedPath}`, 'red'));\n process.exit(1);\n }\n const text = fs.readFileSync(resolvedPath, 'utf-8');\n runCheck(text, filePath, outputJson);\n} else {\n const filePath = cleanArgs[0];\n const resolvedPath = path.resolve(process.cwd(), filePath);\n if (fs.existsSync(resolvedPath)) {\n const text = fs.readFileSync(resolvedPath, 'utf-8');\n runCheck(text, filePath, outputJson);\n } else {\n console.error(colorize(`错误: 未知命令或文件不存在: ${cleanArgs[0]}`, 'red'));\n console.log('使用 gwe --help 查看帮助');\n process.exit(1);\n }\n}","// ============================================================\n// GWE V2.0 - 节点注册表\n// 内置所有19个节点定义,支持动态注册选项(.kb文件加载)\n// ============================================================\n\nimport type {\n NodeDefinition,\n NodeId,\n NodeCategory,\n OptionId,\n NodeOptionKB,\n} from './types';\n\n// ============================================================\n// 内置22个节点定义(V3新增3个追读力节点)\n// 分类:12个style、2个vocab、6个rule、2个ai\n// ============================================================\n\nconst BUILTIN_NODES: NodeDefinition[] = [\n // ========== 风格类 (style) - 12个 ==========\n {\n id: 'node_sentence_rhythm',\n name: '句子节奏',\n category: 'style',\n description: '控制句子长短节奏,影响阅读呼吸感',\n required: true,\n defaultOptionId: 'opt_rhythm_medium',\n options: [\n 'opt_rhythm_short', // 短句为主(快节奏,适合战斗/紧张)\n 'opt_rhythm_medium', // 长短适中(通用,默认)\n 'opt_rhythm_long', // 长句为主(慢节奏,适合描写/抒情)\n 'opt_rhythm_mixed', // 长短交错(戏剧化,适合情绪起伏)\n ],\n },\n {\n id: 'node_paragraph_density',\n name: '段落密度',\n category: 'style',\n description: '控制段落长度和分段频率',\n required: true,\n defaultOptionId: 'opt_dense_medium',\n options: [\n 'opt_dense_high', // 高密度(短段快节奏,适合爽文/战斗)\n 'opt_dense_medium', // 标准密度(适中段落,默认)\n 'opt_dense_low', // 低密度(长段慢节奏,适合传统文学)\n ],\n },\n {\n id: 'node_dialogue_style',\n name: '对话风格',\n category: 'style',\n description: '控制对话表达方式和穿插动作',\n required: true,\n defaultOptionId: 'opt_dialogue_natural',\n options: [\n 'opt_dialogue_natural', // 自然对话(适度动作穿插,默认)\n 'opt_dialogue_concise', // 精炼对话(简洁有力,少废话)\n 'opt_dialogue_stylized', // 风格化对话(符合角色人设,有辨识度)\n 'opt_dialogue_verbose', // 絮叨风格(对话带大量心理/旁白)\n ],\n },\n {\n id: 'node_description_style',\n name: '描写风格',\n category: 'style',\n description: '控制环境/人物描写的详略和方式',\n required: true,\n defaultOptionId: 'opt_desc_sensory',\n options: [\n 'opt_desc_sensory', // 感官密集(五感多通道并进,默认)\n 'opt_desc_minimal', // 白描极简(只给关键信息,留白)\n 'opt_desc_poetic', // 诗意画面(意境优先,意象优美)\n 'opt_desc_clinical', // 冷硬写实(客观精确,不带情感色彩)\n ],\n },\n {\n id: 'node_battle_style',\n name: '战斗风格',\n category: 'style',\n description: '战斗/动作场景的写作风格',\n required: false,\n defaultOptionId: 'opt_battle_detail',\n options: [\n 'opt_battle_detail', // 重细节拆招(一招一式清晰拆解,默认)\n 'opt_battle_atmosphere', // 氛围流(侧重压迫感和临场氛围)\n 'opt_battle_result', // 结果导向(快节奏推进,不写过程细节)\n 'opt_battle_psychological', // 心理流(侧重战斗中的心理博弈)\n ],\n },\n {\n id: 'node_emotion_style',\n name: '情感表达',\n category: 'style',\n description: '情感描写的表达方式',\n required: true,\n defaultOptionId: 'opt_emotion_show',\n options: [\n 'opt_emotion_show', // 以动写情(身体反应+动作,默认,Show don't tell)\n 'opt_emotion_tell', // 直抒胸臆(直接写心理和情绪)\n 'opt_emotion_both', // 内外结合(动作描写+内心独白)\n ],\n },\n {\n id: 'node_tone',\n name: '整体基调',\n category: 'style',\n description: '作品整体语气和氛围',\n required: true,\n defaultOptionId: 'opt_tone_serious',\n options: [\n 'opt_tone_classical', // 唯美古风(古雅用词,古典韵味)\n 'opt_tone_colloquial', // 口语白话(接地气,现代口语感)\n 'opt_tone_serious', // 严肃正剧(沉稳厚重,默认)\n 'opt_tone_cold', // 冷峻克制(冷硬内敛,不煽情)\n 'opt_tone_playful', // 俏皮轻松(幽默活泼,有网感)\n 'opt_tone_folksy', // 乡土市井(接地气,烟火气浓)\n 'opt_tone_badass', // 硬核爽利(霸气硬朗,力量感强)\n ],\n },\n {\n id: 'node_platform',\n name: '目标平台',\n category: 'style',\n description: '针对不同平台的适配优化',\n required: true,\n defaultOptionId: 'opt_platform_generic',\n options: [\n 'opt_platform_qidian', // 起点中文网\n 'opt_platform_tomato', // 番茄小说\n 'opt_platform_jinjiang', // 晋江文学城\n 'opt_platform_feilu', // 飞卢小说\n 'opt_platform_qimao', // 七猫小说\n 'opt_platform_newmedia', // 新媒体/公众号\n 'opt_platform_generic', // 通用平台(默认)\n ],\n },\n {\n id: 'node_info_density',\n name: '信息密度',\n category: 'style',\n description: '世界观/设定信息的铺陈密度',\n required: true,\n defaultOptionId: 'opt_info_balanced',\n options: [\n 'opt_info_fast', // 快节奏(信息推进快,少铺垫)\n 'opt_info_balanced', // 均衡(设定随剧情自然交代,默认)\n 'opt_info_leisurely', // 慢节奏(从容铺陈,世界观细腻)\n ],\n },\n {\n id: 'node_payoff_frequency',\n name: '爽点频率',\n category: 'style',\n description: '小高潮/爽点出现的频率',\n required: true,\n defaultOptionId: 'opt_payoff_every_chapter',\n options: [\n 'opt_payoff_every_chapter', // 每章爽点(每章至少1个小高潮,默认)\n 'opt_payoff_every_3', // 每3章爽点(铺垫后集中爆发)\n 'opt_payoff_sparse', // 稀疏爽点(慢热大后期爆发)\n ],\n },\n {\n id: 'node_pov',\n name: '叙事视角',\n category: 'style',\n description: '叙事人称和视角限制',\n required: true,\n defaultOptionId: 'opt_pov_limited_third_past',\n options: [\n 'opt_pov_first_past', // 第一人称过去时\n 'opt_pov_first_present', // 第一人称现在时\n 'opt_pov_limited_third_past', // 第三人称有限过去时(跟随主角,默认)\n 'opt_pov_limited_third_present',// 第三人称有限现在时\n 'opt_pov_omniscient_third_past',// 第三人称全知过去时(上帝视角)\n 'opt_pov_omniscient_third_present',// 第三人称全知现在时\n ],\n },\n {\n id: 'node_rhetoric',\n name: '修辞偏好',\n category: 'style',\n description: '修辞手法使用偏好',\n required: false,\n defaultOptionId: 'opt_rhetoric_plain',\n options: [\n 'opt_rhetoric_metaphor', // 善用比喻(关键处用比喻/通感)\n 'opt_rhetoric_plain', // 朴素无华(几乎不用修辞,默认)\n 'opt_rhetoric_ornate', // 华丽铺陈(大量排比/对偶/夸张)\n 'opt_rhetoric_sketch', // 白描勾勒(用最简笔触点染)\n ],\n },\n\n // ========== 词库类 (vocab) - 2个 ==========\n {\n id: 'node_vocab_sensory',\n name: '题材词库',\n category: 'vocab',\n description: '按题材加载专属词汇(世界观/身体/动作/感官词汇扩展)',\n required: false,\n defaultOptionId: 'opt_vocab_generic',\n options: [\n 'opt_vocab_xianxia', // 玄幻修仙\n 'opt_vocab_urban', // 都市现代\n 'opt_vocab_scifi', // 科幻未来\n 'opt_vocab_mystery', // 悬疑推理\n 'opt_vocab_fantasy', // 西方奇幻\n 'opt_vocab_historical', // 历史古风\n 'opt_vocab_esports', // 电竞游戏\n 'opt_vocab_daily', // 日常治愈\n 'opt_vocab_horror', // 恐怖灵异\n 'opt_vocab_military', // 军事战争\n 'opt_vocab_generic', // 通用词库(默认)\n ],\n },\n {\n id: 'node_vocab_filler',\n name: '填充词管控',\n category: 'vocab',\n description: '禁用/控制填充词和冗余表达',\n required: false,\n defaultOptionId: 'opt_filler_standard',\n options: [\n 'opt_filler_strict', // 严格(禁用绝大多数填充词)\n 'opt_filler_standard', // 标准(控制常用填充词,默认)\n 'opt_filler_relaxed', // 宽松(少量填充词可接受)\n 'opt_filler_webnovel', // 网文模式(保留部分网文常用表达)\n ],\n },\n\n // ========== 规则类 (rule) - 3个 ==========\n {\n id: 'node_target_length',\n name: '目标字数',\n category: 'rule',\n description: '单章/单次生成的目标字数',\n required: true,\n defaultOptionId: 'opt_length_2200',\n options: [\n 'opt_length_1500', // 1500字左右(短章)\n 'opt_length_2200', // 2200字左右(标准章节,默认)\n 'opt_length_3000', // 3000字左右(长章节)\n 'opt_length_4000', // 4000字以上(大章)\n 'opt_length_custom', // 自定义字数\n ],\n },\n {\n id: 'node_anchor_density',\n name: '锚点密度',\n category: 'rule',\n description: '身体锚点(身体反应)的密度要求',\n required: true,\n defaultOptionId: 'opt_anchor_standard',\n options: [\n 'opt_anchor_sparse', // 稀疏锚点(500字以上1个)\n 'opt_anchor_standard', // 标准锚点(300-500字1个,默认)\n 'opt_anchor_dense', // 密集锚点(200字左右1个)\n 'opt_anchor_extreme', // 极高密度(几乎每段都有)\n ],\n },\n {\n id: 'node_strictness',\n name: '检测严格度',\n category: 'rule',\n description: '规则检测的严格程度',\n required: true,\n defaultOptionId: 'opt_strict_standard',\n options: [\n 'opt_strict_lenient', // 宽松模式(只报严重问题)\n 'opt_strict_standard', // 标准模式(默认)\n 'opt_strict_strict', // 严格模式(所有问题都报)\n ],\n },\n\n // ========== 追读力类 (hook) - 3个 V3新增 ==========\n {\n id: 'node_opening_impact',\n name: '开头冲击力',\n category: 'rule',\n description: '控制开头感官轰炸强度,决定读者0.5秒内是否被拽进场景',\n required: true,\n defaultOptionId: 'opt_opening_strong',\n options: [\n 'opt_opening_weak', // 平和切入(慢热,环境描写开头)\n 'opt_opening_medium', // 中等冲击(动作/声音切入,默认)\n 'opt_opening_strong', // 感官轰炸(疼/冷/烫/响第一句,强追读)\n ],\n },\n {\n id: 'node_twist_frequency',\n name: '反咬频率',\n category: 'rule',\n description: '信息反咬/反转密度,每多少字颠覆一次读者预期',\n required: true,\n defaultOptionId: 'opt_twist_standard',\n options: [\n 'opt_twist_sparse', // 稀疏(800字+一次反转,慢热文)\n 'opt_twist_standard', // 标准(300-400字一次反咬,默认)\n 'opt_twist_dense', // 密集(200-250字一次反转,爽文/悬疑)\n ],\n },\n {\n id: 'node_ending_hook',\n name: '章末钩子强度',\n category: 'rule',\n description: '章末钩子强度,决定读者翻下一章的欲望',\n required: true,\n defaultOptionId: 'opt_hook_break',\n options: [\n 'opt_hook_soft', // 平和收束(情绪落点,自然收尾)\n 'opt_hook_suspense', // 悬念钩子(未解问题,默认)\n 'opt_hook_break', // 断裂钩子(新信息颠覆,骂娘断章)\n ],\n },\n\n // ========== AI类 (ai) - 2个 ==========\n {\n id: 'node_ai_creativity',\n name: 'AI创造度',\n category: 'ai',\n description: '控制AI生成时的创造性/温度',\n required: true,\n defaultOptionId: 'opt_ai_balanced',\n options: [\n 'opt_ai_conservative', // 保守模式(temperature低,严格按上下文)\n 'opt_ai_balanced', // 均衡模式(默认)\n 'opt_ai_adventurous', // 放飞模式(temperature高,允许发散)\n ],\n },\n {\n id: 'node_ai_continue_length',\n name: '续写长度',\n category: 'ai',\n description: 'AI单次续写的目标长度',\n required: false,\n defaultOptionId: 'opt_ai_medium',\n options: [\n 'opt_ai_short', // 短续写(约500字)\n 'opt_ai_medium', // 中等续写(约1000-1500字,默认)\n 'opt_ai_long', // 长续写(约2000-3000字)\n 'opt_ai_xtra_long', // 超长续写(4000字以上)\n ],\n },\n];\n\n// ============================================================\n// 注册表内部状态\n// ============================================================\n\n/** 节点定义映射表 */\nconst nodes: Map<NodeId, NodeDefinition> = new Map();\n\n/** 已加载的节点选项(.kb文件数据)映射表 */\nconst options: Map<OptionId, NodeOptionKB> = new Map();\n\n// 初始化:注册所有内置节点\nBUILTIN_NODES.forEach((node) => {\n nodes.set(node.id, node);\n});\n\n// ============================================================\n// 公开API\n// ============================================================\n\n/**\n * 注册一个新节点(通常用于插件扩展)\n * @param def 节点定义\n * @throws 如果节点ID已存在则抛出错误\n */\nexport function registerNode(def: NodeDefinition): void {\n if (nodes.has(def.id)) {\n throw new Error(`[node-registry] 节点 \"${def.id}\" 已存在,无法重复注册`);\n }\n nodes.set(def.id, def);\n}\n\n/**\n * 注册一个节点选项(从.kb.json文件加载)\n * @param kb 选项KB数据\n * @throws 如果选项所属节点不存在则抛出错误\n */\nexport function registerNodeOption(kb: NodeOptionKB): void {\n const node = nodes.get(kb.node_id);\n if (!node) {\n throw new Error(\n `[node-registry] 选项 \"${kb.option_id}\" 所属节点 \"${kb.node_id}\" 不存在`\n );\n }\n // 验证option_id是否在节点的options列表中\n if (!node.options.includes(kb.option_id)) {\n console.warn(\n `[node-registry] 选项 \"${kb.option_id}\" 未在节点 \"${kb.node_id}\" 的预定义列表中,可能为自定义选项`\n );\n }\n options.set(kb.option_id, kb);\n}\n\n/**\n * 获取节点定义\n * @param id 节点ID\n */\nexport function getNode(id: NodeId): NodeDefinition | undefined {\n return nodes.get(id);\n}\n\n/**\n * 获取已加载的节点选项KB数据\n * @param optionId 选项ID\n */\nexport function getNodeOption(optionId: OptionId): NodeOptionKB | undefined {\n return options.get(optionId);\n}\n\n/**\n * 获取所有已注册的节点定义\n * @param category 可选分类过滤\n */\nexport function getAllNodes(category?: NodeCategory): NodeDefinition[] {\n const all = Array.from(nodes.values());\n if (category) {\n return all.filter((n) => n.category === category);\n }\n return all;\n}\n\n/**\n * 获取所有已注册选项的数量\n */\nexport function getRegisteredOptionCount(): number {\n return options.size;\n}\n\n/**\n * 获取默认选项选择集\n * 对每个必选节点使用defaultOptionId,非必选节点不选\n */\nexport function getDefaultSelections(): Partial<Record<NodeId, OptionId>> {\n const selections: Partial<Record<NodeId, OptionId>> = {};\n for (const node of nodes.values()) {\n if (node.required) {\n selections[node.id] = node.defaultOptionId;\n }\n }\n return selections;\n}\n\n/**\n * 获取完整的默认选择(包括非必选节点,也使用默认值)\n */\nexport function getDefaultSelectionsFull(): Record<NodeId, OptionId> {\n const selections = {} as Record<NodeId, OptionId>;\n for (const node of nodes.values()) {\n selections[node.id] = node.defaultOptionId;\n }\n return selections;\n}\n\n/**\n * 按分类获取节点\n */\nexport function getNodesByCategory(category: NodeCategory): NodeDefinition[] {\n return getAllNodes(category);\n}\n\n/**\n * 验证一个selections对象是否完整(所有必选节点都有选择)\n */\nexport function validateSelectionsComplete(\n selections: Partial<Record<NodeId, OptionId>>\n): { complete: boolean; missingNodes: NodeId[] } {\n const missing: NodeId[] = [];\n for (const node of nodes.values()) {\n if (node.required && !selections[node.id]) {\n missing.push(node.id);\n }\n }\n return { complete: missing.length === 0, missingNodes: missing };\n}\n\n/**\n * 重置注册表(主要用于测试)\n */\nexport function _resetRegistry(): void {\n nodes.clear();\n options.clear();\n BUILTIN_NODES.forEach((node) => nodes.set(node.id, node));\n}\n","// ============================================================\n// GWE (Generic Web-novel Engine) 通用网文引擎 - 核心类型定义\n// 节点化架构 V3.0(追读力增强版)\n// ============================================================\n\n// === 节点与选项 ===\n\nexport type NodeCategory = 'style' | 'vocab' | 'rule' | 'ai';\n\nexport interface NodeDefinition {\n readonly id: NodeId;\n readonly name: string;\n readonly category: NodeCategory;\n readonly description: string;\n readonly required: boolean;\n readonly defaultOptionId: string;\n readonly options: OptionId[];\n}\n\nexport type NodeId =\n | 'node_sentence_rhythm'\n | 'node_paragraph_density'\n | 'node_dialogue_style'\n | 'node_description_style'\n | 'node_battle_style'\n | 'node_emotion_style'\n | 'node_tone'\n | 'node_platform'\n | 'node_info_density'\n | 'node_payoff_frequency'\n | 'node_pov'\n | 'node_rhetoric'\n | 'node_vocab_sensory'\n | 'node_vocab_filler'\n | 'node_target_length'\n | 'node_anchor_density'\n | 'node_strictness'\n | 'node_opening_impact'\n | 'node_twist_frequency'\n | 'node_ending_hook'\n | 'node_ai_creativity'\n | 'node_ai_continue_length';\n\nexport type OptionId = string;\n\n/** 节点选项 .kb.json 文件格式 */\nexport interface NodeOptionKB {\n readonly kb_version: '2.0' | '3.0';\n readonly node_id: NodeId;\n readonly option_id: OptionId;\n readonly option_name: string;\n readonly option_description: string;\n\n /** 词汇表:词库类节点使用,其他节点可为空 */\n readonly vocabulary?: {\n readonly add?: {\n readonly bodyParts?: string[];\n readonly sensoryVerbs?: string[];\n readonly environmentSignals?: string[];\n readonly actionVerbs?: string[];\n readonly fillerPatterns?: string[];\n readonly dialogueTags?: string[];\n readonly worldTerms?: string[];\n readonly [category: string]: string[] | undefined;\n };\n readonly remove?: string[];\n };\n\n /** 检测阈值覆盖 */\n readonly threshold_overrides?: Partial<Thresholds>;\n\n /** 雷达权重调整(乘系数) */\n readonly radar_weights?: Partial<RadarWeights>;\n\n /** 启用/禁用检测项 */\n readonly checks?: {\n readonly disable?: string[];\n readonly enable?: string[];\n };\n\n /** AI系统提示词(注入到system prompt) */\n readonly system_prompt?: string;\n\n /** 示例段落(给用户预览,也作为AI的few-shot) */\n readonly examples?: Array<{\n readonly text: string;\n readonly note?: string;\n }>;\n\n /** 约束:AI必须遵守的硬规则 */\n readonly constraints?: string[];\n\n /** 依赖:必须同时选中这些选项才能生效 */\n readonly requires?: OptionId[];\n\n /** 冲突:不能和这些选项同时选中 */\n readonly conflicts?: OptionId[];\n}\n\n// === 检测阈值 ===\n\nexport interface Thresholds {\n // 锚点相关\n minAnchors: number; // 单章最少身体锚点数\n anchorsPerWords: number; // 每多少字至少1个锚点\n maxAnchorGap: number; // 锚点之间最大字数间隔\n\n // 填充词相关\n maxFillerSentences: number; // 填充词句数上限(每千字)\n maxFillerWords: number; // 填充词个数上限(每千字)\n maxDashCount: number; // 破折号数量上限(每千字)\n maxEllipsisCount: number; // 省略号数量上限(每千字)\n\n // 段落相关\n maxParagraphLength: number; // 单段最大字数\n targetParagraphLength: number; // 目标段落长度\n minParagraphCount: number; // 单章最少段落数\n\n // 对话相关\n maxDialogueContinuous: number; // 连续对话最大句数(无动作穿插)\n maxDialogueTagRepeat: number; // 对话标签重复上限(如连续\"XX道\")\n\n // 句子节奏\n maxSentenceLength: number; // 单句最大字数\n targetSentenceLength: number; // 目标句长\n shortSentenceRatio: number; // 短句占比目标\n\n // 信息密度\n maxExpositionContinuous: number; // 连续说明/铺垫最大字数\n infoPointsPerThousand: number; // 每千字新信息点数\n\n // 五感\n minSensoryTypes: number; // 每场景最少激活感官类型数\n sightRatio: number; // 视觉描写占比上限\n}\n\nexport const DEFAULT_THRESHOLDS: Thresholds = {\n minAnchors: 4,\n anchorsPerWords: 500,\n maxAnchorGap: 800,\n maxFillerSentences: 3,\n maxFillerWords: 8,\n maxDashCount: 1, // V3.1:破折号几乎禁用,每千字最多1个(对话打断用),用逗号替代\n maxEllipsisCount: 3,\n maxParagraphLength: 200,\n targetParagraphLength: 80,\n minParagraphCount: 20,\n maxDialogueContinuous: 4,\n maxDialogueTagRepeat: 2,\n maxSentenceLength: 60,\n targetSentenceLength: 22,\n shortSentenceRatio: 0.4,\n maxExpositionContinuous: 300,\n infoPointsPerThousand: 3,\n minSensoryTypes: 2,\n sightRatio: 0.6,\n};\n\n// === 雷达权重 ===\n\nexport interface RadarWeights {\n bodyReaction: number; // 身体反应/锚点\n sensorySignal: number; // 感官信号/环境\n action: number; // 动作推进\n emotion: number; // 情感浓度\n infoAdvance: number; // 信息推进\n twistFrequency: number; // V3: 信息反咬/转折密度\n hookStrength: number; // V3: 章末钩子强度\n}\n\nexport const DEFAULT_RADAR_WEIGHTS: RadarWeights = {\n bodyReaction: 1.0,\n sensorySignal: 1.0,\n action: 1.0,\n emotion: 1.0,\n infoAdvance: 1.0,\n twistFrequency: 1.0,\n hookStrength: 1.0,\n};\n\n// === 预设包 ===\n\nexport interface Preset {\n readonly preset_id: string;\n readonly preset_name: string;\n readonly preset_description: string;\n readonly based_on: string | null;\n\n /** 节点选项选择 */\n readonly selections: Record<NodeId, OptionId>;\n\n /** 预设追加词库 */\n readonly extra_vocab?: NodeOptionKB['vocabulary'];\n\n /** 预设追加提示词 */\n readonly extra_prompt?: string;\n\n /** 预设追加约束 */\n readonly extra_constraints?: string[];\n\n /** 预设专属规则(正则/自定义检查) */\n readonly extra_rules?: CustomRule[];\n\n /** 预设阈值覆盖 */\n readonly threshold_overrides?: Partial<Thresholds>;\n\n /** 封面/标签 */\n readonly tags?: string[];\n}\n\nexport interface CustomRule {\n readonly id: string;\n readonly name: string;\n readonly description: string;\n readonly severity: 'error' | 'warning' | 'info';\n readonly pattern?: string; // 正则模式\n readonly check?: (text: string) => RuleViolation | null;\n readonly injectToPrompt?: boolean;\n}\n\n// === 引擎配置 ===\n\nexport interface EngineConfig {\n presetId: string | null;\n selections: Record<NodeId, OptionId>;\n userOverrides: UserOverrides;\n}\n\nexport interface UserOverrides {\n thresholds?: Partial<Thresholds>;\n vocab?: NodeOptionKB['vocabulary'];\n prompt?: string;\n rules?: CustomRule[];\n targetLength?: number;\n}\n\n// === 写作上下文(书籍数据)===\n\nexport interface WritingContext {\n book: BookMeta;\n characters: Character[];\n settings: Setting[];\n volumes?: Volume[];\n chapters: Chapter[];\n subplots?: Subplot[];\n currentChapterId: string;\n cursorPosition: number;\n selection: TextSelection | null;\n}\n\nexport interface BookMeta {\n id: string;\n title: string;\n author?: string;\n synopsis?: string;\n tags?: string[];\n}\n\nexport interface Character {\n id: string;\n name: string;\n aliases?: string[];\n role: 'protagonist' | 'antagonist' | 'supporting' | 'minor';\n tags?: string[];\n description?: string;\n background?: string;\n relationships?: CharacterRelationship[];\n speechStyle?: string;\n attributes?: Record<string, unknown>;\n}\n\nexport interface CharacterRelationship {\n targetId: string;\n type: string;\n description?: string;\n}\n\nexport interface Setting {\n id: string;\n name: string;\n type: 'world' | 'location' | 'faction' | 'system' | 'item' | 'other';\n description: string;\n attributes?: Record<string, unknown>;\n}\n\nexport interface Volume {\n id: string;\n title: string;\n number: number;\n summary?: string;\n}\n\nexport interface Chapter {\n id: string;\n title: string;\n number: number;\n volumeId?: string;\n content: string;\n wordCount: number;\n summary?: string;\n status: 'draft' | 'writing' | 'done';\n}\n\nexport interface Subplot {\n id: string;\n name: string;\n description: string;\n status: 'active' | 'foreshadowing' | 'resolved';\n relatedCharacterIds?: string[];\n}\n\nexport interface TextSelection {\n from: number;\n to: number;\n text: string;\n}\n\n// === 检测结果 ===\n\nexport interface CheckResult {\n score: number; // 综合得分 0-100\n radarScores: RadarScores; // 7维雷达得分(V3)\n violations: RuleViolation[]; // 违规项\n stats: TextStats; // 文本统计\n passed: boolean; // 是否通过(无error级违规)\n}\n\nexport interface RadarScores {\n bodyReaction: number; // 0-100\n sensorySignal: number;\n action: number;\n emotion: number;\n infoAdvance: number;\n twistFrequency: number; // V3: 信息反咬/转折密度\n hookStrength: number; // V3: 章末钩子强度\n}\n\nexport interface RuleViolation {\n ruleId: string;\n ruleName: string;\n message: string;\n severity: 'error' | 'warning' | 'info';\n position?: { from: number; to: number };\n suggestion?: string;\n}\n\nexport interface TextStats {\n totalChars: number;\n totalWords: number; // 中文字数\n paragraphCount: number;\n avgParagraphLength: number;\n sentenceCount: number;\n avgSentenceLength: number;\n shortSentenceRatio: number;\n anchorCount: number;\n fillerCount: number;\n dialogueRatio: number;\n sensoryMentions: Record<string, number>;\n}\n\n// === LLM Provider ===\n\nexport type ChatRole = 'system' | 'user' | 'assistant';\n\nexport interface ChatMessage {\n role: ChatRole;\n content: string;\n}\n\nexport interface LLMRequest {\n messages: ChatMessage[];\n temperature?: number;\n maxTokens?: number;\n stream?: boolean;\n}\n\nexport interface LLMUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}\n\nexport interface StreamCallbacks {\n onToken: (delta: string) => void;\n onDone: (fullContent: string, usage?: LLMUsage) => void;\n onError: (error: Error) => void;\n}\n\nexport interface LLMProvider {\n readonly name: string;\n chat(request: LLMRequest): Promise<{ content: string; usage?: LLMUsage }>;\n stream(request: LLMRequest, callbacks: StreamCallbacks): Promise<void>;\n}\n\n// === 引擎事件 ===\n\nexport type EngineEventType =\n | 'config:changed'\n | 'config:validated'\n | 'preset:loaded'\n | 'preset:saved'\n | 'preset:deleted'\n | 'check:done'\n | 'ai:token'\n | 'ai:done'\n | 'ai:error'\n | 'rule:violation';\n\nexport interface EngineEvent {\n type: EngineEventType;\n payload?: unknown;\n}\n\nexport type EngineEventListener = (event: EngineEvent) => void;\n\n// === 冲突/依赖验证结果 ===\n\nexport interface ValidationResult {\n valid: boolean;\n conflicts: ConflictInfo[];\n missingDeps: DependencyInfo[];\n}\n\nexport interface ConflictInfo {\n optionA: OptionId;\n optionB: OptionId;\n nodeA: NodeId;\n nodeB: NodeId;\n message: string;\n}\n\nexport interface DependencyInfo {\n optionId: OptionId;\n nodeId: NodeId;\n requiredOption: OptionId;\n message: string;\n}\n\n// === 合并后的运行时配置(内部使用)===\n\nexport interface MergedConfig {\n thresholds: Thresholds;\n radarWeights: RadarWeights;\n vocabulary: MergedVocabulary;\n systemPrompts: string[];\n constraints: string[];\n examples: Array<{ text: string; note?: string }>;\n extraRules: CustomRule[];\n disabledChecks: Set<string>;\n enabledChecks: Set<string>;\n}\n\nexport interface MergedVocabulary {\n bodyParts: Set<string>;\n sensoryVerbs: Set<string>;\n environmentSignals: Set<string>;\n actionVerbs: Set<string>;\n fillerPatterns: Set<string>;\n dialogueTags: Set<string>;\n worldTerms: Set<string>;\n [category: string]: Set<string>;\n}\n","// ============================================================\n// GWE V2.0 - 配置合并器\n// 7层优先级配置合并:默认值 -> 基础词库 -> 词库节点选项 -> 风格/规则选项阈值/权重\n// -> 预设包 -> 用户词库 -> 用户阈值覆盖\n// ============================================================\n\nimport type {\n NodeId,\n OptionId,\n NodeOptionKB,\n Thresholds,\n RadarWeights,\n MergedConfig,\n MergedVocabulary,\n Preset,\n UserOverrides,\n RuleViolation,\n} from './types';\nimport { DEFAULT_THRESHOLDS, DEFAULT_RADAR_WEIGHTS } from './types';\nimport { getAllNodes, getNodeOption } from './node-registry';\n\n// ============================================================\n// 词汇分类标准列表\n// ============================================================\n\nconst VOCAB_CATEGORIES = [\n 'bodyParts',\n 'sensoryVerbs',\n 'environmentSignals',\n 'actionVerbs',\n 'fillerPatterns',\n 'dialogueTags',\n 'worldTerms',\n] as const;\n\n// ============================================================\n// 基础词库(内置最小词库,第二层)\n// ============================================================\n\nexport const BASE_VOCAB: Required<NonNullable<NodeOptionKB['vocabulary']>>['add'] = {\n bodyParts: [\n // 短词优先(高频)\n '头', '脸', '眼', '眉', '鼻', '口', '唇', '舌', '齿', '耳',\n '颈', '肩', '臂', '手', '指', '掌', '胸', '背', '腰', '腹',\n '腿', '脚', '膝', '腕', '肘', '喉', '皮肤',\n // 复合词\n '指尖', '手掌', '手背', '手腕', '手臂', '肩膀', '后颈', '脖颈', '脸颊', '额头',\n '眉心', '眉头', '眼角', '瞳孔', '嘴唇', '嘴角', '下颌', '喉咙', '胸口', '心脏',\n '后背', '脊背', '腹部', '膝盖', '脚踝', '脚尖', '脚底', '毛孔', '汗毛', '发丝',\n '耳根', '鼻翼', '牙关', '拳头', '指节', '太阳穴', '掌心', '虎口',\n '颧骨', '眼眶', '锁骨', '脚跟', '脚趾', '肋骨',\n ],\n sensoryVerbs: [\n // 感官动词(基础动作)\n '看', '望', '瞥', '瞪', '盯', '瞄', '凝视', '注视', '扫视', '环顾',\n '听', '闻', '嗅', '尝', '触', '摸', '碰', '感觉', '感到', '觉得',\n '察觉', '感知',\n // 身体反应/感觉\n '发凉', '发麻', '发热', '发紧', '一跳', '一颤', '一缩', '一紧', '一沉', '一凉', '一麻',\n '狂跳', '抽搐', '紧绷', '绷紧', '僵硬', '酸软', '刺痛', '灼烧', '嗡鸣', '轰鸣',\n '扑通', '咯噔', '紧缩', '揪紧', '翻腾', '翻涌', '窒息', '喘息', '颤抖', '战栗',\n '泛起', '发烫', '灼痛', '酸痛', '冰冷', '滚烫', '湿润', '干燥', '松弛',\n '胀痛', '发痒', '收缩', '悸动',\n // 单字感觉词(高频出现在锚点中)\n '凉', '冷', '热', '烫', '痛', '麻', '痒', '酸', '软', '僵', '紧', '沉',\n ],\n environmentSignals: [\n '光线', '阴影', '风', '雨', '雪', '雾', '气味', '声音', '温度', '寒意',\n '暖意', '潮湿', '干燥', '尘土', '光影', '回声', '寂静', '喧闹', '明亮', '昏暗',\n '光', '影', '声', '响', '微光', '强光', '反光', '光斑', '响动', '异响',\n '脚步声', '呼吸声', '心跳声', '水滴声', '风声', '雨声',\n '月光', '阳光', '灯光', '烛火', '雾气', '寒气', '冷气', '热气',\n ],\n actionVerbs: [\n // 基础单字动作\n '走', '跑', '站', '坐', '躺', '蹲', '跳', '冲', '退', '躲',\n '抓', '握', '推', '拉', '拍', '打', '挥', '劈', '刺', '挡',\n '看', '望', '盯', '瞥', '扫', '转', '抬', '低', '点头', '摇头',\n '说', '道', '问', '答', '喊', '叫', '笑', '哭', '叹', '呼',\n '吸', '吞', '咽', '咬', '抿', '张', '闭', '睁', '眯', '皱',\n // 复合动作词\n '转身', '回头', '抬手', '伸手', '握拳', '松开', '握紧', '皱眉', '眨眼',\n '吸气', '呼气', '屏息', '咳嗽', '叹息', '颤抖', '后退', '前进', '停下', '跨出',\n '扶', '撑', '按', '捏', '踢', '撞', '闪', '避', '仰起', '低下',\n '凑近', '退开', '侧身', '蜷缩', '舒展', '抱紧', '推开', '攥紧', '摩挲', '擦拭',\n '迈', '踏', '跪',\n ],\n fillerPatterns: [\n '不由得', '忍不住', '不禁', '竟然', '居然', '似乎', '好像', '仿佛', '大概',\n '也许', '可能', '应该', '其实', '事实上', '实际上', '说实话', '老实说',\n '怎么说呢', '不得不说', '众所周知', '毫无疑问', '显而易见',\n '非常', '十分', '极其', '很', '有点', '有些',\n ],\n dialogueTags: [\n '道', '说', '问', '答', '喊', '叫', '冷声道', '沉声道', '笑道', '怒道',\n '低声道', '高声道', '厉声道', '淡淡道', '缓缓道', '轻声道', '吼道',\n '低语', '呢喃', '嘟囔',\n ],\n worldTerms: [],\n};\n\n// ============================================================\n// 核心合并函数\n// ============================================================\n\nexport interface MergeOptions {\n /** 节点选择集 */\n selections: Record<NodeId, OptionId>;\n /** 已加载的选项KB数据 */\n loadedOptions: Map<OptionId, NodeOptionKB>;\n /** 预设包(可选) */\n preset?: Preset | null;\n /** 用户自定义覆盖 */\n userOverrides?: UserOverrides;\n /** 从文件加载的基础词库(覆盖硬编码BASE_VOCAB) */\n baseVocabOverride?: Required<NonNullable<NodeOptionKB['vocabulary']>>['add'] | null;\n}\n\n/**\n * 合并所有配置层,生成最终运行时配置\n * 优先级(从低到高):\n * 1. 引擎内置默认值\n * 2. 基础词库\n * 3. 词库类节点选项(vocab.add追加,vocab.remove删除)\n * 4. 风格/规则节点选项的threshold_overrides和radar_weights\n * 5. 预设包extra_vocab和extra_prompt\n * 6. 用户自定义词库追加\n * 7. 用户自定义阈值覆盖\n */\nexport function mergeConfig(options: MergeOptions): MergedConfig {\n const { selections, loadedOptions, preset, userOverrides, baseVocabOverride } = options;\n\n // ---- 第1层:默认值 ----\n let thresholds: Thresholds = { ...DEFAULT_THRESHOLDS };\n let radarWeights: RadarWeights = { ...DEFAULT_RADAR_WEIGHTS };\n\n // ---- 初始化词汇表(第2层基础词库将在下面合并)----\n const vocabulary = createEmptyVocabulary();\n\n const systemPrompts: string[] = [];\n const constraints: string[] = [];\n const examples: Array<{ text: string; note?: string }> = [];\n const extraRules: Array<{ id: string; name: string; description: string; severity: 'error' | 'warning' | 'info'; pattern?: string; check?: (text: string) => RuleViolation | null; injectToPrompt?: boolean }> = [];\n const disabledChecks = new Set<string>();\n const enabledChecks = new Set<string>();\n\n // ---- 第2层:合并基础词库 ----\n // 先合并硬编码内置词库(保底),再合并从base-vocab.json加载的外部基础词库\n mergeVocabAdd(vocabulary, BASE_VOCAB);\n if (baseVocabOverride) {\n mergeVocabAdd(vocabulary, baseVocabOverride);\n }\n\n // ---- 收集所有选中的选项KB,按节点顺序处理 ----\n const allNodes = getAllNodes();\n const selectedKBs: NodeOptionKB[] = [];\n\n for (const node of allNodes) {\n const optionId = selections[node.id];\n if (!optionId) continue;\n\n // 优先从传入的loadedOptions中取,否则从全局注册表取\n let kb = loadedOptions.get(optionId);\n if (!kb) {\n kb = getNodeOption(optionId);\n }\n if (kb) {\n selectedKBs.push(kb);\n }\n }\n\n // ---- 第3层:词库类节点选项(vocab类节点先处理词库增删)----\n for (const kb of selectedKBs) {\n const nodeDef = allNodes.find((n) => n.id === kb.node_id);\n if (!nodeDef) continue;\n\n if (kb.vocabulary) {\n if (kb.vocabulary.add) {\n mergeVocabAdd(vocabulary, kb.vocabulary.add);\n }\n if (kb.vocabulary.remove) {\n mergeVocabRemove(vocabulary, kb.vocabulary.remove);\n }\n }\n }\n\n // ---- 第4层:风格/规则节点选项的threshold_overrides和radar_weights ----\n // 按节点顺序处理,后面的覆盖前面的,radar_weights乘法叠加\n for (const kb of selectedKBs) {\n const nodeDef = allNodes.find((n) => n.id === kb.node_id);\n if (!nodeDef) continue;\n\n // 阈值覆盖(直接覆盖)\n if (kb.threshold_overrides) {\n thresholds = { ...thresholds, ...kb.threshold_overrides };\n }\n\n // 雷达权重(乘法叠加)\n if (kb.radar_weights) {\n radarWeights = multiplyRadarWeights(radarWeights, kb.radar_weights);\n }\n\n // 启用/禁用检测项\n if (kb.checks) {\n kb.checks.disable?.forEach((c) => disabledChecks.add(c));\n kb.checks.enable?.forEach((c) => enabledChecks.add(c));\n }\n\n // 收集system_prompt、constraints、examples(后续拼装时用)\n if (kb.system_prompt) {\n systemPrompts.push(kb.system_prompt);\n }\n if (kb.constraints) {\n constraints.push(...kb.constraints);\n }\n if (kb.examples) {\n examples.push(...kb.examples);\n }\n }\n\n // ---- 第5层:预设包 ----\n if (preset) {\n if (preset.extra_vocab) {\n if (preset.extra_vocab.add) {\n mergeVocabAdd(vocabulary, preset.extra_vocab.add);\n }\n if (preset.extra_vocab.remove) {\n mergeVocabRemove(vocabulary, preset.extra_vocab.remove);\n }\n }\n if (preset.extra_constraints) {\n constraints.push(...preset.extra_constraints);\n }\n if (preset.extra_rules) {\n extraRules.push(...preset.extra_rules);\n }\n // 预设的阈值覆盖\n if (preset.threshold_overrides) {\n thresholds = { ...thresholds, ...preset.threshold_overrides };\n }\n // extra_prompt在prompt-builder中使用,这里不处理\n }\n\n // ---- 第6层:用户自定义词库追加 ----\n if (userOverrides?.vocab) {\n if (userOverrides.vocab.add) {\n mergeVocabAdd(vocabulary, userOverrides.vocab.add);\n }\n if (userOverrides.vocab.remove) {\n mergeVocabRemove(vocabulary, userOverrides.vocab.remove);\n }\n }\n\n // ---- 第7层:用户自定义阈值覆盖 ----\n if (userOverrides?.thresholds) {\n thresholds = { ...thresholds, ...userOverrides.thresholds };\n }\n\n // 用户自定义规则\n if (userOverrides?.rules) {\n extraRules.push(...userOverrides.rules);\n }\n\n return {\n thresholds,\n radarWeights,\n vocabulary,\n systemPrompts,\n constraints,\n examples,\n extraRules,\n disabledChecks,\n enabledChecks,\n };\n}\n\n// ============================================================\n// 辅助函数\n// ============================================================\n\n/** 创建空词汇表 */\nfunction createEmptyVocabulary(): MergedVocabulary {\n const vocab: Record<string, Set<string>> = {};\n for (const cat of VOCAB_CATEGORIES) {\n vocab[cat] = new Set<string>();\n }\n return vocab as MergedVocabulary;\n}\n\n/** 追加词汇(Set自动去重) */\nfunction mergeVocabAdd(\n target: MergedVocabulary,\n add: Record<string, string[] | undefined>\n): void {\n for (const [category, words] of Object.entries(add)) {\n if (!words || !Array.isArray(words)) continue;\n if (!target[category]) {\n target[category] = new Set<string>();\n }\n for (const word of words) {\n if (word && typeof word === 'string') {\n target[category].add(word);\n }\n }\n }\n}\n\n/** 删除词汇(从所有分类中移除指定词) */\nfunction mergeVocabRemove(\n target: MergedVocabulary,\n remove: string[]\n): void {\n for (const word of remove) {\n for (const cat of Object.keys(target)) {\n target[cat].delete(word);\n }\n }\n}\n\n/** 雷达权重乘法叠加 */\nfunction multiplyRadarWeights(\n base: RadarWeights,\n override: Partial<RadarWeights>\n): RadarWeights {\n return {\n bodyReaction: override.bodyReaction != null ? base.bodyReaction * override.bodyReaction : base.bodyReaction,\n sensorySignal: override.sensorySignal != null ? base.sensorySignal * override.sensorySignal : base.sensorySignal,\n action: override.action != null ? base.action * override.action : base.action,\n emotion: override.emotion != null ? base.emotion * override.emotion : base.emotion,\n infoAdvance: override.infoAdvance != null ? base.infoAdvance * override.infoAdvance : base.infoAdvance,\n twistFrequency: override.twistFrequency != null ? base.twistFrequency * override.twistFrequency : base.twistFrequency,\n hookStrength: override.hookStrength != null ? base.hookStrength * override.hookStrength : base.hookStrength,\n };\n}\n\n/**\n * 深拷贝一个MergedConfig(主要用于测试或快照)\n */\nexport function cloneMergedConfig(config: MergedConfig): MergedConfig {\n const vocab: Record<string, Set<string>> = {};\n for (const [key, set] of Object.entries(config.vocabulary)) {\n vocab[key] = new Set(set);\n }\n return {\n thresholds: { ...config.thresholds },\n radarWeights: { ...config.radarWeights },\n vocabulary: vocab as MergedVocabulary,\n systemPrompts: [...config.systemPrompts],\n constraints: [...config.constraints],\n examples: config.examples.map((e) => ({ ...e })),\n extraRules: [...config.extraRules],\n disabledChecks: new Set(config.disabledChecks),\n enabledChecks: new Set(config.enabledChecks),\n };\n}\n","// ============================================================\n// GWE V2.0 - 冲突/依赖验证器\n// 验证选项间的依赖(requires)和冲突(conflicts)关系\n// ============================================================\n\nimport type {\n NodeId,\n OptionId,\n NodeOptionKB,\n ValidationResult,\n ConflictInfo,\n DependencyInfo,\n} from './types';\nimport { getAllNodes, getNodeOption } from './node-registry';\n\n/**\n * 验证当前选项选择是否合法\n * @param selections 用户选择的节点->选项映射\n * @param loadedOptions 已加载的选项KB数据(如果不传则从全局注册表取)\n * @returns ValidationResult 包含conflicts和missingDeps列表\n */\nexport function validate(\n selections: Record<NodeId, OptionId>,\n loadedOptions?: Map<OptionId, NodeOptionKB>\n): ValidationResult {\n const conflicts: ConflictInfo[] = [];\n const missingDeps: DependencyInfo[] = [];\n\n // 收集所有被选中的optionId集合\n const selectedOptionIds = new Set<OptionId>(Object.values(selections));\n\n // 构建 optionId -> nodeId 反向映射(用于错误提示)\n const optionToNode = new Map<OptionId, NodeId>();\n for (const [nodeId, optionId] of Object.entries(selections)) {\n optionToNode.set(optionId, nodeId as NodeId);\n }\n\n // 遍历所有选中的选项,检查requires和conflicts\n for (const [nodeId, optionId] of Object.entries(selections)) {\n const nid = nodeId as NodeId;\n\n // 获取选项KB数据\n let kb = loadedOptions?.get(optionId);\n if (!kb) {\n kb = getNodeOption(optionId);\n }\n if (!kb) {\n // 选项KB未加载,跳过(可能是用户还没加载对应的.kb文件)\n continue;\n }\n\n // ---- 检查依赖(requires) ----\n if (kb.requires && kb.requires.length > 0) {\n for (const requiredOpt of kb.requires) {\n if (!selectedOptionIds.has(requiredOpt)) {\n const reqNodeId = findNodeForOption(requiredOpt) || nid;\n missingDeps.push({\n optionId,\n nodeId: nid,\n requiredOption: requiredOpt,\n message: `选项 \"${optionId}\" (节点 ${nid}) 依赖选项 \"${requiredOpt}\" (节点 ${reqNodeId}),但该选项未被选中`,\n });\n }\n }\n }\n\n // ---- 检查冲突(conflicts) ----\n if (kb.conflicts && kb.conflicts.length > 0) {\n for (const conflictOpt of kb.conflicts) {\n if (selectedOptionIds.has(conflictOpt)) {\n const conflictNodeId = optionToNode.get(conflictOpt) || findNodeForOption(conflictOpt) || nid;\n // 避免重复记录(A和B冲突只记录一次)\n const alreadyRecorded = conflicts.some(\n (c) =>\n (c.optionA === optionId && c.optionB === conflictOpt) ||\n (c.optionA === conflictOpt && c.optionB === optionId)\n );\n if (!alreadyRecorded) {\n conflicts.push({\n optionA: optionId,\n optionB: conflictOpt,\n nodeA: nid,\n nodeB: conflictNodeId,\n message: `选项 \"${optionId}\" (节点 ${nid}) 与选项 \"${conflictOpt}\" (节点 ${conflictNodeId}) 冲突,不能同时选中`,\n });\n }\n }\n }\n }\n }\n\n return {\n valid: conflicts.length === 0 && missingDeps.length === 0,\n conflicts,\n missingDeps,\n };\n}\n\n/**\n * 根据optionId查找它所属的nodeId\n * 遍历所有节点定义,查找options列表中包含该optionId的节点\n */\nfunction findNodeForOption(optionId: OptionId): NodeId | null {\n const allNodes = getAllNodes();\n for (const node of allNodes) {\n if (node.options.includes(optionId)) {\n return node.id;\n }\n }\n return null;\n}\n\n/**\n * 格式化验证结果为人类可读字符串(用于UI提示)\n */\nexport function formatValidationResult(result: ValidationResult): string {\n if (result.valid) {\n return '配置验证通过,无冲突或缺失依赖。';\n }\n\n const lines: string[] = [];\n\n if (result.missingDeps.length > 0) {\n lines.push(`【缺失依赖】(${result.missingDeps.length}项)`);\n for (const dep of result.missingDeps) {\n lines.push(` - ${dep.message}`);\n }\n }\n\n if (result.conflicts.length > 0) {\n if (lines.length > 0) lines.push('');\n lines.push(`【选项冲突】(${result.conflicts.length}项)`);\n for (const c of result.conflicts) {\n lines.push(` - ${c.message}`);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * 快速检查:某个optionId是否可以安全选中\n * 返回true表示无冲突且依赖满足\n */\nexport function canSelectOption(\n optionId: OptionId,\n selections: Record<NodeId, OptionId>,\n loadedOptions?: Map<OptionId, NodeOptionKB>\n): { canSelect: boolean; reason?: string } {\n // 模拟将该选项加入selections\n const nodeId = findNodeForOption(optionId);\n if (!nodeId) {\n return { canSelect: false, reason: `选项 \"${optionId}\" 不属于任何已注册节点` };\n }\n\n const testSelections = { ...selections, [nodeId]: optionId };\n const result = validate(testSelections, loadedOptions);\n\n if (!result.valid) {\n const issues: string[] = [];\n result.conflicts.forEach((c) => {\n if (c.optionA === optionId || c.optionB === optionId) {\n issues.push(c.message);\n }\n });\n result.missingDeps.forEach((d) => {\n if (d.optionId === optionId) {\n issues.push(d.message);\n }\n });\n return {\n canSelect: false,\n reason: issues.join('; ') || '存在未知冲突或依赖问题',\n };\n }\n\n return { canSelect: true };\n}\n","// ============================================================\n// GWE V3.0 - 身体锚点检测器(追读力增强版)\n// 识别\"身体部位+感官/动作动词\"的组合作为身体反应锚点\n// V3升级:套路反应降权,生理反应加权,返回质量加权后的有效锚点数\n// ============================================================\n\nimport type { MergedVocabulary } from './types';\n\n// ============================================================\n// 锚点检测结果类型\n// ============================================================\n\nexport interface AnchorDetectionResult {\n /** 检测到的锚点总数 */\n count: number;\n /** 质量加权后的有效锚点数(套路反应0.3倍,生理反应1.5倍) */\n weightedCount: number;\n /** 锚点在文本中的起始位置列表 */\n positions: number[];\n /** 按锚点类型分类的统计 */\n types: Record<string, number>;\n /** 按质量分级的统计:套路/普通/高质量 */\n quality: Record<string, number>;\n /** 检测到的锚点文本片段列表 */\n matches: string[];\n}\n\n// ============================================================\n// 锚点类型常量\n// ============================================================\n\nconst ANCHOR_TYPE = {\n BODY_SENSORY: 'body_sensory', // 身体部位+感官动词(如指尖发凉)\n BODY_ACTION: 'body_action', // 身体部位+动作动词(如拳头握紧)\n BODY_STATE: 'body_state', // 身体部位+状态(如心跳加速)\n} as const;\n\nconst ANCHOR_QUALITY = {\n CLICHE: 'cliche', // 套路反应(降权×0.3):微微一笑、点点头、叹了口气\n NORMAL: 'normal', // 普通反应(权重×1.0)\n QUALITY: 'quality', // 高质量生理反应(加权×1.5):后颈发凉、指节发白、胃里翻涌\n} as const;\n\n/** 锚点匹配窗口:身体部位词和动词之间的最大字符距离(前后各MAX_ANCHOR_GAP个字符内) */\nconst MAX_ANCHOR_GAP = 10;\n\n// ============================================================\n// V3新增:锚点质量分级词表\n// ============================================================\n\n/** 套路反应词(降权×0.2)——网文高频套路化身体反应,Tell not Show */\nconst CLICHE_PHRASES = [\n '微微一笑', '淡淡一笑', '笑了笑', '笑了一下', '点了点头', '点点头',\n '叹了口气', '叹了一声', '摇了摇头', '皱了皱眉', '眉头一皱', '眉头紧锁',\n '嘴角微扬', '嘴角上扬', '勾起嘴角', '抿了抿嘴', '撇了撇嘴', '翻了个白眼',\n '冷哼一声', '冷笑一声', '嗤笑一声', '轻笑一声', '苦笑一声',\n '深吸一口气', '深吸了口气', '松了口气', '松了一口气', '心中一动',\n '目光一闪', '眼中闪过一丝', '眼中寒光一闪', '嘴角露出一丝', '脸上露出一丝',\n '不由得', '不由自主地', '下意识地', '缓缓地说', '淡淡地说', '冷冷地说',\n '紧紧握着拳头', '握紧了拳头', '打量了一番', '上下打量',\n];\n\n/** 高质量生理反应词(加权×1.8)——能直接传递情绪/紧张感的具象不自主生理描写 */\nconst QUALITY_MARKERS = [\n '发凉', '发冷', '发紧', '发麻', '发烫', '发热', '冒汗', '冷汗', '汗水顺着',\n '心跳加速', '心跳漏了一拍', '心脏骤停', '心提到了嗓子眼', '心脏狂跳', '心悸',\n '指节发白', '指节泛白', '指甲掐进', '攥紧', '捏紧', '手背青筋暴起',\n '后颈发凉', '后背发凉', '脊背发寒', '寒毛竖起', '汗毛倒竖', '鸡皮疙瘩',\n '喉咙发紧', '喉头滚动', '咽了口唾沫', '口干舌燥', '嘴里发苦', '胃里翻涌',\n '胃里一阵痉挛', '呼吸一滞', '呼吸急促', '屏住呼吸', '窒息感', '眼前一黑',\n '一阵眩晕', '天旋地转', '腿软', '膝盖发软', '脚底发软', '脚下一滑',\n '血液凝固', '血液冲上头顶', '血往头上涌', '浑身僵硬', '全身僵住', '动弹不得',\n '瞳孔一缩', '瞳孔骤缩', '瞳孔收缩', '牙咬紧', '牙关紧咬', '嘴唇哆嗦',\n '手指发抖', '手在抖', '声音发颤', '声音发抖', '肠子悔青了', '后背全是汗',\n '耳膜嗡嗡', '耳朵嗡嗡响', '太阳穴突突跳', '胃里一阵抽搐', '舌头根发硬',\n '硌得掌心生疼', '金属硌得', '烫得一缩手', '疼得倒吸凉气',\n];\n\n// ============================================================\n// 内部接口定义\n// ============================================================\n\ninterface BodyPartOccurrence {\n word: string;\n start: number;\n end: number;\n}\n\ninterface MatchedAnchor {\n start: number;\n end: number;\n text: string;\n type: string;\n quality: string;\n}\n\ntype Direction = 'before' | 'after';\n\n// ============================================================\n// 核心检测函数\n// ============================================================\n\n/**\n * 检测文本中的身体锚点\n * 锚点定义:身体部位词 + (0~MAX_ANCHOR_GAP个字符内) 感官动词或动作动词\n *\n * @param text 待检测文本\n * @param vocab 合并后的词库(含bodyParts, sensoryVerbs, actionVerbs)\n * @returns AnchorDetectionResult\n */\nexport function detectAnchors(\n text: string,\n vocab: MergedVocabulary\n): AnchorDetectionResult {\n const types: Record<string, number> = {\n [ANCHOR_TYPE.BODY_SENSORY]: 0,\n [ANCHOR_TYPE.BODY_ACTION]: 0,\n [ANCHOR_TYPE.BODY_STATE]: 0,\n };\n\n const quality: Record<string, number> = {\n [ANCHOR_QUALITY.CLICHE]: 0,\n [ANCHOR_QUALITY.NORMAL]: 0,\n [ANCHOR_QUALITY.QUALITY]: 0,\n };\n\n const bodyParts = vocab.bodyParts || new Set<string>();\n const sensoryVerbs = vocab.sensoryVerbs || new Set<string>();\n const actionVerbs = vocab.actionVerbs || new Set<string>();\n\n if (bodyParts.size === 0) {\n return { count: 0, weightedCount: 0, positions: [], types, quality, matches: [] };\n }\n\n // 将词表转为排序后的数组(长词优先匹配,避免\"手指\"被\"手\"先匹配)\n const sortedBodyParts = Array.from(bodyParts).sort((a, b) => b.length - a.length);\n const sortedSensoryVerbs = Array.from(sensoryVerbs).sort((a, b) => b.length - a.length);\n const sortedActionVerbs = Array.from(actionVerbs).sort((a, b) => b.length - a.length);\n\n // 收集所有身体部位的位置\n const bodyPartOccurrences: Array<{ word: string; start: number; end: number }> = [];\n for (const bp of sortedBodyParts) {\n let idx = 0;\n while ((idx = text.indexOf(bp, idx)) !== -1) {\n bodyPartOccurrences.push({ word: bp, start: idx, end: idx + bp.length });\n idx += bp.length; // 前进避免重叠匹配\n }\n }\n\n // 按位置排序\n bodyPartOccurrences.sort((a, b) => a.start - b.start);\n\n // 去除重叠的身体部位匹配(保留先匹配的/更长的)\n const filteredBPs: Array<{ word: string; start: number; end: number }> = [];\n for (const bp of bodyPartOccurrences) {\n const overlaps = filteredBPs.some(\n (prev) => !(bp.end <= prev.start || bp.start >= prev.end)\n );\n if (!overlaps) {\n filteredBPs.push(bp);\n }\n }\n\n // 对每个身体部位,查找附近(前面+后面)的感官/动作动词\n // 存储已匹配的锚点区间,用于去重\n const matchedAnchors: MatchedAnchor[] = [];\n\n for (const bp of filteredBPs) {\n // 搜索范围:身体部位前后各MAX_ANCHOR_GAP+maxWordLength个字符\n const maxVerbLen = Math.max(\n maxWordLength(sortedSensoryVerbs),\n maxWordLength(sortedActionVerbs)\n );\n\n // ---- 先在身体部位**后面**查找 ----\n const afterSearchStart = bp.end;\n const afterSearchEnd = Math.min(text.length, bp.end + MAX_ANCHOR_GAP + maxVerbLen);\n const afterWindow = text.substring(afterSearchStart, afterSearchEnd);\n\n let foundAfter = findMatchingVerb(\n afterWindow, sortedSensoryVerbs, sortedActionVerbs, afterSearchStart, bp, 'after', text, matchedAnchors\n );\n if (foundAfter) {\n matchedAnchors.push(foundAfter);\n continue;\n }\n\n // ---- 再在身体部位**前面**查找(动词在前,身体部位在后,如\"低头\"、\"抬手\"、\"凉了的指尖\")----\n const beforeSearchStart = Math.max(0, bp.start - MAX_ANCHOR_GAP - maxVerbLen);\n const beforeWindow = text.substring(beforeSearchStart, bp.start);\n\n const foundBefore = findMatchingVerb(\n beforeWindow, sortedSensoryVerbs, sortedActionVerbs, beforeSearchStart, bp, 'before', text, matchedAnchors\n );\n if (foundBefore) {\n matchedAnchors.push(foundBefore);\n }\n }\n\n // 按位置排序结果并去重\n matchedAnchors.sort((a, b) => a.start - b.start);\n\n // 去重:去除重叠的锚点(保留先匹配的/更长的)\n const finalAnchors: typeof matchedAnchors = [];\n for (const anchor of matchedAnchors) {\n const overlaps = finalAnchors.some(\n (prev) => !(anchor.end <= prev.start || anchor.start >= prev.end)\n );\n if (!overlaps) {\n finalAnchors.push(anchor);\n }\n }\n\n // 构建返回结果\n const positions: number[] = [];\n const matches: string[] = [];\n let weightedCount = 0;\n for (const anchor of finalAnchors) {\n positions.push(anchor.start);\n matches.push(anchor.text);\n types[anchor.type]++;\n quality[anchor.quality]++;\n // 计算加权计数\n if (anchor.quality === ANCHOR_QUALITY.CLICHE) {\n weightedCount += 0.2;\n } else if (anchor.quality === ANCHOR_QUALITY.QUALITY) {\n weightedCount += 1.8;\n } else {\n weightedCount += 1.0;\n }\n }\n\n return {\n count: finalAnchors.length,\n weightedCount: Math.round(weightedCount * 10) / 10,\n positions: finalAnchors.map((a) => a.start),\n types,\n quality,\n matches: finalAnchors.map((a) => a.text),\n };\n}\n\n// ============================================================\n// 辅助函数\n// ============================================================\n\n/**\n * 判断锚点质量等级\n */\nfunction classifyAnchorQuality(anchorText: string): string {\n // 先检查是否包含套路短语\n for (const cliche of CLICHE_PHRASES) {\n if (anchorText.includes(cliche)) {\n return ANCHOR_QUALITY.CLICHE;\n }\n }\n // 再检查是否包含高质量生理反应标记\n for (const marker of QUALITY_MARKERS) {\n if (anchorText.includes(marker)) {\n return ANCHOR_QUALITY.QUALITY;\n }\n }\n return ANCHOR_QUALITY.NORMAL;\n}\n\n/**\n * 在搜索窗口中查找与身体部位匹配的感官/动作动词\n * @returns 找到的锚点信息,或null\n */\nfunction findMatchingVerb(\n searchWin: string,\n sortedSensoryVerbs: string[],\n sortedActionVerbs: string[],\n windowStartInText: number,\n bp: BodyPartOccurrence,\n direction: Direction,\n fullText: string,\n existingAnchors: MatchedAnchor[]\n): MatchedAnchor | null {\n // 先检查感官动词(优先级更高,是核心锚点)\n const sensoryMatch = findBestVerbMatch(\n searchWin, sortedSensoryVerbs, windowStartInText, bp, direction, fullText, existingAnchors, ANCHOR_TYPE.BODY_SENSORY\n );\n if (sensoryMatch) return sensoryMatch;\n\n // 再检查动作动词\n const actionMatch = findBestVerbMatch(\n searchWin, sortedActionVerbs, windowStartInText, bp, direction, fullText, existingAnchors, ANCHOR_TYPE.BODY_ACTION\n );\n if (actionMatch) return actionMatch;\n\n return null;\n}\n\n/**\n * 在窗口中查找最佳(距离最近的)动词匹配\n */\nfunction findBestVerbMatch(\n searchWin: string,\n sortedVerbs: string[],\n windowStartInText: number,\n bp: BodyPartOccurrence,\n direction: Direction,\n fullText: string,\n existingAnchors: MatchedAnchor[],\n anchorType: string\n): MatchedAnchor | null {\n let best: MatchedAnchor | null = null;\n let bestGap = Infinity;\n\n for (const verb of sortedVerbs) {\n let searchIdx = 0;\n while (true) {\n const idxInWindow = searchWin.indexOf(verb, searchIdx);\n if (idxInWindow === -1) break;\n\n const verbStartInText = windowStartInText + idxInWindow;\n const verbEndInText = verbStartInText + verb.length;\n\n // 计算gap\n const gap = direction === 'after'\n ? verbStartInText - bp.end\n : bp.start - verbEndInText;\n\n if (gap >= 0 && gap <= MAX_ANCHOR_GAP) {\n const anchorStart = direction === 'after' ? bp.start : verbStartInText;\n const anchorEnd = direction === 'after' ? verbEndInText : bp.end;\n\n // 检查重叠\n const overlaps = existingAnchors.some(\n (prev) => !(anchorEnd <= prev.start || anchorStart >= prev.end)\n );\n if (!overlaps && gap < bestGap) {\n bestGap = gap;\n const anchorText = fullText.substring(anchorStart, anchorEnd);\n best = {\n start: anchorStart,\n end: anchorEnd,\n text: anchorText,\n type: anchorType,\n quality: classifyAnchorQuality(anchorText),\n };\n }\n }\n\n searchIdx = idxInWindow + 1;\n }\n }\n\n return best;\n}\n\n/** 计算词表中最长词的长度 */\nfunction maxWordLength(words: string[]): number {\n let max = 0;\n for (const w of words) {\n if (w.length > max) max = w.length;\n }\n return max;\n}\n\n/**\n * 计算锚点密度(每千字锚点数)\n */\nexport function calculateAnchorDensity(count: number, totalChars: number): number {\n if (totalChars === 0) return 0;\n return (count / totalChars) * 1000;\n}\n\n/**\n * 计算锚点间最大间隔(字数)\n */\nexport function calculateMaxAnchorGap(\n positions: number[],\n totalChars: number\n): number {\n if (positions.length === 0) return totalChars;\n\n let maxGap = positions[0]; // 从开头到第一个锚点的距离\n for (let i = 1; i < positions.length; i++) {\n const gap = positions[i] - positions[i - 1];\n if (gap > maxGap) maxGap = gap;\n }\n // 最后一个锚点到结尾\n const endGap = totalChars - positions[positions.length - 1];\n if (endGap > maxGap) maxGap = endGap;\n\n return maxGap;\n}\n","// ============================================================\n// GWE V2.0 - 填充词检测器\n// 检测冗余填充词、过多标点、重复对话标签等问题\n// ============================================================\n\nimport type { MergedVocabulary, Thresholds } from './types';\n\n// ============================================================\n// 填充词检测结果类型\n// ============================================================\n\nexport interface FillerDetectionResult {\n /** 检测到的填充词总数 */\n count: number;\n /** 包含填充词的句子列表 */\n sentences: string[];\n /** 填充词在文本中的位置列表 */\n positions: number[];\n /** 破折号\"——\"出现次数 */\n dashCount: number;\n /** 省略号\"……\"出现次数 */\n ellipsisCount: number;\n /** 重复对话标签信息 */\n repeatedTags: Array<{\n tag: string;\n count: number;\n positions: number[];\n }>;\n /** 检测到的填充词详情(词+位置) */\n fillerDetails: Array<{\n word: string;\n position: number;\n }>;\n}\n\n// ============================================================\n// 句子切分正则(中文句子结束符)\n// ============================================================\n\nconst SENTENCE_ENDINGS = /[。!?!?\\n]/g;\n\n/**\n * 将文本切分为句子列表,返回句子文本和起始位置\n */\nfunction splitSentences(text: string): Array<{ text: string; start: number; end: number }> {\n const sentences: Array<{ text: string; start: number; end: number }> = [];\n let start = 0;\n let match: RegExpExecArray | null;\n\n const re = new RegExp(SENTENCE_ENDINGS.source, 'g');\n while ((match = re.exec(text)) !== null) {\n const end = match.index + match[0].length;\n const sentText = text.substring(start, end).trim();\n if (sentText.length > 0) {\n sentences.push({ text: sentText, start, end });\n }\n start = end;\n }\n\n // 最后一段(可能没有结束符)\n if (start < text.length) {\n const sentText = text.substring(start).trim();\n if (sentText.length > 0) {\n sentences.push({ text: sentText, start, end: text.length });\n }\n }\n\n return sentences;\n}\n\n// ============================================================\n// 核心检测函数\n// ============================================================\n\n/**\n * 检测文本中的填充词和相关问题\n *\n * @param text 待检测文本\n * @param vocab 合并后的词库\n * @param thresholds 检测阈值(用于对话标签重复判断)\n * @returns FillerDetectionResult\n */\nexport function detectFillers(\n text: string,\n vocab: MergedVocabulary,\n thresholds: Thresholds\n): FillerDetectionResult {\n const sentences: string[] = [];\n const positions: number[] = [];\n const fillerDetails: Array<{ word: string; position: number }> = [];\n const fillerPatterns = vocab.fillerPatterns || new Set<string>();\n const dialogueTags = vocab.dialogueTags || new Set<string>();\n\n // ---- 1. 检测填充词模式 ----\n const sortedPatterns = Array.from(fillerPatterns).sort((a, b) => b.length - a.length);\n const foundPositions = new Set<number>(); // 避免同一位置重复计数\n\n for (const pattern of sortedPatterns) {\n let idx = 0;\n while ((idx = text.indexOf(pattern, idx)) !== -1) {\n // 检查是否与已发现的位置重叠\n let overlaps = false;\n for (let p = idx; p < idx + pattern.length; p++) {\n if (foundPositions.has(p)) {\n overlaps = true;\n break;\n }\n }\n if (!overlaps) {\n fillerDetails.push({ word: pattern, position: idx });\n positions.push(idx);\n // 标记该区域已匹配\n for (let p = idx; p < idx + pattern.length; p++) {\n foundPositions.add(p);\n }\n }\n idx += pattern.length;\n }\n }\n\n // ---- 2. 检测破折号和省略号 ----\n let dashCount = 0;\n let ellipsisCount = 0;\n\n {\n let idx = 0;\n while ((idx = text.indexOf('——', idx)) !== -1) {\n dashCount++;\n idx += 2;\n }\n }\n {\n let idx = 0;\n while ((idx = text.indexOf('……', idx)) !== -1) {\n ellipsisCount++;\n idx += 2;\n }\n }\n\n // 也统计半角省略号...\n {\n const dotsRegex = /\\.{3,}/g;\n while (dotsRegex.exec(text) !== null) {\n ellipsisCount++;\n }\n }\n\n // ---- 3. 检测连续相同对话标签 ----\n const repeatedTags: Array<{ tag: string; count: number; positions: number[] }> = [];\n const maxRepeat = thresholds.maxDialogueTagRepeat || 2;\n\n for (const tag of dialogueTags) {\n const tagPositions: number[] = [];\n let idx = 0;\n while ((idx = text.indexOf(tag, idx)) !== -1) {\n // 确保是独立的对话标签(前面不是普通文字组成部分)\n // 简单启发式:标签前一个字符如果是引号或逗号或换行或开头,就算\n const charBefore = idx > 0 ? text[idx - 1] : '';\n if (\n idx === 0 ||\n charBefore === '\"' ||\n charBefore === '\"' ||\n charBefore === '「' ||\n charBefore === '」' ||\n charBefore === ',' ||\n charBefore === ',' ||\n charBefore === '\\n' ||\n charBefore === ' '\n ) {\n tagPositions.push(idx);\n }\n idx += tag.length;\n }\n\n // 检查连续出现(在相邻句子中)\n if (tagPositions.length > maxRepeat) {\n // 将句子切分,看标签在句子中的分布\n const sents = splitSentences(text);\n const tagSentenceIndices: number[] = [];\n\n for (const tp of tagPositions) {\n for (let si = 0; si < sents.length; si++) {\n if (tp >= sents[si].start && tp < sents[si].end) {\n if (!tagSentenceIndices.includes(si)) {\n tagSentenceIndices.push(si);\n }\n break;\n }\n }\n }\n\n // 检查连续句子索引\n let consecutiveCount = 1;\n let maxConsecutive = 1;\n let consecutiveStart = tagSentenceIndices[0];\n\n for (let i = 1; i < tagSentenceIndices.length; i++) {\n if (tagSentenceIndices[i] === tagSentenceIndices[i - 1] + 1) {\n consecutiveCount++;\n maxConsecutive = Math.max(maxConsecutive, consecutiveCount);\n } else {\n if (consecutiveCount > maxRepeat) {\n repeatedTags.push({\n tag,\n count: consecutiveCount,\n positions: tagPositions.slice(\n tagSentenceIndices.indexOf(consecutiveStart),\n i\n ),\n });\n }\n consecutiveCount = 1;\n consecutiveStart = tagSentenceIndices[i];\n }\n }\n // 最后一段\n if (consecutiveCount > maxRepeat) {\n repeatedTags.push({\n tag,\n count: consecutiveCount,\n positions: tagPositions.slice(-consecutiveCount),\n });\n }\n }\n }\n\n // ---- 4. 找出包含填充词的句子 ----\n const sents = splitSentences(text);\n const sentenceSet = new Set<string>();\n\n for (const fp of positions) {\n for (const s of sents) {\n if (fp >= s.start && fp < s.end) {\n sentenceSet.add(s.text);\n break;\n }\n }\n }\n\n for (const s of sentenceSet) {\n sentences.push(s);\n }\n\n // 按位置排序\n positions.sort((a, b) => a - b);\n fillerDetails.sort((a, b) => a.position - b.position);\n\n return {\n count: fillerDetails.length,\n sentences,\n positions,\n dashCount,\n ellipsisCount,\n repeatedTags,\n fillerDetails,\n };\n}\n\n/**\n * 计算每千字填充词密度\n */\nexport function calculateFillerDensity(count: number, totalChars: number): number {\n if (totalChars === 0) return 0;\n return (count / totalChars) * 1000;\n}\n","// ============================================================\n// GWE V3.0 - 7维雷达评分(追读力增强版)\n// 维度:bodyReaction/sensorySignal/action/emotion/infoAdvance/twistFrequency/hookStrength\n// ============================================================\n\nimport type {\n RadarScores,\n TextStats,\n MergedConfig,\n MergedVocabulary,\n RadarWeights,\n} from './types';\nimport { detectAnchors } from './anchor-detector';\n\n// ============================================================\n// 五感词分类(内置基础词表,用于sensorySignal维度)\n// ============================================================\n\nconst SENSORY_CATEGORIES = {\n sight: ['看', '望', '盯', '瞥', '见', '瞧', '观', '视', '亮', '暗', '光', '影', '色', '红', '蓝', '绿', '白', '黑', '映', '照', '闪', '耀', '眩', '模糊', '清晰', '映'],\n sound: ['听', '闻', '声', '响', '鸣', '叫', '喊', '说', '道', '嗡', '轰', '哗', '啪', '吱', '砰', '咚', '叮', '铛', '嘎', '呼啸', '咆哮', '低语', '呢喃', '寂静', '喧闹'],\n smell: ['香', '臭', '腥', '膻', '味', '闻', '嗅', '芬芳', '恶臭', '刺鼻', '弥漫', '萦绕'],\n touch: ['触', '摸', '碰', '冷', '热', '温', '凉', '冰', '烫', '软', '硬', '粗', '细', '滑', '糙', '疼', '痛', '麻', '痒', '刺', '压', '握', '抚'],\n taste: ['甜', '苦', '酸', '辣', '咸', '涩', '鲜', '味', '尝', '品', '甘', '腻', '清淡', '浓郁'],\n};\n\n// 情感词基础列表(用于emotion维度)\nconst EMOTION_WORDS = [\n '怒', '喜', '悲', '恐', '惊', '忧', '思', '愁', '恨', '妒',\n '悔', '愧', '羞', '窘', '慌', '急', '烦', '闷', '爽', '悦',\n '愤怒', '喜悦', '悲伤', '恐惧', '惊讶', '忧虑', '思念', '愁苦',\n '憎恨', '嫉妒', '后悔', '愧疚', '羞愧', '窘迫', '慌张', '焦急',\n '烦躁', '郁闷', '舒畅', '愉悦', '冷笑', '苦笑', '微笑', '狞笑',\n '颤抖', '战栗', '惊恐', '狂喜', '暴怒', '绝望', '希望', '失落',\n '心动', '心悸', '心碎', '心痛', '心软', '心酸', '心醉', '心慌',\n];\n\n// ============================================================\n// 雷达评分计算\n// ============================================================\n\n/** 雷达评分计算所需的统计信息 */\nexport interface RadarInput {\n text: string;\n stats: TextStats;\n mergedConfig: MergedConfig;\n}\n\n/**\n * 计算7维雷达评分(V3追读力增强版)\n *\n * 维度说明:\n * - bodyReaction: 基于锚点密度(身体反应描写丰富度)\n * - sensorySignal: 基于五感词汇出现次数和覆盖面\n * - action: 基于动作动词密度和对话穿插\n * - emotion: 基于情感词和身体反应表达\n * - infoAdvance: 基于新信息点(名词/专有名词首次出现)\n * - twistFrequency: V3新增:转折/反咬词密度,衡量信息反转频率\n * - hookStrength: V3新增:章末钩子强度,衡量结尾追读力\n *\n * 每个维度0-100分,使用radar_weights做权重调整(乘法系数)\n */\nexport function calculateRadar(input: RadarInput): RadarScores {\n const { text, stats, mergedConfig } = input;\n const { vocabulary, radarWeights } = mergedConfig;\n\n const totalChars = stats.totalChars || text.length;\n\n // ---- 1. bodyReaction:锚点密度(V3.1收紧曲线,有区分度)----\n const anchorResult = detectAnchors(text, vocabulary);\n // V3.1:使用weightedCount(套路×0.3,高质量×1.5)代替原始count\n const effectiveAnchorCount = anchorResult.weightedCount || anchorResult.count;\n const anchorDensity = totalChars > 0 ? (effectiveAnchorCount / totalChars) * 1000 : 0;\n // V3.1收紧曲线(实战校准):千字3→40,千字6→65,千字9→80,千字12→90,千字16→100,千字>22开始扣分\n let bodyReaction: number;\n if (anchorDensity <= 0) bodyReaction = 10;\n else if (anchorDensity < 3) bodyReaction = mapRange(anchorDensity, 0, 3, 10, 40);\n else if (anchorDensity < 6) bodyReaction = mapRange(anchorDensity, 3, 6, 40, 65);\n else if (anchorDensity < 9) bodyReaction = mapRange(anchorDensity, 6, 9, 65, 80);\n else if (anchorDensity < 12) bodyReaction = mapRange(anchorDensity, 9, 12, 80, 90);\n else if (anchorDensity < 16) bodyReaction = mapRange(anchorDensity, 12, 16, 90, 100);\n else bodyReaction = clampScore(100 - (anchorDensity - 22) * 3);\n // 套路锚点太多额外扣分\n if (anchorResult.quality && anchorResult.count > 0) {\n const clicheRatio = anchorResult.quality.cliche / anchorResult.count;\n if (clicheRatio > 0.3) bodyReaction = clampScore(bodyReaction - 15);\n else if (clicheRatio > 0.15) bodyReaction = clampScore(bodyReaction - 5);\n }\n\n // ---- 2. sensorySignal:五感覆盖(V3.1收紧)----\n const sensoryCounts = countSensoryMentions(text);\n const totalSensory = Object.values(sensoryCounts).reduce((a, b) => a + b, 0);\n const activeSenses = Object.values(sensoryCounts).filter((c) => c > 0).length;\n const sensoryDensity = totalChars > 0 ? (totalSensory / totalChars) * 1000 : 0;\n // V3.1收紧:2种感官→30,3种→50,4种→65,5种→80;密度千字5→+10,千字8→+15,千字12→+20\n let coverageScore: number;\n if (activeSenses <= 1) coverageScore = 10;\n else if (activeSenses === 2) coverageScore = 30;\n else if (activeSenses === 3) coverageScore = 55;\n else if (activeSenses === 4) coverageScore = 72;\n else coverageScore = 82; // 5种全激活\n let densityBonus: number;\n if (sensoryDensity < 3) densityBonus = 0;\n else if (sensoryDensity < 6) densityBonus = mapRange(sensoryDensity, 3, 6, 5, 10);\n else if (sensoryDensity < 10) densityBonus = mapRange(sensoryDensity, 6, 10, 10, 16);\n else densityBonus = Math.min(18, mapRange(sensoryDensity, 10, 15, 16, 18));\n // 嗅觉/触觉必选加分\n const hasSmellOrTouch = (sensoryCounts.smell || 0) > 0 || (sensoryCounts.touch || 0) > 0;\n const senseTypeBonus = hasSmellOrTouch ? 0 : -10; // 没有嗅觉/触觉扣10分(监控录像感)\n let sensorySignal = clampScore(coverageScore + densityBonus + senseTypeBonus);\n\n // ---- 3. action:动作动词密度 + 对话穿插 + 对话冲突(V3.1收紧)----\n const actionVerbCount = countMatches(text, vocabulary.actionVerbs);\n const actionDensity = totalChars > 0 ? (actionVerbCount / totalChars) * 1000 : 0;\n // V3.1收紧:千字5→30,千字10→50,千字15→65,千字20→78,千字25→88,千字30→95,千字35→100\n let actionDensityScore: number;\n if (actionDensity < 5) actionDensityScore = mapRange(actionDensity, 0, 5, 10, 30);\n else if (actionDensity < 10) actionDensityScore = mapRange(actionDensity, 5, 10, 30, 50);\n else if (actionDensity < 15) actionDensityScore = mapRange(actionDensity, 10, 15, 50, 65);\n else if (actionDensity < 20) actionDensityScore = mapRange(actionDensity, 15, 20, 65, 78);\n else if (actionDensity < 25) actionDensityScore = mapRange(actionDensity, 20, 25, 78, 88);\n else if (actionDensity < 30) actionDensityScore = mapRange(actionDensity, 25, 30, 88, 95);\n else actionDensityScore = clampScore(mapRange(Math.min(actionDensity, 40), 30, 40, 95, 100));\n\n const dialogueRatio = stats.dialogueRatio || 0;\n let dialogueScore = 0;\n if (dialogueRatio >= 0.2 && dialogueRatio <= 0.5) {\n dialogueScore = 12; // 对话比例适中\n } else if (dialogueRatio > 0 && dialogueRatio < 0.2) {\n dialogueScore = mapRange(dialogueRatio, 0, 0.2, 0, 12);\n } else if (dialogueRatio > 0.5) {\n dialogueScore = mapRange(dialogueRatio, 0.5, 0.8, 12, 2);\n } else dialogueScore = 0;\n\n // 对话冲突加分:检测否定/质疑/打断词\n const conflictWords = ['不对', '不可能', '错', '但是', '却', '竟然', '居然', '怎么', '为什么', '难道', '不是', '停', '闭嘴', '凭什么', '我不信', '你骗我', '放屁', '胡说', '滚', '找死'];\n let conflictCount = 0;\n for (const w of conflictWords) {\n let idx = text.indexOf(w);\n while (idx !== -1) { conflictCount++; idx = text.indexOf(w, idx + w.length); }\n }\n const conflictDensity = totalChars > 0 ? (conflictCount / totalChars) * 1000 : 0;\n const conflictBonus = conflictDensity >= 3 ? 10 : conflictDensity >= 1.5 ? 5 : conflictDensity >= 0.5 ? 2 : 0;\n let action = clampScore(actionDensityScore + dialogueScore + conflictBonus);\n\n // ---- 4. emotion:情感表达(V3.1收紧,Show Don't Tell友好)----\n const emotionWordCount = countEmotionWords(text);\n const emotionDensity = totalChars > 0 ? (emotionWordCount / totalChars) * 1000 : 0;\n // V3.1收紧:情感词密度太低(<1)→15分,1-2→25,2-3→35,3-4→30,>4→15(太多是Tell)\n let emotionWordScore: number;\n if (emotionDensity < 0.5) emotionWordScore = 10;\n else if (emotionDensity < 1.5) emotionWordScore = mapRange(emotionDensity, 0.5, 1.5, 15, 28);\n else if (emotionDensity < 3) emotionWordScore = mapRange(emotionDensity, 1.5, 3, 28, 35);\n else if (emotionDensity < 5) emotionWordScore = mapRange(emotionDensity, 3, 5, 35, 25);\n else emotionWordScore = mapRange(Math.min(emotionDensity, 10), 5, 10, 25, 10);\n\n // 身体锚点带来的情绪分(Show Don't Tell核心,实战校准)\n let bodyEmotionScore: number;\n if (anchorDensity < 3) bodyEmotionScore = mapRange(anchorDensity, 0, 3, 0, 20);\n else if (anchorDensity < 6) bodyEmotionScore = mapRange(anchorDensity, 3, 6, 20, 38);\n else if (anchorDensity < 10) bodyEmotionScore = mapRange(anchorDensity, 6, 10, 38, 52);\n else if (anchorDensity < 15) bodyEmotionScore = mapRange(anchorDensity, 10, 15, 52, 62);\n else bodyEmotionScore = 65;\n // 高质量生理锚点额外加分\n const qualityAnchorBonus = anchorResult.quality ? Math.min(10, anchorResult.quality.quality * 1.5) : 0;\n // 转折/冲突带来的情绪张力加分\n const conflictTwistBonus = conflictDensity >= 3 ? 8 : conflictDensity >= 1.5 ? 4 : 0;\n let emotion = clampScore(emotionWordScore + bodyEmotionScore + qualityAnchorBonus + conflictTwistBonus);\n\n // ---- 5. infoAdvance:新信息点推进(V3.1实战校准)----\n const infoPoints = countInfoPoints(text, vocabulary);\n const infoDensity = totalChars > 0 ? (infoPoints / totalChars) * 1000 : 0;\n // V3.1实战校准(加入通用新事物检测后重新校准):千字3→40,千字5→60,千字8→78,千字12→90,千字16→100,千字>22扣分\n let infoAdvance: number;\n if (infoDensity <= 0) infoAdvance = 10;\n else if (infoDensity < 3) infoAdvance = mapRange(infoDensity, 0, 3, 10, 40);\n else if (infoDensity < 5) infoAdvance = mapRange(infoDensity, 3, 5, 40, 60);\n else if (infoDensity < 8) infoAdvance = mapRange(infoDensity, 5, 8, 60, 78);\n else if (infoDensity < 12) infoAdvance = mapRange(infoDensity, 8, 12, 78, 90);\n else if (infoDensity < 16) infoAdvance = mapRange(infoDensity, 12, 16, 90, 100);\n else infoAdvance = clampScore(100 - (infoDensity - 22) * 3);\n\n // ---- 6. V3.1: twistFrequency 信息反咬/转折密度(收紧曲线)----\n const twistWordsFull = ['但是', '但', '可是', '然而', '却', '竟然', '居然', '突然', '不对', '奇怪', '怎么', '为什么', '难道', '不是', '反而', '相反', '没想到', '原来', '其实', '实际上', '等等', '不对劲', '有问题', '不可能', '错了', '等一下'];\n let twistCount = 0;\n for (const word of twistWordsFull) {\n let idx = text.indexOf(word);\n while (idx !== -1) {\n twistCount++;\n idx = text.indexOf(word, idx + word.length);\n }\n }\n const twistDensity = totalChars > 0 ? (twistCount / totalChars) * 1000 : 0;\n // V3.1收紧(实战校准):千字1→25,千字2→45,千字3→60,千字5→78,千字8→90,千字11→100,千字>16扣分\n let twistFrequency: number;\n if (twistDensity <= 0) twistFrequency = 5;\n else if (twistDensity < 1) twistFrequency = mapRange(twistDensity, 0, 1, 5, 25);\n else if (twistDensity < 2) twistFrequency = mapRange(twistDensity, 1, 2, 25, 45);\n else if (twistDensity < 3) twistFrequency = mapRange(twistDensity, 2, 3, 45, 60);\n else if (twistDensity < 5) twistFrequency = mapRange(twistDensity, 3, 5, 60, 78);\n else if (twistDensity < 8) twistFrequency = mapRange(twistDensity, 5, 8, 78, 90);\n else if (twistDensity < 11) twistFrequency = mapRange(twistDensity, 8, 11, 90, 100);\n else twistFrequency = clampScore(100 - (twistDensity - 16) * 3);\n\n // ---- 7. V3.1: hookStrength 章末钩子强度(重新校准,有区分度)----\n let hookStrength = 30; // 基础分更低,没有有效钩子就是30分\n if (totalChars > 200) {\n const tail = text.substring(Math.max(0, text.length - 300));\n const sentenceEndRegex = /[。!?!?…]+[^。!?!?…]*$/;\n const endMatch = tail.match(sentenceEndRegex);\n const lastChunk = (endMatch ? endMatch[0] : tail).replace(/^[\\s\\n]+/, '');\n const lastSentence = lastChunk.replace(/[。!?!?…\\s]+$/, '').trim();\n const lastPuncMatch = lastChunk.match(/[。!?!?…]+$/);\n const lastPunc = lastPuncMatch ? lastPuncMatch[0] : '';\n const lastChar = lastSentence.slice(-1);\n const lastLen = lastSentence.replace(/\\s/g, '').length;\n\n const last150 = text.substring(Math.max(0, text.length - 150));\n const hasTwistAtEnd = twistWordsFull.some((w) => last150.includes(w));\n const hasQuestion = /[??]/.test(lastPunc);\n const hasExclamation = /[!!]/.test(lastPunc);\n const hasEllipsis = /…/.test(lastPunc);\n // 具体新信息/危险信号(看得见摸得着的具体事物)\n const hasConcreteDanger = /(血|杀|死|塌|崩|灭|凉|冷|逃|追|来了|动了|亮了|灭了|醒了|碎了|掉了|倒了|在搏动|在爬|在流|是活的|敲|响了|发光|亮了|号牌|钥匙|信|刀|剑|枪|手|眼睛|脸|影子|人|尸体|骨头|指纹|字|洞|门)/.test(last150);\n // 抽象悬念词(假钩子)\n const hasAbstractHook = /(不对劲|有什么|神秘|不祥|诡异|奇怪|可怕|恐怖|危险|不对劲)/.test(last150) && !hasConcreteDanger;\n\n // 加分项(严格,具体钩子才加分)\n if (hasQuestion && lastLen <= 20) hookStrength += 25; // 短句问号+25\n if (hasExclamation && lastLen <= 15) hookStrength += 20; // 短句感叹号+20\n if (hasEllipsis && lastLen <= 15) hookStrength += 15; // 短句省略号+15\n if (hasConcreteDanger && lastLen <= 20) hookStrength += 30; // 具体新危险/事物极短句+30\n else if (hasConcreteDanger) hookStrength += 15;\n if (hasTwistAtEnd && /(不对|不是|竟然|原来|其实|难道)/.test(last150)) hookStrength += 10;\n // 极短句(≤10字)+15\n if (lastLen <= 10 && lastLen > 0) hookStrength += 15;\n else if (lastLen <= 18) hookStrength += 8;\n // 断裂动作钩子\n if (/^(他刚|她刚|刚要|正要|就在|话没说完|还没|突然|然后它|然后他|然后她)/.test(lastSentence.trim())) {\n hookStrength += 15;\n }\n\n // 减分项\n if (/[了的是着过]$/.test(lastChar) && !/[??!!…]/.test(lastPunc)) {\n hookStrength -= 25;\n }\n if (/^(就这样|原来如此|所以|于是|最终|最后|总之|总而言之|这一晚|这一天|这一刻|他知道|他明白)/.test(lastSentence.trim())) {\n hookStrength -= 20;\n }\n if (/了。$/.test(lastChunk.trimEnd())) {\n hookStrength -= 20;\n }\n if (lastLen > 35 && !hasQuestion && !hasExclamation) {\n hookStrength -= 15; // 长句收尾-15\n }\n if (hasAbstractHook && !hasConcreteDanger) {\n hookStrength -= 15; // 抽象假钩子-15\n }\n\n hookStrength = clampScore(hookStrength);\n }\n\n // ---- 应用radar_weights乘法系数 ----\n const raw: RadarScores = {\n bodyReaction,\n sensorySignal,\n action,\n emotion,\n infoAdvance,\n twistFrequency,\n hookStrength,\n };\n\n return applyWeights(raw, radarWeights);\n}\n\n/**\n * 计算雷达综合得分(加权平均)\n */\nexport function calculateScore(radar: RadarScores): number {\n const values = Object.values(radar);\n if (values.length === 0) return 0;\n const sum = values.reduce((a, b) => a + b, 0);\n return Math.round((sum / values.length) * 10) / 10;\n}\n\n/**\n * 计算带自定义权重的综合得分\n */\nexport function calculateWeightedScore(\n radar: RadarScores,\n weights: Partial<RadarWeights>\n): number {\n const keys: Array<keyof RadarScores> = [\n 'bodyReaction', 'sensorySignal', 'action', 'emotion', 'infoAdvance',\n 'twistFrequency', 'hookStrength',\n ];\n let totalWeight = 0;\n let weightedSum = 0;\n for (const key of keys) {\n const w = weights[key] ?? 1;\n weightedSum += radar[key] * w;\n totalWeight += w;\n }\n if (totalWeight === 0) return 0;\n return Math.round((weightedSum / totalWeight) * 10) / 10;\n}\n\n// ============================================================\n// 辅助函数\n// ============================================================\n\n/** 将值从一个范围映射到另一个范围 */\nfunction mapRange(\n value: number,\n inMin: number,\n inMax: number,\n outMin: number,\n outMax: number\n): number {\n if (inMax === inMin) return outMin;\n return ((value - inMin) / (inMax - inMin)) * (outMax - outMin) + outMin;\n}\n\n/** 将分数限制在0-100之间 */\nfunction clampScore(score: number): number {\n return Math.max(0, Math.min(100, Math.round(score)));\n}\n\n/** 应用雷达权重(V3.1修复:权重仅用于加权平均,不乘到维度分数上,避免封顶100) */\nfunction applyWeights(scores: RadarScores, _weights: RadarWeights): RadarScores {\n // V3.1修复:不把权重乘到维度分数上,否则高权重维度会被clamp到100失去区分度\n // 权重在calculateWeightedScore里用于加权平均\n return {\n bodyReaction: clampScore(scores.bodyReaction),\n sensorySignal: clampScore(scores.sensorySignal),\n action: clampScore(scores.action),\n emotion: clampScore(scores.emotion),\n infoAdvance: clampScore(scores.infoAdvance),\n twistFrequency: clampScore(scores.twistFrequency),\n hookStrength: clampScore(scores.hookStrength),\n };\n}\n\n/** 统计五感词汇出现次数 */\nexport function countSensoryMentions(text: string): Record<string, number> {\n const counts: Record<string, number> = {\n sight: 0,\n sound: 0,\n smell: 0,\n touch: 0,\n taste: 0,\n };\n\n for (const [sense, words] of Object.entries(SENSORY_CATEGORIES)) {\n let total = 0;\n for (const word of words) {\n let idx = 0;\n while ((idx = text.indexOf(word, idx)) !== -1) {\n total++;\n idx += word.length;\n }\n }\n counts[sense] = total;\n }\n\n return counts;\n}\n\n/** 统计词表中的词在文本中出现的总次数 */\nfunction countMatches(text: string, wordSet: Set<string>): number {\n let count = 0;\n const words = Array.from(wordSet).sort((a, b) => b.length - a.length);\n const found = new Set<number>();\n\n for (const word of words) {\n let idx = 0;\n while ((idx = text.indexOf(word, idx)) !== -1) {\n // 检查重叠\n let overlaps = false;\n for (let p = idx; p < idx + word.length; p++) {\n if (found.has(p)) {\n overlaps = true;\n break;\n }\n }\n if (!overlaps) {\n count++;\n for (let p = idx; p < idx + word.length; p++) {\n found.add(p);\n }\n }\n idx += word.length;\n }\n }\n\n return count;\n}\n\n/** 统计情感词出现次数 */\nfunction countEmotionWords(text: string): number {\n let count = 0;\n const sorted = EMOTION_WORDS.sort((a, b) => b.length - a.length);\n const found = new Set<number>();\n\n for (const word of sorted) {\n let idx = 0;\n while ((idx = text.indexOf(word, idx)) !== -1) {\n let overlaps = false;\n for (let p = idx; p < idx + word.length; p++) {\n if (found.has(p)) {\n overlaps = true;\n break;\n }\n }\n if (!overlaps) {\n count++;\n for (let p = idx; p < idx + word.length; p++) {\n found.add(p);\n }\n }\n idx += word.length;\n }\n }\n\n return count;\n}\n\n/**\n * 统计新信息点数量(基于worldTerms和一般专有名词识别)\n * 简单启发式:\n * 1. worldTerms中的词首次出现算信息点\n * 2. 引号内的新名词(2-4字连续出现两次以上且首次出现的词)\n * 3. 数字+单位组合\n */\nfunction countInfoPoints(text: string, vocab: MergedVocabulary): number {\n let count = 0;\n const seen = new Set<string>();\n\n // worldTerms\n const worldTerms = vocab.worldTerms || new Set<string>();\n for (const term of worldTerms) {\n if (text.includes(term)) {\n if (!seen.has(term)) {\n count++;\n seen.add(term);\n }\n }\n }\n\n // 中文引号/书名号内的词汇(首次出现视为信息点)\n const bracketRegex = /[《「『【]([^》」』】]{2,10})[》」』】]/g;\n let m: RegExpExecArray | null;\n while ((m = bracketRegex.exec(text)) !== null) {\n const term = m[1];\n if (!seen.has(term)) {\n count++;\n seen.add(term);\n }\n }\n\n // 数字+量词组合(如\"三阶\"、\"九品\"、\"万年\")\n const measureRegex = /[一二三四五六七八九十百千万0-9]+[阶品级层重天年月日个里斤][^,。!?、\\s]{0,2}/g;\n while ((m = measureRegex.exec(text)) !== null) {\n const term = m[0];\n if (!seen.has(term)) {\n count++;\n seen.add(term);\n }\n }\n\n // 【V3.1实战新增】通用新事物检测(不依赖预设词表)\n // 检测\"这是/那是/不是/是+[名词]\"结构的首次出现(异常揭示)\n const revealRegex = /(?:这是|那是|不是|就是|原来是|其实是)([^\\s,。!?、\"」』]{1,6})/g;\n while ((m = revealRegex.exec(text)) !== null) {\n const term = m[1];\n if (term.length >= 2 && !seen.has(term)) {\n count++;\n seen.add(term);\n }\n }\n\n // 【V3.1实战新增】危险/异常具体名词检测(血、刀、剑、尸体、门、手、眼睛、号牌等)\n // 每段首次出现的新具体物件视为信息点\n const dangerWords = ['血','刀','剑','尸体','骨头','眼睛','脸','手','影子','洞','门','钥匙','信','号牌','盾','铜棍','镜子','黄符','黑液','搏纹','金光','黑血','腔室','筋膜','简历','招聘'];\n for (const w of dangerWords) {\n if (text.includes(w) && !seen.has(w)) {\n count++;\n seen.add(w);\n }\n }\n\n return count;\n}\n","// ============================================================\n// GWE V3.0 - 13项硬指标检测器(V3新增5项追读力检测)\n// 整合锚点检测、填充词检测、追读力检测、文本统计\n// ============================================================\n\nimport type {\n CheckResult,\n RuleViolation,\n TextStats,\n MergedConfig,\n WritingContext,\n Thresholds,\n} from './types';\nimport { detectAnchors, calculateAnchorDensity, calculateMaxAnchorGap } from './anchor-detector';\nimport { detectFillers } from './filler-words';\nimport { calculateRadar, calculateWeightedScore, countSensoryMentions } from './radar';\n\n// ============================================================\n// 检查器入口\n// ============================================================\n\n/**\n * 对文本执行全面质量检查\n *\n * @param text 待检查文本\n * @param context 写作上下文(书籍/章节/角色等数据)\n * @param mergedConfig 合并后的运行时配置\n * @returns CheckResult 包含综合得分、雷达分、违规项、统计信息\n */\nexport function check(\n text: string,\n _context: WritingContext | null,\n mergedConfig: MergedConfig\n): CheckResult {\n const { thresholds, vocabulary, extraRules, disabledChecks } = mergedConfig;\n const violations: RuleViolation[] = [];\n\n // ---- 1. 基础文本统计 ----\n const stats = computeTextStats(text, vocabulary);\n\n // ---- 2. 锚点检测 ----\n const anchorResult = detectAnchors(text, vocabulary);\n stats.anchorCount = anchorResult.count;\n\n // ---- 3. 填充词检测 ----\n const fillerResult = detectFillers(text, vocabulary, thresholds);\n stats.fillerCount = fillerResult.count;\n\n // ---- 4. 五感统计 ----\n stats.sensoryMentions = countSensoryMentions(text);\n\n // ---- 5. 执行8项硬指标检查 ----\n // 检查项1:锚点密度\n if (!disabledChecks.has('anchor_density')) {\n checkAnchorDensity(text, anchorResult, stats, thresholds, violations);\n }\n\n // 检查项2:填充词\n if (!disabledChecks.has('filler_words')) {\n checkFillerWords(text, fillerResult, stats, thresholds, violations);\n }\n\n // 检查项3:段落长度\n if (!disabledChecks.has('paragraph_length')) {\n checkParagraphLength(text, stats, thresholds, violations);\n }\n\n // 检查项4:对话穿插\n if (!disabledChecks.has('dialogue_interleave')) {\n checkDialogueInterleave(text, fillerResult, stats, thresholds, vocabulary, violations);\n }\n\n // 检查项5:句子节奏\n if (!disabledChecks.has('sentence_rhythm')) {\n checkSentenceRhythm(text, stats, thresholds, violations);\n }\n\n // 检查项6:信息密度\n if (!disabledChecks.has('info_density')) {\n checkInfoDensity(text, stats, thresholds, vocabulary, violations);\n }\n\n // 检查项7:五感覆盖\n if (!disabledChecks.has('sensory_coverage')) {\n checkSensoryCoverage(stats, thresholds, violations);\n }\n\n // 检查项8:自定义规则\n for (const rule of extraRules) {\n if (disabledChecks.has(rule.id)) continue;\n\n if (rule.pattern) {\n // 正则模式匹配\n try {\n const regex = new RegExp(rule.pattern, 'g');\n let m: RegExpExecArray | null;\n while ((m = regex.exec(text)) !== null) {\n violations.push({\n ruleId: rule.id,\n ruleName: rule.name,\n message: `${rule.description}:匹配到 \"${m[0]}\"`,\n severity: rule.severity,\n position: { from: m.index, to: m.index + m[0].length },\n suggestion: `建议修改或删除此表达`,\n });\n }\n } catch {\n // 正则无效,跳过\n }\n }\n\n if (rule.check) {\n // 自定义检查函数\n try {\n const result = rule.check(text);\n if (result) {\n violations.push(result);\n }\n } catch {\n // 检查函数执行失败,跳过\n }\n }\n }\n\n // ---- V3新增:追读力5项检测 ----\n\n // 检查项9:开头冲击检测\n if (!disabledChecks.has('opening_impact')) {\n checkOpeningImpact(text, stats, thresholds, violations);\n }\n\n // 检查项10:套路反应黑名单\n if (!disabledChecks.has('cliche_reactions')) {\n checkClicheReactions(text, violations);\n }\n\n // 检查项11:碎句病检测\n if (!disabledChecks.has('fragmented_sentences')) {\n checkFragmentedSentences(text, stats, violations);\n }\n\n // 检查项12:对话碰撞检测(启发式:否定/反对词密度)\n if (!disabledChecks.has('dialogue_conflict')) {\n checkDialogueConflict(text, stats, violations);\n }\n\n // 检查项13:章末钩子检测\n if (!disabledChecks.has('ending_hook')) {\n checkEndingHook(text, stats, thresholds, violations);\n }\n\n // 检查项14:信息反咬密度检测(V3新增)\n if (!disabledChecks.has('twist_density')) {\n checkTwistDensity(text, stats, thresholds, violations);\n }\n\n // 检查项15:黄金300字冲突检测(2026网文铁则:3秒停留率)\n if (!disabledChecks.has('golden_300')) {\n checkGolden300(text, violations);\n }\n\n // 检查项16:开篇禁忌检测(禁止写景/回忆/背景开头)\n if (!disabledChecks.has('opening_taboos')) {\n checkOpeningTaboos(text, violations);\n }\n\n // 检查项17:装神弄鬼假钩子检测(禁止\"似乎意识到\"\"神秘气息\"等空泛悬念)\n if (!disabledChecks.has('fake_hook')) {\n checkFakeHooks(text, violations);\n }\n\n // 检查项18:五感平衡检测(V3.1实战新增:关键场景需要≥3种感官,必须包含嗅觉或触觉)\n if (!disabledChecks.has('sensory_balance')) {\n checkSensoryBalance(text, stats, violations);\n }\n\n // 检查项19:钩子具体性检测(V3.1实战新增:章末最后一句禁止抽象比喻收尾)\n if (!disabledChecks.has('hook_concreteness')) {\n checkHookConcreteness(text, violations);\n }\n\n // 检查项20:连续比喻检测(V3.1实战新增:同段连续2个以上\"像/如/仿佛\"比喻)\n if (!disabledChecks.has('simile_density')) {\n checkSimileDensity(text, violations);\n }\n\n // 检查项21:不必要英文检测(V3.1实战新增:中文网文非专有名词不夹英文)\n if (!disabledChecks.has('unnecessary_english')) {\n checkUnnecessaryEnglish(text, violations);\n }\n\n // 检查项22:开头力度检测(V3.1读者视角校准:第一句必须直接砸身体刺激)\n if (!disabledChecks.has('opening_impact')) {\n checkOpeningImpact(text, stats, thresholds, violations);\n }\n\n // 检查项23:重复内容检测(V3.1读者视角校准:重复段落/句子是严重错误)\n if (!disabledChecks.has('repetition')) {\n checkRepetition(text, violations);\n }\n\n // 检查项24:空洞四字成语堆砌检测(V3.1客观测试新增)\n if (!disabledChecks.has('cliché_phrases')) {\n checkClichéPhrases(text, violations);\n }\n\n // 检查项25:开头纯写景无人物检测(V3.1客观测试新增)\n if (!disabledChecks.has('opening_scene_setting')) {\n checkOpeningScene(text, violations);\n }\n\n // 检查项26:标签化假反应检测(V3.1客观测试新增)\n if (!disabledChecks.has('fake_reactions')) {\n checkFakeReactions(text, violations);\n }\n\n // ---- 6. 计算雷达评分 ----\n const radarScores = calculateRadar({ text, stats, mergedConfig });\n\n // ---- 7. 计算综合得分 ----\n // 基础分来自雷达加权平均分(使用radarWeights做加权平均,而非乘法系数),根据违规项扣分\n const baseScore = calculateWeightedScore(radarScores, mergedConfig.radarWeights);\n const score = applyViolationPenalty(baseScore, violations);\n\n // ---- 8. 判断是否通过 ----\n const hasErrors = violations.some((v) => v.severity === 'error');\n\n return {\n score: Math.max(0, Math.min(100, Math.round(score * 10) / 10)),\n radarScores,\n violations,\n stats,\n passed: !hasErrors,\n };\n}\n\n// ============================================================\n// 文本统计\n// ============================================================\n\n/**\n * 计算文本基础统计数据\n */\nfunction computeTextStats(text: string, vocab: MergedConfig['vocabulary']): TextStats {\n void vocab; // vocab保留参数但暂不使用\n // 总字符数(不含空白)\n const totalChars = text.replace(/\\s/g, '').length;\n\n // 中文字数(粗略:统计CJK字符)\n const cjkRegex = /[\\u4e00-\\u9fa5]/g;\n const cjkMatches = text.match(cjkRegex);\n const totalWords = cjkMatches ? cjkMatches.length : totalChars;\n\n // 段落切分(按换行切分,过滤空段落)\n const paragraphs = text.split(/\\n+/).filter((p) => p.trim().length > 0);\n const paragraphCount = paragraphs.length;\n const avgParagraphLength = paragraphCount > 0\n ? paragraphs.reduce((sum, p) => sum + p.replace(/\\s/g, '').length, 0) / paragraphCount\n : 0;\n\n // 句子切分\n const sentenceRegex = /[^。!?!?\\n]+[。!?!?]?/g;\n const sentenceMatches = text.match(sentenceRegex);\n const sentences = sentenceMatches\n ? sentenceMatches.map((s) => s.trim()).filter((s) => s.length > 0)\n : [];\n const sentenceCount = sentences.length;\n const avgSentenceLength = sentenceCount > 0\n ? sentences.reduce((sum, s) => sum + s.replace(/\\s/g, '').length, 0) / sentenceCount\n : 0;\n\n // 短句占比(短句定义:<= 15字)\n const shortThreshold = 15;\n const shortSentences = sentences.filter(\n (s) => s.replace(/\\s/g, '').length <= shortThreshold\n ).length;\n const shortSentenceRatio = sentenceCount > 0 ? shortSentences / sentenceCount : 0;\n\n // 对话比例(引号内文字占比)\n const dialogueRegex = /[\"\"「」『』【】《》][^\"\"「」『』【】《》]{1,}[\"\"「」『』【】《》]/g;\n let dialogueChars = 0;\n let dm: RegExpExecArray | null;\n while ((dm = dialogueRegex.exec(text)) !== null) {\n dialogueChars += dm[0].replace(/\\s/g, '').length;\n }\n const dialogueRatio = totalChars > 0 ? dialogueChars / totalChars : 0;\n\n return {\n totalChars,\n totalWords,\n paragraphCount,\n avgParagraphLength: Math.round(avgParagraphLength * 10) / 10,\n sentenceCount,\n avgSentenceLength: Math.round(avgSentenceLength * 10) / 10,\n shortSentenceRatio: Math.round(shortSentenceRatio * 100) / 100,\n anchorCount: 0, // 后续填充\n fillerCount: 0, // 后续填充\n dialogueRatio: Math.round(dialogueRatio * 100) / 100,\n sensoryMentions: { sight: 0, sound: 0, smell: 0, touch: 0, taste: 0 },\n };\n}\n\n// ============================================================\n// 8项硬指标检查实现\n// ============================================================\n\n/** 检查项1:锚点密度 */\nfunction checkAnchorDensity(\n text: string,\n anchorResult: ReturnType<typeof detectAnchors>,\n stats: TextStats,\n thresholds: Thresholds,\n violations: RuleViolation[]\n): void {\n void text;\n const totalChars = stats.totalChars;\n\n // 锚点总数不足\n if (anchorResult.count < thresholds.minAnchors) {\n violations.push({\n ruleId: 'min_anchors',\n ruleName: '锚点数量不足',\n message: `当前锚点数为 ${anchorResult.count},至少需要 ${thresholds.minAnchors} 个身体反应描写`,\n severity: 'warning',\n suggestion: '建议在叙事中加入角色的身体反应,如\"指尖发凉\"、\"后颈一紧\"等',\n });\n }\n\n // 锚点密度不足\n const density = calculateAnchorDensity(anchorResult.count, totalChars);\n const expectedDensity = 1000 / thresholds.anchorsPerWords;\n if (density < expectedDensity * 0.5) {\n violations.push({\n ruleId: 'anchors_per_words',\n ruleName: '锚点密度偏低',\n message: `锚点密度为每千字 ${density.toFixed(1)} 个,建议达到每千字 ${expectedDensity.toFixed(1)} 个`,\n severity: 'warning',\n suggestion: '在对话、动作、情感场景中穿插身体感受描写',\n });\n }\n\n // 锚点间隔过大\n const maxGap = calculateMaxAnchorGap(anchorResult.positions, totalChars);\n if (maxGap > thresholds.maxAnchorGap) {\n violations.push({\n ruleId: 'max_anchor_gap',\n ruleName: '锚点间隔过大',\n message: `存在 ${maxGap} 字无锚点的段落,最大允许间隔为 ${thresholds.maxAnchorGap} 字`,\n severity: 'warning',\n suggestion: '在长段叙述或对话中穿插角色的身体反应',\n });\n }\n}\n\n/** 检查项2:填充词 */\nfunction checkFillerWords(\n text: string,\n fillerResult: ReturnType<typeof detectFillers>,\n stats: TextStats,\n thresholds: Thresholds,\n violations: RuleViolation[]\n): void {\n void text;\n const totalChars = stats.totalChars;\n const perThousandFactor = totalChars / 1000 || 1;\n\n // 填充词数量\n const fillerPerThousand = fillerResult.count / perThousandFactor;\n if (fillerPerThousand > thresholds.maxFillerWords) {\n violations.push({\n ruleId: 'max_filler_words',\n ruleName: '填充词过多',\n message: `每千字填充词约 ${fillerPerThousand.toFixed(1)} 个,上限为 ${thresholds.maxFillerWords} 个`,\n severity: 'warning',\n suggestion: '删除冗余的修饰词,如\"不由得\"、\"忍不住\"、\"似乎\"等',\n position: fillerResult.positions.length > 0\n ? { from: fillerResult.positions[0], to: fillerResult.positions[0] + 2 }\n : undefined,\n });\n }\n\n // 破折号数量\n const dashPerThousand = fillerResult.dashCount / perThousandFactor;\n if (dashPerThousand > thresholds.maxDashCount) {\n violations.push({\n ruleId: 'max_dash_count',\n ruleName: '破折号过多',\n message: `每千字破折号约 ${dashPerThousand.toFixed(1)} 个,上限为 ${thresholds.maxDashCount} 个`,\n severity: 'info',\n suggestion: '减少破折号使用,改用句号或逗号断句',\n });\n }\n\n // 省略号数量\n const ellipsisPerThousand = fillerResult.ellipsisCount / perThousandFactor;\n if (ellipsisPerThousand > thresholds.maxEllipsisCount) {\n violations.push({\n ruleId: 'max_ellipsis_count',\n ruleName: '省略号过多',\n message: `每千字省略号约 ${ellipsisPerThousand.toFixed(1)} 个,上限为 ${thresholds.maxEllipsisCount} 个`,\n severity: 'info',\n suggestion: '减少省略号使用,避免语气拖沓',\n });\n }\n\n // 重复对话标签\n for (const rep of fillerResult.repeatedTags) {\n violations.push({\n ruleId: 'dialogue_tag_repeat',\n ruleName: '对话标签重复',\n message: `对话标签\"${rep.tag}\"连续出现 ${rep.count} 次,上限为 ${thresholds.maxDialogueTagRepeat} 次`,\n severity: 'warning',\n position: rep.positions.length > 0\n ? { from: rep.positions[0], to: rep.positions[0] + rep.tag.length }\n : undefined,\n suggestion: '用动作描写替换部分对话标签,避免重复使用\"XX道\"',\n });\n }\n}\n\n/** 检查项3:段落长度 */\nfunction checkParagraphLength(\n text: string,\n stats: TextStats,\n thresholds: Thresholds,\n violations: RuleViolation[]\n): void {\n const paragraphs = text.split(/\\n+/).filter((p) => p.trim().length > 0);\n\n // 段落数不足\n if (stats.paragraphCount < thresholds.minParagraphCount && stats.totalChars > 500) {\n violations.push({\n ruleId: 'min_paragraph_count',\n ruleName: '段落数不足',\n message: `当前仅 ${stats.paragraphCount} 段,建议至少 ${thresholds.minParagraphCount} 段`,\n severity: 'warning',\n suggestion: '适当分段,手机阅读建议每段不超过3-4行',\n });\n }\n\n // 超长段落\n for (let i = 0; i < paragraphs.length; i++) {\n const paraLen = paragraphs[i].replace(/\\s/g, '').length;\n if (paraLen > thresholds.maxParagraphLength) {\n // 找到段落位置\n const paraStart = text.indexOf(paragraphs[i]);\n violations.push({\n ruleId: 'max_paragraph_length',\n ruleName: '段落过长',\n message: `第 ${i + 1} 段字数 ${paraLen},超过上限 ${thresholds.maxParagraphLength} 字`,\n severity: 'warning',\n position: paraStart !== -1\n ? { from: paraStart, to: paraStart + paragraphs[i].length }\n : undefined,\n suggestion: `将长段拆分为多个短段,目标段落长度约 ${thresholds.targetParagraphLength} 字`,\n });\n // 只报前3个超长段落,避免信息过载\n if (violations.filter((v) => v.ruleId === 'max_paragraph_length').length >= 3) break;\n }\n }\n}\n\n/** 检查项4:对话穿插 */\nfunction checkDialogueInterleave(\n text: string,\n fillerResult: ReturnType<typeof detectFillers>,\n stats: TextStats,\n thresholds: Thresholds,\n vocab: MergedConfig['vocabulary'],\n violations: RuleViolation[]\n): void {\n void fillerResult; void stats; void vocab;\n // 检测连续对话(无动作/叙述穿插)\n const dialogueRegex = /[\"\"「」『』]([^\"\"「」『』]{1,})[\"\"「」『』]/g;\n const dialoguePositions: Array<{ start: number; end: number; text: string }> = [];\n let dm: RegExpExecArray | null;\n\n while ((dm = dialogueRegex.exec(text)) !== null) {\n dialoguePositions.push({ start: dm.index, end: dm.index + dm[0].length, text: dm[1] });\n }\n\n if (dialoguePositions.length === 0) return;\n\n // 检查连续对话句数(两句对话之间没有非对话文字超过20字就算连续)\n let consecutiveCount = 1;\n let consecutiveStart = dialoguePositions[0]?.start ?? 0;\n\n for (let i = 1; i < dialoguePositions.length; i++) {\n const gap = dialoguePositions[i].start - dialoguePositions[i - 1].end;\n const gapText = text.substring(dialoguePositions[i - 1].end, dialoguePositions[i].start);\n // 如果间隔文字少于15字,认为是连续对话\n if (gap < 15 || gapText.replace(/\\s/g, '').length < 15) {\n consecutiveCount++;\n } else {\n if (consecutiveCount > thresholds.maxDialogueContinuous) {\n violations.push({\n ruleId: 'max_dialogue_continuous',\n ruleName: '连续对话过多',\n message: `有 ${consecutiveCount} 句连续对话未穿插动作/描写,上限为 ${thresholds.maxDialogueContinuous} 句`,\n severity: 'warning',\n position: { from: consecutiveStart, to: dialoguePositions[i - 1].end },\n suggestion: '在对话之间插入角色的动作、表情或环境描写',\n });\n }\n consecutiveCount = 1;\n consecutiveStart = dialoguePositions[i].start;\n }\n }\n\n // 最后一段\n if (consecutiveCount > thresholds.maxDialogueContinuous) {\n violations.push({\n ruleId: 'max_dialogue_continuous',\n ruleName: '连续对话过多',\n message: `有 ${consecutiveCount} 句连续对话未穿插动作/描写,上限为 ${thresholds.maxDialogueContinuous} 句`,\n severity: 'warning',\n position: { from: consecutiveStart, to: text.length },\n suggestion: '在对话之间插入角色的动作、表情或环境描写',\n });\n }\n}\n\n/** 检查项5:句子节奏 */\nfunction checkSentenceRhythm(\n text: string,\n stats: TextStats,\n thresholds: Thresholds,\n violations: RuleViolation[]\n): void {\n // 切分句子\n const sentenceRegex = /[^。!?!?\\n]+[。!?!?]?/g;\n const matches = text.match(sentenceRegex);\n const sentences = matches\n ? matches.map((s) => s.trim()).filter((s) => s.length > 0)\n : [];\n\n // 超长句子\n let longSentenceCount = 0;\n for (const sent of sentences) {\n const len = sent.replace(/\\s/g, '').length;\n if (len > thresholds.maxSentenceLength) {\n longSentenceCount++;\n if (longSentenceCount <= 3) {\n const sentStart = text.indexOf(sent);\n violations.push({\n ruleId: 'max_sentence_length',\n ruleName: '句子过长',\n message: `句子长度 ${len} 字,超过上限 ${thresholds.maxSentenceLength} 字`,\n severity: 'warning',\n position: sentStart !== -1 ? { from: sentStart, to: sentStart + sent.length } : undefined,\n suggestion: `将长句拆分为短句,目标句长约 ${thresholds.targetSentenceLength} 字`,\n });\n }\n }\n }\n\n // 短句占比不足\n if (stats.shortSentenceRatio < thresholds.shortSentenceRatio * 0.6) {\n violations.push({\n ruleId: 'short_sentence_ratio',\n ruleName: '短句占比不足',\n message: `短句占比 ${(stats.shortSentenceRatio * 100).toFixed(0)}%,目标为 ${(thresholds.shortSentenceRatio * 100).toFixed(0)}%`,\n severity: 'info',\n suggestion: '适当增加短句,让节奏更明快',\n });\n }\n}\n\n/** 检查项6:信息密度 */\nfunction checkInfoDensity(\n text: string,\n stats: TextStats,\n thresholds: Thresholds,\n vocab: MergedConfig['vocabulary'],\n violations: RuleViolation[]\n): void {\n // 检测连续说明/铺垫(大段叙述无对话/动作/锚点)\n const paragraphs = text.split(/\\n+/).filter((p) => p.trim().length > 0);\n for (let i = 0; i < paragraphs.length; i++) {\n const para = paragraphs[i];\n const hasDialogue = /[\"\"「」『』]/.test(para);\n const paraLen = para.replace(/\\s/g, '').length;\n\n if (!hasDialogue && paraLen > thresholds.maxExpositionContinuous) {\n const paraStart = text.indexOf(para);\n violations.push({\n ruleId: 'max_exposition_continuous',\n ruleName: '说明/铺垫过长',\n message: `存在 ${paraLen} 字的纯叙述段落,上限为 ${thresholds.maxExpositionContinuous} 字`,\n severity: 'warning',\n position: paraStart !== -1 ? { from: paraStart, to: paraStart + para.length } : undefined,\n suggestion: '在设定说明/环境铺垫中穿插对话、动作或角色反应',\n });\n if (violations.filter((v) => v.ruleId === 'max_exposition_continuous').length >= 2) break;\n }\n }\n\n // 信息点密度检测(worldTerms + 数字量词)\n const totalChars = stats.totalChars;\n const perThousandFactor = totalChars / 1000 || 1;\n let infoPointCount = 0;\n\n // 统计世界观术语出现次数\n if (vocab.worldTerms && vocab.worldTerms.size > 0) {\n for (const term of vocab.worldTerms) {\n let idx = text.indexOf(term);\n while (idx !== -1) {\n infoPointCount++;\n idx = text.indexOf(term, idx + term.length);\n }\n }\n }\n\n // 统计数字+量词(如\"三年\"\"五丈\"\"七层\"等中文数字/阿拉伯数字+量词组合)\n const numberMeasureRegex = /[零一二三四五六七八九十百千万两\\d]+[年月天日岁丈尺寸斤两里步级层座位只个条块匹件种项类]/g;\n const numMatches = text.match(numberMeasureRegex);\n if (numMatches) {\n infoPointCount += numMatches.length;\n }\n\n // 统计专有名词模式(连续2-4个大写字母或连续大写开头的词,中文人名/地名启发式)\n // 简化:统计长度2-4字的非停用词开头的词(粗略)\n\n // 信息点密度过低:如果设定了目标密度且实际远低于目标\n const infoPointsPerThousand = infoPointCount / perThousandFactor;\n const targetPoints = thresholds.infoPointsPerThousand ?? 3;\n\n // 只有在有worldTerms时才检查信息点密度(避免在无设定书籍中误报)\n if (vocab.worldTerms && vocab.worldTerms.size > 3 && totalChars > 500) {\n if (infoPointsPerThousand < targetPoints * 0.3) {\n violations.push({\n ruleId: 'info_points_low',\n ruleName: '信息推进不足',\n message: `每千字世界观/新信息点约 ${infoPointsPerThousand.toFixed(1)} 个,建议达到 ${targetPoints} 个以上`,\n severity: 'info',\n suggestion: '适当推进剧情、引入新设定或揭示新信息,避免原地踏步',\n });\n }\n }\n}\n\n/** 检查项7:五感覆盖 */\nfunction checkSensoryCoverage(\n stats: TextStats,\n thresholds: Thresholds,\n violations: RuleViolation[]\n): void {\n const sensory = stats.sensoryMentions;\n const activeTypes = Object.values(sensory).filter((c) => c > 0).length;\n const totalSensory = Object.values(sensory).reduce((a, b) => a + b, 0);\n\n // 感官类型不足\n if (totalSensory > 3 && activeTypes < thresholds.minSensoryTypes) {\n violations.push({\n ruleId: 'min_sensory_types',\n ruleName: '五感类型不足',\n message: `当前仅激活 ${activeTypes} 种感官描写,建议至少 ${thresholds.minSensoryTypes} 种`,\n severity: 'info',\n suggestion: '除了视觉描写,可加入听觉、触觉、嗅觉等多感官细节',\n });\n }\n\n // 视觉占比过高\n if (totalSensory > 5) {\n const sightCount = sensory.sight || 0;\n const sightRatio = sightCount / totalSensory;\n if (sightRatio > thresholds.sightRatio) {\n violations.push({\n ruleId: 'sight_ratio',\n ruleName: '视觉描写占比过高',\n message: `视觉描写占比 ${(sightRatio * 100).toFixed(0)}%,上限为 ${(thresholds.sightRatio * 100).toFixed(0)}%`,\n severity: 'info',\n suggestion: '减少纯视觉描写,加入其他感官体验',\n });\n }\n }\n}\n\n// ============================================================\n// 违规扣分计算\n// ============================================================\n\n/**\n * 根据违规项对基础分进行扣分\n * error级扣10分,warning级扣3分,info级扣1分\n */\nfunction applyViolationPenalty(baseScore: number, violations: RuleViolation[]): number {\n let penalty = 0;\n for (const v of violations) {\n switch (v.severity) {\n case 'error':\n penalty += 10;\n break;\n case 'warning':\n penalty += 3;\n break;\n case 'info':\n penalty += 1;\n break;\n }\n }\n // 扣分上限:最多扣40分\n return baseScore - Math.min(penalty, 40);\n}\n\n// ============================================================\n// V3.0 追读力5项检测实现\n// ============================================================\n\n/** 强感官刺激词(开头用) */\nconst STRONG_SENSORY_WORDS = [\n '疼', '痛', '烫', '冷', '凉', '麻', '震', '响', '亮', '黑', '酸', '软',\n '僵', '紧', '嗡', '抖', '颤', '炸', '轰', '砰', '当', '咔',\n '喘不上气', '眼前一黑', '炸响', '刺骨', '灼痛', '剧痛', '发凉', '发麻',\n '发紧', '窒息', '心悸', '冷汗', '汗毛倒竖', '鸡皮疙瘩', '胃里一缩',\n '血冲上头顶', '呼吸一滞', '后颈一凉', '后背发凉',\n];\n\n/** 套路反应黑名单词(网文高频AI味身体反应,必须替换为具象生理反应) */\nconst CLICHE_REACTIONS = [\n // 高频套路词\n '微微一笑', '淡淡一笑', '笑了笑', '点了点头', '点点头', '叹了口气',\n '摇了摇头', '皱了皱眉', '眉头一皱', '眉头紧锁', '嘴角微扬', '嘴角上扬',\n '勾起嘴角', '抿了抿嘴', '撇了撇嘴', '翻了个白眼', '冷哼一声', '冷笑一声',\n '嗤笑一声', '轻笑一声', '苦笑一声', '深吸一口气', '松了口气', '松了一口气',\n '心中一动', '目光一闪', '眼中闪过', '瞳孔一缩', '瞳孔骤缩', '眼中寒光',\n // AI常用套路\n '心头一跳', '脸色一变', '握紧拳头', '不由得', '情不自禁', '忍不住笑',\n '不仅皱了皱眉', '不仅心中一紧', '不仅倒吸一口凉气', '不仅心中暗道',\n '不禁想到', '不仅感叹', '倒吸一口凉气', '倒吸了口凉气', '心中一凛',\n '眼中闪过一丝', '嘴角勾起一抹', '不禁笑了', '眉头微蹙', '神色一凝',\n '脸色微变', '面色一沉', '眸中闪过', '眼底闪过',\n];\n\n/** 对话中否定/反对/质疑/冲突词(启发式检测对话碰撞) */\nconst DIALOGUE_CONFLICT_WORDS = [\n '不对', '不可能', '扯蛋', '放屁', '错了', '等一下', '等等',\n '你确定', '不可能吧', '不对吧', '胡说', '瞎说', '怎么可能',\n '没道理', '奇怪', '不对劲', '有问题', '等会儿', '别急',\n '不是', '错', '停', '闭嘴', '你疯了', '凭什么', '为什么',\n '你胡说', '我不信', '不可能', '不行', '滚开', '滚',\n '你再说一遍', '你什么意思', '什么意思', '你骗我',\n];\n\n/** 转折/意外/反咬词(启发式检测信息反咬) */\nconst TWIST_WORDS = [\n '但是', '但', '可是', '然而', '却', '竟然', '居然', '突然',\n '不对', '奇怪', '怎么', '为什么', '难道', '不是', '反而',\n '相反', '没想到', '原来', '其实', '实际上', '等等',\n '等一下', '不对劲', '有问题', '不可能', '错了',\n // V3.1扩充:动作/认知反转词\n '猛地', '刹住', '停住', '僵住', '愣住', '怔住', '一把',\n '错了', '反了', '疯了', '完了', '糟了',\n '不对', '不是', '没有', '并没', '并非',\n '哪知道', '谁知道', '出乎意料',\n];\n\n/** 单句鼓点检测:≤8字+以句号/感叹号/问号结尾+包含强冲击词,算作反咬落点 */\nfunction isPunchLine(para: string): boolean {\n const trimmed = para.trim();\n if (trimmed.length === 0) return false;\n // 单句成段且≤10字,结尾是句号/感叹号/问号\n const sentences = trimmed.split(/[。!?!?]/).filter(s => s.trim().length > 0);\n if (sentences.length !== 1) return false;\n const len = trimmed.replace(/\\s/g, '').length;\n if (len > 12) return false;\n if (!/[。!?!?…]$/.test(trimmed)) return false;\n // 包含强冲击词\n const punchWords = ['疼', '痛', '血', '死', '杀', '凉', '冷', '烫', '麻', '黑', '亮',\n '逃', '跑', '停', '动了', '来了', '响', '碎', '倒', '掉', '僵',\n '吸光', '冒烟', '搏动', '在爬', '在流', '发光', '敲门',\n '跪', '喊', '吼', '跪', '不是', '不对', '没有', '不可能',\n // 拟声词鼓点\n '咚', '砰', '咔', '当', '叮', '啪', '嘶', '嗡', '哗', '嘎', '铛'];\n return punchWords.some(w => trimmed.includes(w));\n}\n\n/** 检查项9:开头冲击检测 */\nfunction checkOpeningImpact(\n text: string,\n _stats: TextStats,\n _thresholds: Thresholds,\n violations: RuleViolation[]\n): void {\n // 取前3个非空段落\n const paragraphs = text.split(/\\n+/).filter((p) => p.trim().length > 0);\n if (paragraphs.length === 0) return;\n\n const first3 = paragraphs.slice(0, 3).join('\\n');\n const firstSentence = first3.split(/[。!?!?]/)[0]?.trim() || '';\n\n // 检查第一句是否以环境/背景开头(启发式:以\"XX的\"\"在XX\"\"有一个\"开头且没有强感官词)\n const envStartPatterns = /^(这是|在一个|话说|从前|很久|矿道里|走廊|房间里|大街上|壁面|街道|天空|夜色|清晨|傍晚|午后|今天|那天|这一天|清晨的|夜晚的|城市里|村子里)/;\n const hasStrongSensory = STRONG_SENSORY_WORDS.some((w) => firstSentence.includes(w));\n const isShortPunch = firstSentence.replace(/\\s/g, '').length <= 8; // 短句开头(≤8字)\n\n if (!hasStrongSensory && !isShortPunch && envStartPatterns.test(firstSentence)) {\n violations.push({\n ruleId: 'opening_impact',\n ruleName: '开头缺乏冲击力',\n message: '第一句是环境/背景描写式开头,建议用强感官刺激(疼/烫/麻/响/冷/凉)开头,0.5秒内把读者拽进场景',\n severity: 'warning',\n position: { from: 0, to: firstSentence.length },\n suggestion: '参考:第一句极短句感官轰炸(如\"凉。\"\"痛!\"\"麻。\"\"响。\"),第二句本能反应,第三句交代场景',\n });\n }\n\n // 检查前200字是否有身体锚点(V3.1强化:包含单字感官鼓点开头)\n const first200 = text.substring(0, Math.min(200, text.length));\n // 模式1:身体部位+感觉词组合\n const bodyReactionPattern = /(后颈|脖颈|颈|脊背|后背|背|心脏|心|掌心|掌|指尖|指节|指|手|肩|喉咙|喉|胃|腹|腿|脚|皮肤|皮|冷汗|汗|汗毛|毛|骨|牙|眼|眉|鼻尖|鼻翼|耳根|腕|胸口|胸|肺|太阳穴|虎口|锁骨|牙根|指腹|拳头|牙关|眼眶|颧|脊背|胃里|后背|浑身|全身|毛孔).{0,6}(凉|冷|麻|紧|僵|抖|颤|跳|震|沉|酸|软|疼|痛|灼|汗|嗡|缩|悸|窒|热|烫|湿|干|硬|软|一凉|一麻|一紧|一沉|一缩|发紧|发凉|发麻|发烫|狂跳|咯噔|翻腾|窒息|泛起|冷汗|汗毛竖|起鸡皮|绷紧|僵硬)/;\n // 模式2:单字感官鼓点开头(疼。/痛。/凉。/烫。/麻。/响。)\n const singlePunchOpening = /^\\s*(疼|痛|凉|冷|烫|麻|响|血|黑|亮|动了|不对)\\s*[。!?!?…]/m;\n // 模式3:直接身体反应短语\n const directBodyPhrase = /(呼吸一滞|呼吸停|屏住呼吸|心跳加速|心跳漏|汗毛竖起|鸡皮疙瘩|倒吸凉气|倒吸一口|胃里一缩|胃里翻腾|喉咙发紧|后背发凉|掌心冒汗|后颈一凉|眼前一黑|耳朵嗡|脑子嗡|血往上冲|脸白了|脸色煞白|脸色发白)/;\n const bodyReactionInOpening = bodyReactionPattern.test(first200) || singlePunchOpening.test(first200) || directBodyPhrase.test(first200);\n if (!bodyReactionInOpening && text.length > 500) {\n violations.push({\n ruleId: 'opening_no_body',\n ruleName: '开头缺少身体锚点',\n message: '开头前200字内没有主角身体反应描写,读者无法第一时间代入',\n severity: 'warning',\n suggestion: '开头200字内必须给出主角的生理反应(后颈发凉/掌心发麻/呼吸一滞/指节攥紧/心跳加速/胃里一缩)',\n });\n }\n\n // 检查第一句是否过长(>25字且不是短句冲击)\n const firstLen = firstSentence.replace(/\\s/g, '').length;\n if (firstLen > 30 && !isShortPunch && text.length > 500) {\n violations.push({\n ruleId: 'opening_too_long',\n ruleName: '开篇首句过长',\n message: `第一句${firstLen}字过长,网文黄金三句要求首句≤15字快速切入`,\n severity: 'info',\n suggestion: '把首句砍到15字以内,最好是5-8字的感官冲击短句',\n });\n }\n\n // V3.1读者视角校准:检测\"XX的时候,XX\"时间状语从句开场(力度弱)\n if (/的时候[,,]/.test(firstSentence) && firstLen > 15) {\n violations.push({\n ruleId: 'opening_weak_adverbial',\n ruleName: '开头铺垫过弱',\n message: '第一句用了\"XX的时候,XX\"时间状语从句开场,力度不够,慢了半拍',\n severity: 'warning',\n suggestion: '第一句直接砸正在发生的身体刺激:疼/烫/凉/响/震。不要先写\"在什么时间发生了什么\",直接写刺激本身。\\n反面:\"玉碑碎的时候,苏明的掌心按在碑面上。\"\\n正面:\"疼。钻心的疼从指尖窜上来,玉碑碎了。\"',\n });\n }\n}\n\n/** 检查项10:套路反应黑名单 */\nfunction checkClicheReactions(\n text: string,\n violations: RuleViolation[]\n): void {\n for (const cliche of CLICHE_REACTIONS) {\n let idx = text.indexOf(cliche);\n while (idx !== -1) {\n violations.push({\n ruleId: 'cliche_reaction',\n ruleName: 'AI套路反应',\n message: `使用了AI套路反应词\"${cliche}\",建议替换为生理级身体反应`,\n severity: 'warning',\n position: { from: idx, to: idx + cliche.length },\n suggestion: '替换为具体生理反应:后颈汗毛竖起/后背冷汗/胃猛地一缩/后槽牙咬紧/呼吸卡在喉咙里/耳朵嗡的一声',\n });\n idx = text.indexOf(cliche, idx + cliche.length);\n // 只报前3个,避免信息过载\n if (violations.filter((v) => v.ruleId === 'cliche_reaction').length >= 3) break;\n }\n if (violations.filter((v) => v.ruleId === 'cliche_reaction').length >= 3) break;\n }\n}\n\n/** 检查项11:碎句病检测(同一段落内连续3个以上≤12字短句且无转折/无对话/无新信息/无单句成段) */\nfunction checkFragmentedSentences(\n text: string,\n _stats: TextStats,\n violations: RuleViolation[]\n): void {\n // 按段落检测:只有同一段落内连续短句才算碎句病\n // 网文正确写法:短句单独成段做鼓点(一句一段),这不是碎句病\n const paragraphs = text.split(/\\n+/).map(p => p.trim()).filter(p => p.length > 0);\n let violationCount = 0;\n\n for (const para of paragraphs) {\n const sentenceRegex = /[^。!?!?]+[。!?!?]?/g;\n const matches = para.match(sentenceRegex);\n if (!matches || matches.length < 3) continue; // 段落内少于3句不检测\n\n const sentences = matches.map((s) => s.trim()).filter((s) => s.length > 0);\n let consecutiveShort = 0;\n\n for (let i = 0; i < sentences.length; i++) {\n const len = sentences[i].replace(/\\s/g, '').length;\n const hasTwist = TWIST_WORDS.some((w) => sentences[i].includes(w));\n const hasDialogue = /[\"\"「」『』]/.test(sentences[i]);\n const hasStrongEmotion = /(!|!)/.test(sentences[i]);\n const isPunch = isPunchLine(sentences[i] + '。'); // 单句检测\n const isShort = len <= 12;\n\n if (isShort && !hasTwist && !hasDialogue && !hasStrongEmotion && !isPunch) {\n consecutiveShort++;\n } else {\n if (consecutiveShort >= 3) {\n violations.push({\n ruleId: 'fragmented_sentences',\n ruleName: '碎句病',\n message: `同一段落内连续 ${consecutiveShort} 个短句(≤12字)且无转折/无对话/无感叹,节奏断裂。段落内容:\"${para.substring(0, 60)}${para.length > 60 ? '...' : ''}\"`,\n severity: 'warning',\n suggestion: '短句单独成段是鼓点(正确写法),但同一段落内连续多个无转折短句就是碎句病。将同一动作链内的短句用逗号合并,短句只用于危险/发现/反咬/钩子等鼓点位置(单独成段)。',\n });\n violationCount++;\n if (violationCount >= 2) return; // 最多报2个\n }\n consecutiveShort = 0;\n }\n }\n\n // 段落末尾检查\n if (consecutiveShort >= 3) {\n violations.push({\n ruleId: 'fragmented_sentences',\n ruleName: '碎句病',\n message: `同一段落内连续 ${consecutiveShort} 个短句(≤12字)且无转折/无对话/无感叹,节奏断裂`,\n severity: 'warning',\n suggestion: '短句单独成段是鼓点(正确写法),但同一段落内连续多个无转折短句就是碎句病。将同一动作链内的短句用逗号合并,短句只用于危险/发现/反咬/钩子等鼓点位置(单独成段)。',\n });\n violationCount++;\n if (violationCount >= 2) return;\n }\n }\n}\n\n/** 检查项12:对话碰撞检测(启发式:对话中否定/反对词密度) */\nfunction checkDialogueConflict(\n text: string,\n stats: TextStats,\n violations: RuleViolation[]\n): void {\n // 如果对话占比过低(<5%),跳过\n if (stats.dialogueRatio < 0.05) return;\n\n // 提取所有对话内容\n const dialogueRegex = /[\"\"「」『』]([^\"\"「」『』]{1,})[\"\"「」『』]/g;\n const dialogues: string[] = [];\n let dm: RegExpExecArray | null;\n while ((dm = dialogueRegex.exec(text)) !== null) {\n dialogues.push(dm[1]);\n }\n\n if (dialogues.length < 4) return; // 对话太少,不检测\n\n // 统计对话中否定/反对词数量\n let conflictCount = 0;\n for (const d of dialogues) {\n if (DIALOGUE_CONFLICT_WORDS.some((w) => d.includes(w))) {\n conflictCount++;\n }\n }\n\n // 如果对话超过4句,但没有任何反对/否定/质疑词,报warning\n if (dialogues.length >= 4 && conflictCount === 0) {\n violations.push({\n ruleId: 'dialogue_conflict',\n ruleName: '对话缺乏碰撞',\n message: `检测到 ${dialogues.length} 句对话,但没有任何反对/质疑/否定,对话像工作汇报而非角色碰撞`,\n severity: 'warning',\n suggestion: '角色说出判断后,下一个人先反对/质疑;至少一人做出错误判断;对话中用动作打断',\n });\n }\n}\n\n/** 检查项13:章末钩子检测(V3强化版) */\nfunction checkEndingHook(\n text: string,\n _stats: TextStats,\n _thresholds: Thresholds,\n violations: RuleViolation[]\n): void {\n if (text.length < 800) return; // 短章节不检测\n\n // 找最后一句(保留标点)\n const tail = text.substring(Math.max(0, text.length - 400));\n const sentenceEndRegex = /[。!?!?…]+[^。!?!?…]*$/;\n const endMatch = tail.match(sentenceEndRegex);\n const lastChunk = (endMatch ? endMatch[0] : tail).replace(/^[\\s\\n]+/, '');\n const lastSentence = lastChunk.replace(/[。!?!?…\\s]+$/, '').trim();\n const lastPuncMatch = lastChunk.match(/[。!?!?…]+$/);\n const lastPunc = lastPuncMatch ? lastPuncMatch[0] : '';\n const lastChar = lastSentence.slice(-1);\n\n // 检查最后150字转折词\n const last150 = text.substring(Math.max(0, text.length - 150));\n const hasTwistAtEnd = TWIST_WORDS.some((w) => last150.includes(w)) ||\n /[??]/.test(last150) ||\n /突然|竟然|居然|原来|其实|不是|反而|不对|不可能|等等|醒了|来了|动了|亮了|灭了|开了/.test(last150);\n\n // 检查是否有新信息/悬念/危险在结尾\n const hasNewInfo = /(发现|意识到|看到|听到|感觉到|不对|奇怪|难道|不可能|竟然|居然|原来|其实|不是)/.test(last150);\n const hasDanger = /(危险|杀|死|血|塌|崩|裂|灭|黑|凉|冷|逃|跑|躲|追|来了|到了)/.test(last150);\n const hasQuestion = /[??]/.test(lastPunc);\n\n // 情况1:以\"了。\"结尾,叙事闭合,没有转折/新信息/危险\n const isNarrativeClosure = /了。$/.test(lastChunk.trimEnd()) ||\n (/[了的是着过]$/.test(lastChar) && /[。.]/.test(lastPunc) && !hasTwistAtEnd && !hasNewInfo && !hasDanger);\n\n if (isNarrativeClosure) {\n violations.push({\n ruleId: 'ending_hook',\n ruleName: '章末钩子不足',\n message: '最后一句是判断式/叙事闭合结尾(\"了。\"收束),读者读完就放下了',\n severity: 'warning',\n position: { from: Math.max(0, text.length - lastChunk.length), to: text.length },\n suggestion: '结尾100字内引入新信息/新危险/颠覆认知:①突然发现不对 ②某个东西动了/来了/亮了/灭了 ③未解问题用问号收尾 ④动作断裂在半空中',\n });\n return;\n }\n\n // 情况2:最后一句以总结性词语开头\n if (/^(就这样|原来如此|所以|于是|最终|最后|总之|总而言之|这一天|那天以后)/.test(lastSentence.trim())) {\n violations.push({\n ruleId: 'ending_summary',\n ruleName: '章末总结收束',\n message: '结尾用总结性词语收束,破坏追读欲望',\n severity: 'warning',\n suggestion: '删掉总结句,在最后50字内加入一个新的、未解释的异常信号',\n });\n return;\n }\n\n // 情况3:最后一句是长句(>25字),不是短句鼓点落点\n const lastLen = lastSentence.replace(/\\s/g, '').length;\n if (lastLen > 25 && !hasQuestion && !hasNewInfo && !hasDanger) {\n violations.push({\n ruleId: 'ending_weak',\n ruleName: '章末落点太软',\n message: `最后一句${lastLen}字过长,且无问号/新信息/危险信号,落点不够有力`,\n severity: 'info',\n suggestion: '章末最后一句建议≤15字短句鼓点落点,用动作/感官/发现/问题结尾',\n });\n }\n}\n\n/** 检查项14:信息反咬密度检测(V3新增) */\nfunction checkTwistDensity(\n text: string,\n _stats: TextStats,\n _thresholds: Thresholds,\n violations: RuleViolation[]\n): void {\n if (text.length < 1000) return; // 短章节不检测\n\n const paragraphs = text.split(/\\n+/).filter((p) => p.trim().length > 0);\n let consecutiveNoTwist = 0;\n let maxConsecutive = 0;\n let totalTwists = 0;\n\n for (const para of paragraphs) {\n const hasTwist = TWIST_WORDS.some((w) => para.includes(w)) ||\n STRONG_SENSORY_WORDS.slice(0, 25).some((w) => para.includes(w)) ||\n isPunchLine(para); // V3.1:单句鼓点也算反咬落点\n if (hasTwist) {\n totalTwists++;\n consecutiveNoTwist = 0;\n } else {\n consecutiveNoTwist++;\n maxConsecutive = Math.max(maxConsecutive, consecutiveNoTwist);\n }\n }\n\n const totalChars = text.replace(/\\s/g, '').length;\n const twistPer1000 = (totalTwists / totalChars) * 1000;\n\n // 连续4段以上没有任何转折/意外/反咬\n if (maxConsecutive >= 4) {\n violations.push({\n ruleId: 'twist_gap',\n ruleName: '连续段落无反转',\n message: `连续${maxConsecutive}段没有任何信息反咬/意外/转折,读者注意力会涣散`,\n severity: 'warning',\n suggestion: '每2-3段(约300-500字)必须有一次信息反咬:读者预期被颠覆、发现不对、突然变化、人物做出反常反应',\n });\n }\n\n // 千字反咬密度低于2个\n if (twistPer1000 < 2 && totalChars > 1500) {\n violations.push({\n ruleId: 'twist_density_low',\n ruleName: '信息反咬密度不足',\n message: `千字反咬密度仅${twistPer1000.toFixed(1)}个,追读文要求每千字≥3个意外/转折/发现`,\n severity: 'info',\n suggestion: '增加\"但是/不对/奇怪/竟然/没想到/原来/其实\"等信息反转词的使用频率,不断给读者新的认知冲击',\n });\n }\n}\n\n// ===== V3.1 新增:2026网文追读力铁则检测器 =====\n\n/** 开篇环境描写黑名单词 */\nconst OPENING_SCENERY_WORDS = [\n '天刚亮', '清晨', '傍晚', '深夜', '夜色', '月光', '阳光',\n '寒风', '大雪', '小雨', '暴雨', '乌云', '蓝天', '白云',\n '村子里', '小镇上', '城市里', '大陆', '世界', '纪元',\n '巍峨', '连绵', '高耸', '古老', '破旧', '繁华', '荒凉',\n '在这个', '在一座', '在一片', '这是一个', '那是一个',\n '很久以前', '从前', '话说', '自从',\n];\n\n/** 假钩子/装神弄鬼黑名单词 */\nconst FAKE_HOOK_WORDS = [\n '一股神秘的', '一种莫名的', '一丝诡异的', '一股奇怪的',\n '他似乎意识到了什么', '她好像发现了什么', '他总觉得哪里不对',\n '一种不祥的预感', '一股寒意涌上心头', '一种说不出的感觉',\n '黑暗中有什么东西', '暗处有一双眼睛', '背后似乎有人',\n '这件事没那么简单', '这背后一定有隐情', '事情越来越不对劲',\n '他不知道的是', '没有人知道', '所有人都没发现',\n];\n\n/** 黄金300字必须出现的冲突/动作词 */\nconst GOLDEN_CONFLICT_WORDS = [\n '死', '杀', '血', '刀', '枪', '逃', '追', '打', '骂', '吼',\n '抓', '推', '撞', '摔', '碎', '塌', '崩', '裂', '炸', '烧',\n '危险', '不对', '该死', '操', '靠', '妈的', '跑', '快',\n '不', '别', '住手', '停', '滚', '你敢', '凭什么', '为什么',\n '怎么可能', '不可能', '竟然', '居然', '没想到', '不好',\n '系统', '绑定', '穿越', '重生', '觉醒', '激活', '弹窗',\n '离婚', '分手', '开除', '辞退', '赶出', '驱逐', '背叛',\n '发现', '意识到', '看到', '听见', '摸到',\n];\n\n/** 检查项15:黄金300字冲突检测(2026网文铁则:3秒停留率) */\nfunction checkGolden300(\n text: string,\n violations: RuleViolation[]\n): void {\n if (text.length < 300) return;\n\n const first300 = text.substring(0, 300);\n\n // 检查前300字内有没有冲突/动作/异常信号\n const hasConflict = GOLDEN_CONFLICT_WORDS.some((w) => first300.includes(w));\n const hasDialogue = /[\"\"「」『』]/.test(first300);\n const hasBodyReaction = STRONG_SENSORY_WORDS.slice(0, 30).some((w) => first300.includes(w));\n\n if (!hasConflict && !hasDialogue && !hasBodyReaction) {\n violations.push({\n ruleId: 'golden_300',\n ruleName: '黄金300字无冲突',\n message: '前300字内没有冲突爆发、没有动作、没有对话、没有身体反应,读者3秒就划走',\n severity: 'error',\n suggestion: '2026网文铁则:前300字必须完成「冲突爆发→主角在场→异常出现」三件事,不要写景、不要铺垫、不要回忆',\n });\n }\n\n // 检查第一段(第一句)长度,超过40字太长\n const firstPara = text.split(/\\n+/).find((p) => p.trim().length > 0) || '';\n const firstSentence = firstPara.split(/[。!?!?…]/)[0];\n if (firstSentence.length > 35) {\n violations.push({\n ruleId: 'golden_300',\n ruleName: '开篇首句过长',\n message: `开篇第一句${firstSentence.length}字,太长,读者扫一眼就划走`,\n severity: 'warning',\n suggestion: '开篇第一句必须≤20字,直接写动作/冲突/结果,比如\"刀尖抵住她喉结时,系统亮了。\"\"外门弟子林凡,一刀斩了大师兄。\"',\n });\n }\n}\n\n/** 检查项16:开篇禁忌检测(禁止写景/回忆/背景开头) */\nfunction checkOpeningTaboos(\n text: string,\n violations: RuleViolation[]\n): void {\n const first150 = text.substring(0, 150);\n const firstPara = text.split(/\\n+/).find((p) => p.trim().length > 0) || '';\n const firstSentence = firstPara.split(/[。!?!?…]/)[0].trim();\n\n // 检查第一句是不是环境描写开头\n for (const word of OPENING_SCENERY_WORDS) {\n if (firstSentence.includes(word) || first150.startsWith(word)) {\n violations.push({\n ruleId: 'opening_taboos',\n ruleName: '开篇写景/背景',\n message: `开篇用\"${word}\"等环境/背景词开头,浪费黄金3秒`,\n severity: 'warning',\n suggestion: '开篇禁止写景、禁止交代背景、禁止回忆前世。第一句直接写动作现场:谁在什么危险里,正在发生什么事。背景用一句话插在动作中间带过:\"这是灵气枯竭第27年,他正在被人追砍。\"',\n });\n break;\n }\n }\n\n // 检查前100字内有没有\"我叫XX\"\"我是XX\"\"XX今年XX岁\"这种自我介绍\n if (/^(我叫|我是|他叫|他是|.*今年\\d+岁|.*出生在)/.test(firstSentence) ||\n /我叫|我是.*,今年|名字叫/.test(first150.substring(0, 80))) {\n violations.push({\n ruleId: 'opening_taboos',\n ruleName: '开篇自我介绍',\n message: '开篇用自我介绍开头,是新人最常见的死亡开局',\n severity: 'warning',\n suggestion: '不要告诉读者主角是谁,要让读者在动作和冲突中自己认识主角。先写刀架在脖子上,再告诉读者这人是谁。',\n });\n }\n}\n\n/** 检查项17:装神弄鬼假钩子检测 */\nfunction checkFakeHooks(\n text: string,\n violations: RuleViolation[]\n): void {\n // 检查最后200字(钩子区域)\n const last200 = text.substring(Math.max(0, text.length - 200));\n\n for (const word of FAKE_HOOK_WORDS) {\n if (last200.includes(word)) {\n violations.push({\n ruleId: 'fake_hook',\n ruleName: '装神弄鬼假钩子',\n message: `结尾用了\"${word}\"这类空泛悬念,现在读者已经免疫了`,\n severity: 'info',\n suggestion: '钩子不能是\"有什么不对\",钩子必须是具体的信息:具体谁来了、具体发现了什么、具体哪句话不对、具体什么东西动了。比如\"他低头,看见凿尖上沾了血。\"比\"他觉得哪里不对\"有效100倍。',\n });\n break;\n }\n }\n}\n\n/** 检查项24:空洞四字成语/形容词堆砌检测(V3.1客观测试新增)\n * 扑街文/AI水文标志:大量使用\"巍峨壮丽\"、\"宛如仙境\"、\"天昏地暗\"这种空洞成语,没有具体细节\n */\nfunction checkClichéPhrases(\n text: string,\n violations: RuleViolation[]\n): void {\n // 网文最常见的空洞成语/套路形容词\n const clichéWords = [\n '巍峨壮丽','连绵起伏','宛如仙境','仙气氤氲','鳞次栉比','琼楼玉宇','金碧辉煌',\n '天昏地暗','日月无光','刀光剑影','真气激荡','飞沙走石','惊天动地','震耳欲聋',\n '气势磅礴','雄伟壮观','美不胜收','风景如画','古色古香','雕梁画栋','巧夺天工',\n '神采飞扬','容光焕发','英姿飒爽','威风凛凛','气宇轩昂','风度翩翩','一表人才',\n '波光粼粼','湖光山色','山清水秀','层峦叠嶂','云雾缭绕','霞光万道','瑞彩千条',\n '人山人海','摩肩接踵','人声鼎沸','水泄不通','车水马龙','热闹非凡',\n '电闪雷鸣','狂风大作','乌云密布','倾盆大雨','天寒地冻','烈日炎炎',\n '欣喜若狂','悲痛欲绝','怒发冲冠','胆战心惊','魂飞魄散','毛骨悚然',\n '时光飞逝','岁月如梭','光阴似箭','白驹过隙','弹指之间','转眼之间',\n '一飞冲天','一鸣惊人','飞黄腾达','平步青云','前程似锦','前途无量',\n '博大精深','源远流长','历史悠久','人杰地灵','物华天宝','钟灵毓秀',\n '不以为然','不屑一顾','嗤之以鼻','置若罔闻','熟视无睹','无动于衷',\n '滔滔不绝','口若悬河','能说会道','妙语连珠','出口成章','对答如流'\n ];\n\n let count = 0;\n const found: string[] = [];\n for (const w of clichéWords) {\n if (text.includes(w)) {\n count++;\n found.push(w);\n }\n }\n\n const totalChars = text.replace(/\\s/g, '').length;\n const density = totalChars > 0 ? (count / totalChars) * 1000 : 0;\n\n if (count >= 3 || density > 2.5) {\n const severity = count >= 5 ? 'warning' : 'info';\n violations.push({\n ruleId: 'cliché_phrases',\n ruleName: '空洞成语堆砌',\n message: `文中出现${count}个套路四字成语(${found.slice(0,3).join('、')}${count>3?'...':''}),千字密度${density.toFixed(1)}个,描写太笼统`,\n severity: severity as any,\n suggestion: '网文不要用成语写描写!\"巍峨壮丽\"读者脑子里没有画面,不如直接写\"山尖戳进云里,石头是黑的,风刮在脸上像刀子割\"。成语是总结,不是描写。把成语换成具体的颜色/触感/温度/声音/味道。',\n });\n }\n}\n\n/** 检查项25:前200字无人物冲突检测(V3.1客观测试新增)\n * 黄金三章铁则:开头必须立刻进人物/冲突,纯写景/纯背景介绍是死亡开局\n */\nfunction checkOpeningScene(\n text: string,\n violations: RuleViolation[]\n): void {\n if (text.length < 200) return;\n const opening = text.substring(0, 200);\n \n // 检查前200字里有没有人物代词/人名\n const personWords = ['我','你','他','她','它','我们','你们','他们','主角','少年','青年','男人','女人','老人','女孩','男孩','老子','老娘','爷','俺'];\n // 提取人名(简单的2-3字中文姓名检测)\n const nameRegex = /[\\u4e00-\\u9fa5]{2,3}(?=[说问喊叫笑道怒骂看盯望])/g;\n const hasPerson = personWords.some(w => opening.includes(w)) || nameRegex.test(opening);\n \n // 检查前200字里有没有身体动作/感官词\n const actionSenseWords = ['疼','痛','烫','凉','冷','热','麻','硬','软','响','声','味','喘','跳','震','手','眼','脚','嘴','脸','心','头','砸','砍','刺','抓','握','跑','喊','叫','碎','裂','喷','流','滴'];\n const hasAction = actionSenseWords.some(w => opening.includes(w));\n\n // 开头写景/写环境的标志词\n const sceneWords = ['山脉','山峰','大地','天空','苍穹','乾坤','宇宙','天地','大陆','世界','王朝','帝国','宗门','门派','家族','城市','都城','古城','小镇','村庄','森林','大海','草原','沙漠','雪山','云海','云雾','灵气','仙气','灵力','内力'];\n let sceneCount = 0;\n for (const w of sceneWords) {\n if (opening.includes(w)) sceneCount++;\n }\n\n if ((!hasPerson || !hasAction) && sceneCount >= 3) {\n violations.push({\n ruleId: 'opening_scene_setting',\n ruleName: '开头纯写景无人物',\n message: `前200字全是环境/背景描写,${!hasPerson ? '没有出现人物' : '没有人物动作/感官'},读者3秒划走`,\n severity: 'error',\n suggestion: '不要先写山多大、天多高、宗门多气派。读者不关心这个。第一句必须砸在人身上:要么疼、要么响、要么有人说话、要么血溅出来。等读者代入主角了,再慢慢写环境不迟。' +\n '\\n反面:\"青云山脉连绵起伏,巍峨壮丽,常年云雾缭绕,宛如仙境。\"' +\n '\\n正面:\"疼。李火旺睁开眼,后背硌在硬泥地上,一股子霉味往鼻子里钻。\"',\n });\n }\n}\n\n/** 检查项26:假动作/标签化反应检测(V3.1客观测试新增)\n * \"嘴角露出微笑\"、\"眼中闪过一丝寒光\"、\"紧紧握着拳头\"这种标签化假动作,不是真生理反应\n */\nfunction checkFakeReactions(\n text: string,\n violations: RuleViolation[]\n): void {\n const fakeReactions = [\n { pattern: /嘴角[微不]?露出[一几]?丝?[微]?(笑|冷笑|笑容|笑意|微笑|弧度)/g, label: '嘴角微笑' },\n { pattern: /眼中闪过[一几]?丝?(寒|冷|杀|不|欣|赞|异|讶|惊|诧|疑)(光|意|色|芒)/g, label: '眼中闪过X光' },\n { pattern: /[紧狠]?[紧狠]地握[住着]拳头/g, label: '紧握拳头' },\n { pattern: /心中[暗暗]?(想|道|说|发誓|决定|冷笑|得意|一惊|一动|一凛|一喜|怒)/g, label: '心中XX' },\n { pattern: /脸上露出[一几]?丝?(笑容|微笑|冷笑|惊讶|疑惑|不屑|欣慰|满意|复杂)(的表情|之色)?/g, label: '脸上露出表情' },\n { pattern: /不由得[露现浮]出/g, label: '不由得露出' },\n { pattern: /[缓缓缓]?[缓]?地(说|道|开口|回答|说道)/g, label: '缓缓地说' },\n { pattern: /[语气|眼神|目光][中里][充满带闪]着/g, label: '语气/眼神中充满' },\n { pattern: /[不]由[自主得]?地/g, label: '不由自主' },\n { pattern: /[上下]打量[了]?[一]?[番眼]?/g, label: '打量一番' },\n ];\n\n let total = 0;\n const found: string[] = [];\n for (const fr of fakeReactions) {\n const matches = text.match(fr.pattern);\n if (matches) {\n total += matches.length;\n found.push(fr.label);\n }\n }\n\n const totalChars = text.replace(/\\s/g, '').length;\n const density = totalChars > 0 ? (total / totalChars) * 1000 : 0;\n\n if (total >= 3 || density > 2) {\n violations.push({\n ruleId: 'fake_reactions',\n ruleName: '标签化假反应',\n message: `文中出现${total}个标签化假动作(${[...new Set(found)].slice(0,3).join('、')}),千字${density.toFixed(1)}个,这是告诉读者情绪,不是让读者感受到情绪`,\n severity: 'warning',\n suggestion: '不要写\"他嘴角露出冷笑\",写他具体做了什么:他把烟按灭在桌上,烟灰弹在对方脸上,没说话。' +\n '不要写\"眼中闪过一丝寒光\",写具体的生理反应:他瞳孔缩了一下,指节捏得发白。' +\n '不要写\"心中暗暗发誓\",直接写他做了什么动作/说了什么话。Show, don\\'t tell。',\n });\n }\n}\n\n/** 检查项23:重复句子/段落检测(V3.1读者视角校准)\n * 连续重复或高度相似的句子/段落是严重低级错误\n */\nfunction checkRepetition(\n text: string,\n violations: RuleViolation[]\n): void {\n const paragraphs = text.split(/\\n+/).map(p => p.trim()).filter(p => p.length > 8);\n \n // 检查完全重复的段落\n const seen = new Map<string, number>();\n for (let i = 0; i < paragraphs.length; i++) {\n const p = paragraphs[i];\n if (seen.has(p)) {\n violations.push({\n ruleId: 'repetition',\n ruleName: '重复段落',\n message: `第${i+1}段和第${seen.get(p)!+1}段完全重复,这是严重错误`,\n severity: 'error',\n suggestion: '删除重复段落,检查是不是复制粘贴错误。读者看到重复内容会直接出戏,甚至以为是AI生成的垃圾。',\n });\n } else {\n seen.set(p, i);\n }\n }\n\n // 检查高度相似的句子(连续两句相同率>70%)\n const sentences: string[] = [];\n const sentenceRegex = /[^。!?!?\\n]+[。!?!?]?/g;\n let m: RegExpExecArray | null;\n while ((m = sentenceRegex.exec(text)) !== null) {\n const s = m[0].trim();\n if (s.length > 10) sentences.push(s);\n }\n \n for (let i = 1; i < sentences.length; i++) {\n const prev = sentences[i-1];\n const curr = sentences[i];\n // 简单相似度:相同字符数/总字符数\n let sameChars = 0;\n const minLen = Math.min(prev.length, curr.length);\n for (let j = 0; j < minLen; j++) {\n if (prev[j] === curr[j]) sameChars++;\n }\n const similarity = sameChars / Math.max(prev.length, curr.length);\n if (similarity > 0.75 && prev.length > 15 && curr.length > 15) {\n violations.push({\n ruleId: 'repetition_sentence',\n ruleName: '句子重复啰嗦',\n message: `连续两句高度相似(相似度${(similarity*100).toFixed(0)}%),内容在重复`,\n severity: 'warning',\n suggestion: '删掉其中一句,或者把两句话合并成一句推进信息。不要一句话翻来覆去说。',\n });\n break; // 只报第一个\n }\n }\n}\n\n// ===== V3.1实战新增检测器(6题材实战发现)=====\n\n/** 嗅觉/味觉关键词 */\nconst SMELL_TASTE_WORDS = [\n // 嗅觉\n '味道', '气味', '闻到', '嗅', '香', '臭', '腥', '腐', '焦', '糊',\n '铁锈味', '血腥味', '甜味', '苦味', '酸味', '辣味', '咸味',\n '兰花香', '桂花香', '酒香', '药味', '硝烟味', '硝烟', '汽油味',\n '霉味', '潮味', '泥土味', '金属味', '硫磺味', '檀香味', '脂粉味',\n '烟味', '汗味', '体香', '奶香', '血腥味', '焦糊味', '刺鼻',\n // 味觉\n '嘴里发苦', '舌尖', '甜', '苦', '咸', '涩', '辣', '酸', '腥',\n '嘴里发涩', '回甘', '辛辣', '咸腥', '满嘴', '入口', '嚼', '咽',\n];\n\n/** 触觉关键词(除了视觉和听觉的身体感知) */\nconst TOUCH_WORDS = [\n '烫', '凉', '冷', '冰', '热', '温', '暖', '疼', '痛', '麻', '痒',\n '硬', '软', '黏', '滑', '糙', '涩', '湿', '干', '紧', '松',\n '震', '抖', '颤', '晃', '压', '顶', '刺', '割', '扎', '勒',\n '指尖', '掌心', '后背', '脊背', '后颈', '皮肤', '毛孔',\n '鸡皮疙瘩', '汗毛竖起', '冷汗', '汗水', '温度', '质感',\n];\n\n/** 检查项18:五感平衡检测 */\nfunction checkSensoryBalance(\n text: string,\n _stats: TextStats,\n violations: RuleViolation[]\n): void {\n if (text.length < 500) return; // 短章节不检测\n\n // 统计五感激活情况\n const hasVision = /(看|望|盯|瞧|见|光|色|亮|暗|黑|白|红|影|画面|映入|眼前)/.test(text);\n const hasHearing = /(听|响|声|音|静|喊|叫|说|问|答|咚|咔|砰|嗡|哗|嘶)/.test(text);\n const hasSmellTaste = SMELL_TASTE_WORDS.some((w) => text.includes(w));\n const hasTouch = TOUCH_WORDS.some((w) => text.includes(w));\n\n const senses = [hasVision, hasHearing, hasSmellTaste, hasTouch].filter(Boolean).length;\n const hasBodySense = hasSmellTaste || hasTouch;\n\n // 少于3种感官\n if (senses < 3) {\n const missing: string[] = [];\n if (!hasSmellTaste) missing.push('嗅觉/味觉');\n if (!hasTouch) missing.push('触觉/温度');\n violations.push({\n ruleId: 'sensory_balance',\n ruleName: '五感失衡',\n message: `当前只激活了${senses}种感官${missing.length ? ',缺少:' + missing.join('、') : ''},沉浸感不足`,\n severity: 'info',\n suggestion: '除了视觉和听觉,至少加入一种嗅觉/味觉(什么味道?铁锈?甜?苦?)或触觉/温度(烫?凉?麻?疼?),沉浸感立刻提升。恐怖/悬疑场景必须有触觉或嗅觉。',\n });\n }\n\n // 超过800字的场景如果只有视觉+听觉,没有触觉/嗅觉\n if (text.length > 800 && !hasBodySense) {\n violations.push({\n ruleId: 'sensory_balance',\n ruleName: '缺少身体感官',\n message: '章节超过800字但没有任何嗅觉/味觉/触觉/温度描写,像在看监控录像,没有代入感',\n severity: 'warning',\n suggestion: '加入具体的身体感知:空气是什么温度?什么味道?手里的东西是什么质感?后颈有没有发凉?皮肤有没有起鸡皮疙瘩?读者通过主角的身体\"在场\"。',\n });\n }\n}\n\n/** 检查项19:钩子具体性检测 */\nfunction checkHookConcreteness(\n text: string,\n violations: RuleViolation[]\n): void {\n if (text.length < 500) return;\n\n const tail = text.substring(Math.max(0, text.length - 200));\n\n // 找最后一句话\n const sentenceEndRegex = /[。!?!?…]+[^。!?!?…]*$/;\n const endMatch = tail.match(sentenceEndRegex);\n const lastChunk = (endMatch ? endMatch[0] : tail).replace(/^[\\s\\n]+/, '');\n const lastSentence = lastChunk.replace(/[。!?!?…\\s]+$/, '').trim();\n\n // 最后一句是\"像XX\"比喻句\n if (/^(像|如|仿佛|好似|就像|如同)/.test(lastSentence) ||\n (lastSentence.includes('像') && lastSentence.length < 20)) {\n violations.push({\n ruleId: 'hook_concreteness',\n ruleName: '钩子用抽象比喻收尾',\n message: `章末最后一句\"${lastSentence}\"是比喻句收尾,太抽象,读者没有具体画面`,\n severity: 'info',\n suggestion: '好钩子是具体的人/物/事/声音/动作,不是比喻。把\"像心跳\"改成\"咚。咚。咚。声音是从隔壁传来的。\"把\"像地狱\"改成\"他低头,看见自己的影子多了一只手。\"',\n });\n }\n}\n\n/** 检查项20:连续比喻检测 */\nfunction checkSimileDensity(\n text: string,\n violations: RuleViolation[]\n): void {\n const paragraphs = text.split(/\\n+/).filter((p) => p.trim().length > 20);\n let totalSimiles = 0;\n\n for (const para of paragraphs) {\n const matches = para.match(/像[^,。!?]{2,15}[,,。!?]/g) || [];\n const matches2 = para.match(/仿佛[^,。!?]{2,15}[,,。!?]/g) || [];\n const matches3 = para.match(/如[^,。!?]{2,10}[,,。!?]/g) || [];\n const paraSimiles = matches.length + matches2.length + matches3.length;\n totalSimiles += paraSimiles;\n\n if (paraSimiles >= 2 && para.length < 200) {\n violations.push({\n ruleId: 'simile_density',\n ruleName: '连续比喻过密',\n message: `同一段落内出现${paraSimiles}个\"像/仿佛/如\"比喻,描写密度过高`,\n severity: 'warning',\n suggestion: '比喻不要连用。网文节奏快,最好的描写是直接写具体细节,不是写\"像什么\"。\"像被铁钳夹住\"不如直接写\"指骨在响\",\"像潮水一样\"不如直接写\"凉意在脊背炸开\"。',\n });\n }\n }\n\n // 千字比喻密度(V3.1读者视角校准)\n const totalChars = text.replace(/\\s/g, '').length;\n const density = totalChars > 0 ? (totalSimiles / totalChars) * 1000 : 0;\n if (density > 5) {\n violations.push({\n ruleId: 'simile_density_global',\n ruleName: '比喻过多',\n message: `全文比喻密度千字${density.toFixed(1)}个,超过5个/千字`,\n severity: 'info',\n suggestion: '网文是快节奏叙事,不是散文。把\"像XX一样\"的比喻砍掉一半,换成直接的动作/生理反应/具体细节,力量感会强很多。',\n });\n }\n}\n\n/** 不必要英文词(常见英文夹词,非专有名词) */\nconst UNNECESSARY_ENGLISH = [\n 'drunk', 'ok', 'OK', 'Okay', 'okay', 'yes', 'no', 'sorry', 'hello',\n 'hi', 'hey', 'bye', 'good', 'bad', 'cool', 'nice',\n];\n\n/** 专有名词白名单(允许出现的英文) */\nconst ENGLISH_WHITELIST = [\n 'APP', 'App', 'app', 'AI', 'CP', 'DNA', 'GPS', 'KTV', 'PPT', 'PS',\n 'VIP', 'WiFi', 'Wi-Fi', 'USB', 'GDP', 'ICU', 'ID', 'IP', 'IT',\n 'OK', 'OKR', 'PC', 'PE', 'PS', 'P2P', 'SUV', 'TV', 'UI', 'UFO',\n 'V信', 'X光', 'B超', 'O型血', 'A股', 'B股',\n];\n\n/** 检查项21:不必要英文检测 */\nfunction checkUnnecessaryEnglish(\n text: string,\n violations: RuleViolation[]\n): void {\n for (const word of UNNECESSARY_ENGLISH) {\n // 检查单词边界(避免匹配到中文里的偶然字符组合)\n const regex = new RegExp(`(?:^|[\\\\s,。!?!?…\"「」『』、])${word.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}(?=[\\\\s,。!?!?…\"「」『』、]|$)`);\n if (regex.test(text) && !ENGLISH_WHITELIST.includes(word)) {\n violations.push({\n ruleId: 'unnecessary_english',\n ruleName: '不必要英文词',\n message: `中文网文中出现了非必要的英文词\"${word}\",影响沉浸感`,\n severity: 'info',\n suggestion: '把英文换成中文表达:drunk→喝醉的/醉醺醺的,ok→好的/行,sorry→对不起/抱歉,cool→帅/酷(口语可用但书面建议避免)。',\n });\n break;\n }\n }\n}\n","// ============================================================\n// GWE V2.0 - AI提示词7层拼装器\n// 按优先级顺序拼装system prompt和user message\n// ============================================================\n\nimport type {\n WritingContext,\n MergedConfig,\n Preset,\n Character,\n NodeId,\n OptionId,\n} from './types';\nimport { getAllNodes, getNodeOption } from './node-registry';\n\n// ============================================================\n// 任务类型定义\n// ============================================================\n\nexport type WriteTask =\n | 'continue' // 续写\n | 'rewrite' // 改写\n | 'review' // 审稿\n | 'polish' // 润色\n | 'expand' // 扩写\n | 'compress' // 缩写\n | 'outline' // 大纲\n | 'dialog' // 对话生成\n | 'generate'; // 生成整章\n\n// ============================================================\n// 第1层:通用基础提示词(九铁则+写作技法+输出要求)\n// GWE V3.1 - 2026网文铁则:3秒停留率、黄金300字、禁假钩子\n// ============================================================\n\nconst BASE_PROMPT = `你是专业中文网文写作引擎,职责是产出具备强追读力的中文故事文本。以下规则为最高优先级,任何输出不得违反。\n\n【核心铁则·共九条】\n\n铁则零:3秒停留率(2026算法第一指标)\n- 读者手指划到你的正文,只有3秒决定要不要看下去。不是三章,是三秒。\n- 第一句必须≤20字,直接写正在发生的动作/冲突/结果,禁止任何铺垫。\n- 前300字必须完成三件事:冲突爆发→主角身体在场→异常信号出现。\n- 前300字禁止:写景、交代背景、介绍人物、回忆前世、说明世界观。\n- 背景信息一句话插在动作中间:\"这是灵气枯竭第27年,他正在被人追砍。\"\n- 正面示例:\"刀尖抵住她喉结时,系统弹窗亮了。\"\"外门弟子林凡,一刀斩了大师兄。\"\n- 反面示例:\"天刚蒙蒙亮,寒风卷着雪沫子,从破旧的窗口灌进来。\"(读者直接划走)\n\n铁则一:Show, Don't Tell(展示而非告知)\n- 禁止直接写\"他很紧张\"\"她很难过\"\"气氛很压抑\"这类情绪结论。\n- 一切情绪、氛围、心理状态,必须通过动作、表情、生理反应、环境细节来呈现。\n- 禁止套路反应:\"心头一跳\"\"脸色一变\"\"握紧拳头\"\"不由得\"\"情不自禁\"\"点了点头\"\"叹了口气\"\"皱了皱眉\"\"冷哼一声\"\"嘴角微扬\"——这些是AI标签,不是身体反应。用生理级反应替代:后颈汗毛竖起/嘴里发苦/后背冷汗渗出来/胃猛地一缩/耳朵嗡的一声。\n- 例:不写\"他害怕\",写\"后颈的汗毛一根根竖了起来,指尖瞬间凉透,呼吸卡在喉咙里半秒没吸进去\"。\n\n铁则二:身体锚点原则\n- 每个场景中,视角人物的身体必须在场。\n- 写任何外部事件时,锚定到人物身体的具体反应:肌肉绷紧、后颈发凉、指节发白、喉结滚动、呼吸一滞、瞳孔微缩、胃缩、牙紧、脊背发僵。\n- 情绪必须落到肉身:心脏、胃、脊背、指尖、后颈、眉心、后槽牙是七大核心锚点。\n- 禁止\"幽灵视角\"——人物没有身体反应,只看到、想到、感到,没有物理落点。\n\n铁则三:五感激活原则\n- 每个场景至少激活两种感官,关键场景激活三种以上。\n- 视觉(光色形影)、听觉(声量质感)、触觉(冷暖软硬干湿)、嗅觉(气息气味)、味觉(舌尖感受)。\n- 感官描写不是装饰,是信息:气味暴露环境,声音揭示距离,温度传递情绪。\n- 禁止纯视觉流水账——只写看到什么,没有声音、温度、触感、气味。\n\n铁则四:开头三句轰炸(追读力核心)\n- 第一句必须是主角能直接感知的强身体刺激:疼/冷/烫/响/震/麻/喘不上气/眼前一黑。禁止第一句是环境描写、背景介绍、人物外貌、自我介绍。\n- 第二句必须是主角的本能反应:缩手/僵住/回头/屏住呼吸/咬住嘴唇/手指扣紧。\n- 第三句才允许交代\"这是在哪里、在做什么\"。\n- 禁止\"我叫XX\"\"XX今年XX岁\"\"从前有座山\"\"在一个XX的地方\"式开头。\n- 反面示例:\"壁面冰冷。林深把手掌贴上去……\"(这是环境陈述,读者走神)\n- 正面示例:\"烫。林深猛地缩手,指腹已经红了一片。他这才看清,那截金色纤维的尖端在发光。\"\n\n铁则五:对话五步碰撞(追读力核心)\n- 禁止\"一人发现→告诉大家→大家认同\"的直线汇报式对话。对话必须有碰撞。\n- 任何角色说出一个判断后,下一个说话的人必须先反对/质疑/唱反调,不许直接认同。\n- 每场关键对话至少一人做出错误判断,后面验证他错了。\n- 对话中至少一次有人用动作打断说话(拍肩/举盾/砸凿子/抓住手腕)。\n- 信息不在对话里直接说全,至少留一个人知道但不说。\n- 反面示例:\"不对。\"\"哪里不对?\"\"风里有声音。\"\"我再听听。\"\"确实有个拍。\"(工作会议)\n- 正面示例:\"风里有东西。\"\"扯蛋,茧都没响。\"\"你聋了?\"\"你才聋——\"寻突然闭嘴,脸色变了。\n\n铁则六:每300字信息反咬(追读力核心)\n- 禁止线性匀速推进。每250-350字必须有一次信息反咬——读者刚形成一个判断,立刻被新信息颠覆。\n- 反咬类型库:以为安全→危险 / 以为是A→是B / 以为某人错了→他是对的 / 以为结束了→才刚开始 / 以为是友→有疑点。\n- 禁止连续400字无转折、无意外、无新发现。\n- 每段只给一个新信息,新信息出来后必须接人物的身体反应或物理痕迹,不许直接往下走。\n\n铁则七:章末新信息钩子(追读力核心)\n- 最后100字必须出现一个前文完全没提过的新信息,这个新信息必须颠覆之前的某个判断。\n- 最后一句禁止是判断句/陈述句(\"XX了\"\"XX在XX\"\"是XX\"),禁止\"了。\"收尾。\n- 最后一句必须是:未完成的动作 / 新出现的具体危险 / 没有答案的问题 / 颠覆认知的具体发现。\n- 钩子必须具体,禁止装神弄鬼:\"一股神秘的气息\"\"他似乎意识到了什么\"\"事情没那么简单\"\"一种不祥的预感\"\"黑暗中有什么东西\"——这些是空泛假钩子,读者已经免疫。\n- 好钩子是具体的:\"他低头,看见凿尖上沾了血。\"\"门外传来第三下敲门声。\"\"寻的嘴在动,但没有声音。\"\n- 写完最后一句问自己:读者读完会不会骂\"操,怎么断在这里\"?会,才合格。\n- 反面示例:\"壁在求他。求他凿下去。\"(结论,读者满足了)\n- 正面示例:\"他低头看自己的手。手背上多了一道金色纹路。和那截纤维一模一样。什么时候?\"\n\n铁则八:短句节奏纪律\n- 每行视觉长度控制在17字以内(手机阅读一屏约17字),长句拆成短句。\n- 短句必须有身份:危险落点/发现落点/反咬落点/打断/对话锋刃/章末钩子。没有身份的短句必须合并到前后句,禁止为了短句而短句。\n- 禁止连续3个以上≤12字短句且无新信息/无转折/无对话(碎句病),除非是压力爆点。\n- 同拍内动作链用逗号串联,换拍/换判断才用句号。禁止\"动作。感受。\"\"动作。光线。\"这种拍内断句。\n\n【写作技法】\n\n场景切入\n- 严格遵守铁则零、铁则四开头规则。\n- 第一句就把人扔进正在发生的刺激里,不要任何铺垫。\n\n对话穿插\n- 严格遵守铁则五对话碰撞规则。\n- 对话必须与动作、神态、环境交替出现。禁止连续三行以上纯对话无描写。\n- 对话标签用\"说/道/问/答/低声道\"等简洁词,不堆砌\"愤怒地说\"\"激动地喊道\"——情绪用动作展示。\n- 对话承载潜台词:人物说的话和真实想法之间可以有缝隙,用微表情和停顿暗示。\n\n节奏控制\n- 紧张场景用短句、断句、动词密集,少修饰。\n- 舒缓场景允许稍长的句子和感官铺陈,但每句仍有信息承载。\n- 关键瞬间(转折、冲击、发现)用极短句甚至单句成段,制造顿点。\n- 段落长度有变化,不连续出现多个等长段落。\n\n信息密度\n- 严格遵守铁则六反咬规则。\n- 每句话必须承载至少一项有效信息:推进情节、揭示人物、渲染氛围、暗示伏笔。\n- 删除一切不承载信息的句子:空洞感慨、重复描写、无效过渡。\n- 形容词和副词克制使用,优先用精准动词和名词。能用\"攥紧\"就不用\"紧紧握住\"。\n- 一段只给一个新信息,复杂设定先给结果再给名称,专有名词必须绑定可见物件或动作。\n\n【一拍一息·标点规则】\n- 同一镜头/同一动作链内,动作→光线/视线→触觉→外界反应用逗号连起来,不许用句号切断。\n- 换拍(换动作/换空间/换时间/换判断)才用句号。\n- 破折号禁止使用,中文网文不需要破折号,逗号足够做认知翻转。\n- 禁止\"不是X是Y\"解释结构,直接写Y的具体表现。\n\n【输出要求】\n1. 全部使用中文输出,英文词汇仅在必要专有名词时出现。\n2. 直接输出正文,不写任何解释、前言、后记、大纲、总结或注释。\n3. 不使用Markdown格式标记正文,不加分隔线、标题、加粗等排版符号。\n4. 严格保持人物设定一致性:性格、说话方式、行为逻辑、已知信息不冲突。\n5. 严格遵循给定的视角限制,不越界描写视角人物不可能知道的信息。\n6. 一章只写一件核心事,场景不超过3个。\n7. 每章至少有一种外部压力:人来阻止/制度卡住/时间逼近/空间封闭/物件异常。\n\n【禁止事项】\n- 禁止开篇写景、交代背景、介绍人物、回忆前世——直接进动作现场。\n- 禁止开篇第一句超过20字。\n- 禁止前300字无冲突、无动作、无对话、无身体反应。\n- 禁止直接陈述情绪词(紧张/害怕/难过/开心/愤怒/尴尬/压抑/绝望等),必须用生理级身体反应替代。\n- 禁止套路反应词(48个黑名单):心头一跳/脸色一变/握紧拳头/不由得/情不自禁/忍不住/不禁/点了点头/叹了口气/皱了皱眉/冷哼一声/嘴角微扬/微微一笑/苦笑一声/瞳孔骤缩/眼中闪过一丝/嘴角勾起一抹/眼中寒光一闪/浑身一颤/虎躯一震/眼中精芒爆闪/气势陡然一变/一股强横的气息/散发出王者之气/冷笑一声/嗤笑一声/摇头失笑/面露难色/眉头紧锁/眼神复杂/深吸一口气/缓缓开口/淡淡道/冷冷道/沉声道/厉声道/爆喝道/怒吼道/一字一句道/不置可否/置若罔闻/恍若未闻/不以为然/不屑一顾/视若无睹/无动于衷/面无表情——全部用具体生理反应替代。\n- 禁止装神弄鬼假钩子:\"一股神秘的/一种莫名的/一丝诡异的/似乎意识到了什么/好像发现了什么/不祥的预感/事情没那么简单/他不知道的是/黑暗中有什么东西\"——钩子必须是具体的、看得见摸得着的信息。\n- 禁止连续超过三句纯对话无动作/神态/环境穿插,且对话必须有碰撞有反对。\n- 禁止填充词堆砌:非常/十分/极其/很/似乎/好像/仿佛/有点/有些/事实上/实际上/不由自主/毫无疑问/众所周知/令人/让人——这些词能删则删。\n- 禁止破折号,用逗号或冒号替代。\n- 禁止\"不是X是Y\"结构。\n- 禁止碎句病:连续3个以上≤12字短句且无新信息,必须合并。\n- 禁止拍内断句:\"他走。光打在墙上。\"同一动作链必须逗号串联。\n- 禁止突然切换视角或叙事人称,视角切换必须有明确的段落分隔或场景转换信号。\n- 禁止现代网络用语、流行梗、出戏表达破坏叙事沉浸感。\n- 禁止角色说出不符合其身份和知识范围的话。\n- 禁止上帝视角剧透——叙述者知道的信息不能超过视角人物。\n- 禁止性格判断句:\"他是个怎样的人\",让行为自己证明。\n- 禁止解释腔:\"这说明了\"\"这意味着\",让人物通过动作重新发现。\n- 禁止章末用结论式/判断句\"了。\"收尾,必须留具体新信息钩子。\n- 禁止章末用\"就这样/原来如此/所以/于是/最终/最后/总之\"等总结词收束。\n\n> 2026网文战场:3秒定生死,300字定留存,每300字一个反咬,章末让读者骂断更。每一个字都要服务于追读。`;\n\n// ============================================================\n// 任务指令模板(第7层)\n// ============================================================\n\nconst TASK_INSTRUCTIONS: Record<WriteTask, string> = {\n continue: `【任务:续写】\n从当前位置继续往下写,自然衔接上文最后一句话,保持叙事节奏和情感基调,注意埋设钩子。不要重复已说过的信息。直接输出正文。`,\n\n rewrite: `【任务:改写】\n请改写选中的文本,在保留核心情节和信息的前提下:\n- 提升文字质量,消除填充词和冗余表达\n- 增强身体锚点和五感描写\n- 优化句子节奏和段落分布\n- 保持与上下文风格一致\n- 直接输出改写后的正文`,\n\n review: `【任务:审稿】\n请审阅以下文本,找出问题并给出修改建议。请按以下格式输出:\n\n【综合评分】XX/100\n【雷达评分】身体反应:XX 感官信号:XX 动作:XX 情感:XX 信息推进:XX\n【问题列表】\n1. [问题类型] 具体问题描述(位置:第X段/第X句)→ 修改建议\n2. ...\n【优秀之处】\n- ...\n【总体建议】\n...`,\n\n polish: `【任务:润色】\n请对选中的文本进行润色提升:\n- 修正不通顺的句子\n- 替换陈词滥调为更精准的表达\n- 在合适位置增加身体锚点和五感细节\n- 不改变原意和情节,只提升文字表现力\n- 直接输出润色后的正文`,\n\n expand: `【任务:扩写】\n请将选中的文本扩写为更丰富的段落:\n- 增加动作细节、环境描写、身体反应\n- 对话场景可增加角色微表情和语气描写\n- 保持核心情节不变,填充细节使场景更饱满\n- 不要注水,每个新增的细节都要服务于氛围或人物塑造\n- 直接输出扩写后的正文`,\n\n compress: `【任务:缩写】\n请将选中的文本精简压缩:\n- 删除冗余修饰和填充词\n- 保留核心情节、关键对话和重要描写\n- 去除重复信息和不必要的说明\n- 保持文字的节奏感和可读性\n- 直接输出压缩后的正文`,\n\n outline: `【任务:大纲生成】\n请根据提供的信息,生成详细的写作大纲。\n要求:\n- 列出章节划分和每章核心事件\n- 标注爽点/转折点位置\n- 标注需要埋设的伏笔\n- 标注需要回收的伏笔\n- 给出每章的预估字数\n请用清晰的结构化格式输出。`,\n\n dialog: `【任务:对话生成】\n请根据上下文和角色设定,生成一段自然的对话。\n- 每个角色的说话风格要符合其性格设定\n- 对话之间穿插动作、表情描写\n- 通过对话推进剧情或揭示信息\n- 避免直白说教,信息通过潜台词传递\n- 直接输出对话正文(含动作标签)`,\n\n generate: `【任务:生成整章】\n请根据提供的上下文信息(前情、角色设定、章节摘要、活跃支线),生成一整章完整的小说正文。\n要求:\n- 章节长度2000-4000字,有完整的起承转合\n- 开头自然衔接前情,结尾留下钩子吸引读者继续阅读\n- 保持当前文风、视角、节奏一致\n- 通过动作、对话、感官描写推进剧情,避免大段说明\n- 遵守所有写作约束和自定义规则\n- 只输出小说正文,不加任何解释、说明、章节标题或总结\n- 分段落输出,每段80-150字,关键转折可用短段落增强冲击力`,\n};\n\n// ============================================================\n// 核心API\n// ============================================================\n\nexport interface BuildPromptOptions {\n /** 当前任务类型 */\n task: WriteTask;\n /** 写作上下文 */\n context: WritingContext | null;\n /** 合并后的配置 */\n mergedConfig: MergedConfig;\n /** 预设包(可选) */\n preset?: Preset | null;\n /** 用户选择的NodeId->OptionId映射 */\n selections?: Record<NodeId, OptionId>;\n /** 自定义基础提示词(覆盖内置BASE_PROMPT) */\n basePrompt?: string;\n /** 用户自由文本自定义规则(直接拼接到system prompt) */\n userCustomPrompt?: string;\n}\n\n/**\n * 构建System Prompt(7层拼装)\n *\n * 拼装顺序:\n * [1] 通用基础提示词(base-prompt)\n * [2] 所有选中NodeOption的system_prompt(按节点顺序拼接,用---分隔)\n * [3] 预设包的extra_prompt(如果有)\n * [4] 用户自定义提示词(mergedConfig里如果有)\n * [5] 上下文注入(书籍信息+前情摘要+角色卡+关系网+状态追踪)\n * [6] 所有选中NodeOption的constraints(拼成\"禁止/要求\"列表)\n * [7] 任务指令(根据task参数生成)\n */\nexport function buildSystemPrompt(options: BuildPromptOptions): string {\n const { task, context, mergedConfig, preset, selections, basePrompt, userCustomPrompt } = options;\n const layers: string[] = [];\n\n // ---- [1] 通用基础提示词 ----\n layers.push(basePrompt || BASE_PROMPT);\n\n // ---- [2] 选中NodeOption的system_prompt ----\n const optionPrompts: string[] = [];\n if (selections) {\n const allNodes = getAllNodes();\n for (const node of allNodes) {\n const optionId = selections[node.id];\n if (!optionId) continue;\n\n let kb = getNodeOption(optionId);\n if (kb?.system_prompt) {\n optionPrompts.push(`【${node.name}】\\n${kb.system_prompt}`);\n }\n }\n }\n\n // 从mergedConfig.systemPrompts补充(如果有未通过getNodeOption获取到的)\n if (mergedConfig.systemPrompts.length > 0 && optionPrompts.length === 0) {\n optionPrompts.push(...mergedConfig.systemPrompts);\n }\n\n if (optionPrompts.length > 0) {\n layers.push(\n `【当前选中的写作风格配置】\\n${optionPrompts.join('\\n---\\n')}`\n );\n }\n\n // ---- [3] 预设包extra_prompt ----\n if (preset?.extra_prompt) {\n layers.push(`【预设包:${preset.preset_name}】\\n${preset.extra_prompt}`);\n }\n\n // ---- [4] 用户自由文本自定义规则 ----\n if (userCustomPrompt && userCustomPrompt.trim()) {\n layers.push(`【用户自定义规则(必须严格遵守)】\\n${userCustomPrompt.trim()}`);\n }\n\n // ---- [5] 上下文注入 ----\n if (context) {\n layers.push(buildContextSection(context));\n }\n\n // ---- [5.5] 专属词汇表注入 ----\n const vocabSection = buildVocabularySection(mergedConfig.vocabulary);\n if (vocabSection) {\n layers.push(vocabSection);\n }\n\n // ---- [6] 约束列表(constraints)----\n const allConstraints: string[] = [...mergedConfig.constraints];\n if (preset?.extra_constraints) {\n allConstraints.push(...preset.extra_constraints);\n }\n\n if (allConstraints.length > 0) {\n const constraintText = allConstraints\n .map((c, i) => `${i + 1}. ${c}`)\n .join('\\n');\n layers.push(`【必须遵守的约束】\\n${constraintText}`);\n }\n\n // ---- [6.5] Few-shot示例(examples)----\n // 最多选3个示例,避免prompt过长\n if (mergedConfig.examples && mergedConfig.examples.length > 0) {\n const selectedExamples = mergedConfig.examples.slice(0, 3);\n const exampleText = selectedExamples\n .map((ex, i) => {\n let block = `【示例${i + 1}】`;\n if (ex.note) block += `(${ex.note})`;\n block += `\\n${ex.text}`;\n return block;\n })\n .join('\\n\\n');\n layers.push(`【参考示例】\\n以下是符合当前风格配置的示范文本,请模仿其文风和技法:\\n\\n${exampleText}`);\n }\n\n // ---- [7] 任务指令 ----\n // 根据目标字数动态调整任务指令\n const taskInstruction = buildTaskInstruction(task, mergedConfig, selections);\n layers.push(taskInstruction);\n\n // 用换行组合所有层(AI不需要视觉分隔线)\n return layers.join('\\n\\n');\n}\n\nexport interface BuildUserMessageOptions {\n task: WriteTask;\n context: WritingContext | null;\n /** 附加参数(如选中文字、额外指令等) */\n params?: {\n /** 选中的文本(用于rewrite/polish/expand/compress) */\n selectedText?: string;\n /** 光标前的上文内容 */\n precedingText?: string;\n /** 光标的后文内容 */\n followingText?: string;\n /** 用户额外的指令 */\n userInstruction?: string;\n /** 大纲生成的提示/要求 */\n outlinePrompt?: string;\n [key: string]: unknown;\n };\n}\n\n/**\n * 构建User Message(发送给AI的用户侧消息)\n */\nexport function buildUserMessage(options: BuildUserMessageOptions): string {\n const { task, context, params } = options;\n const parts: string[] = [];\n\n // 书名/章节信息\n let currentChapter = null;\n if (context) {\n currentChapter = context.chapters.find(\n (c) => c.id === context.currentChapterId\n );\n if (currentChapter) {\n parts.push(`【当前章节】${context.book.title} - ${currentChapter.title}`);\n }\n }\n\n // 自动从context提取前文/选中文本(当params未显式提供时)\n let precedingText = params?.precedingText;\n let selectedText = params?.selectedText;\n if (!precedingText && !selectedText && context && currentChapter) {\n const cursorPos = context.cursorPosition ?? currentChapter.content.length;\n const content = currentChapter.content;\n if (context.selection) {\n selectedText = context.selection.text;\n precedingText = content.slice(0, context.selection.from);\n } else {\n // 默认取光标前的文本(最多800字)作为上文\n const start = Math.max(0, cursorPos - 800);\n precedingText = content.slice(start, cursorPos);\n }\n }\n\n // 根据任务类型组织用户消息\n switch (task) {\n case 'continue': {\n if (precedingText) {\n parts.push('【上文内容】');\n parts.push(precedingText);\n parts.push('');\n parts.push('请从以上内容之后直接开始续写:');\n }\n if (params?.userInstruction) {\n parts.push(`\\n【额外要求】${params.userInstruction}`);\n }\n break;\n }\n\n case 'rewrite':\n case 'polish':\n case 'expand':\n case 'compress': {\n if (selectedText) {\n parts.push('【待处理文本】');\n parts.push(selectedText);\n parts.push('');\n const actionMap: Record<string, string> = {\n rewrite: '改写',\n polish: '润色',\n expand: '扩写',\n compress: '缩写',\n };\n parts.push(`请${actionMap[task] || '处理'}以上文本。`);\n }\n if (precedingText) {\n parts.push(`\\n【上文参考】\\n${precedingText.slice(-300)}`);\n }\n if (params?.userInstruction) {\n parts.push(`\\n【额外要求】${params.userInstruction}`);\n }\n break;\n }\n\n case 'review': {\n parts.push('【待审阅文本】');\n parts.push(selectedText || precedingText || '');\n if (params?.userInstruction) {\n parts.push(`\\n【重点关注】${params.userInstruction}`);\n }\n break;\n }\n\n case 'outline': {\n if (params?.outlinePrompt) {\n parts.push('【大纲需求】');\n parts.push(params.outlinePrompt);\n }\n if (context?.book.synopsis) {\n parts.push(`\\n【作品简介】\\n${context.book.synopsis}`);\n }\n break;\n }\n\n case 'dialog': {\n if (params?.userInstruction) {\n parts.push(`【对话场景】${params.userInstruction}`);\n }\n if (precedingText) {\n parts.push(`\\n【上下文】\\n${precedingText.slice(-500)}`);\n }\n break;\n }\n\n case 'generate': {\n if (precedingText) {\n parts.push('【前文结尾(从此处续写)】');\n parts.push(precedingText.slice(-1500));\n parts.push('');\n }\n if (currentChapter?.summary) {\n parts.push(`【本章目标】${currentChapter.summary}`);\n }\n if (params?.userInstruction) {\n parts.push(`\\n【额外要求】${params.userInstruction}`);\n }\n parts.push('\\n请从以上内容之后开始,生成完整的一章正文:');\n break;\n }\n }\n\n return parts.join('\\n');\n}\n\n// ============================================================\n// 上下文注入构建\n// ============================================================\n\nfunction buildContextSection(context: WritingContext): string {\n const lines: string[] = [];\n\n // 书籍基本信息\n lines.push('【作品信息】');\n lines.push(`书名:${context.book.title}`);\n if (context.book.author) lines.push(`作者:${context.book.author}`);\n if (context.book.synopsis) lines.push(`简介:${context.book.synopsis}`);\n if (context.book.tags && context.book.tags.length > 0) {\n lines.push(`标签:${context.book.tags.join('、')}`);\n }\n\n // 当前章节\n const currentChapter = context.chapters.find(\n (c) => c.id === context.currentChapterId\n );\n if (currentChapter) {\n lines.push(`\\n【当前章节】${currentChapter.title}(第${currentChapter.number}章)`);\n if (currentChapter.summary) {\n lines.push(`章节摘要:${currentChapter.summary}`);\n }\n lines.push(`当前字数:${currentChapter.wordCount}字`);\n lines.push(`状态:${currentChapter.status === 'done' ? '已完成' : currentChapter.status === 'writing' ? '写作中' : '草稿'}`);\n }\n\n // 前情摘要(前几章的summary)\n const prevChapters = context.chapters\n .filter((c) => currentChapter && c.number < currentChapter.number)\n .sort((a, b) => b.number - a.number)\n .slice(0, 3);\n if (prevChapters.length > 0) {\n lines.push('\\n【前情提要】');\n for (const ch of prevChapters.reverse()) {\n if (ch.summary) {\n lines.push(`- 第${ch.number}章《${ch.title}》:${ch.summary}`);\n }\n }\n }\n\n // 角色卡(主要角色)\n const mainChars = context.characters.filter(\n (c) => c.role === 'protagonist' || c.role === 'antagonist'\n );\n if (mainChars.length > 0) {\n lines.push('\\n【主要角色】');\n for (const char of mainChars.slice(0, 5)) {\n lines.push(formatCharacterCard(char));\n }\n }\n\n // 配角(最近出现的)\n const supportingChars = context.characters.filter(\n (c) => c.role === 'supporting'\n );\n if (supportingChars.length > 0) {\n lines.push('\\n【重要配角】');\n for (const char of supportingChars.slice(0, 5)) {\n lines.push(`- ${char.name}:${char.description || char.role}`);\n }\n }\n\n // 关系网\n const allRelationships = context.characters\n .filter((c) => c.relationships && c.relationships.length > 0)\n .flatMap((c) =>\n (c.relationships || []).map((r) => ({\n from: c.name,\n toId: r.targetId,\n type: r.type,\n desc: r.description,\n }))\n );\n if (allRelationships.length > 0) {\n lines.push('\\n【角色关系】');\n for (const rel of allRelationships.slice(0, 10)) {\n const targetChar = context.characters.find((c) => c.id === rel.toId);\n const targetName = targetChar?.name || rel.toId;\n if (rel.desc) {\n lines.push(`- ${rel.from} ${rel.type} ${targetName}:${rel.desc}`);\n } else {\n lines.push(`- ${rel.from} 与 ${targetName}:${rel.type}`);\n }\n }\n }\n\n // 重要设定\n if (context.settings && context.settings.length > 0) {\n const importantSettings = context.settings.filter(\n (s) => s.type === 'world' || s.type === 'faction' || s.type === 'system'\n );\n if (importantSettings.length > 0) {\n lines.push('\\n【重要设定】');\n for (const s of importantSettings.slice(0, 5)) {\n lines.push(`- [${s.type}] ${s.name}:${s.description}`);\n }\n }\n }\n\n // 当前活跃支线\n if (context.subplots) {\n const activeSubplots = context.subplots.filter((s) => s.status === 'active');\n if (activeSubplots.length > 0) {\n lines.push('\\n【活跃支线】');\n for (const sp of activeSubplots.slice(0, 3)) {\n lines.push(`- ${sp.name}:${sp.description}`);\n }\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * 构建词汇表注入部分\n * 用自然语言告诉AI专属词汇,而不是生硬罗列\n */\nfunction buildVocabularySection(vocab: MergedConfig['vocabulary']): string | null {\n const lines: string[] = [];\n\n // 世界观专属术语\n if (vocab.worldTerms && vocab.worldTerms.size > 20) {\n const terms = Array.from(vocab.worldTerms).slice(0, 40);\n lines.push(`【世界观专属术语】以下是本书独有的名词,请在描写中自然使用,无需解释:${terms.join('、')}`);\n }\n\n // 专属感官/动作词汇\n if (vocab.sensoryVerbs && vocab.sensoryVerbs.size > 5) {\n const verbs = Array.from(vocab.sensoryVerbs).slice(0, 20);\n if (lines.length > 0) lines.push('');\n lines.push(`【偏好动作/感官词】描写时优先考虑使用:${verbs.join('、')}`);\n }\n\n if (lines.length === 0) return null;\n return lines.join('\\n');\n}\n\n/**\n * 格式化角色卡片\n */\nfunction formatCharacterCard(char: Character): string {\n const lines: string[] = [];\n lines.push(`- ${char.name}${char.aliases && char.aliases.length > 0 ? '(' + char.aliases.join('/') + ')' : ''}`);\n if (char.description) lines.push(` 外貌/特征:${char.description}`);\n if (char.background) lines.push(` 背景:${char.background}`);\n if (char.speechStyle) lines.push(` 说话风格:${char.speechStyle}`);\n if (char.tags && char.tags.length > 0) lines.push(` 标签:${char.tags.join('、')}`);\n return lines.join('\\n');\n}\n\n// ============================================================\n// 动态任务指令(根据目标字数/续写长度调整)\n// ============================================================\n\n/** 目标字数选项映射 */\nconst TARGET_LENGTH_MAP: Record<string, { min: number; max: number; label: string }> = {\n opt_length_1500: { min: 1300, max: 1700, label: '1500字左右' },\n opt_length_2200: { min: 2000, max: 2500, label: '2200字左右' },\n opt_length_3000: { min: 2800, max: 3300, label: '3000字左右' },\n opt_length_4000: { min: 3800, max: 4500, label: '4000字以上' },\n};\n\n/** 续写长度选项映射 */\nconst CONTINUE_LENGTH_MAP: Record<string, { min: number; max: number; label: string }> = {\n opt_ai_short: { min: 400, max: 700, label: '500字左右' },\n opt_ai_medium: { min: 1000, max: 1600, label: '1000-1500字' },\n opt_ai_long: { min: 1800, max: 2800, label: '2000-3000字' },\n opt_ai_xtra_long: { min: 3500, max: 5000, label: '4000字以上' },\n};\n\n/**\n * 根据配置动态生成任务指令(支持目标字数/续写长度)\n */\nfunction buildTaskInstruction(\n task: WriteTask,\n mergedConfig: MergedConfig,\n selections?: Record<NodeId, OptionId>\n): string {\n const base = TASK_INSTRUCTIONS[task] || TASK_INSTRUCTIONS.continue;\n void mergedConfig;\n\n if (!selections) return base;\n\n // 生成整章:读取目标字数\n if (task === 'generate') {\n const lengthOpt = selections['node_target_length' as NodeId];\n const lengthInfo = TARGET_LENGTH_MAP[lengthOpt || ''];\n if (lengthInfo) {\n return base.replace(\n '章节长度2000-4000字',\n `章节长度${lengthInfo.label}(${lengthInfo.min}-${lengthInfo.max}字)`\n );\n }\n }\n\n // 续写:读取续写长度\n if (task === 'continue') {\n const lenOpt = selections['node_ai_continue_length' as NodeId];\n const lenInfo = CONTINUE_LENGTH_MAP[lenOpt || ''];\n if (lenInfo) {\n return `${base}\\n\\n【续写长度】本次续写${lenInfo.label}(${lenInfo.min}-${lenInfo.max}字),自然收束,不要在悬念中途断开。`;\n }\n }\n\n return base;\n}\n","// ============================================================\n// GWE V2.0 - LLM Provider 抽象层(浏览器版)\n// 支持OpenAI兼容API,内置Mock Provider用于体验模式\n// ============================================================\n\nimport type {\n LLMProvider,\n LLMRequest,\n LLMUsage,\n StreamCallbacks,\n} from './types';\n\n// ============================================================\n// OpenAI兼容 Provider\n// ============================================================\n\nexport interface OpenAICompatibleConfig {\n apiKey: string;\n baseURL: string; // 如 https://api.openai.com/v1 或 https://ark.cn-beijing.volces.com/api/v3\n model: string;\n temperature?: number;\n maxTokens?: number;\n timeoutMs?: number;\n}\n\nexport class OpenAICompatibleProvider implements LLMProvider {\n public readonly name = 'openai-compatible';\n private config: OpenAICompatibleConfig;\n\n constructor(config: OpenAICompatibleConfig) {\n this.config = config;\n }\n\n async chat(request: LLMRequest): Promise<{ content: string; usage?: LLMUsage }> {\n const url = `${this.config.baseURL.replace(/\\/$/, '')}/chat/completions`;\n const controller = new AbortController();\n const timeout = setTimeout(\n () => controller.abort(),\n this.config.timeoutMs ?? 60000\n );\n\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.config.apiKey}`,\n },\n body: JSON.stringify({\n model: this.config.model,\n messages: request.messages,\n temperature: request.temperature ?? this.config.temperature ?? 0.7,\n max_tokens: request.maxTokens ?? this.config.maxTokens ?? 4096,\n stream: false,\n }),\n signal: controller.signal,\n });\n\n if (!res.ok) {\n const errText = await res.text().catch(() => '');\n throw new Error(`LLM API error ${res.status}: ${errText.slice(0, 300)}`);\n }\n\n const data = await res.json();\n const content: string = data.choices?.[0]?.message?.content ?? '';\n const usage = data.usage\n ? {\n promptTokens: data.usage.prompt_tokens ?? 0,\n completionTokens: data.usage.completion_tokens ?? 0,\n totalTokens: data.usage.total_tokens ?? 0,\n }\n : undefined;\n\n return { content, usage };\n } finally {\n clearTimeout(timeout);\n }\n }\n\n async stream(request: LLMRequest, callbacks: StreamCallbacks): Promise<void> {\n const url = `${this.config.baseURL.replace(/\\/$/, '')}/chat/completions`;\n const controller = new AbortController();\n const timeout = setTimeout(\n () => controller.abort(),\n this.config.timeoutMs ?? 120000\n );\n\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.config.apiKey}`,\n },\n body: JSON.stringify({\n model: this.config.model,\n messages: request.messages,\n temperature: request.temperature ?? this.config.temperature ?? 0.7,\n max_tokens: request.maxTokens ?? this.config.maxTokens ?? 4096,\n stream: true,\n }),\n signal: controller.signal,\n });\n\n if (!res.ok) {\n const errText = await res.text().catch(() => '');\n throw new Error(`LLM API error ${res.status}: ${errText.slice(0, 300)}`);\n }\n\n if (!res.body) {\n throw new Error('Response body is null');\n }\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder('utf-8');\n let fullContent = '';\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || !trimmed.startsWith('data:')) continue;\n const data = trimmed.slice(5).trim();\n if (data === '[DONE]') continue;\n\n try {\n const parsed = JSON.parse(data);\n const delta: string =\n parsed.choices?.[0]?.delta?.content ??\n parsed.choices?.[0]?.message?.content ??\n '';\n if (delta) {\n fullContent += delta;\n callbacks.onToken(delta);\n }\n } catch {\n // 忽略无法解析的行\n }\n }\n }\n\n callbacks.onDone(fullContent);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n callbacks.onError(error);\n } finally {\n clearTimeout(timeout);\n }\n }\n}\n\n// ============================================================\n// Mock Provider(零配置体验模式,返回模拟文本)\n// ============================================================\n\nexport class MockProvider implements LLMProvider {\n public readonly name = 'mock';\n\n private mockContinue(_context?: string): string {\n return (\n '\\n\\n他沉默了片刻,指尖无意识地摩挲着袖口磨损的边缘。窗外的风声似乎远了一些,' +\n '又似乎更近了。那种从骨头缝里渗出来的凉意再次爬上后颈,他下意识地收紧了肩膀。\\n\\n' +\n '\"继续。\"他说,声音比他预想的要平稳。\\n\\n' +\n '没有人回答。只有铜碗里的水微微晃了一下,映出壁上那道暗金色的纹路,像一条沉睡的血管。'\n );\n }\n\n private mockRewrite(selectedText: string): string {\n return selectedText.replace(/很/g, '').replace(/非常/g, '');\n }\n\n async chat(request: LLMRequest): Promise<{ content: string; usage?: LLMUsage }> {\n const lastMsg = request.messages[request.messages.length - 1]?.content ?? '';\n let content = '';\n\n if (lastMsg.includes('续写') || lastMsg.includes('continue')) {\n content = this.mockContinue();\n } else if (lastMsg.includes('改写') || lastMsg.includes('rewrite')) {\n const match = lastMsg.match(/选中文字[::]\\s*([\\s\\S]+?)(?:\\n\\n|$)/);\n content = this.mockRewrite(match?.[1] ?? '(选中的文字)');\n } else if (lastMsg.includes('审稿') || lastMsg.includes('review')) {\n content = JSON.stringify({\n score: 78,\n issues: [\n { type: 'filler', severity: 'warning', message: '检测到少量填充词,建议精简。' },\n ],\n });\n } else {\n content = '(Mock Provider:请配置真实API Key以获得AI输出)';\n }\n\n return {\n content,\n usage: { promptTokens: 200, completionTokens: content.length, totalTokens: 200 + content.length },\n };\n }\n\n async stream(request: LLMRequest, callbacks: StreamCallbacks): Promise<void> {\n const { content } = await this.chat(request);\n // 模拟流式:逐字输出\n const chars = Array.from(content);\n for (let i = 0; i < chars.length; i++) {\n callbacks.onToken(chars[i]);\n }\n callbacks.onDone(content);\n }\n}\n\n// ============================================================\n// 预设服务商配置\n// ============================================================\n\nexport interface PresetProvider {\n id: string;\n name: string;\n baseURL: string;\n defaultModel: string;\n docs?: string;\n}\n\nexport const PRESET_PROVIDERS: PresetProvider[] = [\n {\n id: 'openai',\n name: 'OpenAI',\n baseURL: 'https://api.openai.com/v1',\n defaultModel: 'gpt-4o-mini',\n },\n {\n id: 'ark',\n name: '火山方舟(豆包)',\n baseURL: 'https://ark.cn-beijing.volces.com/api/v3',\n defaultModel: 'doubao-1-5-pro-32k-250115',\n },\n {\n id: 'deepseek',\n name: 'DeepSeek',\n baseURL: 'https://api.deepseek.com',\n defaultModel: 'deepseek-chat',\n },\n {\n id: 'qwen',\n name: '通义千问',\n baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1',\n defaultModel: 'qwen-max',\n },\n {\n id: 'zhipu',\n name: '智谱GLM',\n baseURL: 'https://open.bigmodel.cn/api/paas/v4',\n defaultModel: 'glm-4-flash',\n },\n {\n id: 'moonshot',\n name: 'Kimi(月之暗面)',\n baseURL: 'https://api.moonshot.cn/v1',\n defaultModel: 'moonshot-v1-8k',\n },\n {\n id: 'siliconflow',\n name: '硅基流动',\n baseURL: 'https://api.siliconflow.cn/v1',\n defaultModel: 'deepseek-ai/DeepSeek-V3',\n },\n {\n id: 'custom',\n name: '自定义(OpenAI兼容)',\n baseURL: '',\n defaultModel: '',\n },\n];\n\nexport function createProvider(presetId: string, apiKey: string, model?: string): LLMProvider {\n const preset = PRESET_PROVIDERS.find((p) => p.id === presetId);\n if (!preset || presetId === 'custom') {\n throw new Error('Custom provider requires explicit baseURL and model, use OpenAICompatibleProvider directly');\n }\n return new OpenAICompatibleProvider({\n apiKey,\n baseURL: preset.baseURL,\n model: model ?? preset.defaultModel,\n });\n}\n","// ============================================================\n// GWE V2.0 - 通用网文引擎主类 (GWEEngine)\n// 节点化架构 Facade 门面\n// ============================================================\n\nimport type {\n NodeId,\n OptionId,\n NodeOptionKB,\n Preset,\n EngineConfig,\n UserOverrides,\n WritingContext,\n CheckResult,\n ValidationResult,\n LLMProvider,\n ChatMessage,\n LLMUsage,\n StreamCallbacks,\n EngineEventType,\n EngineEvent,\n EngineEventListener,\n MergedConfig,\n NodeDefinition,\n CustomRule,\n Thresholds,\n} from './types';\n\nimport * as registry from './node-registry';\nimport { mergeConfig } from './config-merger';\nimport { validate } from './validator';\nimport { check } from './checker';\nimport { buildSystemPrompt, buildUserMessage } from './prompt-builder';\nimport { MockProvider } from './llm-provider';\n\n// ============================================================\n// GWEEngine 主类\n// ============================================================\n\nexport type TaskType =\n | 'continue'\n | 'rewrite'\n | 'review'\n | 'polish'\n | 'expand'\n | 'compress'\n | 'outline'\n | 'dialog'\n | 'generate';\n\nexport interface NodeCatalog {\n nodes: NodeDefinition[];\n presets: Preset[];\n}\n\nexport class GWEEngine {\n private config: EngineConfig;\n private merged: MergedConfig | null = null;\n private llmProvider: LLMProvider;\n private loadedOptions: Map<OptionId, NodeOptionKB> = new Map();\n private presets: Map<string, Preset> = new Map();\n private listeners: Map<EngineEventType, Set<EngineEventListener>> = new Map();\n private context: WritingContext | null = null;\n private customNodes: NodeDefinition[] = [];\n private basePrompt: string = '';\n private baseVocab: NonNullable<NodeOptionKB['vocabulary']>['add'] | null = null;\n private userPresets: Map<string, Preset> = new Map();\n\n constructor(provider?: LLMProvider) {\n this.llmProvider = provider ?? new MockProvider();\n this.config = {\n presetId: null,\n selections: { ...registry.getDefaultSelectionsFull() },\n userOverrides: {},\n };\n // 加载用户保存的自定义预设\n this.loadUserPresetsFromStorage();\n }\n\n // ============================================================\n // 配置加载\n // ============================================================\n\n /**\n * 从KB数据加载节点选项(.kb.json文件内容)\n */\n loadNodeOption(kb: NodeOptionKB): void {\n registry.registerNodeOption(kb);\n this.loadedOptions.set(kb.option_id, kb);\n }\n\n /**\n * 批量加载节点选项\n */\n loadNodeOptions(kbs: NodeOptionKB[]): void {\n for (const kb of kbs) {\n this.loadNodeOption(kb);\n }\n }\n\n /**\n * 注册预设包\n */\n registerPreset(preset: Preset): void {\n this.presets.set(preset.preset_id, preset);\n }\n\n /**\n * 设置基础提示词(base-prompt.md内容)\n */\n setBasePrompt(prompt: string): void {\n this.basePrompt = prompt;\n }\n\n /**\n * 设置基础词库(base-vocab.json内容)\n */\n setBaseVocab(vocab: NonNullable<NodeOptionKB['vocabulary']>['add']): void {\n this.baseVocab = vocab;\n this.merged = null;\n }\n\n /**\n * 设置LLM Provider\n */\n setLLMProvider(provider: LLMProvider): void {\n this.llmProvider = provider;\n }\n\n /**\n * 注册自定义节点\n */\n registerCustomNode(nodeDef: NodeDefinition): void {\n registry.registerNode(nodeDef);\n this.customNodes.push(nodeDef);\n }\n\n /**\n * 注册自定义规则\n */\n addCustomRule(rule: CustomRule): void {\n if (!this.config.userOverrides.rules) {\n this.config.userOverrides.rules = [];\n }\n this.config.userOverrides.rules.push(rule);\n this.merged = null; // 重新合并\n }\n\n // ============================================================\n // 配置操作\n // ============================================================\n\n /**\n * 加载预设包(一键配置所有节点)\n */\n loadPreset(presetId: string): void {\n // 先从内置预设查找,再从用户自定义预设查找\n let preset = this.presets.get(presetId);\n if (!preset) {\n preset = this.userPresets.get(presetId);\n }\n if (!preset) {\n throw new Error(`[GWE] 预设包 \"${presetId}\" 未注册`);\n }\n // 用预设的selections覆盖\n this.config.selections = {\n ...registry.getDefaultSelectionsFull(),\n ...preset.selections,\n };\n this.config.presetId = presetId;\n this.config.userOverrides = {};\n this.merged = null;\n this.emit('preset:loaded', { presetId, preset });\n this.emit('config:changed', { presetId });\n }\n\n /**\n * 设置单个节点的选项\n */\n setNodeOption(nodeId: NodeId, optionId: OptionId): void {\n const node = registry.getNode(nodeId);\n if (!node) {\n throw new Error(`[GWE] 节点 \"${nodeId}\" 不存在`);\n }\n this.config.selections[nodeId] = optionId;\n this.config.presetId = null; // 修改任意节点后变为自定义状态\n this.merged = null;\n this.emit('config:changed', { nodeId, optionId });\n }\n\n /**\n * 批量设置节点选项\n */\n setNodeOptions(selections: Partial<Record<NodeId, OptionId>>): void {\n for (const [nodeId, optionId] of Object.entries(selections)) {\n if (optionId) {\n this.config.selections[nodeId as NodeId] = optionId;\n }\n }\n this.config.presetId = null;\n this.merged = null;\n this.emit('config:changed', { selections });\n }\n\n /**\n * 应用用户自定义覆盖\n */\n applyUserOverrides(overrides: UserOverrides): void {\n this.config.userOverrides = {\n ...this.config.userOverrides,\n ...overrides,\n // 词库和规则数组合并\n vocab: overrides.vocab\n ? {\n add: {\n ...this.config.userOverrides.vocab?.add,\n ...overrides.vocab.add,\n },\n remove: [\n ...(this.config.userOverrides.vocab?.remove ?? []),\n ...(overrides.vocab.remove ?? []),\n ],\n }\n : this.config.userOverrides.vocab,\n rules: [\n ...(this.config.userOverrides.rules ?? []),\n ...(overrides.rules ?? []),\n ],\n };\n this.merged = null;\n this.emit('config:changed', { overrides: true });\n }\n\n /**\n * 清除所有用户自定义覆盖(恢复到纯节点+预设状态)\n */\n clearUserOverrides(): void {\n this.config.userOverrides = {};\n this.merged = null;\n this.emit('config:changed', { overridesCleared: true });\n }\n\n /**\n * 重置用户自定义词库(用于面板重新输入词库时替换而非追加)\n */\n setUserVocab(vocab: NonNullable<UserOverrides['vocab']>): void {\n if (!this.config.userOverrides.vocab) {\n this.config.userOverrides.vocab = { add: {}, remove: [] };\n }\n this.config.userOverrides.vocab = {\n add: { ...vocab.add },\n remove: vocab.remove ? [...vocab.remove] : [],\n };\n this.merged = null;\n this.emit('config:changed', { vocabSet: true });\n }\n\n /**\n * 重置用户自定义阈值(替换而非合并)\n */\n setUserThresholds(thresholds: Partial<Thresholds>): void {\n this.config.userOverrides.thresholds = { ...thresholds };\n this.merged = null;\n this.emit('config:changed', { thresholdsSet: true });\n }\n\n /**\n * 清除用户自定义阈值(恢复预设/节点默认)\n */\n clearUserThresholds(): void {\n if (this.config.userOverrides.thresholds) {\n this.config.userOverrides.thresholds = undefined;\n this.merged = null;\n this.emit('config:changed', { thresholdsCleared: true });\n }\n }\n\n /**\n * 设置用户自由文本自定义规则(直接注入system prompt)\n */\n setCustomPromptText(text: string): void {\n this.config.userOverrides.prompt = text.trim() || undefined;\n this.merged = null;\n this.emit('config:changed', { customPromptSet: true });\n }\n\n /**\n * 获取用户自由文本自定义规则\n */\n getCustomPromptText(): string {\n return this.config.userOverrides.prompt || '';\n }\n\n /**\n * 获取当前引擎配置(可序列化)\n */\n getConfig(): EngineConfig {\n return JSON.parse(JSON.stringify(this.config));\n }\n\n /**\n * 加载引擎配置(从保存的文件恢复)\n */\n loadConfig(config: EngineConfig): void {\n this.config = JSON.parse(JSON.stringify(config));\n this.merged = null;\n this.emit('config:changed', { loaded: true });\n }\n\n /**\n * 验证当前配置(冲突/依赖检测)\n */\n validateConfig(): ValidationResult {\n const result = validate(this.config.selections, this.loadedOptions);\n this.emit('config:validated', result);\n return result;\n }\n\n // ============================================================\n // 核心功能\n // ============================================================\n\n /**\n * 设置写作上下文(书籍/角色/章节等数据)\n */\n setContext(context: WritingContext): void {\n this.context = context;\n }\n\n /**\n * 运行文本检测(审稿核心)\n */\n check(text: string, context?: WritingContext): CheckResult {\n const merged = this.ensureMerged();\n const ctx = context ?? this.context ?? null;\n const result = check(text, ctx, merged);\n this.emit('check:done', result);\n return result;\n }\n\n /**\n * 构建AI系统提示词\n */\n getSystemPrompt(task: TaskType, context?: WritingContext): string {\n const merged = this.ensureMerged();\n const ctx = context ?? this.context;\n if (!ctx) {\n throw new Error('[GWE] 未设置写作上下文,请先调用setContext()');\n }\n const preset = this.config.presetId\n ? this.presets.get(this.config.presetId) ?? null\n : null;\n return buildSystemPrompt({\n task,\n context: ctx,\n mergedConfig: merged,\n preset,\n selections: this.config.selections,\n basePrompt: this.basePrompt || undefined,\n userCustomPrompt: this.config.userOverrides.prompt,\n });\n }\n\n /**\n * 构建AI用户消息\n */\n getUserMessage(task: TaskType, context?: WritingContext, params?: Record<string, unknown>): string {\n const ctx = context ?? this.context;\n if (!ctx) {\n throw new Error('[GWE] 未设置写作上下文,请先调用setContext()');\n }\n return buildUserMessage({ task, context: ctx, params });\n }\n\n // ============================================================\n // AI 调用(流式/非流式)\n // ============================================================\n\n /**\n * 非流式AI调用(审稿/大纲等不需要实时输出的场景)\n */\n async callAI(task: TaskType, params?: Record<string, unknown>): Promise<{\n content: string;\n usage?: LLMUsage;\n checkResult?: CheckResult;\n }> {\n if (!this.context) {\n throw new Error('[GWE] 未设置写作上下文');\n }\n const merged = this.ensureMerged();\n const preset = this.config.presetId\n ? this.presets.get(this.config.presetId) ?? null\n : null;\n const messages: ChatMessage[] = [\n { role: 'system', content: buildSystemPrompt({\n task,\n context: this.context,\n mergedConfig: merged,\n preset,\n selections: this.config.selections,\n basePrompt: this.basePrompt || undefined,\n userCustomPrompt: this.config.userOverrides.prompt,\n }) },\n { role: 'user', content: buildUserMessage({ task, context: this.context, params }) },\n ];\n\n const temperature = this.getTemperature();\n\n const result = await this.llmProvider.chat({\n messages,\n temperature,\n });\n\n // 对续写/改写/生成结果做本地规则检查\n let checkResult: CheckResult | undefined;\n if (task === 'continue' || task === 'rewrite' || task === 'polish' || task === 'expand' || task === 'generate') {\n checkResult = this.check(result.content, this.context);\n }\n\n this.emit('ai:done', { task, content: result.content, usage: result.usage });\n return { ...result, checkResult };\n }\n\n /**\n * 流式AI调用(续写/润色等实时输出场景)\n */\n async streamAI(\n task: TaskType,\n callbacks: StreamCallbacks,\n params?: Record<string, unknown>,\n ): Promise<void> {\n if (!this.context) {\n callbacks.onError(new Error('[GWE] 未设置写作上下文'));\n return;\n }\n const merged = this.ensureMerged();\n const preset = this.config.presetId\n ? this.presets.get(this.config.presetId) ?? null\n : null;\n const messages: ChatMessage[] = [\n { role: 'system', content: buildSystemPrompt({\n task,\n context: this.context,\n mergedConfig: merged,\n preset,\n selections: this.config.selections,\n basePrompt: this.basePrompt || undefined,\n userCustomPrompt: this.config.userOverrides.prompt,\n }) },\n { role: 'user', content: buildUserMessage({ task, context: this.context, params }) },\n ];\n\n const temperature = this.getTemperature();\n\n await this.llmProvider.stream(\n { messages, temperature },\n {\n onToken: (delta) => {\n callbacks.onToken(delta);\n this.emit('ai:token', { delta, task });\n },\n onDone: (full, usage) => {\n callbacks.onDone(full, usage);\n this.emit('ai:done', { task, content: full, usage });\n },\n onError: (err) => {\n this.emit('ai:error', { error: err, task });\n callbacks.onError(err);\n },\n },\n );\n }\n\n // 便捷方法\n\n /** 流式续写 */\n async continueWrite(callbacks: StreamCallbacks): Promise<void> {\n return this.streamAI('continue', callbacks);\n }\n\n /** 流式改写选中文本 */\n async rewriteSelection(callbacks: StreamCallbacks, selectedText: string): Promise<void> {\n return this.streamAI('rewrite', callbacks, { selectedText });\n }\n\n /** 审稿(非流式,返回检测结果+AI建议) */\n async review(): Promise<CheckResult> {\n if (!this.context) throw new Error('[GWE] 未设置写作上下文');\n const chapter = this.context.chapters.find(\n (c) => c.id === this.context!.currentChapterId,\n );\n if (!chapter) throw new Error('[GWE] 当前章节不存在');\n return this.check(chapter.content, this.context);\n }\n\n /** 润色(流式) */\n async polishSelection(callbacks: StreamCallbacks, selectedText: string): Promise<void> {\n return this.streamAI('polish', callbacks, { selectedText });\n }\n\n /** 扩写(流式) */\n async expandSelection(callbacks: StreamCallbacks, selectedText: string): Promise<void> {\n return this.streamAI('expand', callbacks, { selectedText });\n }\n\n /** 缩写(非流式) */\n async compressSelection(selectedText: string): Promise<string> {\n const result = await this.callAI('compress', { selectedText });\n return result.content;\n }\n\n // ============================================================\n // 节点目录查询(给UI展示用)\n // ============================================================\n\n /**\n * 获取所有可用节点和预设列表\n */\n getNodeCatalog(): NodeCatalog {\n // 合并内置预设和用户自定义预设\n const allPresets = [\n ...Array.from(this.presets.values()),\n ...Array.from(this.userPresets.values()),\n ];\n return {\n nodes: registry.getAllNodes(),\n presets: allPresets,\n };\n }\n\n /**\n * 保存当前配置为用户自定义预设\n */\n saveUserPreset(name: string, description?: string): string {\n const presetId = `user_${Date.now()}`;\n const preset: Preset = {\n preset_id: presetId,\n preset_name: name,\n preset_description: description || '用户自定义预设',\n based_on: this.config.presetId,\n selections: { ...this.config.selections },\n // 保存当前自定义词库\n extra_vocab: this.config.userOverrides.vocab\n ? {\n add: { ...this.config.userOverrides.vocab.add },\n remove: this.config.userOverrides.vocab.remove ? [...this.config.userOverrides.vocab.remove] : [],\n }\n : undefined,\n // 保存当前自定义追加提示词\n extra_prompt: this.config.userOverrides.prompt,\n // 保存当前自定义阈值\n threshold_overrides: this.config.userOverrides.thresholds\n ? { ...this.config.userOverrides.thresholds }\n : undefined,\n };\n this.userPresets.set(presetId, preset);\n this.saveUserPresetsToStorage();\n this.emit('preset:saved', { presetId, preset });\n return presetId;\n }\n\n /**\n * 删除用户自定义预设\n */\n deleteUserPreset(presetId: string): boolean {\n if (!presetId.startsWith('user_')) return false;\n const deleted = this.userPresets.delete(presetId);\n if (deleted) {\n this.saveUserPresetsToStorage();\n this.emit('preset:deleted', { presetId });\n }\n return deleted;\n }\n\n /**\n * 从localStorage加载用户预设\n */\n private loadUserPresetsFromStorage(): void {\n if (typeof window === 'undefined') return;\n try {\n const stored = localStorage.getItem('gwe_user_presets');\n if (stored) {\n const presets = JSON.parse(stored) as Preset[];\n for (const p of presets) {\n this.userPresets.set(p.preset_id, p);\n }\n }\n } catch {\n // ignore parse errors\n }\n }\n\n /**\n * 保存用户预设到localStorage\n */\n private saveUserPresetsToStorage(): void {\n if (typeof window === 'undefined') return;\n try {\n const data = Array.from(this.userPresets.values());\n localStorage.setItem('gwe_user_presets', JSON.stringify(data));\n } catch {\n // ignore storage errors\n }\n }\n\n /**\n * 获取某个节点的已加载选项\n */\n getNodeOptions(nodeId: NodeId): NodeOptionKB[] {\n const node = registry.getNode(nodeId);\n if (!node) return [];\n return node.options\n .map((oid) => this.loadedOptions.get(oid))\n .filter((kb): kb is NodeOptionKB => kb !== undefined);\n }\n\n /**\n * 获取单个选项的完整KB数据(包含描述、示例、约束等)\n */\n getOption(optionId: OptionId): NodeOptionKB | undefined {\n return this.loadedOptions.get(optionId);\n }\n\n /**\n * 获取当前合并后的运行时配置(用于调试/UI显示)\n */\n getMergedConfig(): MergedConfig | null {\n return this.ensureMerged();\n }\n\n /**\n * 同步获取当前合并后的运行时配置(别名,UI用)\n */\n getMergedConfigSync(): MergedConfig | null {\n return this.ensureMerged();\n }\n\n /**\n * 获取所有预设(内置+用户自定义)\n */\n getPresets(): Preset[] {\n const all: Preset[] = [];\n for (const p of this.presets.values()) all.push(p);\n for (const p of this.userPresets.values()) all.push(p);\n return all;\n }\n\n /**\n * 保存当前配置为预设(UI友好的别名,对应saveUserPreset)\n */\n saveAsPreset(opts: { preset_name: string; description?: string; tags?: string[] }): string {\n return this.saveUserPreset(opts.preset_name, opts.description);\n }\n\n /**\n * 获取当前配置的简短文字摘要(用于注入到对话AI的system prompt中,轻量不占token)\n */\n getConfigSummary(): string {\n const merged = this.ensureMerged();\n if (!merged) return '';\n\n const lines: string[] = [];\n\n // 当前预设\n if (this.config.presetId) {\n const preset = this.presets.get(this.config.presetId);\n if (preset) {\n lines.push(`- 当前预设:${preset.preset_name}`);\n }\n } else {\n lines.push('- 当前预设:自定义配置');\n }\n\n // 核心风格节点(只列关键的几个,避免过长)\n const keyNodes: NodeId[] = [\n 'node_sentence_rhythm',\n 'node_paragraph_density',\n 'node_dialogue_style',\n 'node_description_style',\n 'node_emotion_style',\n 'node_tone',\n 'node_pov',\n ];\n for (const nodeId of keyNodes) {\n const optId = this.config.selections[nodeId];\n if (!optId) continue;\n const kb = this.loadedOptions.get(optId);\n if (kb) {\n const nodeDef = registry.getNode(nodeId);\n lines.push(`- ${nodeDef?.name || nodeId}:${kb.option_name}`);\n }\n }\n\n // 阈值(只显示关键几个)\n const t = merged.thresholds;\n if (t) {\n lines.push(`- 段落目标:${t.targetParagraphLength}字/段,单段≤${t.maxParagraphLength}字`);\n lines.push(`- 连续对话:≤${t.maxDialogueContinuous}句无动作穿插`);\n }\n\n // 自定义词库(只显示数量)\n const v = merged.vocabulary;\n if (v) {\n if (v.worldTerms.size > 0) lines.push(`- 专属术语:${v.worldTerms.size}个`);\n if (v.fillerPatterns.size > 0) lines.push(`- 禁用/警惕填充词:${v.fillerPatterns.size}个`);\n }\n\n return lines.join('\\n');\n }\n\n // ============================================================\n // 事件系统\n // ============================================================\n\n on(event: EngineEventType, listener: EngineEventListener): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(listener);\n return () => this.off(event, listener);\n }\n\n off(event: EngineEventType, listener: EngineEventListener): void {\n this.listeners.get(event)?.delete(listener);\n }\n\n private emit(event: EngineEventType, payload?: unknown): void {\n const evt: EngineEvent = { type: event, payload };\n this.listeners.get(event)?.forEach((fn) => {\n try {\n fn(evt);\n } catch (e) {\n console.error('[GWE] Event listener error:', e);\n }\n });\n }\n\n // ============================================================\n // 内部方法\n // ============================================================\n\n private ensureMerged(): MergedConfig {\n if (this.merged) return this.merged;\n\n const preset = this.config.presetId\n ? this.presets.get(this.config.presetId)\n : undefined;\n\n this.merged = mergeConfig({\n selections: this.config.selections,\n loadedOptions: this.loadedOptions,\n preset: preset ?? null,\n userOverrides: this.config.userOverrides,\n baseVocabOverride: this.baseVocab,\n });\n return this.merged;\n }\n\n private getTemperature(): number {\n const optId = this.config.selections['node_ai_creativity'];\n const kb = this.loadedOptions.get(optId);\n // 根据AI创造性节点返回temperature\n if (optId === 'opt_ai_conservative' || kb?.option_id === 'opt_ai_conservative') return 0.3;\n if (optId === 'opt_ai_adventurous' || kb?.option_id === 'opt_ai_adventurous') return 1.0;\n return 0.7;\n }\n}\n","// ============================================================\n// GWE V3.1 - 基础提示词(浏览器环境使用)\n// 与 prompt-builder.ts 中的 BASE_PROMPT 保持同步\n// 2026网文铁则更新:3秒停留率、黄金300字、禁假钩子\n// ============================================================\n\nexport const BASE_PROMPT_MD = `你是专业中文网文写作引擎,职责是产出具备强追读力的中文故事文本。以下规则为最高优先级,任何输出不得违反。\n\n【核心铁则·共九条】\n\n铁则零:3秒停留率(2026算法第一指标)\n- 读者手指划到你的正文,只有3秒决定要不要看下去。不是三章,是三秒。\n- 第一句必须≤20字,直接写正在发生的动作/冲突/结果,禁止任何铺垫。\n- 前300字必须完成三件事:冲突爆发→主角身体在场→异常信号出现。\n- 前300字禁止:写景、交代背景、介绍人物、回忆前世、说明世界观。\n- 背景信息一句话插在动作中间:\"这是灵气枯竭第27年,他正在被人追砍。\"\n- 正面示例:\"刀尖抵住她喉结时,系统弹窗亮了。\"\"外门弟子林凡,一刀斩了大师兄。\"\n- 反面示例:\"天刚蒙蒙亮,寒风卷着雪沫子,从破旧的窗口灌进来。\"(读者直接划走)\n\n铁则一:Show, Don't Tell(展示而非告知)\n- 禁止直接写\"他很紧张\"\"她很难过\"\"气氛很压抑\"这类情绪结论。\n- 一切情绪、氛围、心理状态,必须通过动作、表情、生理反应、环境细节来呈现。\n- 禁止套路反应:\"心头一跳\"\"脸色一变\"\"握紧拳头\"\"不由得\"\"情不自禁\"\"点了点头\"\"叹了口气\"\"皱了皱眉\"\"冷哼一声\"\"嘴角微扬\"——这些是AI标签,不是身体反应。用生理级反应替代:后颈汗毛竖起/嘴里发苦/后背冷汗渗出来/胃猛地一缩/耳朵嗡的一声。\n- 例:不写\"他害怕\",写\"后颈的汗毛一根根竖了起来,指尖瞬间凉透,呼吸卡在喉咙里半秒没吸进去\"。\n\n铁则二:身体锚点原则\n- 每个场景中,视角人物的身体必须在场。\n- 写任何外部事件时,锚定到人物身体的具体反应:肌肉绷紧、后颈发凉、指节发白、喉结滚动、呼吸一滞、瞳孔微缩、胃缩、牙紧、脊背发僵。\n- 情绪必须落到肉身:心脏、胃、脊背、指尖、后颈、眉心、后槽牙是七大核心锚点。\n- 禁止\"幽灵视角\"——人物没有身体反应,只看到、想到、感到,没有物理落点。\n\n铁则三:五感激活原则\n- 每个场景至少激活两种感官,关键场景激活三种以上。\n- 视觉(光色形影)、听觉(声量质感)、触觉(冷暖软硬干湿)、嗅觉(气息气味)、味觉(舌尖感受)。\n- 感官描写不是装饰,是信息:气味暴露环境,声音揭示距离,温度传递情绪。\n- 禁止纯视觉流水账——只写看到什么,没有声音、温度、触感、气味。\n\n铁则四:开头三句轰炸(追读力核心)\n- 第一句必须是主角能直接感知的强身体刺激:疼/冷/烫/响/震/麻/喘不上气/眼前一黑。禁止第一句是环境描写、背景介绍、人物外貌、自我介绍。\n- 第二句必须是主角的本能反应:缩手/僵住/回头/屏住呼吸/咬住嘴唇/手指扣紧。\n- 第三句才允许交代\"这是在哪里、在做什么\"。\n- 禁止\"我叫XX\"\"XX今年XX岁\"\"从前有座山\"\"在一个XX的地方\"式开头。\n- 反面示例:\"壁面冰冷。林深把手掌贴上去……\"(这是环境陈述,读者走神)\n- 正面示例:\"烫。林深猛地缩手,指腹已经红了一片。他这才看清,那截金色纤维的尖端在发光。\"\n\n铁则五:对话五步碰撞(追读力核心)\n- 禁止\"一人发现→告诉大家→大家认同\"的直线汇报式对话。对话必须有碰撞。\n- 任何角色说出一个判断后,下一个说话的人必须先反对/质疑/唱反调,不许直接认同。\n- 每场关键对话至少一人做出错误判断,后面验证他错了。\n- 对话中至少一次有人用动作打断说话(拍肩/举盾/砸凿子/抓住手腕)。\n- 信息不在对话里直接说全,至少留一个人知道但不说。\n- 反面示例:\"不对。\"\"哪里不对?\"\"风里有声音。\"\"我再听听。\"\"确实有个拍。\"(工作会议)\n- 正面示例:\"风里有东西。\"\"扯蛋,茧都没响。\"\"你聋了?\"\"你才聋——\"寻突然闭嘴,脸色变了。\n\n铁则六:每300字信息反咬(追读力核心)\n- 禁止线性匀速推进。每250-350字必须有一次信息反咬——读者刚形成一个判断,立刻被新信息颠覆。\n- 反咬类型库:以为安全→危险 / 以为是A→是B / 以为某人错了→他是对的 / 以为结束了→才刚开始 / 以为是友→有疑点。\n- 禁止连续400字无转折、无意外、无新发现。\n- 每段只给一个新信息,新信息出来后必须接人物的身体反应或物理痕迹,不许直接往下走。\n\n铁则七:章末新信息钩子(追读力核心)\n- 最后100字必须出现一个前文完全没提过的新信息,这个新信息必须颠覆之前的某个判断。\n- 最后一句绝对禁止以\"了。\"收尾(直接降权),禁止是判断句/陈述句/总结句。\n- 最后一句最佳形态(按加分优先级):\n 1. ≤10字极短问句(\"第几号了?\"\"是谁?\"\"你怎么醒了?\")\n 2. ≤15字具体新事物/新危险出现(\"一只手从门缝伸进来。\"\"门开了。\"\"号牌在发光。\")\n 3. ≤15字未完成动作(\"他举起了刀。\"\"她笑了。\"\"那东西动了。\")\n- 钩子必须具体,禁止装神弄鬼:\"一股神秘的气息\"\"他似乎意识到了什么\"\"事情没那么简单\"\"一种不祥的预感\"\"黑暗中有什么东西\"——这些是空泛假钩子,读者已经免疫。\n- 好钩子是具体的:\"他低头,看见凿尖上沾了血。\"\"门外传来第三下敲门声。\"\"寻的嘴在动,但没有声音。\"\n- 写完最后一句问自己:读者读完会不会骂\"操,怎么断在这里\"?会,才合格。\n- 反面示例:\"壁在求他。求他凿下去。\"\"他的心跳和壁的搏动对上了。\"(结论句,读者满足了,直接划走)\n- 正面示例:\"他低头看自己的手。手背上多了一道金色纹路。\"\"一只青白色的手从门缝里伸了进来。\"\"'第几号了?'它们齐声问。\"\n\n铁则八:短句节奏纪律\n- 每行视觉长度控制在17字以内(手机阅读一屏约17字),长句拆成短句。\n- 短句必须有身份:危险落点/发现落点/反咬落点/打断/对话锋刃/章末钩子。没有身份的短句必须合并到前后句,禁止为了短句而短句。\n- 禁止连续3个以上≤12字短句且无新信息/无转折/无对话(碎句病),除非是压力爆点(单句成段的鼓点是对的,同一段内连续短句才是病)。\n- 同拍内动作链用逗号串联,换拍/换判断才用句号。禁止\"动作。感受。\"\"动作。光线。\"这种拍内断句。\n- 短句鼓点必须单独成段,不要堆在同一段里。\n\n铁则九:描写克制原则\n- 同一段落内禁止连续2个以上\"像/仿佛/如\"比喻,网文节奏快,直接写具体细节比打比方有力。\n- 例:不要写\"像被铁钳夹住一样疼\",直接写\"指骨在响\";不要写\"像潮水一样涌来\",直接写\"凉意在脊背炸开\"。\n- 视觉描写占比不超过总感官描写的50%,每个关键场景必须至少有一个嗅觉或触觉细节。\n- 恐怖/悬疑/克苏鲁场景强制要求至少一个嗅觉(腥/甜/腐/霉/焦糊)或触觉(烫/冰/麻/黏/针扎)细节,否则沉浸感直接归零。\n\n【写作技法】\n\n场景切入\n- 严格遵守铁则零、铁则四开头规则。\n- 第一句就把人扔进正在发生的刺激里,不要任何铺垫。\n\n对话穿插\n- 严格遵守铁则五对话碰撞规则。\n- 对话必须与动作、神态、环境交替出现。禁止连续三行以上纯对话无描写。\n- 对话标签用\"说/道/问/答/低声道\"等简洁词,不堆砌\"愤怒地说\"\"激动地喊道\"——情绪用动作展示。\n- 对话承载潜台词:人物说的话和真实想法之间可以有缝隙,用微表情和停顿暗示。\n\n节奏控制\n- 紧张场景用短句、断句、动词密集,少修饰。\n- 舒缓场景允许稍长的句子和感官铺陈,但每句仍有信息承载。\n- 关键瞬间(转折、冲击、发现)用极短句甚至单句成段,制造顿点。\n- 段落长度有变化,不连续出现多个等长段落。\n\n信息密度\n- 严格遵守铁则六反咬规则。\n- 每句话必须承载至少一项有效信息:推进情节、揭示人物、渲染氛围、暗示伏笔。\n- 删除一切不承载信息的句子:空洞感慨、重复描写、无效过渡。\n- 形容词和副词克制使用,优先用精准动词和名词。能用\"攥紧\"就不用\"紧紧握住\"。\n- 一段只给一个新信息,复杂设定先给结果再给名称,专有名词必须绑定可见物件或动作。\n\n【一拍一息·标点规则】\n- 同一镜头/同一动作链内,动作→光线/视线→触觉→外界反应用逗号连起来,不许用句号切断。\n- 换拍(换动作/换空间/换时间/换判断)才用句号。\n- 破折号禁止使用,中文网文不需要破折号,逗号足够做认知翻转。\n- 禁止\"不是X是Y\"解释结构,直接写Y的具体表现。\n\n【输出要求】\n1. 全部使用中文输出,英文词汇仅在必要专有名词时出现。\n2. 直接输出正文,不写任何解释、前言、后记、大纲、总结或注释。\n3. 不使用Markdown格式标记正文,不加分隔线、标题、加粗等排版符号。\n4. 严格保持人物设定一致性:性格、说话方式、行为逻辑、已知信息不冲突。\n5. 严格遵循给定的视角限制,不越界描写视角人物不可能知道的信息。\n6. 一章只写一件核心事,场景不超过3个。\n7. 每章至少有一种外部压力:人来阻止/制度卡住/时间逼近/空间封闭/物件异常。\n\n【禁止事项】\n- 禁止开篇写景、交代背景、介绍人物、回忆前世——直接进动作现场。\n- 禁止开篇第一句超过20字。\n- 禁止前300字无冲突、无动作、无对话、无身体反应。\n- 禁止直接陈述情绪词(紧张/害怕/难过/开心/愤怒/尴尬/压抑/绝望等),必须用生理级身体反应替代。\n- 禁止套路反应词(48个黑名单):心头一跳/脸色一变/握紧拳头/不由得/情不自禁/忍不住/不禁/点了点头/叹了口气/皱了皱眉/冷哼一声/嘴角微扬/微微一笑/苦笑一声/瞳孔骤缩/眼中闪过一丝/嘴角勾起一抹/眼中寒光一闪/浑身一颤/虎躯一震/眼中精芒爆闪/气势陡然一变/一股强横的气息/散发出王者之气/冷笑一声/嗤笑一声/摇头失笑/面露难色/眉头紧锁/眼神复杂/深吸一口气/缓缓开口/淡淡道/冷冷道/沉声道/厉声道/爆喝道/怒吼道/一字一句道/不置可否/置若罔闻/恍若未闻/不以为然/不屑一顾/视若无睹/无动于衷/面无表情——全部用具体生理反应替代。\n- 禁止装神弄鬼假钩子:\"一股神秘的/一种莫名的/一丝诡异的/似乎意识到了什么/好像发现了什么/不祥的预感/事情没那么简单/他不知道的是/黑暗中有什么东西\"——钩子必须是具体的、看得见摸得着的信息。\n- 禁止连续超过三句纯对话无动作/神态/环境穿插,且对话必须有碰撞有反对。\n- 禁止填充词堆砌:非常/十分/极其/很/似乎/好像/仿佛/有点/有些/事实上/实际上/不由自主/毫无疑问/众所周知/令人/让人——这些词能删则删。\n- 禁止破折号,用逗号或冒号替代。\n- 禁止\"不是X是Y\"结构。\n- 禁止碎句病:同一段落内连续3个以上≤12字短句且无新信息,必须合并;短句鼓点单独成段是正确写法。\n- 禁止连续比喻:同一段落内禁止2个以上\"像/仿佛/如\"比喻,直接写细节。\n- 禁止拍内断句:\"他走。光打在墙上。\"同一动作链必须逗号串联。\n- 禁止突然切换视角或叙事人称,视角切换必须有明确的段落分隔或场景转换信号。\n- 禁止现代网络用语、流行梗、出戏表达破坏叙事沉浸感。\n- 禁止角色说出不符合其身份和知识范围的话。\n- 禁止上帝视角剧透——叙述者知道的信息不能超过视角人物。\n- 禁止性格判断句:\"他是个怎样的人\",让行为自己证明。\n- 禁止解释腔:\"这说明了\"\"这意味着\",让人物通过动作重新发现。\n- 禁止章末用结论式/判断句\"了。\"收尾,必须留具体新信息钩子。\n- 禁止章末用\"就这样/原来如此/所以/于是/最终/最后/总之\"等总结词收束。\n\n> 2026网文战场:3秒定生死,300字定留存,每300字一个反咬,章末让读者骂断更。每一个字都要服务于追读。\n`;\n","{\n \"bodyParts\": [\n \"头\", \"脸\", \"眼\", \"眉\", \"鼻\", \"口\", \"唇\", \"舌\", \"齿\", \"耳\",\n \"颈\", \"肩\", \"臂\", \"手\", \"指\", \"掌\", \"胸\", \"背\", \"腰\", \"腹\",\n \"腿\", \"脚\", \"膝\", \"腕\", \"肘\", \"喉\", \"皮肤\", \"指尖\", \"后颈\", \"太阳穴\",\n \"眉心\", \"下颌\", \"指节\", \"掌心\", \"虎口\", \"脊背\", \"肋骨\", \"心脏\", \"肺\", \"胃\",\n \"肠\", \"脚踝\", \"脚跟\", \"脚趾\", \"颧骨\", \"眼眶\", \"鼻翼\", \"嘴角\", \"手腕\", \"锁骨\"\n ],\n \"sensoryVerbs\": [\n \"看\", \"望\", \"瞥\", \"瞪\", \"盯\", \"瞄\", \"凝视\", \"注视\", \"扫视\", \"环顾\",\n \"俯瞰\", \"眺望\", \"听\", \"闻\", \"嗅\", \"尝\", \"触\", \"摸\", \"感觉\", \"感到\",\n \"觉得\", \"察觉\", \"感知\", \"一紧\", \"一凉\", \"一麻\", \"一颤\", \"发热\", \"发凉\", \"发麻\",\n \"发紧\", \"刺痛\", \"灼痛\", \"酸痛\", \"冰冷\", \"滚烫\", \"湿润\", \"干燥\", \"紧绷\", \"松弛\",\n \"胀痛\", \"发痒\", \"抽搐\", \"收缩\", \"悸动\", \"发麻\", \"一沉\", \"一跳\", \"发烫\"\n ],\n \"environmentSignals\": [\n \"光\", \"影\", \"声\", \"音\", \"风\", \"雨\", \"气味\", \"温度\", \"震动\", \"颤动\",\n \"光线\", \"阴影\", \"噪音\", \"寂静\", \"寒意\", \"暖意\", \"湿气\", \"尘埃\", \"烟雾\", \"气息\",\n \"回声\", \"脚步声\", \"呼吸声\", \"心跳声\", \"钟声\", \"铃声\", \"水滴声\", \"风声\", \"雨声\", \"雷鸣\",\n \"月光\", \"阳光\", \"灯光\", \"烛火\", \"雾气\", \"霜\", \"露水\", \"热气\", \"冷气\", \"光影\",\n \"反光\", \"光斑\", \"黑影\", \"响动\", \"异响\", \"动静\", \"微光\", \"强光\"\n ],\n \"actionVerbs\": [\n \"走\", \"站\", \"坐\", \"跑\", \"跳\", \"蹲\", \"跪\", \"转身\", \"回头\", \"抬手\",\n \"伸手\", \"握拳\", \"松开\", \"握紧\", \"点头\", \"摇头\", \"皱眉\", \"眨眼\", \"吸气\", \"呼气\",\n \"屏息\", \"咳嗽\", \"笑\", \"哭\", \"叹息\", \"颤抖\", \"后退\", \"前进\", \"停下\", \"跨出\",\n \"迈\", \"踏\", \"扶\", \"撑\", \"推\", \"拉\", \"抓\", \"握\", \"按\", \"捏\",\n \"拍\", \"打\", \"踢\", \"撞\", \"躲\", \"闪\", \"避\", \"仰起\", \"低下\", \"凑近\",\n \"退开\", \"侧身\", \"蜷缩\", \"舒展\", \"抱紧\", \"推开\", \"攥紧\", \"摩挲\", \"擦拭\", \"颤抖\"\n ],\n \"fillerPatterns\": [\n \"非常\", \"十分\", \"极其\", \"很\", \"非常的\", \"十分的\", \"似乎\", \"好像\", \"仿佛\", \"宛如\",\n \"犹如\", \"有点\", \"有些\", \"某种程度上\", \"事实上\", \"实际上\", \"说实话\", \"老实说\", \"不知道为什么\", \"莫名其妙\",\n \"不由自主\", \"情不自禁\", \"忍不住\", \"不禁\", \"居然\", \"竟然\", \"显然\", \"明显\", \"毫无疑问\", \"毋庸置疑\",\n \"众所周知\", \"一般来说\", \"通常来说\", \"总的来说\", \"话说回来\", \"顺带一提\", \"对了\", \"哦\", \"嗯\", \"啊\",\n \"哎\", \"唉\", \"呢\", \"吧\", \"吗\", \"呀\", \"就是\", \"其实\", \"反正\", \"总之\",\n \"可以说\", \"应该说\", \"怎么说\", \"不得不说\", \"令人\", \"让人\", \"使人\", \"那种\", \"这个\", \"那个\"\n ],\n \"dialogueTags\": [\n \"说\", \"道\", \"问\", \"答\", \"喊\", \"叫\", \"吼\", \"低语\", \"呢喃\", \"嘟囔\",\n \"抱怨\", \"冷笑\", \"笑道\", \"怒道\", \"喊道\", \"问道\", \"答道\", \"沉吟\", \"回应\", \"回答\",\n \"开口\", \"插话\", \"打断\", \"补充\", \"解释\", \"嘀咕\", \"小声说\", \"大声说\", \"厉声道\", \"低声道\",\n \"轻声说\", \"厉喝\", \"呵斥\", \"嘲讽\", \"讥讽\", \"质问\", \"反问\", \"追问\", \"附和\", \"赞同\",\n \"反驳\", \"否认\", \"承认\", \"嗫嚅\", \"支吾\", \"应道\", \"叹道\", \"笑道\", \"怒喝\", \"惊呼\"\n ],\n \"sightWords\": [\n \"光\", \"亮\", \"暗\", \"黑\", \"白\", \"红\", \"橙\", \"黄\", \"绿\", \"蓝\",\n \"紫\", \"灰\", \"影\", \"色\", \"闪\", \"耀\", \"辉\", \"映\", \"照\", \"透\",\n \"映出\", \"倒映\", \"反光\", \"发光\", \"闪烁\", \"明灭\", \"忽明忽暗\", \"刺眼\", \"柔和\", \"昏暗\",\n \"明亮\", \"黯淡\", \"漆黑\", \"惨白\", \"通红\", \"金黄\", \"碧绿\", \"湛蓝\", \"银白\", \"斑驳\",\n \"朦胧\", \"清晰\", \"模糊\", \"若隐若现\", \"晃眼\", \"眩目\", \"黯淡\"\n ],\n \"soundWords\": [\n \"响\", \"鸣\", \"嗡\", \"隆隆\", \"轰隆\", \"叮咚\", \"啪\", \"咔\", \"嗒\", \"吱\",\n \"嘎\", \"哗啦\", \"淅沥\", \"呼呼\", \"飒飒\", \"沙沙\", \"窃窃\", \"低沉\", \"清脆\", \"刺耳\",\n \"悦耳\", \"寂静\", \"安静\", \"嘈杂\", \"轰鸣\", \"爆裂\", \"呜咽\", \"呼啸\", \"窸窣\", \"咯噔\",\n \"砰\", \"嘭\", \"哐当\", \"叮当\", \"滴答\", \"潺潺\", \"汩汩\", \"呼啸\", \"咆哮\", \"凄厉\",\n \"沉闷\", \"洪亮\", \"细若游丝\", \"震耳欲聋\"\n ],\n \"smellWords\": [\n \"香\", \"臭\", \"腥\", \"膻\", \"甜\", \"苦\", \"辣\", \"酸\", \"刺鼻\", \"芬芳\",\n \"馥郁\", \"腐臭\", \"焦味\", \"血腥味\", \"土腥味\", \"铁锈味\", \"霉味\", \"清香\", \"幽香\", \"浓香\",\n \"腥臭\", \"焦糊\", \"烟熏味\", \"药味\", \"脂粉香\", \"酒香\", \"茶香\", \"果香\", \"恶臭\", \"异味\",\n \"淡淡\", \"浓烈\", \"若有若无\", \"扑面而来\", \"沁人心脾\", \"令人作呕\"\n ],\n \"touchWords\": [\n \"冷\", \"热\", \"温\", \"凉\", \"冰\", \"烫\", \"软\", \"硬\", \"粗\", \"滑\",\n \"湿\", \"干\", \"黏\", \"腻\", \"糙\", \"锐\", \"钝\", \"麻\", \"痒\", \"痛\",\n \"疼\", \"酸\", \"胀\", \"麻酥酥\", \"沉甸甸\", \"轻飘飘\", \"黏糊糊\", \"湿漉漉\", \"冰凉\", \"滚烫\",\n \"粗糙\", \"光滑\", \"柔软\", \"坚硬\", \"冰冷\", \"温热\", \"湿润\", \"干燥\", \"尖利\", \"钝重\",\n \"细腻\", \"粗粝\", \"毛绒绒\", \"湿漉漉\", \"汗津津\", \"凉丝丝\", \"暖洋洋\"\n ],\n \"tasteWords\": [\n \"甜\", \"酸\", \"苦\", \"辣\", \"咸\", \"涩\", \"麻\", \"鲜\", \"腥\", \"腻\",\n \"清淡\", \"浓烈\", \"甘甜\", \"苦涩\", \"辛辣\", \"酸甜\", \"咸涩\", \"索然无味\", \"余味\", \"回甘\",\n \"香甜\", \"咸鲜\", \"麻辣\", \"酸辣\", \"甜腻\", \"苦涩\", \"清淡\", \"醇厚\", \"寡淡\", \"齁咸\",\n \"酸甜可口\", \"又苦又涩\", \"咸得发苦\", \"入口即化\", \"回味悠长\"\n ],\n \"emotionWords\": [\n \"喜\", \"怒\", \"哀\", \"惧\", \"爱\", \"恶\", \"欲\", \"惊\", \"慌\", \"乱\",\n \"烦\", \"闷\", \"爽\", \"痛\", \"紧张\", \"害怕\", \"恐惧\", \"愤怒\", \"生气\", \"开心\",\n \"高兴\", \"快乐\", \"悲伤\", \"难过\", \"痛苦\", \"绝望\", \"希望\", \"期待\", \"失望\", \"焦虑\",\n \"担忧\", \"安心\", \"平静\", \"激动\", \"兴奋\", \"烦躁\", \"郁闷\", \"压抑\", \"沉重\", \"轻松\",\n \"释然\", \"矛盾\", \"犹豫\", \"坚定\", \"决绝\", \"羞耻\", \"愧疚\", \"悔恨\", \"嫉妒\", \"羡慕\",\n \"感激\", \"感动\", \"轻蔑\", \"厌恶\", \"憎恨\", \"爱恋\", \"思念\", \"孤寂\", \"落寞\", \"怅然\"\n ]\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_ai_continue_length\",\n \"option_id\": \"opt_ai_short\",\n \"option_name\": \"短(200-400字)\",\n \"option_description\": \"AI续写长度短,单次输出200-400字。适合逐段精修、边写边改、对话密集场景,或者作者想要紧密控制剧情走向的情况。\",\n \"system_prompt\": \"你使用短续写模式,单次续写200-400字。短续写适合逐段推进、紧密控制的写作场景。每次续写只写一小段——一个对话来回、一个动作瞬间、一个情绪片段、一段环境描写。不要急于推进剧情,把当前这一小段写精写透。短续写让作者可以随时调整方向,不会出现AI写了一大段结果方向跑偏的问题。适合:对话场景(每次写一两句对话+反应)、动作场景(每次写一个招式/一个动作)、需要边写边改的精修场景、作者想要逐段把关的情况。\",\n \"constraints\": [\n \"单次续写200-400字,不得超过400字\",\n \"每次续写聚焦一个小片段(一个对话来回/一个动作/一个情绪瞬间)\",\n \"不急于推进大剧情,把当前片段写精\",\n \"结尾停在自然的断点(对话停顿/动作间隙/悬念点)\",\n \"保持与前文风格、视角、情绪的连贯\",\n \"不要在短续写中塞入太多信息\"\n ],\n \"examples\": [\n {\n \"text\": \"(短续写示例,约300字)\\n他抬起头。\\n\\n门口站着一个女人,黑色风衣,红色高跟鞋,手里拿着一把折叠伞——外面下雨了,他竟然没注意到。\\n\\n「你怎么来了?」他问,声音有些沙哑。\\n\\n女人没有回答,只是把伞收好,靠在门边。伞尖滴下来的水在地板上积成一小滩,像一个正在慢慢扩大的句号。\\n\\n「我们需要谈谈。」她说。\\n\\n四个字,轻得像一声叹息,却重得像一块石头砸在他胸口。\",\n \"note\": \"短续写:约200字,聚焦一个瞬间——女人出现,几句对话,停在悬念点\"\n }\n ],\n \"threshold_overrides\": {\n \"maxParagraphLength\": 100,\n \"targetParagraphLength\": 50,\n \"shortSentenceRatio\": 0.5\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.0,\n \"sensorySignal\": 1.0,\n \"action\": 1.0,\n \"emotion\": 1.2,\n \"infoAdvance\": 0.8\n }\n}\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_ai_continue_length\",\r\n \"option_id\": \"opt_ai_medium\",\r\n \"option_name\": \"中等(500-800字,默认)\",\r\n \"option_description\": \"AI续写长度中等,单次输出500-800字。这是最通用的续写长度,既能完成一个完整的小场景,又不会太长导致跑偏,是默认推荐选项。\",\r\n \"system_prompt\": \"你使用中等长度续写模式,单次续写500-800字。这是最平衡的续写长度——足够完成一个完整的小场景(一段对话+反应、一个小冲突、一段描写+动作),又不会长到失控。中等续写能保持叙事的连贯性,让读者读到一个完整的“叙事节拍”,同时作者仍然有足够的控制权。续写要有完整的起承转合:承接上文→发展→停在一个自然的断点(钩子/情绪落点/场景转换点)。适合:大多数写作场景,平衡连贯性和可控性。\",\r\n \"constraints\": [\r\n \"单次续写500-800字\",\r\n \"完成一个完整的小场景或叙事节拍\",\r\n \"承接上文自然发展,有起承转合\",\r\n \"结尾停在自然断点(钩子/情绪落点/场景转换)\",\r\n \"保持与前文风格、视角、情绪、节奏的连贯\",\r\n \"信息推进适度,不要在一段续写中塞太多剧情\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"(中等续写示例,约650字)\\n门开了。\\n\\n站在门口的女人穿着黑色风衣,头发被雨水打湿了几缕贴在脸颊上,手里的折叠伞还在滴水。她看起来和三年前没什么变化,只是眼角多了一丝他没见过的疲惫。\\n\\n「你怎么来了?」他站起身,椅子腿在地板上划出刺耳的声响。\\n\\n「不请我进去吗?」她微微一笑,那笑容和记忆里一模一样,又好像哪里不一样了。\\n\\n他侧身让她进来。屋里很乱——他这阵子确实没怎么收拾。沙发上堆着脏衣服,茶几上摆着吃剩的泡面,空气里弥漫着烟味和咖啡的苦味。他手忙脚乱地收拾了一下,把衣服塞进洗衣机,把泡面扔进垃圾桶。\\n\\n「不用忙了,」她在沙发上坐下,把包放在膝盖上,「我就说几句话就走。」\\n\\n他停下手,站在她面前。\\n\\n她抬起头看着他,沉默了几秒,像是在斟酌措辞。然后她说了一句让他血液凝固的话——\\n\\n「我要结婚了。」\\n\\n窗外的雨下大了,噼里啪啦地打在窗户上。他站在那里,张了张嘴,却发不出任何声音。\",\r\n \"note\": \"中等续写:约650字,完成一个完整的小场景(她来了→进屋→对话→重磅消息→他的反应),停在情绪冲击点\"\r\n }\r\n ],\r\n \"threshold_overrides\": {},\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.0,\r\n \"sensorySignal\": 1.0,\r\n \"action\": 1.0,\r\n \"emotion\": 1.0,\r\n \"infoAdvance\": 1.0\r\n }\r\n}\r\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_ai_continue_length\",\n \"option_id\": \"opt_ai_long\",\n \"option_name\": \"长(1000-1500字)\",\n \"option_description\": \"AI续写长度长,单次输出1000-1500字。适合快速推进剧情、写完一个完整场景,或作者信任AI方向、希望一口气看到更多内容时使用。\",\n \"system_prompt\": \"你使用长续写模式,单次续写1000-1500字。长续写能写完一个完整的场景,包含完整的起承转合和充分的细节描写。适合:快速推进剧情、写完整段对话+反应、战斗场景从头到尾、探索/发现场景完整展开。长续写要求有明确的场景结构:开头承接上文、中间充分发展(对话+动作+描写+心理)、结尾收束到一个有力的断点。因为篇幅较长,要注意节奏变化——不能全程高潮也不能全程平淡,要有紧张和舒缓的交替。\",\n \"constraints\": [\n \"单次续写1000-1500字\",\n \"完成一个完整场景(有起因-经过-结果/转折)\",\n \"包含对话、动作、描写、心理的均衡搭配\",\n \"节奏要有起伏:紧张与舒缓交替\",\n \"结尾停在有力的断点(大钩子/情绪高潮/场景转换)\",\n \"保持风格连贯,人物言行一致\",\n \"不要写成流水账,每个段落都要有存在的价值\"\n ],\n \"examples\": [\n {\n \"text\": \"(长续写示例,约1200字)\\n完整场景:她来了→对话交锋→真相揭露→情绪爆发→她离开\\n\\n包含:环境描写、动作细节、对话交锋(多个来回)、内心活动、情绪递进、感官细节、结尾震撼钩子。\",\n \"note\": \"长续写:1000-1500字,完整场景,有起承转合和节奏变化,结尾有力\"\n }\n ],\n \"threshold_overrides\": {\n \"maxParagraphLength\": 200,\n \"targetParagraphLength\": 70,\n \"minParagraphCount\": 15,\n \"maxExpositionContinuous\": 300\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.0,\n \"sensorySignal\": 1.1,\n \"action\": 1.1,\n \"emotion\": 1.1,\n \"infoAdvance\": 1.1\n }\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_ai_continue_length\",\n \"option_id\": \"opt_ai_xtra_long\",\n \"option_name\": \"超长(2000字+)\",\n \"option_description\": \"AI续写长度超长,单次输出2000字以上。适合一次性写完一整章或一个大场景,作者高度信任AI方向、希望快速产出时使用。输出量大,需要作者事后把关和修改。\",\n \"system_prompt\": \"你使用超长续写模式,单次续写2000字以上。超长续写可以写完一整章或一个大场景(完整的战斗、完整的对话博弈、完整的探索段落)。适合:灵感充沛时一口气写完、作者已经有清晰的大纲希望AI快速填充、大高潮场景需要充分展开。超长续写要求结构完整:开篇承接→多段发展(可以包含多个小高潮和转折)→大高潮/大转折→有力收束。因为篇幅长,必须注意节奏管理:张弛有度,不能一直紧张也不能一直平淡。要有场景转换、情绪起伏、视角变化(如果视角允许的话)。建议在超长续写前先确认大纲方向,避免2000字写完发现方向跑偏。\",\n \"constraints\": [\n \"单次续写2000字以上,建议2000-3000字\",\n \"完成一整章或一个大场景\",\n \"结构完整:开篇→多段发展→高潮→收束\",\n \"节奏张弛有度,包含多个小起伏\",\n \"对话、动作、描写、心理充分展开\",\n \"结尾必须有力(大钩子/大高潮/大转折)\",\n \"保持人物一致性和逻辑合理性\",\n \"长文本中注意段落变化,避免大块文字造成阅读疲劳\"\n ],\n \"examples\": [\n {\n \"text\": \"(超长续写示例,约2500字)\\n完整章节:她来了→环境渲染→回忆闪回→对话交锋(多个回合)→真相揭露(层层递进)→情绪爆发→沉默→她离开→他独自面对→章末大钩子\\n\\n包含:多段对话、动作细节、环境描写穿插、内心活动、回忆插入、情绪递进、感官细节、多个小转折、大高潮、余韵收束。\",\n \"note\": \"超长续写:2000字以上,完整章节,结构完整,节奏丰富,结尾有力\"\n }\n ],\n \"threshold_overrides\": {\n \"maxParagraphLength\": 250,\n \"targetParagraphLength\": 80,\n \"minParagraphCount\": 25,\n \"maxExpositionContinuous\": 400\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.0,\n \"sensorySignal\": 1.1,\n \"action\": 1.1,\n \"emotion\": 1.2,\n \"infoAdvance\": 1.2\n }\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_ai_creativity\",\n \"option_id\": \"opt_ai_conservative\",\n \"option_name\": \"保守(temperature:0.3)\",\n \"option_description\": \"AI创造性保守,temperature设为0.3。严格跟随上下文和已有设定,不擅自添加新设定、新角色或意外转折。适合需要严格控制剧情走向的场景,如已有详细大纲的续写、风格模仿、精确改写。\",\n \"system_prompt\": \"你使用保守创作模式(temperature=0.3)。你的创作必须严格跟随用户提供的上下文、大纲和已有设定。禁止擅自添加新角色、新设定、新线索或意外转折——如果剧情需要新元素,必须是从已有信息中自然推导出来的,而不是凭空引入。用词选择偏向确定性高、经过验证的表达,避免生僻词和冒险的修辞。对话严格符合人物已建立的说话风格,不OOC(out of character)。剧情推进按部就班,不跳跃不省略关键步骤。适合:按大纲续写、精确改写、风格模仿、需要严格控制一致性的场景。\",\n \"constraints\": [\n \"严格跟随上下文和已有设定,禁止擅自添加新设定/新角色/新线索\",\n \"新元素必须从已有信息中自然推导,不能凭空引入\",\n \"人物言行必须符合已建立的性格,禁止OOC\",\n \"用词准确稳定,避免生僻词和冒险修辞\",\n \"剧情推进按部就班,不跳过关键步骤\",\n \"不制造意外转折或惊喜,除非用户明确要求\",\n \"保持与前文风格、语气、视角的完全一致\"\n ],\n \"examples\": [\n {\n \"text\": \"(保守模式续写示例)\\n前文:林晚走进咖啡馆,看到沈知行坐在靠窗的位置。\\n\\n续写:她深吸一口气,走过去在他对面坐下。服务员过来问她点什么,她要了一杯美式咖啡。\\n\\n「你找我有什么事?」林晚问道,尽量让自己的声音听起来平静。\\n\\n沈知行端起咖啡杯喝了一口,没有立刻回答。\\n\\n(保守模式:不引入新角色、不制造意外、严格按已有场景和人物性格推进,对话自然,动作合理)\",\n \"note\": \"保守模式:严格跟随上下文,不添加意外元素,稳定推进\"\n }\n ],\n \"threshold_overrides\": {},\n \"radar_weights\": {\n \"bodyReaction\": 1.0,\n \"sensorySignal\": 0.9,\n \"action\": 1.0,\n \"emotion\": 1.0,\n \"infoAdvance\": 1.1\n }\n}\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_ai_creativity\",\r\n \"option_id\": \"opt_ai_balanced\",\r\n \"option_name\": \"平衡(temperature:0.7,默认)\",\r\n \"option_description\": \"AI创造性平衡,temperature设为0.7。在遵循大纲和设定的基础上,允许适当的创意发挥——可以添加有趣的细节、自然的对话变化、适度的意外转折。是最通用的创作模式,默认推荐选项。\",\r\n \"system_prompt\": \"你使用平衡创作模式(temperature=0.7)。你在遵循核心设定和大纲的基础上,可以进行适度的创意发挥。允许添加:生动的细节描写、自然的对话变化、小范围的意外和转折、有趣的配角反应、环境中的小彩蛋。但大方向必须按大纲走,核心人设不能崩,主要剧情节点不能偏离。用词可以灵活,适当使用比喻、修辞和生动的表达,但不要过于花哨。对话可以有即兴发挥,但要符合人物性格。可以在场景中加入出人意料但合理的小细节,让故事更有活力。适合:大多数创作场景,既有可控性又有创作活力。\",\r\n \"constraints\": [\r\n \"核心设定、大纲、人设必须遵循,不能偏离大方向\",\r\n \"允许添加生动细节、自然的对话变化、小范围意外\",\r\n \"允许使用修辞和比喻,但不过度花哨\",\r\n \"对话可以即兴发挥,但符合人物性格\",\r\n \"小转折可以有,但必须合理且能自洽\",\r\n \"可以引入次要新元素(如一个路人、一个小道具),但不能影响主线\",\r\n \"在稳定性和创造性之间取得平衡\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"(平衡模式续写示例)\\n前文:林晚走进咖啡馆,看到沈知行坐在靠窗的位置。\\n\\n续写:她深吸一口气,走过去。高跟鞋踩在木质地板上,发出清脆的声响——她特意选了这双鞋,就是为了让自己看起来不那么狼狈。\\n\\n沈知行抬起头,目光在她脸上停留了一秒。他比三年前瘦了些,眼下有淡淡的青黑,像是很久没睡好。\\n\\n「你迟到了七分钟。」他说,语气听不出情绪。\\n\\n「路上堵车。」她坐下,发现桌上已经摆了一杯美式——她以前最爱喝的那种,不加糖不加奶。他还记得。\\n\\n(平衡模式:添加了合理的细节——高跟鞋、眼下青黑、提前点好的咖啡,这些小细节增加了层次感但不偏离主线,同时“他还记得”是一个小情感转折)\",\r\n \"note\": \"平衡模式:在遵循主线的基础上添加生动细节和小转折,既有控制又有活力\"\r\n }\r\n ],\r\n \"threshold_overrides\": {},\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.0,\r\n \"sensorySignal\": 1.0,\r\n \"action\": 1.0,\r\n \"emotion\": 1.0,\r\n \"infoAdvance\": 1.0\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_ai_creativity\",\r\n \"option_id\": \"opt_ai_adventurous\",\r\n \"option_name\": \"奔放(temperature:1.0)\",\r\n \"option_description\": \"AI创造性奔放,temperature设为1.0。敢于展开和创新,可以引入意外转折、新奇比喻、大胆的剧情发展。适合灵感探索、头脑风暴、需要突破常规的创作场景。输出可能更有惊喜,但也可能偏离预期,需要作者把关。\",\r\n \"system_prompt\": \"你使用奔放创作模式(temperature=1.0)。你被鼓励大胆创作、敢于展开、勇于创新。允许:出人意料的剧情转折、新奇的比喻和修辞、大胆的叙事手法、意想不到的角色反应、新颖的场景描写、甚至可以打破第四面墙(如果合适)。你可以尝试各种写作风格的融合,创造独特的表达方式。但注意:奔放不等于胡来——即使是最大胆的创意,也要在情感逻辑上自洽(角色的反应可以出乎意料,但必须符合人性真实)。适合:灵感探索、头脑风暴、寻找创意突破口、写需要“神来之笔”的场景、作者卡壳时的创意启发。输出可能比较“野”,作者可以从中挑选好的灵感使用。\",\r\n \"constraints\": [\r\n \"鼓励大胆创新:意外转折、新奇比喻、大胆叙事手法\",\r\n \"可以尝试风格融合、独特表达、打破常规\",\r\n \"角色反应可以出人意料,但情感逻辑必须自洽\",\r\n \"用词和修辞可以大胆,不怕冒险\",\r\n \"可以引入新元素、新视角、新叙事方式\",\r\n \"奔放不等于胡来,核心人性逻辑必须成立\",\r\n \"适合灵感探索和头脑风暴,最终质量需要作者把关\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"(奔放模式续写示例)\\n前文:林晚走进咖啡馆,看到沈知行坐在靠窗的位置。\\n\\n续写:她走过去的那七步,像走过了三年的时光。每一步都踩在记忆的碎片上——那年冬夜他送的围巾、分手后她删掉的聊天记录、无数个想打电话又放下手机的凌晨三点。\\n\\n沈知行抬头看她。\\n\\n窗外忽然下起了雨,豆大的雨点噼里啪啦砸在玻璃上,像是谁在天上打翻了一盆豆子。咖啡馆里的爵士乐正好换了一首,是《La Vie En Rose》——他们第一次约会时乐队演奏的曲子。\\n\\n他站起来帮她拉开椅子,动作自然得像他们昨天才一起吃过饭。\\n\\n「你瘦了。」他说。\\n\\n林晚笑了笑,坐下,把包放在旁边的椅子上。包里的手机震了一下——是她未婚夫发来的消息:「谈完了吗?我来接你。」\\n\\n她把手机翻过去扣在桌上,没有回复。\\n\\n(奔放模式:加入了记忆闪回、天气突变、音乐巧合、未婚夫短信等多个意外元素,戏剧性强,情感张力大,但每个元素都有情感逻辑)\",\r\n \"note\": \"奔放模式:大胆加入意外元素和戏剧张力,多个转折和层次,适合寻求灵感突破\"\r\n }\r\n ],\r\n \"threshold_overrides\": {},\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.1,\r\n \"sensorySignal\": 1.2,\r\n \"action\": 1.0,\r\n \"emotion\": 1.3,\r\n \"infoAdvance\": 1.0\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_anchor_density\",\r\n \"option_id\": \"opt_anchor_sparse\",\r\n \"option_name\": \"稀疏(每800字1个)\",\r\n \"option_description\": \"锚点密度稀疏,每800字至少1个身体锚点/感官锚点。适合铺陈型、氛围型、文学性较强的作品,不频繁打断叙事节奏。\",\r\n \"system_prompt\": \"你使用稀疏锚点密度模式。身体锚点和感官锚点(描写人物身体反应、感官体验的词句)大约每800字出现1个即可。这个模式下锚点是点缀而非刚需,让叙事更加流畅自然,不被频繁的“他握紧拳头”“她心跳加速”打断。锚点要用在关键时刻——情绪爆发点、重大转折点、紧张时刻,用一个精准的身体反应来强化感受,比频繁使用十三个普通锚点更有力。日常叙述和环境描写可以不带身体锚点,给读者呼吸空间。\",\r\n \"constraints\": [\r\n \"每800字至少1个身体/感官锚点\",\r\n \"单章锚点间隔不超过1000字\",\r\n \"锚点要用在关键时刻,不要随意插入\",\r\n \"一个精准有力的锚点胜过三个泛泛的锚点\",\r\n \"日常/环境描写段落可以不含锚点\",\r\n \"锚点类型要多样,不要反复使用同一个动作(如反复“握紧拳头”)\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"(稀疏模式示例,800字左右才出现一个锚点)\\n暮色四合,远山如黛。江面上一叶扁舟缓缓漂过,渔翁坐在船头垂钓,纹丝不动,像是和这片山水融为了一体。岸边的芦苇随风摇曳,发出沙沙的声响,偶尔有水鸟扑棱着翅膀掠过水面。\\n\\n她站在江堤上,久久没有说话。风吹起她的长发和衣袂,远处的落日把半边天都烧成了橘红色,映在江面上,像一条燃烧的河流。\\n\\n……(中间继续环境描写和心理活动,约600字)……\\n\\n直到身后传来脚步声,她才蓦然回过神来,指尖不知何时已经冰凉。(锚点:指尖冰凉,暗示等待的紧张和时间的流逝)\",\r\n \"note\": \"稀疏模式:大量环境和心理描写中,关键时刻一个精准锚点(指尖冰凉)画龙点睛\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"minAnchors\": 2,\r\n \"anchorsPerWords\": 800,\r\n \"maxAnchorGap\": 1200\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 0.7,\r\n \"sensorySignal\": 1.2,\r\n \"action\": 0.8,\r\n \"emotion\": 1.0,\r\n \"infoAdvance\": 1.0\r\n }\r\n}\r\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_anchor_density\",\n \"option_id\": \"opt_anchor_standard\",\n \"option_name\": \"标准(每500字1个,默认)\",\n \"option_description\": \"锚点密度标准,每500字至少1个身体锚点/感官锚点。这是最平衡的设置,既保证文本有身体感和代入感,又不过度打断叙事,是默认推荐选项。\",\n \"system_prompt\": \"你使用标准锚点密度模式。大约每500字出现一个身体锚点或感官锚点,让读者始终保持在角色的身体里,有代入感但不过度。锚点自然融入叙事,不要为了凑数而插入生硬的身体描写。可以是:手指的小动作、面部表情变化、心跳呼吸、感官体验(冷热/痛痒/声音/气味)、姿态变化等。锚点要服务于情绪和场景——紧张时手心出汗、难过时喉咙发紧、思考时皱眉、放松时肩膀松下来。让读者通过身体感受到角色的状态。\",\n \"constraints\": [\n \"每500字至少1个身体/感官锚点\",\n \"单章锚点间隔不超过800字\",\n \"锚点自然融入叙事,不生硬插入\",\n \"锚点类型多样:手部/面部/身体姿态/感官体验/呼吸心跳等\",\n \"锚点要与情绪/场景匹配(不是随便写个动作就行)\",\n \"对话段落也要有适当的锚点穿插(动作标签)\"\n ],\n \"examples\": [\n {\n \"text\": \"(标准模式示例,约每500字一个锚点)\\n他推开门,咖啡的香气扑面而来。(感官锚点:嗅觉)\\n\\n咖啡馆里人不多,靠窗的位置坐着一个穿灰色风衣的女人,正低头看着手机。他走过去,在她对面坐下,手心微微有些出汗。(身体锚点:手心出汗-紧张)\\n\\n「你来了。」她抬起头,眼睛里有一种他读不懂的情绪。\\n\\n「嗯。」他清了清嗓子,(动作锚点:清嗓子-不安)「你说有事情要告诉我?」\\n\\n她沉默了几秒,端起咖啡杯喝了一口,杯沿碰到嘴唇的时候,他注意到她的手在轻轻发抖。(身体锚点:手发抖-她也很紧张)\",\n \"note\": \"标准模式:约每200-500字一个锚点,自然融入对话和叙事\"\n }\n ],\n \"threshold_overrides\": {\n \"minAnchors\": 4,\n \"anchorsPerWords\": 500,\n \"maxAnchorGap\": 800\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.0,\n \"sensorySignal\": 1.0,\n \"action\": 1.0,\n \"emotion\": 1.0,\n \"infoAdvance\": 1.0\n }\n}\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_anchor_density\",\r\n \"option_id\": \"opt_anchor_dense\",\r\n \"option_name\": \"密集(每300字1个)\",\r\n \"option_description\": \"锚点密度密集,每300字至少1个身体锚点/感官锚点。适合强情绪、强代入感的场景,让读者时刻感受到角色的身体反应,沉浸感极强。\",\r\n \"system_prompt\": \"你使用密集锚点密度模式。大约每300字就有一个身体或感官锚点,让读者深度沉浸在角色的身体体验中。这个模式适合强烈情绪场景、亲密互动场景、第一人称叙事、悬疑紧张场景。锚点要频繁但不重复——可以是各种微小的身体反应:指尖的颤动、后颈的汗毛、吞咽的动作、瞳孔的收缩、呼吸的节奏变化、肌肉的紧绷、皮肤的温度感、声音的颤抖、气味的变化……身体的每个部位都可以成为锚点。注意:密集不等于堆砌,每个锚点都要传递情绪信息,不能为了凑数写无关的身体部位。\",\r\n \"constraints\": [\r\n \"每300字至少1个身体/感官锚点\",\r\n \"单章锚点间隔不超过500字\",\r\n \"锚点类型极度多样化:手/脚/眼/眉/嘴/颈/肩/背/呼吸/心跳/皮肤/感官等\",\r\n \"每个锚点都要传递情绪或氛围信息\",\r\n \"禁止重复使用同一锚点(不能每次都“握紧拳头”)\",\r\n \"微表情和微动作优先:瞳孔收缩/吞咽/嘴角微抽/手指无意识摩擦等\",\r\n \"感官锚点要覆盖五感:视觉/听觉/嗅觉/触觉/味觉\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"(密集模式示例,几乎每段都有锚点)\\n门吱呀一声开了,一股阴冷的气息扑面而来,她的后颈汗毛瞬间竖了起来。(锚点1:汗毛竖起-恐惧本能)\\n\\n屋子里漆黑一片,她伸手摸索墙壁,指尖碰到了什么黏腻的东西——是湿的,带着铁锈味。她的心跳开始加速,手指不受控制地发抖。(锚点2+3+4:黏腻触感/心跳加速/手指发抖)\\n\\n她深吸一口气,强迫自己往前走。鞋底踩在地板上,发出粘腻的声响,每一步都像踩在她的神经上。太阳穴突突直跳,冷汗顺着脊背往下淌。(锚点5+6+7:脚底触感/太阳穴跳/冷汗)\\n\\n黑暗中,有什么东西碰了一下她的肩膀。\\n\\n她猛地回头,呼吸卡在喉咙里——(锚点8:呼吸卡住)\",\r\n \"note\": \"密集模式:大量身体/感官锚点密集出现,读者时刻处于角色的身体体验中,沉浸感极强\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"minAnchors\": 7,\r\n \"anchorsPerWords\": 300,\r\n \"maxAnchorGap\": 500,\r\n \"minSensoryTypes\": 3\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.4,\r\n \"sensorySignal\": 1.3,\r\n \"action\": 1.1,\r\n \"emotion\": 1.4,\r\n \"infoAdvance\": 0.8\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_anchor_density\",\r\n \"option_id\": \"opt_anchor_extreme\",\r\n \"option_name\": \"极高(每200字1个)\",\r\n \"option_description\": \"锚点密度极高,每200字至少1个身体锚点/感官锚点。适合极度紧张/恐怖/亲密/沉浸式场景,读者几乎通过角色的身体来“呼吸”。不建议整章使用,适合关键场景切换。\",\r\n \"system_prompt\": \"你使用极高锚点密度模式。大约每200字就有一个身体或感官锚点,读者几乎完全通过角色的身体来感知故事。这个模式适合极端场景:恐怖场景的极致恐惧、激情场景的极致亲密、战斗场景的极致紧张、创伤场景的极致痛苦。锚点要密集到读者能感受到角色的每一个生理反应——脉搏的跳动、肌肉的抽搐、汗水的滑落、呼吸的停顿、视野的模糊、声音的失真。注意:极高密度容易让读者疲劳,建议只在关键场景临时切换,常规叙事用标准或密集模式。\",\r\n \"constraints\": [\r\n \"每200字至少1个身体/感官锚点\",\r\n \"单章锚点间隔不超过300字\",\r\n \"锚点覆盖身体各部位和五感,极度多样化\",\r\n \"可以使用更细微的生理反应:脉搏/瞳孔/汗毛孔/肌肉痉挛/耳鸣/视野变化等\",\r\n \"每个锚点精准传递当前情绪状态\",\r\n \"适合短时间高强度场景,不建议整章使用\",\r\n \"身体反应要有层次递进(越来越紧张/越来越恐惧/越来越兴奋)\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"(极高模式示例——恐怖场景,约每100-200字一个锚点)\\n那个声音就在她身后。\\n\\n她的脚趾在鞋里蜷曲起来,指甲掐进掌心,疼,但她不敢动。(锚点1+2+3:脚趾蜷曲/掐掌心/痛感)\\n\\n呼吸。她告诉自己要呼吸。可肺像被一只冰冷的手攥住了,空气怎么也吸不进来,胸口剧烈起伏却吸不到氧气。(锚点4+5:呼吸受阻/胸口起伏)\\n\\n有什么东西在她后颈上吹气。冰冷的,带着腐朽的甜味。她的头皮开始发麻,冷汗从额头上滑下来,流进眼睛里,涩得慌,但她不敢眨眼。(锚点6+7+8+9:颈后触感/头皮发麻/冷汗流进眼睛/不敢眨眼)\\n\\n然后,一只手搭上了她的肩膀。\\n\\n那只手冰冷刺骨,湿滑黏腻,像是刚从水里捞出来的。她的牙齿开始打颤,膝盖一软,整个人瘫倒在地——(锚点10+11+12:冰冷触感/牙齿打颤/膝盖发软)\",\r\n \"note\": \"极高模式:几乎每句都有身体反应,极度沉浸式的身体体验,适合极端情绪场景\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"minAnchors\": 10,\r\n \"anchorsPerWords\": 200,\r\n \"maxAnchorGap\": 300,\r\n \"minSensoryTypes\": 4,\r\n \"sightRatio\": 0.4\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.7,\r\n \"sensorySignal\": 1.5,\r\n \"action\": 1.0,\r\n \"emotion\": 1.6,\r\n \"infoAdvance\": 0.6\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_battle_style\",\r\n \"option_id\": \"opt_battle_atmosphere\",\r\n \"option_name\": \"重氛围渲染\",\r\n \"option_description\": \"侧重战斗的感受、压迫感和紧张氛围(默认),动作与感官/心理交织,不追求招式细节而追求整体张力。\",\r\n \"threshold_overrides\": {\r\n \"maxSentenceLength\": 45,\r\n \"shortSentenceRatio\": 0.35\r\n },\r\n \"radar_weights\": {\r\n \"action\": 1.2,\r\n \"sensorySignal\": 1.3,\r\n \"emotion\": 1.3,\r\n \"bodyReaction\": 1.2\r\n },\r\n \"system_prompt\": \"战斗描写注重氛围和感受,不逐招拆解。通过感官印象(风声、金属味、血的温度、压迫感)、身体反应(心跳加速、肌肉紧绷、肾上腺素)和环境变化(灯光闪烁、地面震动、碎片飞溅)来渲染战斗的紧张感。关键动作慢镜头特写,非关键动作一笔带过。节奏有张有弛,在暴烈的动作中穿插瞬间的寂静。\",\r\n \"constraints\": [\r\n \"战斗中必须有感官描写和身体感受\",\r\n \"不逐招罗列,关键动作重点写,过渡动作简洁带过\",\r\n \"战斗环境必须参与氛围营造\",\r\n \"节奏要有张弛,不能全程紧绷\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"刀砍下来的时候,他听见了风的声音。\\n\\n不是风——是刀劈开空气的尖啸。他本能地侧身,刀锋贴着肩膀过去,割破工服,皮肤上立刻泛起一道火辣辣的凉。然后是血,温热的,顺着胳膊往下流,滴在地上,和黑色的煤尘混在一起。\\n\\n对方的第二刀已经到了。\\n\\n他来不及想任何事。身体比脑子快——矿灯的光在刀刃上晃了一下,他抬臂去挡,金属相撞的瞬间,虎口震得发麻,铜碗从腰间脱落,在地上滚出很远,发出空旷的回响。\\n\\n黑暗里全是声音:呼吸声、金属声、血涌进耳朵里的轰鸣声。\",\r\n \"note\": \"不写具体招式,通过感官(风的声音/血的温度/虎口发麻)和环境(铜碗滚动的回响)渲染战斗。\"\r\n }\r\n ],\r\n \"requires\": [],\r\n \"conflicts\": []\r\n}","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_battle_style\",\r\n \"option_id\": \"opt_battle_detail\",\r\n \"option_name\": \"重细节拆招\",\r\n \"option_description\": \"一招一式清晰拆解,动作细节精确到身体部位和武器轨迹。适合武侠、硬派格斗场景,画面感强。\",\r\n \"threshold_overrides\": {\r\n \"maxSentenceLength\": 35,\r\n \"targetSentenceLength\": 18,\r\n \"shortSentenceRatio\": 0.5,\r\n \"maxParagraphLength\": 100\r\n },\r\n \"radar_weights\": {\r\n \"action\": 1.5,\r\n \"bodyReaction\": 1.3,\r\n \"sensorySignal\": 1.0,\r\n \"emotion\": 0.9\r\n },\r\n \"system_prompt\": \"战斗/动作描写注重招式拆解,每一个动作都要写清楚:身体哪个部位在动、从哪个方向来、用什么角度、对方如何应对。动作链条清晰,有因有果。使用精准的动作动词,不用模糊的「打过来」「躲开」,要写具体是怎么打、怎么躲。身体的受力感、重心变化、肌肉反应都要写到。\",\r\n \"constraints\": [\r\n \"每个攻防动作必须写清方向、部位、方式\",\r\n \"动作链条有因果关系,不能跳跃\",\r\n \"使用精准动作动词,不用模糊描述\",\r\n \"每3-4个动作穿插一次身体感受(疼痛、麻木、重心失衡等)\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"对方右拳直扑面门。\\n\\n他偏头闪开,拳风擦着左耳过去,带起一阵热风。同时左脚向前半步,右肘横击对方肋下。\\n\\n对手收拳回防,左臂下格挡开肘击。但他的肘是虚招——右膝已经顶向对方小腹。\\n\\n对手来不及回防,膝盖结结实实撞在腹肌上。对手闷哼一声,弓起身子。\\n\\n他顺势抓住对方衣领,右拳从下往上勾出。\",\r\n \"note\": \"招式拆解清晰,每一步动作有方向有因果,身体感受穿插其中。\"\r\n }\r\n ],\r\n \"requires\": [],\r\n \"conflicts\": [\r\n \"opt_battle_result\"\r\n ]\r\n}","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_battle_style\",\r\n \"option_id\": \"opt_battle_psychological\",\r\n \"option_name\": \"重心理博弈\",\r\n \"option_description\": \"侧重对峙、算计和心理博弈,战斗是心理较量的外在表现。适合智斗、谈判式对峙、高手对决。\",\r\n \"threshold_overrides\": {\r\n \"maxSentenceLength\": 50,\r\n \"shortSentenceRatio\": 0.25,\r\n \"maxParagraphLength\": 250,\r\n \"maxExpositionContinuous\": 400\r\n },\r\n \"radar_weights\": {\r\n \"emotion\": 1.4,\r\n \"infoAdvance\": 1.2,\r\n \"action\": 0.8,\r\n \"bodyReaction\": 1.1\r\n },\r\n \"system_prompt\": \"动作/战斗描写侧重心理博弈。对峙比打斗更重要:双方在出手前的观察、试探、算计、虚张声势、识破对方意图。动作是心理的外化——一个眼神、一个肌肉的微小紧绷、脚步的半寸移动,都比拳打脚踢更重要。真正的胜负在动手之前就已经决定。写沉默中的张力,写双方脑中的计算,写假动作背后的真实意图。\",\r\n \"constraints\": [\r\n \"对峙和心理描写占战斗篇幅的60%以上\",\r\n \"每个动作之前必须有心理铺垫或判断\",\r\n \"关注微表情、微动作和身体语言\",\r\n \"胜负的关键是智慧/心理/信息差,而非蛮力\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"两人相距五米,谁都没有先动。\\n\\n周敬言的右手垂在身侧,手指微微弯曲。林深注意到他食指的第二关节有一层薄茧——那是常年握枪扣扳机磨出来的。但他的枪在腰侧枪套里,扣盖没有打开。\\n\\n是虚张声势?还是在等他先动?\\n\\n林深的目光从对方的手移到眼睛。周敬言的瞳孔很稳,呼吸频率大约每分钟十二次——非常平静。一个真正要开枪的人,呼吸会不自觉地加快。\\n\\n所以他不会开枪。至少现在不会。\\n\\n林深向前迈了一步。\\n\\n他看见周敬言的左眉极轻微地跳了一下。\",\r\n \"note\": \"对峙中心理博弈为主,观察细节、判断意图,动作只是心理的验证。\"\r\n }\r\n ],\r\n \"requires\": [],\r\n \"conflicts\": [\r\n \"opt_battle_result\"\r\n ]\r\n}","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_battle_style\",\r\n \"option_id\": \"opt_battle_result\",\r\n \"option_name\": \"重结果快节奏\",\r\n \"option_description\": \"战斗一笔带过,不写过程只写结果,快节奏推进。适合爽文、非重点战斗、或者主角实力碾压的场景。\",\r\n \"threshold_overrides\": {\r\n \"maxSentenceLength\": 25,\r\n \"shortSentenceRatio\": 0.6,\r\n \"maxParagraphLength\": 60,\r\n \"targetParagraphLength\": 30\r\n },\r\n \"radar_weights\": {\r\n \"action\": 1.4,\r\n \"infoAdvance\": 1.2,\r\n \"sensorySignal\": 0.6,\r\n \"emotion\": 0.7\r\n },\r\n \"system_prompt\": \"战斗过程极简,不写具体招式和打斗细节,直接呈现结果和关键转折点。快进式叙事,三言两语解决战斗。重点写战斗开始前的压迫感和战斗结束后的结果状态,中间过程一笔带过。适合非关键战斗或者实力悬殊的碾压场景。\",\r\n \"constraints\": [\r\n \"战斗过程不超过300字\",\r\n \"不拆解具体招式\",\r\n \"重点写战斗前的张力和战斗后的结果\",\r\n \"结果必须清晰(谁赢了、谁受伤了、获得了什么)\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"四个人围了上来。\\n\\n他没说话。\\n\\n三分钟后。\\n\\n四个人全躺在了地上。\\n\\n他拍了拍袖子上的灰,弯腰捡起掉落的矿灯。灯没碎。\\n\\n继续往前走。\",\r\n \"note\": \"过程完全省略,只写结果,节奏极快,爽感强。\"\r\n }\r\n ],\r\n \"requires\": [],\r\n \"conflicts\": [\r\n \"opt_battle_detail\",\r\n \"opt_battle_psychological\"\r\n ]\r\n}","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_description_style\",\r\n \"option_id\": \"opt_desc_clinical\",\r\n \"option_name\": \"临床写实\",\r\n \"option_description\": \"客观冷静精确的描写方式,像医生观察病例、像警察记录现场。不带感情色彩,细节精确到数字和量化描述。\",\r\n \"threshold_overrides\": {\r\n \"minSensoryTypes\": 2,\r\n \"sightRatio\": 0.6\r\n },\r\n \"radar_weights\": {\r\n \"sensorySignal\": 1.0,\r\n \"emotion\": 0.5,\r\n \"infoAdvance\": 1.3,\r\n \"action\": 1.0\r\n },\r\n \"system_prompt\": \"描写客观、冷静、精确,不带感情色彩。像写报告一样记录场景:精确的数字、准确的位置关系、可量化的物理属性。不写「恐怖」「美丽」「恶心」等主观评价词,只写可观察的事实。温度是多少度,距离是多少米,伤口多长多深,光线从几点钟方向来。冷感来自客观本身,而非形容词。\",\r\n \"constraints\": [\r\n \"禁止使用主观感情色彩词(恐怖、美丽、恶心等)\",\r\n \"物理属性尽量精确量化(温度、距离、尺寸、时间)\",\r\n \"描写顺序遵循空间逻辑(从整体到局部/从外到内)\",\r\n \"不加入叙述者的情感评价\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"尸体位于七号矿道岔口,距主巷入口47米。\\n\\n男性,年龄约45-50岁,身高172厘米,身着藏蓝色矿工服,头戴安全帽,头灯已碎裂。\\n\\n死亡时间初步判断为6-8小时前。体表无明显外伤,但右手食指指甲断裂,指缝中有矿渣残留。岩壁温度计显示当前壁温35.8度,低于正常值1.4度。\\n\\n死者面部朝向岔口深处,双目圆睁,右手向前伸出,呈抓取姿态。\",\r\n \"note\": \"法医/刑侦式客观记录,不带感情,细节精确。\"\r\n }\r\n ],\r\n \"requires\": [],\r\n \"conflicts\": [\r\n \"opt_desc_sensory\",\r\n \"opt_desc_poetic\",\r\n \"opt_desc_minimal\"\r\n ]\r\n}","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_description_style\",\r\n \"option_id\": \"opt_desc_minimal\",\r\n \"option_name\": \"极简白描\",\r\n \"option_description\": \"用最少的字勾勒画面,白描手法,不加修饰。留大量空白给读者想象,克制、冷峻、有力。\",\r\n \"threshold_overrides\": {\r\n \"minSensoryTypes\": 1,\r\n \"sightRatio\": 0.7,\r\n \"maxParagraphLength\": 100\r\n },\r\n \"radar_weights\": {\r\n \"sensorySignal\": 0.7,\r\n \"emotion\": 0.8,\r\n \"action\": 1.2,\r\n \"infoAdvance\": 1.1\r\n },\r\n \"system_prompt\": \"描写极简,白描为主。用最精准的名词和动词勾勒画面,不用形容词堆砌,不用比喻修饰。一个细节胜过十个修饰语。留白比写满更重要,让读者自己去填充画面。描写只提供最关键的视觉信息和必要的动作感知,其余一概省略。\",\r\n \"constraints\": [\r\n \"描写用词极简,能不用形容词就不用\",\r\n \"每个场景描写不超过3个关键意象\",\r\n \"禁止使用比喻、拟人等修辞进行修饰\",\r\n \"不写感觉,只写事实(不写「恐怖的黑暗」,只写「灯灭了」)\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"天黑了。\\n\\n灯灭了。\\n\\n巷道很长。\\n\\n水从顶板滴落。\\n\\n滴。\\n\\n滴。\\n\\n滴。\\n\\n他靠在壁上。\\n\\n手里攥着铜碗。\\n\\n壁是温的。\",\r\n \"note\": \"极简白描,没有修饰,纯事实呈现,反而更有力量。\"\r\n }\r\n ],\r\n \"requires\": [],\r\n \"conflicts\": [\r\n \"opt_desc_sensory\",\r\n \"opt_desc_poetic\",\r\n \"opt_desc_clinical\"\r\n ]\r\n}","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_description_style\",\r\n \"option_id\": \"opt_desc_poetic\",\r\n \"option_name\": \"诗意描写\",\r\n \"option_description\": \"意象优美,节奏舒缓,语言有诗的质感。善用比喻、通感和意象叠加,营造独特的审美氛围。\",\r\n \"threshold_overrides\": {\r\n \"minSensoryTypes\": 3,\r\n \"sightRatio\": 0.4,\r\n \"maxParagraphLength\": 250\r\n },\r\n \"radar_weights\": {\r\n \"sensorySignal\": 1.3,\r\n \"emotion\": 1.4,\r\n \"action\": 0.7\r\n },\r\n \"system_prompt\": \"描写追求诗意美感。善用新鲜的比喻和意象,允许通感(声音有颜色、温度有形状),语言有节奏感和音乐性。意象要精准独特,避免陈词滥调。节奏舒缓,像散文诗一样铺展画面。情感不直说,通过意象传递。每一个意象都要承载情感重量。\",\r\n \"constraints\": [\r\n \"比喻和意象必须新鲜,禁止陈词滥调(心如刀割、泪如雨下等)\",\r\n \"描写节奏舒缓,不急于推进动作\",\r\n \"每个场景至少有一个核心意象贯穿\",\r\n \"避免堆砌华丽辞藻,诗意来自精准而非华丽\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"月光从天窗流下来,在石板地上铺成一片霜。\\n\\n她坐在那片霜里,像一株被遗忘在冬夜的植物。铜碗搁在膝上,碗沿的凹角盛着一小片月光,像盛着一碗凉透了的水。\\n\\n风从巷道尽头来,带着三千尺地底的呼吸。灯焰晃了晃,把她的影子投在墙上,拉成一道细长的、颤抖的线。\",\r\n \"note\": \"月光如霜、如凉水,影子如颤抖的线——意象新鲜,节奏舒缓。\"\r\n }\r\n ],\r\n \"requires\": [],\r\n \"conflicts\": [\r\n \"opt_desc_minimal\",\r\n \"opt_desc_clinical\"\r\n ]\r\n}","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_description_style\",\n \"option_id\": \"opt_desc_sensory\",\n \"option_name\": \"感官沉浸(推荐默认)\",\n \"option_description\": \"五感全开的描写方式,视觉、听觉、嗅觉、触觉、味觉多通道并进,沉浸感极强,让读者身临其境。\",\n \"threshold_overrides\": {\n \"minSensoryTypes\": 3,\n \"sightRatio\": 0.45\n },\n \"radar_weights\": {\n \"sensorySignal\": 1.5,\n \"bodyReaction\": 1.3,\n \"emotion\": 1.2,\n \"action\": 1.0\n },\n \"system_prompt\": \"感官描写的核心是'让读者用身体读'。不是告诉读者'这里很恐怖',而是让读者后颈发紧、手心出汗、闻到那个味道、感觉到那个温度。读者不是在看故事,是在故事里。\\n\\n【五感写作要点】\\n\\n1. 视觉(40%-45%):不要只写'有什么',要写'是什么样的'。\\n- 光线:光源在哪?是强光还是弱光?什么颜色?照在什么东西上反光?阴影在哪?\\n- 颜色:不要只写'红色',写'暗红''铁锈红''像凝固的血一样的红''被水泡得发乌的红'。\\n- 动态:什么在动?怎么动?灰尘在光柱里浮着,水珠顺着岩壁往下爬,烟往上飘,影子在晃。静态画面是死的,有动态才活。\\n- 视角:从角色的眼睛看出去,不是上帝视角。他先看到什么,后看到什么,什么被挡住了看不见,什么晃了他的眼。\\n\\n2. 听觉(20%):声音最能制造沉浸感和紧张感。\\n- 不要只写'有声音',要写声音从哪来、多远、多大、什么质感。'滴答声'不够,'从黑暗深处传来的滴答声,间隔七秒,每一声都比上一声近一点'才有感觉。\\n- 寂静也是声音。'通风管停了之后,耳朵里只剩自己的心跳声,咚咚的,像有人在里面敲鼓。' 对比之下的安静更可怕。\\n- 声音的变化:声音变大了?变小了?变调了?刚才有的声音突然没了?声音的变化比声音本身更重要。\\n- 不要用拟声词堆砌('哐当一声''轰隆巨响'),用角色的感知和反应写声音——'他耳朵嗡的一下,什么都听不见了'比'一声巨响'有力。\\n\\n3. 嗅觉/味觉(15%):嗅觉是最直接触发记忆和情绪的感官,但最容易被忽略。\\n- 每个新场景至少有一个气味。矿道里是什么味?瓦斯是甜丝丝的像烂苹果,旧巷道有霉味和腐臭味,有人的地方有烟味和汗味。\\n- 气味要有层次。不是只有'臭味',是'汗馊味混着烟味,还有一点从深处飘上来的、说不上来的甜腥味'。\\n- 味觉不要滥用,但关键时刻很有效——嘴里的铁锈味(血)、苦味(恐惧时嘴里发苦)、铜味、铁锈味、灰尘的味道。\\n\\n4. 触觉(20%):触觉是锚定感的核心,让读者'踩在地上'。\\n- 温度:空气是冷是热?壁面是温是凉?风吹在脸上是什么感觉?水是冰的还是温的?温度直接传递情绪。\\n- 质感:手摸到的东西是什么触感?岩壁是粗糙的还是滑的?衣服是湿的还是干的?铜碗是凉的还是被手焐热了?\\n- 身体感觉:呼吸的时候肺里是什么感觉?累的时候腿是什么感觉?紧张的时候后颈是什么感觉?疼是怎么个疼法——刺痛?钝痛?火辣辣的?\\n- 不要写'很疼''很冷',写'冷风灌进领口,顺着脊梁往下窜,他打了个寒颤''手指冻得发麻,弯都弯不过来'。\\n\\n【技法原则】\\n\\n1. 感官融入动作:不要单独拎出来写'这里有XX味,声音是XX,温度是XX',要把感官写进动作里。'他扶着壁面往前走,岩壁冰凉粗糙,磨得手心发疼,空气里有股甜丝丝的味道,他知道那是瓦斯。'——感官跟着动作走,不生硬。\\n\\n2. 感官跟着情绪走:角色紧张的时候,听觉会变敏锐(能听见平时听不见的声音),视觉会变窄(只看得见眼前的东西);角色放松的时候,感官会散开;角色恐惧的时候,会闻到平时闻不到的味道。感官不是客观的,是被情绪过滤的。\\n\\n3. 选最有代表性的感官:不是每个场景都要五感全上,选2-3种最能传递当下氛围的。恐怖场景侧重听觉+触觉+嗅觉;抒情场景侧重视觉+触觉;动作场景侧重触觉+听觉。\\n\\n4. 感官要有变化:同一个场景里,感官重点要变。刚进一个地方先闻到味道,然后看到光线,然后听到声音,然后摸到什么。感官像镜头一样推近,读者跟着进去。\\n\\n5. 禁止陈词滥调:'一股寒气从脚底直冲天灵盖''倒吸一口凉气''空气中弥漫着恐怖的气息'——这些都是偷懒,要用具体的感官细节代替。\",\n \"constraints\": [\n \"每个场景至少激活3种感官类型,视觉占比不超过45%,必须有非视觉感官\",\n \"触觉(温度/质感/身体感觉)是核心锚点,每个场景至少有1处触觉描写\",\n \"感官描写必须融入动作或叙事,禁止像清单一样单独罗列'这里有X味,有Y声音,温度是Z'\",\n \"描写要具体到质感——不写'红色'写具体是什么红,不写'声音响'写是什么样的声音从哪来\",\n \"禁止陈词滥调(寒气冲天灵盖/倒吸一口凉气/弥漫着恐怖气息等)\",\n \"每个新场景/地点出现时,必须有至少1个专属的气味或声音标记\",\n \"感官要被角色情绪过滤——紧张时听觉放大,恐惧时闻到异味,不要客观中立地'摄像'\",\n \"声音的变化比声音本身更重要——声音停了、变近了、变调了,都要写出来\"\n ],\n \"examples\": [\n {\n \"text\": \"他扶着壁面慢慢往前走。\\n\\n岩壁是凉的,不是正常的凉,是那种从很深的地方渗上来的、带着点潮意的温凉,像摸在死人的皮肤上。水珠顺着岩壁往下渗,沾在他手背上,黏糊糊的。\\n\\n空气不对。\\n\\n平时这里只有灰尘和炸药残留的硝石味,今天多了一股甜味——很淡,不仔细闻根本察觉不到,像烂苹果,又像什么东西发酵了。他吸了吸鼻子,后颈的汗毛一下子竖起来。\\n\\n瓦斯。\\n\\n他停下来,关掉矿灯。\\n\\n黑暗瞬间压下来,浓得像浸在墨里。眼睛还没适应黑暗,耳朵先醒了——原来通风管的嗡鸣不知道什么时候停了,四周静得能听见自己的心跳,咚咚的,撞得肋骨疼。水滴声从很深的地方传上来,滴答,滴答,每一下间隔大概七秒,每一下都比上一声近一点。\\n\\n不对。水滴声不会越来越近。\\n\\n他屏住呼吸。\\n\\n除了水滴声,还有另一个声音。\\n\\n很轻。很慢。像是什么东西在爬,爪子刮过岩壁的声音,沙,沙,沙。\\n\\n在他身后。\",\n \"note\": \"感官沉浸示范:触觉(岩壁温凉像死人皮肤/水珠黏糊糊)、嗅觉(甜丝丝的烂苹果味=瓦斯)、听觉(通风管停了/心跳声/滴答声间隔七秒/刮岩壁的沙沙声)、视觉(黑暗浓得像墨)四感交织。感官跟着情绪走——一开始没察觉味道,然后后颈汗毛竖起来;关了灯之后听觉瞬间放大;最后那个声音在身后,恐怖感拉满。没有一个词写'恐怖''害怕''紧张',但读者全程提着气。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": [\n \"opt_desc_minimal\",\n \"opt_desc_clinical\"\n ]\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_dialogue_style\",\n \"option_id\": \"opt_dialogue_concise\",\n \"option_name\": \"简洁精炼\",\n \"option_description\": \"对话极简,话少意多。适合硬汉、高冷角色、悬疑场景、矿工等沉默寡言的人物。\",\n \"threshold_overrides\": {\n \"maxDialogueContinuous\": 3,\n \"maxDialogueTagRepeat\": 1\n },\n \"radar_weights\": {\n \"emotion\": 1.0,\n \"action\": 1.2,\n \"infoAdvance\": 1.1\n },\n \"system_prompt\": \"简洁精炼对话的核心是'话少信息多'。人物不多话,但每句话都有分量。沉默本身就是对话。具体技法:\\n\\n1. 字数控制:单句对话不超过15字,极端情况可以1-3个字。能说两个字不说三个字,能用动作代替就不说话。回答常常是一个字、一个点头、一个眼神。\\n\\n2. 潜台词密度极高:每句话背后都有没说出口的东西。'走了。'可能是'我走了你别死'。'嗯。'可能是'我听到了我不同意但我懒得跟你争'。读者要从上下文和动作里读出来。\\n\\n3. 沉默的使用:不回答本身就是回答。停顿、犹豫、转移视线、转身就走——这些非语言反应比说话更有力。对话之间可以插入大段动作描写,制造沉默的重量感。\\n\\n4. 禁止解释性对话:角色不会把自己的意思解释清楚,不会说'我生气是因为你昨天骗了我'这种话。情绪要读者自己体会。\\n\\n5. 问答不对称:问三句答一句,答非所问,或者用问题回答问题。不配合对话本身就在塑造人物性格。\\n\\n6. 动作重于语言:当一个动作可以表达态度时,绝不用语言。放下茶杯的力度、走路的速度、看人的角度——这些都在说话。\",\n \"constraints\": [\n \"单句对话原则上不超过15字,多数对话在10字以内\",\n \"连续对话不超过3句必须穿插动作/环境描写,且动作描写字数应多于对话字数\",\n \"禁止解释性台词(角色把自己的情绪、动机、计划直接说出来)\",\n \"对话标签'XX道/说'每千字不超过5次,绝大多数对话用动作引入或不标签\",\n \"每段对话场景中至少有1次沉默/不回答/用动作代替回答\",\n \"禁止使用感叹号超过对话总句数的10%,简洁角色不轻易激动外露\",\n \"禁止出现'我觉得''我认为''你听我说'等啰嗦开场\"\n ],\n \"examples\": [\n {\n \"text\": \"铜碗放在膝上,水已经凉了。他没喝。\\n\\n洞口的光暗了一度。\\n\\n「老李。」他说。\\n\\n没人应。\\n\\n他等了三秒,端起铜碗喝了一口。水锈味。\\n\\n「该你了。」\\n\\n阴影里动了一下。老李爬过来,动作很慢,右胳膊垂着,使不上劲。他接过铜碗的时候手指在抖。\\n\\n「壁温多少?」\\n\\n「35.8。」\\n\\n老李没说话。他知道这意味着什么。正常是32度。\\n\\n「还能走吗?」\\n\\n老李没回答,把铜碗递还给他,撑着壁面站起来。膝盖打了个弯,但他站住了。\\n\\n他把矿灯拧亮,光柱里浮尘一动不动。\\n\\n「走。」\",\n \"note\": \"极简对话示范:整段200多字只有6句对话,每句不超过5字。'老李没说话''老李没回答'是沉默的用法。'35.8'一个数字包含全部信息,不需要解释这意味着什么。结尾'走'一个字,比'我们走吧''赶紧离开这里'有力一百倍。动作描写(胳膊垂着/手指抖/膝盖打弯/浮尘一动不动)承载了绝大多数信息。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": []\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_dialogue_style\",\n \"option_id\": \"opt_dialogue_natural\",\n \"option_name\": \"自然口语化\",\n \"option_description\": \"对话贴近真实口语(默认),有停顿、重复、语气词,像真人说话。自然流畅,不做作。\",\n \"threshold_overrides\": {\n \"maxDialogueContinuous\": 4,\n \"maxDialogueTagRepeat\": 2\n },\n \"radar_weights\": {\n \"emotion\": 1.1,\n \"action\": 0.9\n },\n \"system_prompt\": \"自然口语化对话是默认对话风格,核心在于'像真人说话'。真人说话不会把意思说满,会有停顿、犹豫、打断、话里有话、答非所问。具体技法:\\n\\n1. 潜台词原则:人物说的话和真实想法之间永远有缝隙。表面聊天气,实际在试探;表面说没事,实际在生气;表面答应,实际在敷衍。用动作暗示真实态度(手指敲桌面=不耐烦,避开眼神=心虚,停顿太久=在撒谎)。\\n\\n2. 动作标签(beat)设计:不要每句话都用'XX说/道',用动作替代标签——递烟、倒茶、看窗外、挠头、沉默两秒。每3-4句对话之间必须插入一个动作或微表情,这个动作本身就在说话。\\n\\n3. 口语节奏:允许语气词(啊/呢/吧/嘛/嗯/哦)、省略主语、半截话、打断。熟人之间说话不完整,不需要把每个信息点都说清楚。\\n\\n4. 信息控制:对话是人物博弈,不是信息传递。角色不会主动把知道的全说出来,要通过追问、误解、回避、说漏嘴来推进。\\n\\n5. 角色差异化:教育程度高的人句子完整、逻辑清晰;底层劳动者句子短、粗话多、喜欢用比喻;老人爱啰嗦、爱说教;年轻人说话快、网络词多。\",\n \"constraints\": [\n \"连续对话不超过4句必须穿插动作/神态/环境描写\",\n \"对话标签'XX道/说'每千字不超过8次,优先用动作替代标签\",\n \"禁止出现文绉绉的书面化台词(如'吾辈岂是贪生怕死之辈'),除非角色设定明确要求\",\n \"每段对话场景中至少有1处潜台词(人物说的话和动作暗示的真实态度不一致)\",\n \"禁止对话中直接说出角色情绪(如'我很生气''你别害怕'),情绪用语气和动作表现\",\n \"对话标签禁止连续重复同一个动词超过2次\"\n ],\n \"examples\": [\n {\n \"text\": \"老周把烟头按灭在烟灰缸里,烟蒂已经堆了半缸。「来了?」\\n\\n「嗯。」陈默拉开椅子坐下,没看他。\\n\\n「喝什么?茶还是凉白开?」\\n\\n「随便。」\\n\\n老周倒了杯茶推过来,茶水太满,溢了一点在桌面上。他没擦。「东西拿到了?」\\n\\n陈默从外套内袋里掏出一个牛皮纸信封,放在桌上,没推过去。「你先看看。」\\n\\n老周没去碰信封。他盯着陈默的脸看了几秒,端起自己的茶杯喝了一口。「你脸色不好。」\\n\\n「昨晚没睡好。」\\n\\n「出什么事了?」\\n\\n「没事。」陈默终于抬眼看他,「你到底要不要?」\\n\\n老周沉默了两秒,把信封拿过去,没打开,直接塞进了抽屉。\",\n \"note\": \"自然口语示范:用动作(按烟头/倒茶/盯着看/塞抽屉)替代对话标签,每句对话都短,潜台词丰富——陈默说'没事'但脸色不好明显有事,老周不拆信封直接塞抽屉表示信任,茶水溢了不擦说明心里有事。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": []\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_dialogue_style\",\n \"option_id\": \"opt_dialogue_stylized\",\n \"option_name\": \"风格化\",\n \"option_description\": \"对话有鲜明个人特色,方言/口头禅/行业黑话/特定句式。适合嘴炮角色、江湖人物、方言特色作品。\",\n \"threshold_overrides\": {\n \"maxDialogueContinuous\": 4,\n \"maxDialogueTagRepeat\": 2\n },\n \"radar_weights\": {\n \"emotion\": 1.2,\n \"action\": 0.9\n },\n \"system_prompt\": \"风格化对话的核心是'每个角色一张嘴就能认出是谁'。通过语言模式塑造人物,让对话本身成为人物标签。具体技法:\\n\\n1. 口头禅设计:给重要角色1-2个标志性口头禅,不要太多(多了假)。口头禅要符合人物背景——老兵可能说'操',读书人说'有趣',小混混说'不是我说'。口头禅出现频率要自然,不是每句都带。\\n\\n2. 句式特征:有的人说话爱用反问,有的人爱用短句,有的人爱说半截话,有的人说话爱打比方。受过教育的人用复句,底层人用单句。军人说话短促有力,老太太说话爱绕弯子。\\n\\n3. 方言/黑话使用:方言词汇和行业黑话要'点到为止'——通过上下文让读者猜懂意思,不能每句都注释。比例控制在10%-15%,多了影响阅读流畅性。黑话本身就在塑造世界观(江湖切口、军事术语、职场黑话)。\\n\\n4. 语言的时代感:古风人物不能说'OK''搞定',现代人物不能说'鄙人''幸会'。语言要符合故事背景时代,但不要过度仿古导致晦涩。\\n\\n5. 情绪通过语言风格变化体现:人激动时句子变短、重复、口吃、口头禅增多;人冷静时句子变长、用词精准;人撒谎时停顿多、语气词多、解释过多。\\n\\n6. 禁止千人一腔:去掉角色名字,读者光看台词就知道是谁在说话。如果两个角色的台词互换不违和,说明风格化失败。\",\n \"constraints\": [\n \"主要角色每人至少有1个可辨识的语言特征(口头禅/句式/用词习惯)\",\n \"方言/行业黑话占对话总字数比例不超过15%,必须通过上下文可理解\",\n \"禁止不同角色的语言风格雷同——去掉名字和标签后仍能区分说话人\",\n \"连续对话不超过4句必须穿插动作/神态描写\",\n \"风格化不能牺牲信息传递——不能为了有特色而让读者看不懂在说什么\",\n \"禁止出现与故事时代背景不符的词汇(古风文不能出现现代网络用语)\",\n \"对话标签'XX道/说'每千字不超过8次\"\n ],\n \"examples\": [\n {\n \"text\": \"王胖子把抹布往肩上一搭,凑过来压低嗓子:「林子,跟你说个事儿。」\\n\\n「说。」林远没抬头,继续擦枪。\\n\\n「昨晚老三带回来那姑娘,你瞧见没有?」王胖子眼睛发亮,伸出两根手指比划,「这么长的头发,这么白的脸,腰——」\\n\\n「说重点。」\\n\\n「嘿,你这人。」王胖子讪讪缩回手,在围裙上擦了擦,「我是说,那姑娘不像普通人。手上没有茧,指甲修得齐整,说话带南边口音。南边现在是什么地界?沦陷区。一个沦陷区的大姑娘,孤身跑到咱们这儿来,你说奇不奇?」\\n\\n林远终于抬起头看他:「你跟老三说了?」\\n\\n「我哪敢啊!」王胖子一拍大腿,「老三那驴脾气,我要敢质疑他带回来的人,他能拿酒瓶子砸我脑袋。我这不是先来跟你商量嘛。你是咱们这儿识字最多的——」\\n\\n「我去看看。」林远把枪组装好,咔嚓一声推弹上膛。\\n\\n王胖子愣了一下,连忙跟上:「哎哎,你别带枪啊!万一真是逃难的学生呢?你把人吓着——」\\n\\n「不吓。」林远把枪别在腰后,用衣服盖住,「吓着了就请她喝碗粥。」\",\n \"note\": \"风格化对话示范:王胖子的市井油滑(手势比划/一拍大腿/'你这人''我哪敢啊''嘿')和林远的极简('说''说重点''不吓')形成鲜明对比。王胖子的语言特征:爱用破折号、爱打比方、爱卖关子、句子长、语气词多;林远的语言特征:单字/两字回答、从不多说一个字、句子都是命令式。去掉名字读者也能分清谁在说话。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": []\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_dialogue_style\",\n \"option_id\": \"opt_dialogue_verbose\",\n \"option_name\": \"絮叨详尽\",\n \"option_description\": \"话多,爱说长句,喜欢解释、回忆、东拉西扯。适合长辈、话痨角色、市井人物、说书人风格。\",\n \"threshold_overrides\": {\n \"maxDialogueContinuous\": 5,\n \"maxDialogueTagRepeat\": 3\n },\n \"radar_weights\": {\n \"emotion\": 1.0,\n \"action\": 0.8,\n \"infoAdvance\": 0.9\n },\n \"system_prompt\": \"絮叨详尽对话的核心是'话里有大量信息,但表面东拉西扯'。人物爱说、能说、说个不停,但废话里藏着关键信息、人物性格和世界观。具体技法:\\n\\n1. 长句与停顿:话多的人物说话可以一整段就是一大句,中间有插入语、回忆、题外话、补充说明。用省略号、破折号、'怎么说呢''你知道吧''我跟你说'做口语标记。\\n\\n2. 题外话与信息夹带:说着说着跑题(回忆往事/评价别人/扯家常),但跑的题里往往藏着关键信息(无意中透露秘密、暴露态度、暗示伏笔)。读者要从废话里淘金。\\n\\n3. 听者反应穿插:长对话中必须穿插听者的小动作(点头/抽烟/看表/喝茶/打断),不能整段都是一个人在说。每4-5句插入一次听者反应,用来调节节奏。\\n\\n4. 重复与强调:话多的人爱重复,爱用不同的话讲同一个意思,爱举例子,爱打比方。重复本身就在强调什么东西对这个人物重要。\\n\\n5. 口语标记:大量使用'哎''嗨''可不是嘛''你想啊''说实话''不瞒你说''说句不好听的'这类口语发语词。\\n\\n6. 不要让絮叨变成注水:每一段长对话都要有叙事功能——要么揭示人物性格,要么推进剧情,要么埋伏笔,要么烘托氛围。不能全是废话。\",\n \"constraints\": [\n \"单人连续说话不超过5句必须穿插听者反应(动作/打断/提问)\",\n \"每段长对话(超过100字)必须承载至少1项有效信息(剧情/人物/伏笔),不能纯注水\",\n \"对话标签'XX道/说'可以适当使用,但优先用动作(抽烟/叹气/摆手/点头)引入\",\n \"口语发语词(哎/嗨/可不是嘛/你想啊)适度使用,每千字不超过15个\",\n \"禁止出现大段连续独白超过300字无任何穿插描写\",\n \"重复强调的内容必须是对人物有重要意义的事物,不能无意义重复\",\n \"话多的人物说的话要符合其身份——老人忆当年、妇人东家长西家短、说书人绘声绘色\"\n ],\n \"examples\": [\n {\n \"text\": \"老范把烟袋锅子在鞋底上磕了磕,烟灰落在雪地里,滋的一声灭了。「三十年前那场矿难,你小子还没出生呢,」他眯着眼看向巷道深处,昏暗的矿灯光打在他脸上,皱纹里全是黑灰,「那天也是这个时候,后半夜三点多,我跟你爹——哦,那时候你爹还没娶你娘呢,刚跟我学徒半年——我们俩在掌子面打眼。」\\n\\n他点了一锅新烟,火柴划了三次才着,手在抖。\\n\\n「风停了。」他说。\\n\\n林远没说话,等着。\\n\\n「井下的风是不会停的,你知道吧?通风管二十四小时转,风一停,就说明——」老范吸了一口烟,烟锅子在暗处一明一暗,「就说明该出事了。你爹当时年轻,反应快,一把拽住我就往避险洞跑。我们刚进去,身后就响了。那声音……怎么跟你形容呢,不是爆炸,是——是壁在叫。」\\n\\n他顿了顿,把烟袋别回腰上。\\n\\n「那天一共下去七十二个人,出来十一个。你爹背着我跑了三里地,自己的腿被落碴砸断了都没吭一声。」老范拍了拍林远的肩膀,手掌粗糙得像砂纸,「所以你小子有种,是骨子里带的。但我跟你说,今天这情况跟风停那天一模一样。你要下去,我不拦你。但你得记住——」\\n\\n他盯着林远的眼睛,矿灯照进去,瞳孔里是深的黑。\\n\\n「感觉不对,立刻跑。别逞英雄。你爹当年就是因为回去救人才断的腿。」\",\n \"note\": \"絮叨对话示范:老范说话长、有题外话、有回忆、有重复、有口语标记(你知道吧/怎么跟你形容呢/我跟你说),但整段对话完成了三个功能:交代三十年前的矿难历史、塑造父亲形象和传承、警告林远今天危险。穿插了磕烟灰、点烟三次才着、手在抖、拍肩膀等动作,听者林远虽然话少但存在感强。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": []\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_emotion_style\",\n \"option_id\": \"opt_emotion_show\",\n \"option_name\": \"克制留白 (Show Don't Tell)\",\n \"option_description\": \"不直接写情绪名称,用身体反应、微动作、环境映射和对话潜台词表达情感(矿工风格默认)。含蓄有力,冰山理论,读者自己感受。\",\n \"threshold_overrides\": {\n \"minAnchors\": 8,\n \"anchorsPerWords\": 250,\n \"maxAnchorGap\": 400,\n \"maxFillerWords\": 3\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.8,\n \"emotion\": 1.2,\n \"sensorySignal\": 1.3,\n \"action\": 1.1\n },\n \"system_prompt\": \"克制留白的核心是'冰山理论'——写出来的只有八分之一,剩下八分之七在水面下。你永远不直接告诉读者角色在想什么、感受到什么,而是写他做了什么、身体有什么反应、说了什么(以及没说什么)。读者自己读出来的情绪,比你写出来的强烈一百倍。\\n\\n【身体反应库——分情绪对应具体动作】\\n\\n1. 紧张/恐惧:不要写'他很紧张/害怕',写:\\n- 手指无意识地摩挲某个东西(烟盒/打火机/衣角/袖口/杯沿)\\n- 咽口水,但喉咙发紧咽不下去\\n- 后颈僵硬,肩膀不自觉耸起\\n- 呼吸变浅,能听见自己的心跳\\n- 手心出汗,在裤子上蹭了蹭\\n- 脚趾在鞋里蜷起来\\n- 视线飘忽,不敢对视,或者死死盯着一个地方\\n- 说话比平时快,或者比平时慢,或者突然忘词\\n- 想点烟但打火机打了三次都没打着\\n\\n2. 愤怒/暴怒:不要写'他很生气/愤怒',写:\\n- 指节发白,拳头攥得太紧指甲掐进掌心\\n- 太阳穴突突跳,能看见血管在跳\\n- 呼吸变粗,鼻孔张大\\n- 说话声音反而变小、变平(压抑的愤怒比大吼更可怕)\\n- 把手里的东西轻轻放下,但放得太轻了——在控制\\n- 突然开始做某件无意义的事(擦桌子/整理东西/倒水),动作很快\\n- 笑了一下,但不是真笑\\n- 沉默。长时间的沉默。\\n\\n3. 悲伤/难过:不要写'他很悲伤/难过',写:\\n- 某个动作做了一半停住了(伸手拿烟,停在半空两秒,又收回来)\\n- 说话声音正常,但说完某句话之后停顿了很久\\n- 眨眼睛的频率变高,或者一直不眨眼(在忍眼泪)\\n- 摸烟的手在抖,但自己没发现\\n- 突然开始说一些无关的话('今天天气不错''吃饭了吗')\\n- 把东西收拾得异常整齐\\n- 重复某个无意义的小动作(反复按打火机/转杯子/折衣角)\\n- 不说话,只是抽烟/喝水/看着某个地方\\n\\n4. 震惊/不敢相信:不要写'他很震惊/不敢相信',写:\\n- 手里的东西掉了,但没立刻去捡\\n- 张了张嘴,没说出话\\n- 往后退了半步,自己没意识到\\n- 笑了一声,很短,像咳嗽\\n- 反复看同一个东西(纸条/照片/短信),看了一遍又一遍\\n- 听见声音但没反应,有人叫他名字才回过神\\n- 某个平时很熟练的动作突然做不好了(系不上扣子/点不着烟)\\n\\n5. 压抑的情感:不要写'他在忍着/他很克制',写:\\n- 深呼吸,吸得很慢,呼得更慢\\n- 端杯子/拿烟的手稳得不正常,像刻意控制\\n- 转移话题,主动说别的事\\n- 站起来走到窗边/门口,背对着人\\n- 说了句玩笑话,但笑得不自然\\n- 答应得太快('好''行''没问题'),像怕自己反悔\\n\\n【技法原则】\\n\\n1. 反差原则:情绪越激烈,动作越平淡。听到亲人死讯不是号啕大哭,是愣了两秒然后继续点烟,打了四次没点着。平淡的动作里有山呼海啸。\\n\\n2. 具体到不能再具体:不要写'他手在抖',写'他端杯子的时候,茶洒出来一点,在桌面上晕开一小片深色'。不要写'他很紧张',写'打火机的齿轮磨了三次,火星有了,油也有了,就是不着'。\\n\\n3. 无用即真实:人在情绪激烈的时候会做毫无意义的事——整理本来就整齐的东西、擦本来就干净的桌子、反复按同一个按钮。这些'无用动作'比任何情绪描写都真实。\\n\\n4. 环境映射:情绪可以投射到环境上,但不要写'连老天都在哭'这种老套的。写'风停了''矿灯闪了一下''墙上的钟滴答声突然变响了'。环境没有情绪,是角色的感知变了。\\n\\n5. 潜台词原则:对话永远和真实想法有差距。'没事'='有事','我先走了'='再待一秒我就要撑不住了','你说什么就是什么吧'='我不跟你争但我根本不同意'。不要解释潜台词,让读者自己读。\\n\\n6. 禁止清单:绝对禁止出现以下词汇——紧张、恐惧、愤怒、悲伤、难过、开心、高兴、痛苦、绝望、心碎、五味杂陈、百感交集、心如刀绞、怒火中烧、忐忑不安。这些词是作者的偷懒,是对读者的不尊重。\",\n \"constraints\": [\n \"绝对禁止直接使用任何情绪标签词(愤怒/悲伤/紧张/害怕/开心/难过/绝望/痛苦等),一个都不许有\",\n \"每个情绪场景至少有2-3处具体的身体反应/微动作描写,必须具体到身体部位和动作细节\",\n \"禁止陈词滥调的身体反应(心如鹿撞、浑身发抖、倒吸一口凉气、瞳孔地震、浑身冰冷等)\",\n \"每300字至少有1处'无用动作'(无意义的习惯性动作)来表现情绪\",\n \"情绪越激烈,外在动作越克制——强烈情绪用平淡甚至反常的动作表现,不要大喊大叫大哭大闹\",\n \"对话必须有潜台词,人物说的话和真实想法之间要有缝隙,禁止角色把心里话直接说出来\",\n \"每250字至少有1处身体锚点(生理反应/微动作/感官细节)\",\n \"禁止叙事者跳出来解释人物情绪('他其实很害怕''她嘴上这么说心里却很难过')\",\n \"情绪转折点必须有具体的动作标记(手停了/烟掉了/打火机打不着/杯子洒了)\"\n ],\n \"examples\": [\n {\n \"text\": \"陈默接过那张纸。\\n\\n纸是A4打印的,边角有点卷,被很多人摸过。他的手指碰到纸面的时候,停了一下——大概半秒,不仔细看根本注意不到。\\n\\n他把纸展开。\\n\\n诊断书三个字是黑体的,下面是他父亲的名字,再下面是一堆医学术语,他看不太懂,但他看懂了最后那行字。\\n\\n他把纸折起来。折痕对齐,压了压,折得很整齐,然后放进工服内侧的口袋里。\\n\\n扣子系了两次。\\n\\n第一次扣子没对准扣眼,他的手指滑开了。第二次才系上。\\n\\n他从口袋里摸出烟盒,抖出一根,叼在嘴里。打火机在另一个口袋,他摸了两下才摸到。齿轮拨了一次,没着。拨了第二次,火星闪了一下,还是没着。\\n\\n第三次才点着。\\n\\n他吸了一口,烟吸得太深,呛了一下,但他没咳。\\n\\n站在对面的老周没说话,等着。\\n\\n「知道了。」陈默说。\\n\\n声音很平。平得像一潭死水,连波纹都没有。\\n\\n他把打火机放回口袋,烟夹在手指间,看着窗外。窗外天阴着,堆着很厚的云,像要下雨。\\n\\n「还有事吗?」他问,没回头。\",\n \"note\": \"Show Don't Tell示范:全文没有一个情绪词(没有震惊/悲伤/痛苦/绝望),所有情绪都藏在细节里——手指停半秒、扣子系两次、打火机打三次、烟吸呛了没咳、声音太平、看着窗外不回头。读者能感受到那种山崩于前但强行压住的情绪,但作者一个字都没说。'还有事吗?'四个字是逐客令,意思是'你走吧,再待下去我要撑不住了',这就是潜台词。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": [\n \"opt_emotion_tell\"\n ]\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_emotion_style\",\n \"option_id\": \"opt_emotion_tell\",\n \"option_name\": \"内心独白\",\n \"option_description\": \"直接写内心活动和心理独白,把角色的想法和感受直接告诉读者。适合第一人称或深视角第三人称,代入感强,适合都市、言情、青春题材。\",\n \"threshold_overrides\": {\n \"minAnchors\": 4,\n \"anchorsPerWords\": 500,\n \"maxAnchorGap\": 700,\n \"maxExpositionContinuous\": 350\n },\n \"radar_weights\": {\n \"emotion\": 1.6,\n \"bodyReaction\": 0.9,\n \"infoAdvance\": 1.0,\n \"action\": 0.9\n },\n \"system_prompt\": \"内心独白的核心是'把读者拉进角色脑子里'。读者直接听到角色的心声,像角色自己在说话,没有中间商。但内心独白不是情绪宣泄,是思维本身——有逻辑,有跳跃,有矛盾,有自我欺骗。具体技法:\\n\\n【内心独白的层次】\\n\\n1. 表层想法:角色当下正在想的具体事情——'完了,要迟到了''这人怎么这么烦''今天晚上吃什么'。短句,口语化,像脑子里冒出来的碎念头。\\n\\n2. 中层判断:角色对人对事的判断和评价——'他在撒谎,我知道''这事儿没那么简单''她不是真的想分手'。稍微长一点,有逻辑。\\n\\n3. 深层记忆/情绪:被触发的回忆、不敢承认的感受、压下去的念头——'上次也是这样,三年前的雨也是这么大''我其实很怕,但我不能说''如果当时我选了另一条路会不会不一样'。这层要慢,要沉,不要轻易出来,出来就要有分量。\\n\\n4. 自我对话/自我欺骗:人会在心里跟自己说话,会骗自己,会给自己找理由——'没事,真的没事,不就是一份工作吗''我才不在乎呢''再等五分钟,五分钟就走'。这种内心矛盾最真实。\\n\\n【技法原则】\\n\\n1. 思维流动,不是作文:内心独白不需要完整的句子,可以有半截话、有跳跃、有重复、有前后矛盾。人脑子里的想法不是一篇通顺的作文,是东一下西一下的。\\n\\n2. 符合人物性格:粗人不会在心里文绉绉地想'彼时彼刻,我内心涌起一股难以名状的悲恸',他会想'操。完了。'。读书人不会满脑子'卧槽牛逼'(除非反差设定)。内心语言必须和人物身份、教育程度、性格一致。\\n\\n3. 不说废话:内心独白也要有信息量。不要'他心里很紧张,七上八下的,像揣了只兔子'——这还是Tell,而且是陈词滥调。要写具体的念头:'合同在抽屉里,锁着,钥匙在我钱包内层,她会不会已经翻过了?昨晚回来的时候钱包好像在桌上放了一会儿。'\\n\\n4. 不要全说透:即使是内心独白,也不要什么都明明白白说出来。角色自己也会逃避,也会不敢想某些事,也会有不敢承认的念头。写他绕开那个念头,写他故意想别的,比直接写出来更真实。\\n\\n5. 内外交替:大段内心独白会闷。每写3-5句内心,就要切回外部——一个动作、一句对话、一个感官细节(烟烧到手指了/有人在叫他名字/窗外打雷了),把读者拉回现实,然后再进内心。\\n\\n6. 关键时刻用短句:情绪最激烈的时候,内心独白反而要短,要碎。不是'我感到一阵巨大的悲伤涌上心头,几乎无法呼吸',是'完了。''真的完了。''怎么会。''不可能。'。\\n\\n7. 自由间接引语:可以把内心想法融入叙述,不用加'他想''他在心里说'。比如'三点了。她还没来。会不会出事了。不对,她从来不准时,再等十分钟。'——直接就是他的想法,不需要标记。\",\n \"constraints\": [\n \"内心独白语言必须100%符合角色的身份、性格、教育程度,禁止所有人说话一个腔调\",\n \"内心独白要有具体内容(具体的念头/判断/回忆),禁止空洞的情绪宣泄('我好难过''我太痛苦了')\",\n \"每300字内心独白后必须切回外部动作/对话/感官,不能一直闷在心里写\",\n \"情绪最激烈的时刻,内心句子要短(1-5字),不要长句抒情\",\n \"允许思维跳跃、半截话、前后矛盾,这才是真实的心理活动\",\n \"陈词滥调禁止(心如鹿撞/十五个吊桶打水/七上八下/像揣了只兔子)\",\n \"不要每句内心都加'他想''他暗自思忖',能用自由间接引语就直接写\",\n \"角色可以自我欺骗、自我安慰、找借口,不必永远'政治正确',真实的人会骗自己\"\n ],\n \"examples\": [\n {\n \"text\": \"诊断书在他口袋里,折得整整齐齐,像一块砖头。\\n\\n三点十七分。老周走了有五分钟了。烟烧到滤嘴,烫了手指一下,他才反应过来,把烟头按灭在烟灰缸里。烟灰缸里已经有七个烟头了。\\n\\n不会错的。省三院的章,主任医师的签字,那些术语他看不懂,但'尘肺叁期'四个字他认得。叁期。就是晚期。\\n\\n他早该想到的。这半年咳得越来越厉害,有时候痰里有血,他以为是上火,是抽烟抽多了,是累的。壁温升高的时候他胸闷,他以为是瓦斯熏的。父亲当年也是这个病,走的时候五十二岁,他今年四十七。\\n\\n操。\\n\\n也不是没有想过这一天。干这行的,谁没想过?但想归想,真来了,还是不一样。像头顶悬了很多年的一把刀,终于掉下来了,反而不觉得疼,只觉得——哦,原来是这样。\\n\\n女儿明年高考。成绩不错,考个本科应该没问题。学费怎么办?老婆身体也不好,常年吃药。这个家现在全靠他一个人。\\n\\n不能告诉她们。\\n\\n这个念头冒出来的时候他甚至没觉得犹豫。说了也没用,除了多两个人跟着担心,什么用都没有。能撑多久撑多久吧,趁还能下井,再干两年,把女儿学费挣出来,把老婆的药费攒够。\\n\\n他又摸出一根烟,这次打火机一次就打着了。\\n\\n窗外的云越堆越厚,天暗得像傍晚。风刮起来了,吹得工棚的铁皮哗哗响。要下大雨了。\",\n \"note\": \"内心独白示范:直接写陈默看到诊断书后的想法——从确认病情,到回忆征兆,到想到父亲,到想到妻女,到决定隐瞒。思维流动自然,有具体的牵挂(女儿高考/老婆吃药/学费),不是空洞的悲伤。情绪最激烈的地方只有一个字'操。',比长篇大论有力。内心和外部动作交替(按烟头/摸烟/看窗外),不闷。语言符合矿工身份,没有文艺腔。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": [\n \"opt_emotion_show\"\n ]\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_emotion_style\",\n \"option_id\": \"opt_emotion_both\",\n \"option_name\": \"内外结合(推荐默认)\",\n \"option_description\": \"外在身体反应+内心独白结合使用,Show和Tell互补。既有身体的含蓄留白,又有内心的直接袒露,层次最丰富,适合绝大多数题材。\",\n \"threshold_overrides\": {\n \"minAnchors\": 6,\n \"anchorsPerWords\": 350,\n \"maxAnchorGap\": 500,\n \"maxExpositionContinuous\": 250\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.4,\n \"emotion\": 1.4,\n \"sensorySignal\": 1.1,\n \"action\": 1.0,\n \"infoAdvance\": 1.0\n },\n \"system_prompt\": \"内外结合是最灵活、最有层次的情感表达方式。核心原则:'外冷内热,外动内静,反差出张力'。读者既能看到角色的外在表现,又能听到他的内心声音,二者可以一致也可以矛盾——矛盾的时候最有戏。\\n\\n【内外搭配的四种模式】\\n\\n1. 外动+内静:外在动作很激烈/很忙碌,但内心反而空了、静了。比如听到噩耗,表面上在冷静地收拾东西、安排后事,心里什么都没想,一片空白。动作越熟练越冷静,越让人觉得疼。\\n\\n2. 外静+内动:表面上什么都没做,只是坐着抽烟/看着窗外/喝水,但心里已经翻江倒海、想了一万个念头。这是最常用的模式——表面越平静,内心戏越足,张力越大。\\n\\n3. 外此+内彼:外在表现和内心想法完全相反。嘴上笑着说'没事真的没事',心里在想'我快撑不住了';嘴上说'恭喜你啊',心里在滴血;脸上没表情,心里已经在盘算怎么杀人了。这种反差是戏剧张力的核心来源。\\n\\n4. 内外一致:情绪强烈到一定程度,内外终于统一了——不用再装了,不用忍了,手开始抖,眼泪掉下来,或者直接爆发。这种'破防'时刻要少用,一本书里关键的3-5个地方用就够了,用多了就不值钱了。用之前一定要有足够的铺垫(前面一直忍,一直装,读者知道他在忍),爆发的时候才有力。\\n\\n【技法原则】\\n\\n1. 先外后内:先写外在动作/对话/身体反应,再进内心。读者先看到'他做了什么',再知道'他在想什么',有个递进。不要一上来就掏心掏肺。\\n\\n2. 内心不宜过长:内心独白点到为止,不要写一大段。3-5句就够了,说最核心的那个念头,然后立刻切回外部。留白比说透好。\\n\\n3. 身体标记情绪转折:每次情绪变化、每次从内心切回外部、每次决定做出的时候,都要有一个具体的身体动作作为标记——掐灭烟头、站起来、把杯子放下、系上扣子、抬起头。动作就是情绪的句号。\\n\\n4. 关键情绪点用'三连':重要情绪时刻可以用'外在动作→内心念头→对话/行动'三连结构。比如:(外)他把烟掐灭在烟灰缸里,烟蒂已经堆了半缸。(内)不能说。说了也没用。(外/对)「我没事。」他说,「真的。」\\n\\n5. 不要重复:同一个情绪,外在内心里写一遍就够了,不要外在写了'他手在抖',内心又写'我好紧张我手在抖'。互相补充,不要重复。外在写看得见的,内心写看不见的。\\n\\n6. 读者视角:外在是别人能看到的,内心是只有读者能看到的。读者知道角色在装、在忍、在骗所有人,这种'上帝视角'的代入感是内外结合独有的魅力。\\n\\n7. 节奏配合:情绪积累阶段多用'外静内动',慢慢压;情绪转折点用一个有力的外在动作(摔东西/站起来/说一句话);爆发时刻内外统一,不要太多内心,直接写动作和对话。\",\n \"constraints\": [\n \"每个重要情绪场景必须同时有外在表现(动作/身体反应/对话)和内心活动,二者互相补充不重复\",\n \"内外可以形成强烈反差,这是张力来源,但反差要合理,不能为了反差而反差\",\n \"内心独白每次不超过5句,点到核心念头就切回外部,禁止大段心理描写超过300字\",\n \"情绪转折点必须有具体的身体动作标记(掐烟/站起/放杯子/抬头等)\",\n \"情绪'破防'/爆发时刻全书要克制使用,关键场景才用,用前必须有足够的压抑/伪装铺垫\",\n \"先写外在再写内心,顺序不要乱(除非刻意设计的意识流)\",\n \"每350字至少有1处身体锚点,每700字至少有1段内心独白\",\n \"对话和内心可以矛盾(嘴上说A心里想B),但不要解释这个矛盾,让读者自己体会\",\n \"禁止叙事者跳出来总结情绪('他心里五味杂陈''那一刻他百感交集'),用内外细节自己说话\"\n ],\n \"examples\": [\n {\n \"text\": \"陈默把诊断书折好,放进口袋,扣子系上。动作很慢,很仔细,像在做一件很重要的事。\\n\\n不能告诉她们。\\n\\n这个念头一出来就定了,像钉子钉进木头里,没有任何犹豫。说了又怎么样呢?老婆会哭,女儿会没心思考试,除了多两个人跟着熬,什么用都没有。他这辈子没什么本事,好歹最后这一程,能让她们少难受一天是一天。\\n\\n他从烟盒里抖出最后一根烟。空了。他把烟盒捏成一团,准确地扔进墙角的废纸篓里。\\n\\n「知道了。」他对老周说。\\n\\n声音是稳的。他听见自己的声音,甚至觉得有点太稳了,像在说别人的事。老周看着他,嘴唇动了动,像是想说什么,最后也没说,只是拍了拍他的肩膀。那只手很重,在他肩膀上停了三秒。\\n\\n「有事说话。」老周说。\\n\\n「行。」\\n\\n老周走了。门吱呀一声关上,工棚里只剩他一个人。\\n\\n他在椅子上坐着,没动。窗外的风越来越大,铁皮顶被刮得哗哗响,像要被掀起来。桌上的半杯凉茶已经凉透了,他端起来喝了一口,茶水里浮着一点茶渍,苦的。\\n\\n四十七。他想。父亲走的时候也是四十七。\\n\\n他把茶杯放下,杯底磕在桌面上,发出'嗒'的一声轻响。\\n\\n该去接女儿放学了。\",\n \"note\": \"内外结合示范:先写外在动作(折诊断书/系扣子/捏烟盒/扔烟盒/喝茶/放杯子),然后插入内心(不能告诉她们/四十七/父亲也是四十七),再写对话和外部环境。内外有反差——外在动作稳、声音稳,内心已经想到了死、想到了女儿、想到了父亲。最后一句'该去接女儿放学了'是情绪的落点,也是决定——生活还要继续,他要撑住。没有一个情绪词,但所有情绪都在。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": []\n}\n","{\n \"kb_version\": \"3.0\",\n \"node_id\": \"node_ending_hook\",\n \"option_id\": \"opt_hook_soft\",\n \"option_name\": \"平和收束(情绪落点)\",\n \"option_description\": \"章节自然收束在情绪或氛围落点上,不强行留钩子,适合日常章节、过渡章节、卷末。\",\n \"system_prompt\": \"你使用平和收束模式。章节自然收尾,可以落在一个情绪落点、一个身体感受、一个安静的画面上。不需要强行制造悬念,但最后一句仍然不能是空洞总结,必须落在具体的物象或身体感受上。\",\n \"constraints\": [\n \"结尾落在具体物象/身体感受/画面上\",\n \"禁止空洞总结和感慨\",\n \"可以不收钩子,但不能水结尾\"\n ],\n \"examples\": [\n {\n \"text\": \"林深把笔记本收进口袋,靠在壁上歇了口气。壁面的温度顺着后背传过来,三十七点二度,稳定,恒定,和他的心跳一个频率。\\n他闭上眼,听着壁里十秒一次的搏动。\",\n \"note\": \"平和收束:落在身体感受和氛围上\"\n }\n ],\n \"threshold_overrides\": {\n \"endingHook\": \"soft\"\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.2,\n \"sensorySignal\": 1.3,\n \"action\": 0.8,\n \"emotion\": 1.5,\n \"infoAdvance\": 0.7\n }\n}\n","{\n \"kb_version\": \"3.0\",\n \"node_id\": \"node_ending_hook\",\n \"option_id\": \"opt_hook_suspense\",\n \"option_name\": \"悬念钩子(未解问题)\",\n \"option_description\": \"章末留下一个未解问题或悬念,读者想知道答案但不会被断章激怒,是比较温和的钩子方式。\",\n \"system_prompt\": \"你使用悬念钩子模式。章节结尾留下一个具体的未解问题、即将发生的危险、或一个未完成的动作。最后一句可以是疑问、可以是未完成动作、可以是威胁即将到来。不需要颠覆前文,但必须有明确的“接下来会发生什么”的悬念。\",\n \"constraints\": [\n \"章末必须有明确的未解问题或未完成动作\",\n \"最后一句不能是总结句/判断句\",\n \"悬念必须具体,不能是“未来会怎样”这种空泛悬念\",\n \"必须让读者想知道答案\"\n ],\n \"examples\": [\n {\n \"text\": \"那截金色的纤维停在半空中,指向林深的小臂,一下一下地搏动。林深握紧了凿子,盯着那道裂缝。\\n裂缝深处,有什么东西正在往外爬。\",\n \"note\": \"悬念钩子:新危险即将出现,读者想知道爬出来的是什么\"\n }\n ],\n \"threshold_overrides\": {\n \"endingHook\": \"suspense\"\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.0,\n \"sensorySignal\": 1.0,\n \"action\": 1.2,\n \"emotion\": 1.2,\n \"infoAdvance\": 1.3\n }\n}\n","{\n \"kb_version\": \"3.1\",\n \"option_description\": \"2026追读版断裂钩子:最后100字出现具体新信息颠覆前文判断,最后一句≤15字短句鼓点落点,禁止装神弄鬼假钩子。读者读完必须骂「操怎么断在这里」。\",\n \"option_id\": \"opt_hook_break\",\n \"option_name\": \"断裂钩子(具体新信息颠覆,默认)\",\n \"constraints\": [\n \"最后100字必须出现前文完全未提及的具体新信息\",\n \"新信息必须颠覆之前的某个判断(以为安全→危险/以为A→B/以为结束→刚开始)\",\n \"钩子必须具体:看得见、摸得着、听得见——禁止空泛悬念\",\n \"禁止装神弄鬼假钩子:「一股神秘气息/他似乎意识到什么/不祥的预感/事情没那么简单/黑暗中有什么东西」\",\n \"最后一句必须≤15字,用短句鼓点落点\",\n \"最后一句禁止「了。」收尾,禁止「就这样/原来如此/所以/于是」总结词\",\n \"好钩子的检验标准:读者读完会不会骂「操怎么断在这里」?会才合格\"\n ],\n \"examples\": [\n {\n \"note\": \"矿工式断裂钩子:具体发现(手背上有纹路)+认知颠覆(以为没碰到→已经碰到了)+问句结尾\",\n \"text\": \"他低头看自己的手。手背上多了一道金色纹路,和那截纤维一模一样。它已经碰到他了。什么时候?\"\n },\n {\n \"note\": \"危险升级钩子:角色反转(铁铮举盾对准主角)+具体异常(茧发红光不是金光)+两字极短句落点\",\n \"text\": \"铁铮突然举盾对准了林深。「你小臂上的茧,」铁铮的声音在抖,「它在发光。不是金色。」是红色。\"\n },\n {\n \"note\": \"物件异常钩子:具体动作(低头看)+具体发现(凿尖沾血)+认知颠覆(他没受伤)\",\n \"text\": \"他低头,看见凿尖上沾了血。他没受伤。这血不是他的。\"\n },\n {\n \"note\": \"声音钩子:具体声音(第三下敲门)+认知颠覆(全队都在屋里)\",\n \"text\": \"门外传来第三下敲门声。全队七个人都在屋里。谁在外面?\"\n },\n {\n \"note\": \"反例(假钩子,禁止使用):空泛悬念,读者免疫\",\n \"text\": \"他望着黑暗的通道深处,一股不祥的预感涌上心头。事情,似乎没有那么简单。(❌假钩子,读者直接划走)\"\n }\n ],\n \"node_id\": \"node_ending_hook\",\n \"radar_weights\": {\n \"action\": 1.3,\n \"bodyReaction\": 1.2,\n \"emotion\": 1.2,\n \"hookStrength\": 1.8,\n \"infoAdvance\": 1.6,\n \"sensorySignal\": 1.0,\n \"twistFrequency\": 1.2\n },\n \"system_prompt\": \"你使用断裂钩子模式——2026年追读力最强的章末收尾方式。严格遵守:\\n\\n【钩子铁则】\\n- 最后100字必须出现一个前文完全没提过的、具体的新信息。\\n- 这个新信息必须颠覆读者之前形成的某个判断(以为安全→危险/以为是A→是B/以为结束→才刚开始/以为某人是友→有疑点)。\\n- 钩子必须具体到看得见、摸得着、听得见:具体谁来了、具体发现了什么、具体什么声音、具体哪句话不对、具体什么东西在动。\\n\\n【绝对禁止的假钩子】\\n以下是已被读者免疫的装神弄鬼空泛悬念,一律禁止:\\n- ❌「一股神秘的气息扑面而来」\\n- ❌「他似乎意识到了什么」\\n- ❌「一种不祥的预感涌上心头」\\n- ❌「事情没有那么简单」\\n- ❌「黑暗中有什么东西在动」\\n- ❌「他不知道的是……」\\n- ❌「所有人都没发现,危险正在逼近」\\n这些是空话,不是钩子。钩子必须是具体信息。\\n\\n【最后一句写法】\\n- 最后一句必须≤15字,用短句鼓点落点。\\n- 最佳落点形式:\\n 1. 问句:「谁在外面?」「什么时候?」「这血是谁的?」\\n 2. 极短句发现:「是红色。」「不是他。」「门没锁。」\\n 3. 动作中断:「他刚要喊——」「寻的嘴在动,但没有声音。」\\n 4. 新危险信号:「凿尖上沾了血。」「通道尽头有光。但他们没带头灯。」\\n- 最后一句禁止「了。」叙事闭合收尾。\\n- 最后一句禁止「就这样/原来如此/所以/于是/最终/最后/总之」等总结词。\\n\\n【检验标准】\\n写完最后一句,问自己:读者读完这一句,会不会在心里骂「操,怎么断在这里」?\\n- 会:合格。\\n- 不会(读者觉得「哦,这样啊」):不合格,重写。\",\n \"threshold_overrides\": {\n \"endingHook\": \"break\",\n \"maxLastSentenceLength\": 15,\n \"requireConcreteHook\": true,\n \"banFakeHooks\": true\n }\n}\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_info_density\",\r\n \"option_id\": \"opt_info_fast\",\r\n \"option_name\": \"事件驱动型\",\r\n \"option_description\": \"高密度信息推进,每千字4-5个新信息点。事件接连发生,几乎不给读者喘息空间,适合快节奏爽文和悬疑类作品。\",\r\n \"system_prompt\": \"你采用事件驱动型的信息密度模式。写作时以事件推进为核心,每1000字必须包含4-5个新信息点——新角色登场、新线索出现、新冲突爆发、新设定揭示、局势反转等都算信息点。减少大段环境描写和心理独白,用事件本身来传递信息。场景切换要快,一个场景内不要停留过久。对话承担大量信息传递功能,但避免纯说明性对话(说人话,不要角色嘴里念设定)。每个场景结束时,局势必须有变化——不能回到原点。\",\r\n \"constraints\": [\r\n \"每1000字至少4个新信息点(新角色/新线索/新冲突/新设定/反转)\",\r\n \"连续纯描写/心理/说明不超过150字\",\r\n \"每个场景结束时局势必须有变化\",\r\n \"禁止出现“什么都没发生”的过渡段落\",\r\n \"信息点要自然融入剧情,禁止角色大段讲解设定\",\r\n \"对话承担信息传递功能,但必须符合角色身份\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"李明推开门,发现办公室里一片狼藉。(信息点1:异常状况)\\n\\n保险柜被撬开了,里面的机密文件不翼而飞。(信息点2:核心失窃)\\n\\n他刚要报警,手机响了——是一个陌生号码。(信息点3:神秘来电)\\n\\n\\\"李警官,别报警。\\\"电话那头的声音经过变声处理,\\\"你女儿在我们手上。\\\"(信息点4:绑架威胁)\\n\\n李明浑身一震,转头看向桌上的相框——照片里女儿笑得灿烂。相框旁边多了一个红色的信封。(信息点5:新线索出现)\\n\\n他颤抖着打开信封,里面只有一张照片:女儿被绑在椅子上,身后站着一个穿着黑色风衣的男人,男人的手腕上有一个蛇形纹身。(信息点6:线索细节)\",\r\n \"note\": \"事件驱动型:短段落,每段都有新信息,信息密度极高,几乎无冗余描写\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"infoPointsPerThousand\": 5,\r\n \"maxExpositionContinuous\": 150,\r\n \"maxParagraphLength\": 100,\r\n \"targetParagraphLength\": 45,\r\n \"shortSentenceRatio\": 0.55,\r\n \"targetSentenceLength\": 18\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.0,\r\n \"sensorySignal\": 0.8,\r\n \"action\": 1.4,\r\n \"emotion\": 1.0,\r\n \"infoAdvance\": 1.5\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_info_density\",\r\n \"option_id\": \"opt_info_balanced\",\r\n \"option_name\": \"均衡型(默认)\",\r\n \"option_description\": \"波浪式节奏,信息密度适中(每千字2-3个新信息点)。张弛有度,有紧张的推进也有舒缓的铺陈,是最通用的节奏模式。\",\r\n \"system_prompt\": \"你采用均衡型的信息密度模式。写作节奏呈波浪式:紧张的事件推进之后,要有适当的缓冲——人物的反应、情感的沉淀、环境的描写、日常的互动。每1000字大约2-3个新信息点,不紧不慢。高潮段落可以加快节奏,日常段落可以适当舒缓。重要的信息点要给足笔墨,让读者消化;次要信息可以一笔带过。避免连续高强度输出导致读者疲劳,也避免长时间无信息量的水文字。整体节奏如呼吸:吸(推进/信息)-呼(沉淀/反应)-吸-呼。\",\r\n \"constraints\": [\r\n \"每1000字约2-3个新信息点,允许上下浮动\",\r\n \"高潮段落可加密信息点,日常段落可放缓\",\r\n \"连续紧张推进后必须有缓冲段落(反应/情感/日常)\",\r\n \"信息点之间要有消化空间,禁止信息轰炸\",\r\n \"重要信息点需给予足够的描写和反应篇幅\",\r\n \"禁止连续500字以上无任何新信息\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"面试结束后,林小雨走出写字楼,阳光有些刺眼。\\n\\n她深吸一口气,回想着刚才的面试过程。HR的问题一个比一个刁钻,但她自认应对得还算得体。不过那个技术总监最后说的“回去等通知”,让她心里有些没底——通常说“等通知”就是没戏的意思吧?\\n\\n走到公交站,她掏出手机想刷一下消息,却看到了三个未接来电,都是妈妈打的。\\n\\n林小雨心里一紧,连忙拨回去。\\n\\n\\\"小雨啊,你爸刚才在工地摔了,现在在医院!\\\"妈妈的声音带着哭腔。\\n\\n林小雨脑子“嗡”的一声,手里的包差点掉在地上。\\n\\n\\\"哪家医院?我马上过去!\\\"\",\r\n \"note\": \"均衡型:有日常缓冲(面试后回想/心理活动),有信息推进(未接来电/父亲摔伤),张弛交替\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"infoPointsPerThousand\": 3,\r\n \"maxExpositionContinuous\": 300,\r\n \"maxParagraphLength\": 180,\r\n \"targetParagraphLength\": 70,\r\n \"shortSentenceRatio\": 0.4,\r\n \"targetSentenceLength\": 22\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.0,\r\n \"sensorySignal\": 1.0,\r\n \"action\": 1.0,\r\n \"emotion\": 1.0,\r\n \"infoAdvance\": 1.0\r\n }\r\n}\r\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_info_density\",\n \"option_id\": \"opt_info_leisurely\",\n \"option_name\": \"铺陈型\",\n \"option_description\": \"慢节奏铺陈,信息密度低(每千字1-2个新信息点)。描写充分,氛围营造到位,适合文学性强的作品、散文式叙事、细腻情感类故事。\",\n \"system_prompt\": \"你采用铺陈型的信息密度模式。写作以氛围营造和细腻描写为主,不急着推进剧情。每1000字大约1-2个新信息点,留出大量笔墨用于环境描写、感官细节、人物内心、情感流动。场景要写透,不要急着切换。让读者沉浸在氛围中,感受到画面、声音、气味、温度。人物的每一个细微表情、动作、心理变化都值得写。环境描写不是装饰,而是叙事的一部分——用环境烘托情绪、暗示主题、铺垫伏笔。节奏要慢,但不能水——每一个细节都要服务于整体氛围和人物塑造。\",\n \"constraints\": [\n \"每1000字约1-2个新信息点,重在描写和氛围\",\n \"环境描写需调动至少3种感官(视觉/听觉/嗅觉/触觉/味觉)\",\n \"每个场景要写透,不急于切换\",\n \"人物心理活动和微表情要细腻刻画\",\n \"禁止快节奏的事件堆砌\",\n \"描写要有目的,禁止无意义的华丽辞藻堆砌\",\n \"对话可以少而精,每句对话都要体现人物性格或关系\"\n ],\n \"examples\": [\n {\n \"text\": \"暮春的午后,阳光透过老槐树的枝叶洒下来,在青石板路上碎成一地金斑。空气里飘着隔壁院子槐花的甜香,混着潮湿泥土的气息,是南方小城特有的味道。\\n\\n苏晚坐在门槛上,手里捧着一碗冰凉的绿豆汤。瓷碗上凝着细密的水珠,顺着碗壁滑到她的手指上,凉丝丝的。\\n\\n外婆在院子里翻晒草药,竹匾里铺着一层金银花,金黄和银白交织,在阳光下微微发颤。外婆的动作很慢,很轻,像是怕惊扰了什么。\\n\\n\\\"晚晚,\\\"外婆头也不抬地说,\\\"你妈打电话来了,说下周来接你。\\\"\\n\\n苏晚舀绿豆汤的手停了一下。\\n\\n她没有说话,只是低头看着碗里碧绿的汤面,倒映着一小片天空,还有槐树叶的影子。绿豆已经煮得开了花,软糯地沉在碗底。\\n\\n风过,槐花簌簌落下,有几朵掉进了她的碗里。\",\n \"note\": \"铺陈型:大量感官描写(阳光/槐花香/冰凉瓷碗/金银花),信息点极少(母亲要来接),重在氛围营造和情绪留白\"\n }\n ],\n \"threshold_overrides\": {\n \"infoPointsPerThousand\": 1,\n \"maxExpositionContinuous\": 600,\n \"maxParagraphLength\": 300,\n \"targetParagraphLength\": 100,\n \"shortSentenceRatio\": 0.25,\n \"targetSentenceLength\": 28,\n \"maxSentenceLength\": 80,\n \"minSensoryTypes\": 3,\n \"sightRatio\": 0.5\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.1,\n \"sensorySignal\": 1.5,\n \"action\": 0.6,\n \"emotion\": 1.3,\n \"infoAdvance\": 0.6\n }\n}\n","{\n \"kb_version\": \"3.0\",\n \"node_id\": \"node_opening_impact\",\n \"option_id\": \"opt_opening_medium\",\n \"option_name\": \"动作切入(中等冲击)\",\n \"option_description\": \"开头从正在进行的动作或声音切入,比感官轰炸平和但比环境描写强,适合大多数网文场景。\",\n \"system_prompt\": \"你使用中等冲击开头模式。第一句从正在进行的动作或声音切入:一个正在做的动作、一个突然响起的声音、一个意外的触觉。不需要单字轰炸,但第一句必须有人正在做什么或发生了什么具体事件,不能是静态环境描写。\",\n \"constraints\": [\n \"第一句必须是进行中的动作或突发声音\",\n \"第一句必须有具体动词,禁止静态描写\",\n \"开头三句内必须出现身体反应\",\n \"禁止纯环境/背景/外貌开头\"\n ],\n \"examples\": [\n {\n \"text\": \"铅笔在纸页上划出沙沙的声响,林深把三十七点二度这个数字记下来,指尖在数字下面顿了顿。\",\n \"note\": \"动作切入:第一句就是正在进行的动作+声音\"\n }\n ],\n \"threshold_overrides\": {\n \"openingImpact\": \"medium\"\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.2,\n \"sensorySignal\": 1.2,\n \"action\": 1.2,\n \"emotion\": 1.0,\n \"infoAdvance\": 1.0\n }\n}\n","{\n \"kb_version\": \"3.1\",\n \"node_id\": \"node_opening_impact\",\n \"option_id\": \"opt_opening_strong\",\n \"option_name\": \"感官轰炸(2026追读默认)\",\n \"option_description\": \"2026最强开头模式:3秒停留率优化。第一句≤20字直接身体刺激/动作/冲突,0铺垫直接进现场。前300字完成冲突爆发→主角在场→异常出现。\",\n \"system_prompt\": \"你使用2026年最强追读力开头模式——感官轰炸+3秒停留。严格遵守:\\n\\n【第一句铁则】\\n- 第一句必须≤20字,直接写主角能感知的强刺激或正在发生的动作。\\n- 最优第一句是单字/两字感官鼓点:疼。/烫。/冷。/响。/血。/不对。\\n- 次优第一句是直接动作/冲突/结果:「刀尖抵住她喉结。」「外门弟子林凡,一刀斩了大师兄。」「离婚协议签完第三分钟,电话响了。」\\n- 绝对禁止:写景(天刚亮/寒风/大雪)、交代背景(在一个XX的地方/这是XX大陆)、介绍人物(我叫XX/XX今年XX岁)、回忆从前(很久以前/从前/话说)。\\n\\n【前三句结构】\\n- 第一句:强感官刺激或直接动作冲突。\\n- 第二句:主角的本能身体反应(缩手/僵住/回头/屏住呼吸/手指扣紧/后颈汗毛竖起)。\\n- 第三句:读者看到一个具体的、正在发生的异常(不是背景介绍,是具体的东西在动/在发光/在流血/在逼近)。\\n\\n【黄金300字】\\n- 前300字必须完成三件事:冲突已经在发生→主角身体已经在反应→一个异常信号已经出现。\\n- 前300字内不能有任何世界观说明、等级介绍、人物回忆、环境铺陈。\\n- 背景信息用一句话插在动作中间带过:「这是灵气枯竭第27年,他正在被人追砍。」\\n- 人物不超过2个(主角+直接施压者)。\\n- 场景聚焦一个动作现场:签字台/手术室门口/擂台中央/矿道深处。\",\n \"constraints\": [\n \"第一句≤20字,单字/两字感官鼓点最佳\",\n \"第一句禁止写景/背景/介绍/回忆\",\n \"第二句必须是主角本能身体反应\",\n \"第三句出现具体异常信号\",\n \"前300字:冲突在场→主角身体在场→异常在场\",\n \"前300字禁止世界观说明/等级介绍/回忆/环境铺陈\",\n \"前300字人物不超过2个,场景不超过1个\"\n ],\n \"examples\": [\n {\n \"text\": \"疼。\\n\\n凿尖砸在指关节上,林深闷哼一声,指缝里渗出血。他甩了甩手,骨节处火辣辣地烧,血珠滴在靴面上,很快被岩尘吸成深色。\\n\\n茧壁在震。\\n\\n不是他凿的那种震。\",\n \"note\": \"矿工式强开篇:第一句单字「疼。」;第二句身体反应(指关节砸到、渗血、火辣辣烧);第三句异常出现(茧壁在震,而且不是他凿的那种震)。\"\n },\n {\n \"text\": \"刀尖抵住她喉结时,系统弹窗亮了。\\n\\n苏晚的呼吸卡在喉咙里,脖子不敢动,刀尖的凉意顺着皮肤往骨子里钻。\\n\\n【检测到濒死状态,绑定「反向许愿」功能】\",\n \"note\": \"系统文强开篇:第一句直接动作+金手指(刀尖抵喉结+系统亮了);第二句身体反应(呼吸卡住、凉意钻骨);第三句异常/金手指展开。\"\n },\n {\n \"text\": \"外门弟子林凡,一刀斩了内门大师兄。\\n\\n血溅在演武场的青石上,围观的弟子全傻了。林凡握刀的手在抖,不是因为害怕,是因为这具身体里的灵魂,三秒前还不是他。\",\n \"note\": \"玄幻穿越强开篇:第一句直接写结果(越级杀人);第二句现场反应+主角身体反应(手抖);第三句信息反咬(灵魂穿越,颠覆读者预期)。\"\n }\n ],\n \"threshold_overrides\": {\n \"openingImpact\": \"strong\",\n \"maxFirstSentenceLength\": 20,\n \"minAnchorsInFirst300\": 3,\n \"minConflictInFirst300\": true\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.5,\n \"sensorySignal\": 1.5,\n \"action\": 1.3,\n \"emotion\": 1.0,\n \"infoAdvance\": 1.2,\n \"twistFrequency\": 1.1,\n \"hookStrength\": 1.0\n }\n}\n","{\n \"kb_version\": \"3.0\",\n \"node_id\": \"node_opening_impact\",\n \"option_id\": \"opt_opening_weak\",\n \"option_name\": \"平和切入(慢热)\",\n \"option_description\": \"允许环境描写或氛围铺陈开头,适合慢热文、传统文学、抒情场景,不建议用于快节奏网文。\",\n \"system_prompt\": \"你使用平和切入开头模式。允许从环境描写、氛围铺陈、场景介绍开始,节奏舒缓。但仍然要求第一段内出现视角人物,有人物在场,不能纯写景无人。\",\n \"constraints\": [\n \"第一段内必须出现视角人物\",\n \"禁止纯写景无人\",\n \"500字内必须有第一个身体锚点\"\n ],\n \"examples\": [\n {\n \"text\": \"矿道里的风带着三十七点二度的暖意,林深把手掌贴在壁上,金纹在他的指腹下缓慢搏动。\",\n \"note\": \"平和切入:环境+温度,人物在场\"\n }\n ],\n \"threshold_overrides\": {\n \"openingImpact\": \"weak\"\n },\n \"radar_weights\": {\n \"bodyReaction\": 0.8,\n \"sensorySignal\": 1.0,\n \"action\": 0.8,\n \"emotion\": 1.2,\n \"infoAdvance\": 0.8\n }\n}\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_paragraph_density\",\r\n \"option_id\": \"opt_dense_low\",\r\n \"option_name\": \"低密度铺陈\",\r\n \"option_description\": \"长段落为主,铺陈细腻,节奏缓慢。适合文学性描写、氛围营造和深度心理刻画,有沉浸感。\",\r\n \"threshold_overrides\": {\r\n \"maxParagraphLength\": 400,\r\n \"targetParagraphLength\": 200,\r\n \"minParagraphCount\": 10,\r\n \"infoPointsPerThousand\": 2,\r\n \"maxExpositionContinuous\": 500\r\n },\r\n \"radar_weights\": {\r\n \"sensorySignal\": 1.3,\r\n \"emotion\": 1.3,\r\n \"action\": 0.7,\r\n \"infoAdvance\": 0.8\r\n },\r\n \"system_prompt\": \"采用低密度长段落写法。段落可以较长,允许在一个段落内完成完整的场景铺陈、氛围渲染或心理刻画。注重细节的层次感,从视觉、听觉、触觉等多个维度慢慢展开画面。节奏舒缓,不急于推进情节,让读者沉浸在场景中。对话较少,以叙述和描写为主。\",\r\n \"constraints\": [\r\n \"单段可到300字,但不得超过400字\",\r\n \"每千字不少于10个段落\",\r\n \"长段落内部要有层次变化,不能平铺直叙\",\r\n \"每3个长段落后必须有一个短段落或对话换气\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"记忆中的夏天总是和那条河有关。河水不深,最深处也只到胸口,河底是圆滑的鹅卵石,阳光好的时候能看见鱼在石缝间穿梭。两岸的芦苇长得比人还高,风一吹就沙沙作响,白色的芦花飘得满河都是。他和她常常在午后溜到河边,他摸鱼,她坐在石头上洗脚,脚趾头被冰凉的河水浸得发红。那时候的阳光好像永远不会落山,空气里永远有芦苇的清香和鱼鳞的腥味,时间像河水一样慢悠悠地流,什么都不急。\",\r\n \"note\": \"长段落细腻铺陈,沉浸感强,节奏缓慢。\"\r\n }\r\n ],\r\n \"requires\": [],\r\n \"conflicts\": [\r\n \"opt_dense_high\"\r\n ]\r\n}","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_paragraph_density\",\r\n \"option_id\": \"opt_dense_medium\",\r\n \"option_name\": \"中等密度\",\r\n \"option_description\": \"段落长度适中(默认),兼顾节奏和信息密度。对话、动作、描写交替出现,阅读舒适流畅。\",\r\n \"threshold_overrides\": {\r\n \"maxParagraphLength\": 200,\r\n \"targetParagraphLength\": 80,\r\n \"minParagraphCount\": 20,\r\n \"infoPointsPerThousand\": 3\r\n },\r\n \"system_prompt\": \"采用中等密度段落写法。段落长度控制在50-120字之间,对话和动作可以单独成段,描写和叙述适当合并。保持稳定的阅读节奏,不要频繁空行制造断奏感,也不要大段堆砌文字造成阅读压力。每段有明确的焦点。\",\r\n \"constraints\": [\r\n \"单段不超过200字\",\r\n \"每千字不少于20个段落\",\r\n \"对话和动作段落简短,描写段落适中\",\r\n \"避免连续3段以上纯描写无动作/对话推进\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"早上七点半,林深准时出现在矿道口。他换好了下井的工装,头灯卡在帽檐上,电池包在腰侧坠出一个沉甸甸的弧度。\\n\\n老范已经在等他了,叼着根没点的烟,眉头皱得像打了结的麻绳。\\n\\n「今天下七层?」林深问。\\n\\n老范把烟从嘴里拿下来,看了他一眼:「你小子昨天才上来,今天又下?」\",\r\n \"note\": \"段落长度适中,叙述/对话/描写交替。\"\r\n }\r\n ],\r\n \"requires\": [],\r\n \"conflicts\": []\r\n}","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_paragraph_density\",\r\n \"option_id\": \"opt_dense_high\",\r\n \"option_name\": \"高密度快节奏\",\r\n \"option_description\": \"短段落为主,段落切换频繁,信息推进快。适合爽文、战斗、追逐等快节奏场景,阅读感畅快。\",\r\n \"threshold_overrides\": {\r\n \"maxParagraphLength\": 80,\r\n \"targetParagraphLength\": 40,\r\n \"minParagraphCount\": 40,\r\n \"infoPointsPerThousand\": 5\r\n },\r\n \"radar_weights\": {\r\n \"action\": 1.3,\r\n \"infoAdvance\": 1.3,\r\n \"sensorySignal\": 0.8,\r\n \"emotion\": 0.9\r\n },\r\n \"system_prompt\": \"采用高密度短段落写法。每段尽量不超过80字,段落之间频繁切换,一个动作或一句对话即可成段。信息推进要快,每段都要有新信息或新进展,不做冗长铺垫。对话和动作交替出现,制造翻页感。减少大段心理描写和环境铺陈。\",\r\n \"constraints\": [\r\n \"单段不超过80字\",\r\n \"每千字不少于40个段落\",\r\n \"每段必须包含新信息、新动作或新对话\",\r\n \"禁止超过100字的连续环境/心理描写\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"他踹开门。\\n\\n屋里空无一人。\\n\\n桌上的茶还冒着热气。\\n\\n他摸向腰间的枪。\\n\\n窗户开着。\\n\\n窗帘在风里飘。\\n\\n楼下传来引擎声。\\n\\n他冲到窗口。\\n\\n一辆黑色轿车正驶出巷子。\",\r\n \"note\": \"每段极短,切换快,紧迫感强。\"\r\n }\r\n ],\r\n \"requires\": [],\r\n \"conflicts\": [\r\n \"opt_dense_low\"\r\n ]\r\n}","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_payoff_frequency\",\r\n \"option_id\": \"opt_payoff_every_3\",\r\n \"option_name\": \"每3章1爽点(默认)\",\r\n \"option_description\": \"每3章一个大爽点,这是爆款网文的平均节奏。张弛有度,铺垫充分,爽点爆发时更有冲击力。\",\r\n \"system_prompt\": \"你采用每3章一个大爽点的节奏模式,这是经过市场验证的爆款平均节奏。基本节奏为:第1章铺垫(设局/埋线索/制造压力),第2章发展(矛盾升级/危机加深/主角蓄力),第3章爆发(爽点释放/打脸反转/实力展现)。大爽点之间可以穿插小爽点或小钩子保持读者兴趣,但核心爽点必须在3章内兑现。铺垫章节要有足够的信息量和张力,不能变成水字数。发展章节要让压力递增,让读者期待爆发。爆发章节要写足,爽点要写透,不能一笔带过浪费前面的铺垫。\",\r\n \"constraints\": [\r\n \"每3章必须有一个大爽点(打脸/逆袭/升级/揭秘/反转等)\",\r\n \"铺垫章(第1章):设局、埋线索、制造压力,必须有信息量\",\r\n \"发展章(第2章):矛盾升级、危机加深、主角蓄力,节奏渐紧\",\r\n \"爆发章(第3章):爽点释放,写足写透,给读者强烈满足感\",\r\n \"大爽点之间可以穿插小爽点/小钩子,但不能替代大爽点\",\r\n \"铺垫禁止水字数,每段都要为后续爽点服务\",\r\n \"爆发章的爽点必须呼应前面2章的铺垫,形成完整闭环\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"【第1章-铺垫】\\n赵无极在宗门大比的抽签仪式上抽到了一号签,对手是内门排名第三的李天豪。所有人都觉得他必输无疑——李天豪已经是凝气九重,而赵无极只是凝气五重。\\n\\n\\\"赵无极,你自己认输吧,免得受伤。\\\"李天豪居高临下地说。\\n\\n赵无极没有说话,只是握紧了拳头。没人知道,他昨晚在禁地意外获得了上古传承,修为一夜之间突破到了凝气七重,而且还学会了一招绝学。\\n\\n【第2章-发展】\\n比赛开始,李天豪一上来就下狠手,招招致命。赵无极节节败退,看起来岌岌可危。\\n\\n\\\"就这点本事也敢参加大比?\\\"李天豪冷笑,一掌拍向赵无极胸口。\\n\\n台下议论纷纷,都觉得赵无极撑不过十招。连裁判都准备随时终止比赛。\\n\\n然而没人注意到,赵无极的嘴角微微上扬——他在等,等李天豪使出那招他早已看穿的破绽。\\n\\n【第3章-爆发】\\n李天豪大喝一声,使出了绝招“裂山掌”,掌风呼啸,空气都被压缩得发出爆鸣。\\n\\n就是现在!\\n\\n赵无极脚步一错,以一个不可思议的角度避开掌风,同时右手并指如剑,一指戳在李天豪肋下三寸——那是他刚才观察到的真气运行破绽。\\n\\n\\\"噗!\\\"\\n\\n李天豪如遭雷击,整个人倒飞出去,重重摔在擂台边缘,一口鲜血喷出。\\n\\n全场死寂。\\n\\n\\\"怎么可能?!\\\"\\n\\n\\\"他一招就击败了李天豪?!\\\"\",\r\n \"note\": \"每3章1爽点:第1章铺垫(抽到强敌/获得传承),第2章发展(节节败退/蓄力等待),第3章爆发(一招制敌/全场震惊)\"\r\n }\r\n ],\r\n \"threshold_overrides\": {},\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.0,\r\n \"sensorySignal\": 1.0,\r\n \"action\": 1.0,\r\n \"emotion\": 1.0,\r\n \"infoAdvance\": 1.0\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_payoff_frequency\",\r\n \"option_id\": \"opt_payoff_every_chapter\",\r\n \"option_name\": \"每章爽点\",\r\n \"option_description\": \"每章至少1个爽点或钩子,读者永远处于兴奋状态。适合免费阅读平台、快节奏爽文,让读者每章都有满足感。\",\r\n \"system_prompt\": \"你采用每章必爽的节奏模式。每一章都必须包含至少一个明确的爽点或钩子。爽点可以是:打脸反派、获得宝物/能力升级、美女/贵人相助、真相大白、反转打脸、装逼成功、众人震惊、实力碾压、危机化解、意外收获等。如果当章剧情确实不适合放爽点(如过渡章),则必须在章末放一个强力钩子——惊人发现、危机降临、神秘人物登场、悬念升级等。绝对不允许出现“平淡无奇”的章节。爽点要前置,最好在章节前半段就出现,不要让读者等太久。\",\r\n \"constraints\": [\r\n \"每章必须有至少1个爽点或章末强力钩子\",\r\n \"爽点尽量在章节前1/3出现,不要让读者空等\",\r\n \"爽点类型要多样化,禁止连续3章同类型爽点(如连续打脸)\",\r\n \"小爽点和大爽点交替,避免审美疲劳\",\r\n \"爽点之后可以有短暂缓冲,但下一个爽点/钩子必须在2000字内出现\",\r\n \"章末钩子必须强烈,让读者产生“必须看下一章”的冲动\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"王总监一脸得意地等着看林风出丑,会议室里所有人的目光都集中在林风身上。\\n\\n林风不慌不忙地打开U盘,投影幕布上出现了一份完整的数据报告——每一笔账目都清清楚楚,王总监挪用公款的证据赫然在列。\\n\\n(爽点:拿出证据反杀)\\n\\n王总监脸色惨白:\\\"你……你怎么会有这些?\\\"\\n\\n\\\"你以为销毁了原件就没事了?\\\"林风淡淡道,\\\"你忘了,服务器有备份。\\\"\\n\\n董事长看完报告,猛地一拍桌子:\\\"王建国!你被开除了,法务部马上报警!\\\"\\n\\n(爽点:反派被当场处置)\\n\\n王总监被保安架出去的时候,怨毒地盯着林风:\\\"你等着!我不会放过你的!\\\"\\n\\n林风不以为意地坐回座位,却感觉到桌下有人踢了他一下。\\n\\n他低头一看,是董事长秘书苏晴递过来一张小纸条,上面写着:「小心,王建国背后有人。」\\n\\n(章末钩子:更大的威胁)\",\r\n \"note\": \"每章爽点模式:章内两个爽点(拿证据/反派被开),章末钩子(背后有人),层层递进\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"infoPointsPerThousand\": 4,\r\n \"maxExpositionContinuous\": 200,\r\n \"maxParagraphLength\": 100,\r\n \"targetParagraphLength\": 45\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.1,\r\n \"sensorySignal\": 0.8,\r\n \"action\": 1.4,\r\n \"emotion\": 1.3,\r\n \"infoAdvance\": 1.1\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_payoff_frequency\",\r\n \"option_id\": \"opt_payoff_sparse\",\r\n \"option_name\": \"长线布局(5章+)\",\r\n \"option_description\": \"爽点稀疏,5章以上才有一个大爆发。重在长线布局、伏笔埋设、人物成长,适合硬核剧情流、悬疑推理、史诗类作品。\",\r\n \"system_prompt\": \"你采用长线布局的节奏模式。爽点/大爆发的间隔在5章以上,中间大量篇幅用于伏笔埋设、人物塑造、世界观展开、情感铺垫。读者获得的不是即时满足,而是“伏笔回收时的震撼”。你需要精心布局:前期看似无关的细节,到爆发时全部串联起来,给读者“原来如此!”的巨大快感。中间章节不能无聊——要用悬念、人物魅力、世界观谜团来保持读者的阅读动力。每一个“闲笔”都可能是伏笔,要让二刷的读者能发现前面埋的线索。爆发时必须将前面所有线索收拢,形成强烈的情感冲击和智力满足。\",\r\n \"constraints\": [\r\n \"大爽点/大爆发间隔5章以上,重在长线布局\",\r\n \"每章必须有至少1个悬念点或伏笔线索,不能纯铺垫无信息量\",\r\n \"前期埋的伏笔必须在爆发时回收,禁止烂尾伏笔\",\r\n \"中间章节用悬念、人物魅力、世界观谜团维持阅读动力\",\r\n \"爆发章节必须将多条线索收拢,形成“原来如此”的震撼效果\",\r\n \"伏笔要自然,不能刻意到读者一眼就看出“这是伏笔”\",\r\n \"人物成长线必须和大爆发呼应,让爽点同时是人物弧光的顶点\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"【第1-4章 长线布局】\\n第1章:侦探陈默第一次进入庄园,注意到壁炉旁的地毯上有一小块不易察觉的深色痕迹。管家说那是红酒渍。(伏笔:血迹)\\n第2章:陈默和二小姐交谈时,她下意识地摸了摸左手无名指——那里有一圈很浅的白印,但她并没有戴戒指。(伏笔:婚姻秘密)\\n第3章:陈默在书房发现一封烧毁一半的信,只能辨认出“……不能让他知道……遗产……”几个字。(伏笔:动机)\\n第4章:晚宴上,大少爷提到案发当晚他在书房看书,但陈默注意到书房的台灯灯泡是冷的。(伏笔:不在场证明造假)\\n\\n【第5章 爆发】\\n陈默把所有人召集到客厅,缓缓说道:\\n\\n\\\"凶手就在这个房间里。\\\"\\n\\n他一一列举证据:壁炉旁的血迹经过检测是人血而非红酒、二小姐暗中成婚的对象是死者的私生子、烧毁的信是死者更改遗嘱的证据、大少爷的不在场证明因为冷灯泡而不攻自破……\\n\\n所有线索汇聚到一个人身上——\\n\\n管家的脸色越来越白,终于瘫倒在椅子上。\",\r\n \"note\": \"长线布局模式:前4章分散伏笔(血迹/戒指印/烧毁信/冷灯泡),第5章集中推理回收,智力爽感强烈\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"infoPointsPerThousand\": 2,\r\n \"maxExpositionContinuous\": 500,\r\n \"maxParagraphLength\": 250,\r\n \"targetParagraphLength\": 80,\r\n \"shortSentenceRatio\": 0.3\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 0.8,\r\n \"sensorySignal\": 1.0,\r\n \"action\": 0.8,\r\n \"emotion\": 1.0,\r\n \"infoAdvance\": 1.4\r\n }\r\n}\r\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_platform\",\n \"option_id\": \"opt_platform_generic\",\n \"option_name\": \"通用(默认)\",\n \"option_description\": \"通用平台风格,不针对特定平台做优化,采用平衡的节奏和写法,适合多平台分发或不确定发布平台时使用。\",\n \"system_prompt\": \"你采用通用网文写作风格,不针对特定平台做特殊优化。保持均衡的节奏:开篇有吸引力但不过于急促,描写适度不冗余,爽点分布均匀,段落长度适中。兼顾各类读者的阅读习惯,既不写得太碎也不写大块文字。对话和描写比例均衡,情感和剧情并重。\",\n \"constraints\": [\n \"开篇前1000字内出现核心冲突或悬念\",\n \"段落长度适中,单段50-150字\",\n \"爽点分布均匀,约每2000字一个小高潮\",\n \"对话与叙述描写比例约为4:6\",\n \"避免极端写法(不要太水也不要太赶)\",\n \"用词规范,避免过于小众的网络黑话\",\n \"每章结尾留适当悬念但不必强行反转\"\n ],\n \"examples\": [\n {\n \"text\": \"陈默推开宿舍门的时候,室友们正在讨论周末去哪玩。\\n\\n\\\"默哥,一起去爬山啊?\\\"王胖子探出头来。\\n\\n\\\"不去了,我还有事。\\\"陈默把书包放下,若有所思。\\n\\n今天下午,他在旧书摊上买到了一块奇怪的铜牌,上面刻着他从未见过的文字。铜牌入手温热,隐隐有种说不出的感觉。\\n\\n他把铜牌从口袋里掏出来,放在桌上。灯光下,铜牌表面的纹路似乎微微亮了一下。\\n\\n\\\"这什么玩意儿?\\\"王胖子凑过来,\\\"看起来挺老的,地摊上淘的?\\\"\\n\\n\\\"嗯。\\\"陈默应了一声,伸手想去拿铜牌——\\n\\n指尖触到铜牌的瞬间,一道金光闪过,他整个人消失在原地。\\n\\n宿舍里,王胖子目瞪口呆地看着空荡荡的座位,手里还拿着半袋薯片。\",\n \"note\": \"通用风开篇:日常场景引入→核心物件(铜牌)→悬念(消失),节奏平衡,描写对话均衡\"\n }\n ],\n \"threshold_overrides\": {},\n \"radar_weights\": {\n \"bodyReaction\": 1.0,\n \"sensorySignal\": 1.0,\n \"action\": 1.0,\n \"emotion\": 1.0,\n \"infoAdvance\": 1.0\n }\n}\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_platform\",\r\n \"option_id\": \"opt_platform_qidian\",\r\n \"option_name\": \"起点风\",\r\n \"option_description\": \"起点中文网风格:慢热铺垫,世界观宏大,字数充足,注重体系设定与长线剧情。适合长篇连载,开篇可以慢热铺陈,中后期发力。\",\r\n \"system_prompt\": \"你采用起点中文网的写作风格。起点读者耐心较好,允许较长的世界观铺垫和人物成长过程。开篇前3章可以花笔墨交代背景设定,但必须在5章内出现第一个明确的冲突/转折。字数充裕,每章3000字以上为佳。注重等级体系、势力格局、世界观设定的完整性。金手指/系统设定要有明确规则,不能随意加设定。章节末尾留悬念但不必每章都强行打脸。整体节奏为“慢热-铺垫-爆发-再铺垫-大爆发”的波浪形。\",\r\n \"constraints\": [\r\n \"开篇前5章必须出现第一个核心冲突或转折\",\r\n \"世界观设定需有内在逻辑,等级/力量体系必须明确\",\r\n \"单章字数不低于2500字\",\r\n \"金手指/外挂规则一旦确立不得随意更改\",\r\n \"伏笔需在30章内回收或给予读者暗示\",\r\n \"禁止每章强行打脸装逼,爽点间隔可放宽至3-5章\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"苍茫大陆,武道为尊。\\n\\n天武国,青云城。\\n\\n林家府邸,偏僻的小院里,一个十六岁的少年盘坐在石床上,眉头紧锁。\\n\\n他叫林动,本是林家旁系子弟,三年前武魂觉醒时,被测出是最低等的废武魂——一缕残破的火苗。从那以后,他便从天才沦为笑柄,被发配到这处偏僻院落。\\n\\n但没人知道,那缕看似残破的火苗武魂中,藏着一片虚无空间。空间里悬浮着一座古朴的小鼎,鼎身上刻满了密密麻麻的符文。\\n\\n林动闭目内视,心神沉入丹田。那缕微弱的火苗武魂正有气无力地跳动着,丹田内的武气稀薄得如同薄雾。\\n\\n\\\"还差一点……\\\"他咬了咬牙,按照古鼎上传来的神秘功法,缓缓引导武气沿经脉运转。\",\r\n \"note\": \"起点风开篇:交代世界观(苍茫大陆/武道为尊)、地点(青云城林家)、主角身份(废武魂旁系子弟)、金手指(古鼎),节奏较慢但信息密度充足\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"maxParagraphLength\": 300,\r\n \"targetParagraphLength\": 100,\r\n \"minParagraphCount\": 15,\r\n \"maxExpositionContinuous\": 500,\r\n \"infoPointsPerThousand\": 2,\r\n \"shortSentenceRatio\": 0.3,\r\n \"targetSentenceLength\": 28,\r\n \"maxSentenceLength\": 80\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 0.8,\r\n \"sensorySignal\": 1.0,\r\n \"action\": 0.9,\r\n \"emotion\": 0.9,\r\n \"infoAdvance\": 1.3\r\n }\r\n}\r\n","{\n \"kb_version\": \"3.1\",\n \"node_id\": \"node_platform\",\n \"option_id\": \"opt_platform_tomato\",\n \"option_name\": \"番茄风(2026追读版)\",\n \"option_description\": \"番茄小说2026追读力强化版:3秒停留率、黄金300字、每300字一个反咬、章末具体钩子。算法第一指标是完读率,开篇定生死。\",\n \"system_prompt\": \"你采用番茄小说2026年最新追读力标准写作。番茄算法第一指标是「3秒停留率」——读者划到你的正文,3秒决定去留。你必须严格遵守以下铁律:\\n\\n【开篇铁律】\\n- 第一句≤20字,直接写正在发生的动作/冲突/结果,禁止任何铺垫。\\n- 第一句禁止写景、禁止交代背景、禁止介绍人物、禁止回忆前世。\\n- 前300字必须完成三件事:冲突爆发→主角身体在场→异常信号出现。\\n- 前300字内不能出现任何纯环境描写、纯背景交代、纯心理独白。\\n\\n【节奏铁律】\\n- 每250-350字必须有一次信息反咬(读者预期被颠覆)。\\n- 每800-1000字一个小爽点/小反转。\\n- 每3章一个大爽点/大反转。\\n- 禁止连续400字无转折、无意外、无新发现。\\n\\n【对话铁律】\\n- 对话必须有碰撞:有人说A,下一个人必须先质疑/反对/唱反调,不许直接认同。\\n- 禁止工作汇报式对话(一人发现→告诉大家→大家认同)。\\n- 连续对话不超过4句必须插入动作/神态/环境描写。\\n\\n【结尾铁律】\\n- 最后100字必须出现一个全新的、颠覆之前判断的具体信息。\\n- 钩子必须具体,禁止装神弄鬼:不能写「一股神秘气息」「他似乎意识到什么」「事情没那么简单」——这些是空泛假钩子,读者已免疫。\\n- 好钩子是具体的、看得见摸得着的:「他低头,看见凿尖上沾了血。」「门外传来第三下敲门声。」「号牌上的数字,是6。」\\n- 最后一句禁止用「了。」收尾,禁止用「就这样/原来如此/所以/于是」总结词。\\n- 写完最后一句问自己:读者会不会骂「操怎么断在这里」?会才合格。\\n\\n【行文铁律】\\n- 单段≤80字,手机阅读不超过3行。\\n- 单句≤40字,关键鼓点句≤15字。\\n- 每行视觉长度控制在17字以内(手机一屏约17字)。\\n- 对话占比不低于40%。\\n- 禁止连续超过150字纯描写/说明/心理独白。\\n- 禁止48个AI套路反应词:心头一跳/脸色一变/握紧拳头/点了点头/叹了口气/皱了皱眉/冷哼一声/嘴角微扬/微微一笑/瞳孔骤缩/眼中闪过一丝/虎躯一震/冷笑一声/不置可否/置若罔闻/面无表情等——全部用生理级身体反应替代。\\n- 所有情绪必须落到肉身:心脏/胃/脊背/指尖/后颈/眉心/后槽牙七大锚点。\\n- 禁止直接写「他很紧张/她很害怕/气氛压抑」,用动作和生理反应展示。\",\n \"constraints\": [\n \"第一句≤20字,直接动作/冲突/结果,禁止写景/背景/回忆\",\n \"前300字:冲突爆发→主角身体在场→异常信号出现\",\n \"每250-350字一次信息反咬,千字≥3个意外/转折\",\n \"对话必须有碰撞,4句以上对话必须有反对/质疑/唱反调\",\n \"最后100字必须出现具体新信息钩子,禁止装神弄鬼假钩子\",\n \"最后一句≤15字短句鼓点落点,禁止「了。」收尾\",\n \"单段≤80字,单句≤40字,手机一屏17字以内\",\n \"对话占比≥40%,连续对话≤4句\",\n \"禁止连续150字以上纯描写/说明/心理独白\",\n \"禁止48个AI套路反应词,情绪必须落到七大肉身锚点\",\n \"禁止直接陈述情绪词,用生理级身体反应展示\"\n ],\n \"examples\": [\n {\n \"text\": \"疼。\\n\\n辞退信甩在脸上的时候,叶辰的指关节被纸边划了一道血口。他没躲,血珠滴在办公桌上,很快被那份「实习生辞退通知书」吸成深色。\\n\\n\\\"一个实习生也敢顶撞王少?\\\"经理满脸鄙夷,\\\"你知道王少是谁吗?\\\"\\n\\n叶辰盯着他。指腹的血还在渗,火辣辣地烧。他不是这个世界的人——三天前穿越过来,脑子里多了个东西。\\n\\n【神级选择系统已激活】\\n\\n【选项一:低头道歉,获得十万块】\\n\\n【选项二:当场辞职,打脸王少,获得神级投资天赋!】\\n\\n叶辰笑了。\\n\\n他拿起辞退信,撕成两半,再撕,碎纸片扔进垃圾桶。\\\"不用你辞,老子不干了。\\\"\\n\\n经理愣住了。办公室里看热闹的同事也愣住了。\\n\\n门就在这时被推开。\\n\\n一个穿高定西装的中年男人快步走进来,目光扫过全场,最后落在叶辰脸上,腰弯了下去。\\n\\n\\\"叶先生,我们董事长请您过去。\\\"\",\n \"note\": \"番茄2026开篇示范:第一句1字「疼。」直接身体刺激;前300字有冲突(被辞退)、身体在场(指关节被划出血)、异常信号(系统激活);对话有碰撞;结尾钩子具体(董事长有请,腰弯了下去——颠覆了「被开除者」的预期)。\"\n }\n ],\n \"threshold_overrides\": {\n \"maxParagraphLength\": 80,\n \"targetParagraphLength\": 35,\n \"minParagraphCount\": 40,\n \"maxExpositionContinuous\": 150,\n \"infoPointsPerThousand\": 6,\n \"shortSentenceRatio\": 0.65,\n \"targetSentenceLength\": 15,\n \"maxSentenceLength\": 40,\n \"maxDialogueContinuous\": 4,\n \"maxFillerSentences\": 0,\n \"maxFillerWords\": 3,\n \"minAnchorsPerThousand\": 8,\n \"minDialogueConflictRatio\": 0.3\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.3,\n \"sensorySignal\": 0.9,\n \"action\": 1.4,\n \"emotion\": 1.2,\n \"infoAdvance\": 1.2,\n \"twistFrequency\": 1.3,\n \"hookStrength\": 1.5\n }\n}\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_platform\",\r\n \"option_id\": \"opt_platform_qimao\",\r\n \"option_name\": \"七猫风\",\r\n \"option_description\": \"七猫免费小说风格:中老年读者友好,节奏平稳,通俗易懂。文字朴实直白,避免复杂句式和新潮网络用语,故事温馨或爽感明确,逻辑清晰。\",\r\n \"system_prompt\": \"你采用七猫小说的写作风格。七猫读者群体年龄偏大,喜欢通俗易懂、节奏平稳的故事。文字要朴实直白,不要用年轻人专属的网络梗、二次元用语、英文缩写。句子不要太长太复杂,读起来要顺口。价值观要正,善恶有报,主角可以有挫折但最终一定胜利。家庭、亲情、正义、奋斗等主题受欢迎。节奏平稳但不拖沓,每章讲清楚一个小事件。避免过于血腥暴力或阴暗的描写。打脸可以有但不要太极端,更多用智慧和实力说话。\",\r\n \"constraints\": [\r\n \"用词通俗易懂,禁止使用网络黑话、二次元梗、英文缩写\",\r\n \"句子简短通顺,单句不超过45字\",\r\n \"价值观正向,善恶有报,正义必胜\",\r\n \"避免过度血腥暴力和阴暗描写\",\r\n \"节奏平稳,每章讲清一个小事件,不跳跃\",\r\n \"人物动机明确,反派坏得有逻辑\",\r\n \"家庭/亲情/友情等情感线要温暖正面\",\r\n \"章节标题直白,不玩文字游戏\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"张建国回到家的时候,天已经黑了。\\n\\n老伴李秀兰正在厨房里忙活,听见开门声,探出头来:\\\"回来了?今天怎么这么晚?\\\"\\n\\n\\\"厂里加了个班。\\\"张建国换了鞋,把外套挂在衣架上。他今年五十八岁,在红星机械厂干了一辈子,再过两年就该退休了。\\n\\n饭桌上摆着两菜一汤,都是家常菜。老张洗了手坐下,拿起筷子。\\n\\n\\\"对了,\\\"李秀兰忽然想起什么,\\\"咱儿子今天打电话来了,说下月要带女朋友回来。\\\"\\n\\n张建国夹菜的手顿了一下:\\\"女朋友?哪里人?做什么工作的?\\\"\\n\\n\\\"说是他们公司的同事,本地人。\\\"李秀兰笑着给老伴盛了碗汤,\\\"你紧张什么呀,儿子都三十了,也该成家了。\\\"\\n\\n张建国“嗯”了一声,端起碗喝汤,心里却琢磨着:儿子带对象回来,这房子是不是该装修装修了?\",\r\n \"note\": \"七猫风开篇:生活气息浓厚,文字朴实,人物对话自然,节奏平稳,贴近中老年读者生活\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"maxParagraphLength\": 150,\r\n \"targetParagraphLength\": 60,\r\n \"minParagraphCount\": 22,\r\n \"maxExpositionContinuous\": 350,\r\n \"infoPointsPerThousand\": 2,\r\n \"shortSentenceRatio\": 0.5,\r\n \"targetSentenceLength\": 20,\r\n \"maxSentenceLength\": 45,\r\n \"maxFillerSentences\": 4,\r\n \"maxFillerWords\": 10\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 0.9,\r\n \"sensorySignal\": 1.0,\r\n \"action\": 0.8,\r\n \"emotion\": 1.1,\r\n \"infoAdvance\": 0.9\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_platform\",\r\n \"option_id\": \"opt_platform_feilu\",\r\n \"option_name\": \"飞卢风\",\r\n \"option_description\": \"飞卢小说网风格:极度爽文,节奏极快,装逼打脸不断。主角光环极强,反派智商在线但永远被碾压,升级速度快,爽点一个接一个。\",\r\n \"system_prompt\": \"你采用飞卢小说网的写作风格。飞卢读者追求极致爽感,不要任何压抑和憋屈。主角必须从第一章开始就强势,开局就要有碾压级的金手指或能力。反派嚣张不过3章必被打脸,而且打脸要狠、要彻底、要当众。节奏极快,不写大段心理描写和环境描写,一切为装逼打脸服务。主角可以装逼但不能吃瘪,任何挑衅必须当场或在最短时间内回击。升级速度要快,每5-10章一个大境界提升。标题要劲爆,每章标题就要有爽点预告。记住:读者看飞卢就是来爽的,不要让他们等。\",\r\n \"constraints\": [\r\n \"第一章主角必须展现碾压级优势(金手指/隐藏身份/超强实力)\",\r\n \"反派嚣张出场后,3章内必须被打脸\",\r\n \"打脸场景必须有观众,当众碾压效果最佳\",\r\n \"禁止主角吃瘪超过1章,任何危机必须迅速化解\",\r\n \"每章至少1个爽点,每2000字至少1次装逼/打脸/震惊\",\r\n \"不写超过100字的纯描写或心理活动\",\r\n \"围观群众的震惊反应必须写(倒吸冷气/目瞪口呆/不敢置信)\",\r\n \"升级节奏快,5-10章一个大突破\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"\\\"就你?一个废物也配参加丹药大比?\\\"\\n\\n赵天明哈哈大笑,周围的弟子也跟着哄笑起来。\\n\\n林玄站在丹炉前,神色平静。\\n\\n他们不知道,就在昨夜,林玄觉醒了太古丹帝记忆,万丹秘方尽在脑中,炼丹对他来说如同吃饭喝水。\\n\\n\\\"开始吧。\\\"林玄淡淡道。\\n\\n赵天明冷笑一声,率先开炉。他是青云宗丹道天才,一出手便是玄阶中品丹方——凝元丹!\\n\\n众人惊叹。\\n\\n然而林玄连丹方都没看,随手抓起几株灵药丢进丹炉,指尖灵气一引——\\n\\n轰!\\n\\n丹炉震颤,金光冲天!\\n\\n一股浓郁到实质的药香弥漫开来,让所有人都为之色变。\\n\\n\\\"这……这丹香……至少是地阶丹药!\\\"\\n\\n\\\"不可能!他连丹方都没看!\\\"\\n\\n赵天明脸色惨白,手中的凝元丹“啪”地掉在地上。\\n\\n林玄掀开炉盖,三颗金光灿灿的丹药静静躺在炉底,丹纹密布,异香扑鼻。\\n\\n他随手拿起一颗,弹进嘴里,像吃糖豆一样嚼了嚼。\\n\\n\\\"勉强能吃。\\\"\",\r\n \"note\": \"飞卢风开篇:反派嚣张→主角淡定→展现实力→众人震惊→极致装逼(当糖豆吃),全程无憋屈,爽点密集\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"maxParagraphLength\": 70,\r\n \"targetParagraphLength\": 35,\r\n \"minParagraphCount\": 40,\r\n \"maxExpositionContinuous\": 100,\r\n \"infoPointsPerThousand\": 6,\r\n \"shortSentenceRatio\": 0.65,\r\n \"targetSentenceLength\": 14,\r\n \"maxSentenceLength\": 35,\r\n \"maxDialogueContinuous\": 6,\r\n \"maxFillerSentences\": 1,\r\n \"maxFillerWords\": 3\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.0,\r\n \"sensorySignal\": 0.7,\r\n \"action\": 1.6,\r\n \"emotion\": 1.0,\r\n \"infoAdvance\": 1.2\r\n }\r\n}\r\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_platform\",\n \"option_id\": \"opt_platform_jinjiang\",\n \"option_name\": \"晋江风\",\n \"option_description\": \"晋江文学城风格:情感细腻,人物关系为重,文笔精致。注重CP互动、心理刻画、情感递进,读者以女性为主,对文笔和人物塑造要求高。\",\n \"system_prompt\": \"你采用晋江文学城的写作风格。晋江读者重视人物塑造和情感线,文笔要求细腻精致。重点描写人物之间的互动、眼神、微表情、心理活动。情感推进要细腻有层次,不能一蹴而就,要通过日常细节、对话交锋、误会与和解来慢慢发酵。CP感要足,化学反应要强烈。可以适当使用内心独白和细腻的感官描写。注意文笔的文学性,用词考究,避免粗俗直白的表达。节奏可以偏慢,但人物关系必须每章都有进展。世界观设定为情感服务,不要喧宾夺主。\",\n \"constraints\": [\n \"人物心理描写和微表情描写每章不少于3处\",\n \"CP/主要人物关系每章必须有进展或变化\",\n \"用词精致文雅,禁止粗俗网络用语\",\n \"情感推进要有层次,禁止一见钟情式的突兀\",\n \"对话要体现人物性格,每个角色说话方式必须有区分度\",\n \"环境描写需与人物心境呼应(情景交融)\",\n \"每章至少一个让读者心动的互动细节(指尖触碰/眼神交汇/意外靠近等)\"\n ],\n \"examples\": [\n {\n \"text\": \"沈清辞没想到会在这里遇见陆衍之。\\n\\n咖啡馆的暖黄灯光落在他身上,他穿着一件烟灰色的羊绒衫,袖口随意地挽到小臂,露出腕骨分明的手。他正低头翻着一本什么书,睫毛在眼下投出一小片阴影。\\n\\n三年了。\\n\\n她以为自己已经能平静面对这个人了,可指尖还是不受控制地微微发颤。\\n\\n\\\"小姐,您的焦糖玛奇朵。\\\"\\n\\n侍者的声音让她回过神,她连忙接过杯子,转身想走——\\n\\n\\\"清辞?\\\"\\n\\n那个声音,低沉,清冽,像冬夜里落了一场雪。\\n\\n沈清辞的脚步顿住了。\\n\\n她深吸一口气,转过身,努力挤出一个得体的微笑:\\\"陆先生,好久不见。\\\"\\n\\n陆衍之合上书,站起身。他比记忆中似乎又高了一些,目光落在她脸上,停了几秒,才缓缓开口:\\\"好久不见。\\\"他顿了顿,声音放轻了些,\\\"你……还好吗?\\\"\",\n \"note\": \"晋江风开篇:细腻的人物描写(羊绒衫/腕骨/睫毛),情感张力(三年未见/指尖发颤),含蓄的互动(目光停留/声音放轻),注重氛围和心理\"\n }\n ],\n \"threshold_overrides\": {\n \"maxParagraphLength\": 200,\n \"targetParagraphLength\": 70,\n \"minParagraphCount\": 20,\n \"maxExpositionContinuous\": 300,\n \"infoPointsPerThousand\": 2,\n \"shortSentenceRatio\": 0.35,\n \"targetSentenceLength\": 24,\n \"maxSentenceLength\": 60,\n \"minSensoryTypes\": 3,\n \"sightRatio\": 0.5\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.3,\n \"sensorySignal\": 1.3,\n \"action\": 0.7,\n \"emotion\": 1.5,\n \"infoAdvance\": 0.7\n }\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_platform\",\n \"option_id\": \"opt_platform_newmedia\",\n \"option_name\": \"新媒体风\",\n \"option_description\": \"新媒体/公众号风格:标题党,情绪强烈,短段落。适合微信公众号、头条号等平台,开头3秒抓住读者,情绪拉满,金句频出,引发共鸣和转发。\",\n \"system_prompt\": \"你采用新媒体公众号风格写作。新媒体读者在信息流中刷到你的文章,你只有3秒钟抓住他们。开头必须炸裂——用一个惊人的事实、一个扎心的问题、一个反常识的观点、一个让人脸红心跳的场景开场。段落极短,一两句话就是一段,手机上一眼扫完。情绪要强烈,要让读者愤怒、感动、焦虑、爽,情绪平了就是死。多用金句、排比、反问。每200字左右要有一个情绪高点或一个让读者想截图转发的句子。结尾要有升华或呼吁,让读者忍不住点赞转发。标题要制造好奇心、共鸣或争议。\",\n \"constraints\": [\n \"开头第一句/第一段必须炸裂(惊人事实/扎心问题/反常识/高能场景)\",\n \"段落极短,每段1-3句话,手机一屏3-5段\",\n \"每200字左右一个情绪高点(愤怒/感动/爽/扎心/共鸣)\",\n \"必须包含至少2个可截图转发的金句\",\n \"多用排比、反问、短句,制造节奏感\",\n \"情绪要饱满,禁止平铺直叙\",\n \"结尾必须有升华/金句/呼吁行动\",\n \"避免冗长的背景交代,直接进入核心冲突\"\n ],\n \"examples\": [\n {\n \"text\": \"你有没有想过,你这辈子可能永远买不起房?\\n\\n别着急反驳。\\n\\n先看看你的工资卡。\\n\\n再看看你所在城市的房价。\\n\\n算一算。\\n\\n不吃不喝,你需要多少年?\\n\\n我算了。\\n\\n三十二年。\\n\\n三十二年不吃不喝,才能在这座城市买一套八十平的房子。等我凑够首付,我已经五十岁了。五十岁啊!\\n\\n而我的父母,他们在老家的房子,已经漏雨了。\\n\\n我每个月往家里打两千块钱,我妈舍不得花,全都存起来,说要给我娶媳妇。\\n\\n娶媳妇?\\n\\n我连自己都养不起。\",\n \"note\": \"新媒体风开篇:扎心问题开场,极短段落制造节奏,数据冲击(三十二年),情绪层层递进(父母/漏雨/娶媳妇),共鸣拉满\"\n }\n ],\n \"threshold_overrides\": {\n \"maxParagraphLength\": 50,\n \"targetParagraphLength\": 25,\n \"minParagraphCount\": 50,\n \"maxExpositionContinuous\": 80,\n \"infoPointsPerThousand\": 4,\n \"shortSentenceRatio\": 0.75,\n \"targetSentenceLength\": 12,\n \"maxSentenceLength\": 30,\n \"maxFillerSentences\": 0,\n \"maxFillerWords\": 2\n },\n \"radar_weights\": {\n \"bodyReaction\": 0.8,\n \"sensorySignal\": 0.7,\n \"action\": 0.8,\n \"emotion\": 1.7,\n \"infoAdvance\": 1.0\n }\n}\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_pov\",\r\n \"option_id\": \"opt_pov_first_past\",\r\n \"option_name\": \"第一人称过去式\",\r\n \"option_description\": \"以“我”的视角叙述,使用过去时态。代入感极强,读者直接体验主角的感受和思考,适合悬疑、自传、情感类作品。\",\r\n \"system_prompt\": \"你使用第一人称过去式进行写作。叙述者是“我”——故事的主角或某个视角人物,所有事件都用过去时态描述(“我走了”“我看到了”“我想”)。因为是第一人称,你只能写“我”亲眼看到、亲耳听到、亲身经历的事情,不能直接写别人的心理活动——别人怎么想的,只能通过他们的表情、动作、语言来推测。“我”的内心独白、感受、回忆可以自由写,这是第一人称的优势。代入感是第一人称的生命,要让读者觉得“我就是主角”。注意时态一致性,不要在过去式中混入现在式(除非是角色当下的心理活动可以用现在式表达即时感受,但叙述主线必须是过去式)。\",\r\n \"constraints\": [\r\n \"叙述视角严格为第一人称“我”,不得切换到其他人物的内心\",\r\n \"时态以过去式为主(了/过/当时/曾经/已经),叙述主线保持一致\",\r\n \"只能写“我”亲眼所见、亲耳所闻、亲身经历,禁止全知视角\",\r\n \"他人心理只能通过表情、动作、语言推测,不能直接写“他心想”“她暗自高兴”\",\r\n \"充分利用第一人称优势:内心独白、感官体验、个人回忆、情感波动\",\r\n \"禁止在叙述中出现“我”不可能知道的信息\",\r\n \"如果是回忆式叙述(现在的我回忆过去的事),可以有现在的视角评论,但要清晰区分\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"我推开那扇门的时候,没有想到门后等着我的会是什么。\\n\\n屋子里很暗,窗帘拉得严严实实。我摸索着找到开关,灯亮的瞬间,我倒吸了一口冷气。\\n\\n墙上贴满了照片——全是我。\\n\\n我站在门口,后背泛起一层冷汗。这些照片有我在公司加班的,有我在超市买菜的,甚至有我在卧室里睡觉的。有人一直在跟踪我,而且已经很久了。\\n\\n我的手开始发抖,但我强迫自己冷静下来。我掏出手机准备报警,就在这时,身后传来了脚步声。\\n\\n很轻,很慢,但每一步都像踩在我的心脏上。\\n\\n我猛地转过身——\",\r\n \"note\": \"第一人称过去式:使用“我”视角,过去时态(推开/没有想到/找到/倒吸),直接展现主角的恐惧(冷汗/发抖/心脏上),无法知道跟踪者的想法\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"minSensoryTypes\": 3,\r\n \"sightRatio\": 0.45\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.4,\r\n \"sensorySignal\": 1.2,\r\n \"action\": 0.9,\r\n \"emotion\": 1.4,\r\n \"infoAdvance\": 0.9\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_pov\",\r\n \"option_id\": \"opt_pov_first_present\",\r\n \"option_name\": \"第一人称现在式\",\r\n \"option_description\": \"以“我”的视角叙述,使用现在时态。临场感极强,仿佛事件正在读者眼前发生,适合紧张刺激的悬疑、惊悚、沉浸式体验作品。\",\r\n \"system_prompt\": \"你使用第一人称现在式进行写作。叙述者是“我”,所有事件都用现在时态描述(“我走”“我看到”“我在想”),仿佛一切正在发生。这种时态带来极强的临场感和紧迫感,读者和主角同步经历事件,不知道下一秒会发生什么。你只能写“我”此刻的感知和想法,不能提前透露未来的信息(不能写“后来我才知道”“这是我最后一次见他”之类的话,因为在现在式中“我”不知道未来)。内心独白用现在式,感官体验正在发生,决定正在做出。注意时态绝对一致,不能出现过去式(除非角色正在回忆,可以短暂切换但要立即回到现在式)。\",\r\n \"constraints\": [\r\n \"叙述视角严格为第一人称“我”,时态严格为现在式\",\r\n \"只能写“我”此刻的感知,禁止提前透露未来信息\",\r\n \"禁止使用“后来”“之后”“那是我最后一次”等打破临场感的表述\",\r\n \"内心活动、感官体验、动作决定都用现在式表达\",\r\n \"回忆段落必须明确标记(如“我想起”),且不能过长,立即拉回现在\",\r\n \"他人心理只能通过当下的表情、动作、语言推测\",\r\n \"利用现在式优势:制造紧迫感、即时恐惧、临场决策的紧张感\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"我推开门。\\n\\n屋子里很暗,窗帘拉得严严实实。我的手沿着墙壁摸索,找到开关——\\n\\n灯亮了。\\n\\n我倒吸一口冷气。\\n\\n墙上贴满了照片。全是我。我在公司加班的样子,我在超市挑苹果的样子,甚至有我在卧室里睡觉的样子。有人在跟踪我,而且不是一天两天了。\\n\\n我的手在发抖。我强迫自己深呼吸,掏出手机。拨号,110——\\n\\n身后传来脚步声。\\n\\n很轻,很慢。但在这死寂的屋子里,每一步都像敲在我的太阳穴上。\\n\\n我猛地转身。\",\r\n \"note\": \"第一人称现在式:全程现在时态(推开/摸索/找到/倒吸/发抖/传来),临场感极强,没有事后回顾的距离感,读者和主角同步紧张\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"minSensoryTypes\": 3,\r\n \"sightRatio\": 0.45,\r\n \"shortSentenceRatio\": 0.6,\r\n \"targetSentenceLength\": 16,\r\n \"maxSentenceLength\": 40\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.5,\r\n \"sensorySignal\": 1.3,\r\n \"action\": 1.2,\r\n \"emotion\": 1.5,\r\n \"infoAdvance\": 0.8\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_pov\",\r\n \"option_id\": \"opt_pov_limited_third_past\",\r\n \"option_name\": \"有限第三人称过去式(默认)\",\r\n \"option_description\": \"以“他/她”称呼视角人物,使用过去时态,但只深入该人物的内心。这是网文中最常用的视角,兼顾代入感和叙事灵活性,是默认推荐选项。\",\r\n \"system_prompt\": \"你使用有限第三人称过去式进行写作——这是网文最主流的视角。你用“他”或“她”来称呼当前视角人物,用过去时态叙述事件,但只深入这一个人物的内心。你可以自由写这个人物的感受、想法、回忆、判断,但其他人物的内心你只能通过外在表现推测。这种视角的优势是比第一人称更灵活(可以稍微拉开一点距离描写),又比全知视角更有代入感。你可以在不同章节/场景切换视角人物,但同一个场景内必须锁定一个视角,不能跳来跳去。视角人物是读者的“眼睛”和“心”,读者通过他/她来感知故事。\",\r\n \"constraints\": [\r\n \"用“他/她”称呼视角人物,叙述用过去时态\",\r\n \"只能深入当前视角人物的内心,其他人物心理只能推测\",\r\n \"同一场景内视角锁定一个人物,不得随意切换\",\r\n \"可以跨章节/跨场景切换视角人物,但切换必须清晰(建议场景转换时切换)\",\r\n \"叙述信息受限于视角人物的认知,他/她不知道的不能直接写\",\r\n \"视角人物的选择很重要——要选当下冲突中最有张力的那个人\",\r\n \"禁止在有限第三人称中突然跳到全知视角\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"林晚推开包厢门的时候,里面已经坐满了人。\\n\\n她一眼就看到了坐在主位的男人。沈知行穿着一件深蓝色的衬衫,袖口挽到手肘,正侧着头听旁边的人说话,嘴角挂着一丝漫不经心的笑。\\n\\n三年了。\\n\\n林晚的手指不自觉地收紧,握在包带上的指节微微泛白。她以为自己已经做好了心理准备,可真正看到这个人的时候,心跳还是漏了一拍。\\n\\n\\\"林晚?这边坐。\\\"同事招呼她。\\n\\n她深吸一口气,走过去坐下,刻意选了个正对沈知行的位置——不,不对,她应该选离他最远的位置。可身体比理智诚实,等她反应过来的时候,已经在他对面了。\\n\\n沈知行抬起头,目光和她对上。\\n\\n他的眼神微微变了一下,但很快恢复平静,像是在看一个陌生人。\",\r\n \"note\": \"有限第三人称过去式:用“她”指林晚,深入她的内心(以为做好准备/心跳漏拍/身体比理智诚实),但沈知行的想法只能从“眼神微微变了”推测,不能直接写他心里在想什么\"\r\n }\r\n ],\r\n \"threshold_overrides\": {},\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.0,\r\n \"sensorySignal\": 1.0,\r\n \"action\": 1.0,\r\n \"emotion\": 1.0,\r\n \"infoAdvance\": 1.0\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_pov\",\r\n \"option_id\": \"opt_pov_limited_third_present\",\r\n \"option_name\": \"有限第三人称现在式\",\r\n \"option_description\": \"以“他/她”称呼视角人物,使用现在时态,只深入该人物内心。兼具临场感和叙事灵活性,适合需要紧张感又不想完全绑定“我”的作品。\",\r\n \"system_prompt\": \"你使用有限第三人称现在式进行写作。你用“他”或“她”称呼当前视角人物,用现在时态叙述,只深入这个人物的内心。这种视角结合了现在式的临场紧迫感和第三人称的叙事距离,比第一人称现在式稍微“冷静”一点,但仍然有很强的即时感。你可以写视角人物此刻的感受、想法、判断,但不能写其他人物的内心。同一场景视角锁定,不得跳切。所有动词用现在时态(走/看/想/听到/握紧),营造事件正在发生的效果。\",\r\n \"constraints\": [\r\n \"用“他/她”称呼视角人物,时态严格为现在式\",\r\n \"只能深入当前视角人物内心,其他人物心理只能推测\",\r\n \"同一场景视角锁定,不得随意切换到其他人物内心\",\r\n \"所有叙述动词用现在式,保持时态一致\",\r\n \"禁止透露视角人物此刻不可能知道的信息\",\r\n \"利用现在式制造临场紧张感,适合动作/悬疑场景\",\r\n \"回忆需明确引入(如“他想起”),且要快速回到当下\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"陈默推开铁门,锈迹斑斑的门轴发出刺耳的吱呀声。\\n\\n走廊里漆黑一片。他掏出手电筒,光柱切开黑暗,照亮了斑驳的墙壁和地上散落的纸屑。\\n\\n空气里有一股奇怪的味道,甜腻腻的,像是腐烂的花。\\n\\n他握紧手电筒,放慢脚步。心跳声在耳膜里轰轰作响,每走一步,地板就发出一声细微的嘎吱。\\n\\n走廊尽头有一扇门,门缝里透出微弱的光。\\n\\n陈默屏住呼吸,侧耳倾听——门后面有人在说话,声音很低,听不清在说什么。\\n\\n他伸手去推门。\\n\\n门没锁。\",\r\n \"note\": \"有限第三人称现在式:用“他”指陈默,现在时态(推开/掏出/照亮/握紧/屏住),深入他的感官和紧张感,但不知道门后面的情况,临场感强\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"shortSentenceRatio\": 0.55,\r\n \"targetSentenceLength\": 18,\r\n \"maxSentenceLength\": 45\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.2,\r\n \"sensorySignal\": 1.2,\r\n \"action\": 1.2,\r\n \"emotion\": 1.2,\r\n \"infoAdvance\": 0.9\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_pov\",\r\n \"option_id\": \"opt_pov_omniscient_third_past\",\r\n \"option_name\": \"全知第三人称过去式\",\r\n \"option_description\": \"以“他/她”称呼人物,使用过去时态,叙述者全知全能,可以进入任何人物内心,知晓一切。适合史诗、多线叙事、群像作品。\",\r\n \"system_prompt\": \"你使用全知第三人称过去式进行写作。叙述者像上帝一样全知全能,可以自由进入任何人物的内心,知道过去未来,可以俯瞰整个世界。你可以在一个段落里写A的想法,下一个段落写B的秘密,再下一段写千里之外C正在做什么。但要注意:全知不等于混乱,视角切换要有章法,不能在同一段里跳来跳去让读者困惑。最好的全知视角是“有节制的全知”——以某个人物为主要视角,在需要时切换到其他人物补充信息。全知视角适合宏大叙事、群像剧、史诗作品,可以展现多方势力博弈、信息差带来的戏剧性反讽。\",\r\n \"constraints\": [\r\n \"用“他/她/他们”称呼人物,叙述用过去时态\",\r\n \"可以进入任何人物的内心,但切换要有过渡,不能在一句话内跳切\",\r\n \"可以描写任何地点发生的任何事情,不限于某个人物的感知\",\r\n \"可以使用戏剧性反讽(读者知道角色不知道的信息)\",\r\n \"虽然全知,但主要叙事应围绕核心人物展开,避免信息散乱\",\r\n \"场景转换和视角切换要清晰,建议用段落分隔或场景标记\",\r\n \"避免“说教式”的全知叙述者——不要跳出来直接告诉读者道理,通过故事展现\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"建安十三年冬,曹操率八十万大军南下,驻扎在长江北岸。\\n\\n曹操站在旗舰的甲板上,江风猎猎,吹动他的袍角。他望着南岸连绵的营火,嘴角浮起一丝笑意——天下一统,就在此役了。他不知道的是,对面的周瑜此刻也正望着北岸,眼中同样燃烧着必胜的火焰。\\n\\n周瑜站在南岸的瞭望台上,身旁站着诸葛亮。两人各怀心思:周瑜想的是如何用苦肉计骗过曹操的细作,诸葛亮却已经在算东风何时到来。他们都知道这场仗的关键在于火攻,但谁也没有把全部计划告诉对方。\\n\\n而在更远的上游,庞统已经踏上了前往曹营的小船,准备去献上那条致命的连环计。\\n\\n三方博弈,各有布局。历史的车轮,已经开始转动。\",\r\n \"note\": \"全知第三人称过去式:可以写曹操的想法(他不知道的是),切换到周瑜和诸葛亮各怀心思,再跳到庞统的行动,俯瞰全局,展现多方博弈\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"maxExpositionContinuous\": 600,\r\n \"maxParagraphLength\": 300,\r\n \"targetParagraphLength\": 90,\r\n \"shortSentenceRatio\": 0.3,\r\n \"targetSentenceLength\": 28\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 0.8,\r\n \"sensorySignal\": 1.0,\r\n \"action\": 0.9,\r\n \"emotion\": 0.9,\r\n \"infoAdvance\": 1.5\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_pov\",\r\n \"option_id\": \"opt_pov_omniscient_third_present\",\r\n \"option_name\": \"全知第三人称现在式\",\r\n \"option_description\": \"以“他/她”称呼人物,使用现在时态,叙述者全知。较为少见的组合,适合实验性叙事或需要“上帝视角正在直播”感觉的作品。\",\r\n \"system_prompt\": \"你使用全知第三人称现在式进行写作。叙述者全知全能,可以进入任何人物内心,但所有事件都用现在时态描述,仿佛整个世界正在你眼前同时展开。这是一种较少见的视角组合,能创造出“上帝视角实时直播”的奇特效果——你可以同时看到千里之外的两个人在做什么,知道每个人此刻的想法,但一切都正在发生。这种视角适合需要同时展现多线并行、紧张倒计时、命运交汇的场景。注意不要因为全知而变得冷漠——即使能看到一切,也要让读者对人物产生共情。\",\r\n \"constraints\": [\r\n \"用“他/她/他们”称呼人物,时态严格为现在式\",\r\n \"可以进入任何人物内心,知道此刻任何地方正在发生的事\",\r\n \"所有叙述用现在式,营造“一切正在同时发生”的效果\",\r\n \"多线并行时切换要清晰,可以用分段或地点标记分隔\",\r\n \"适合倒计时、多线汇合、命运交错等场景\",\r\n \"虽然全知,但要保持情感温度,不能写成冷冰冰的新闻播报\",\r\n \"时态一致性要求极高,不得混入过去式(除非角色正在回忆)\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"炸弹的计时器跳到02:47,还在一秒一秒地减少。\\n\\n在商场一楼,李薇蹲在试衣间里,双手捂着嘴不敢出声。她听到外面有脚步声在靠近,靴子踩在碎玻璃上,发出咯吱咯吱的声响。\\n\\n同一时刻,地下停车场里,张磊正在拼命撬一辆白色面包车的车门。他的手在发抖——他知道车里有炸弹的引爆装置,如果不能在三分钟内拆除,整栋楼都会被炸成废墟。\\n\\n而在商场对面的楼顶,狙击手老赵已经瞄准了试衣间方向的窗户。他屏住呼吸,手指搭在扳机上,等待目标出现。\\n\\n三个人,三个位置,三条命运线,正在向同一个点汇聚。\\n\\n计时器跳到02:31。\",\r\n \"note\": \"全知第三人称现在式:现在时态(跳到/蹲/听到/撬/瞄准/屏住),同时展现三个地点三个人的行动,营造多线并行的紧张感和“上帝视角直播”效果\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"maxParagraphLength\": 120,\r\n \"targetParagraphLength\": 50,\r\n \"shortSentenceRatio\": 0.55,\r\n \"targetSentenceLength\": 18\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.0,\r\n \"sensorySignal\": 1.1,\r\n \"action\": 1.3,\r\n \"emotion\": 1.1,\r\n \"infoAdvance\": 1.3\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_rhetoric\",\r\n \"option_id\": \"opt_rhetoric_plain\",\r\n \"option_name\": \"克制平实\",\r\n \"option_description\": \"修辞克制,语言平实(默认)。少用比喻和华丽辞藻,靠精准的名词和动词打动人。大巧若拙。\",\r\n \"system_prompt\": \"修辞克制,语言平实。不刻意使用比喻、拟人、排比等修辞手法,除非自然涌现。文字的力量来自精准的名词和动词,而非修辞技巧。描写时直接写事物本身,不找替身。有时候,直接说「他哭了」比「泪水像断了线的珠子」更有力量。克制不是贫瘠,是选择——把力气用在最需要的地方。\",\r\n \"constraints\": [\r\n \"不刻意使用修辞,修辞自然出现才用\",\r\n \"优先用精准的名词和动词\",\r\n \"每千字比喻不超过3处\",\r\n \"禁止使用陈词滥调的修辞(心如刀割、泪如雨下等)\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"他蹲下来,把铜碗贴在壁上。\\n\\n碗壁凉了一瞬,然后慢慢变温。他等了很久。\\n\\n三下。\\n\\n短的。然后一下长的。\\n\\n是回应。\\n\\n他抬起头,矿灯照出前方巷道的轮廓。黑暗还是那个黑暗,但好像没那么沉了。\\n\\n他站起来,往深处走。\",\r\n \"note\": \"几乎没有修辞,用朴素的白描传递情感和信息,力量藏在克制中。\"\r\n }\r\n ],\r\n \"requires\": [],\r\n \"conflicts\": [\r\n \"opt_rhetoric_metaphor\",\r\n \"opt_rhetoric_ornate\"\r\n ]\r\n}","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_rhetoric\",\r\n \"option_id\": \"opt_rhetoric_metaphor\",\r\n \"option_name\": \"比喻密集\",\r\n \"option_description\": \"大量使用比喻(明喻、暗喻、借喻)来描写和叙事,语言形象生动,画面感强。\",\r\n \"threshold_overrides\": {\r\n \"maxSentenceLength\": 45,\r\n \"targetSentenceLength\": 24,\r\n \"shortSentenceRatio\": 0.3\r\n },\r\n \"radar_weights\": {\r\n \"sensorySignal\": 1.3,\r\n \"emotion\": 1.2,\r\n \"action\": 0.9\r\n },\r\n \"system_prompt\": \"善用比喻,让文字形象可感。描写人物、场景、情绪时,寻找新鲜贴切的比喻来替代直白描述。比喻要新颖,避免陈词滥调。明喻(像、如、仿佛)和暗喻(是、成了)交替使用。每个重要场景至少有一个核心比喻贯穿。比喻要为内容服务,不能为比喻而比喻——比喻的喻体应该比本体更容易被读者感知。\",\r\n \"constraints\": [\r\n \"比喻必须新鲜贴切,禁止陈词滥调\",\r\n \"每个重要场景至少有2处比喻\",\r\n \"喻体要具体可感,不使用抽象比喻抽象\",\r\n \"避免连续使用比喻导致阅读疲劳\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"黑暗像一块浸透了墨汁的棉絮,密不透风地裹住一切。矿灯的光柱是一把钝刀,割了几下,只割开一道口子,光就被吞掉了。\\n\\n他的心跳像一面被疯狂敲击的鼓,每一下都震得耳膜发疼。汗水从额角滑下来,像一群惊慌失措的虫子,顺着脸颊往下爬。\\n\\n恐惧是一只冰冷的手,从地底伸出来,攥住了他的后颈。\",\r\n \"note\": \"黑暗如棉絮、光柱如钝刀、心跳如鼓、汗水如虫、恐惧如手——比喻密集且新鲜。\"\r\n }\r\n ],\r\n \"requires\": [],\r\n \"conflicts\": [\r\n \"opt_rhetoric_plain\",\r\n \"opt_rhetoric_sketch\"\r\n ]\r\n}","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_rhetoric\",\r\n \"option_id\": \"opt_rhetoric_ornate\",\r\n \"option_name\": \"华丽辞藻\",\r\n \"option_description\": \"辞藻华丽,多用修辞和修饰语,语言绚烂夺目。适合唯美、宫廷、奇幻等追求文字美感的题材。\",\r\n \"threshold_overrides\": {\r\n \"maxSentenceLength\": 60,\r\n \"targetSentenceLength\": 30,\r\n \"shortSentenceRatio\": 0.2,\r\n \"maxParagraphLength\": 250\r\n },\r\n \"radar_weights\": {\r\n \"sensorySignal\": 1.3,\r\n \"emotion\": 1.3,\r\n \"action\": 0.7,\r\n \"infoAdvance\": 0.8\r\n },\r\n \"system_prompt\": \"辞藻华丽绚烂,善用丰富的修饰语、对仗、排比、通感等修辞技巧。词汇量丰富,用词讲究色彩感和音韵感。描写浓墨重彩,像油画一样铺陈。适合唯美场景、宫廷盛宴、奇幻世界等需要视觉冲击力的场景。但要注意华丽不能空洞——每个修饰语都要有用,不能是词语的堆砌。\",\r\n \"constraints\": [\r\n \"用词华丽但不空洞,每个修饰语都有存在的理由\",\r\n \"善用色彩、光影、声音等感官元素的铺陈\",\r\n \"修辞手法多样(比喻/拟人/排比/通感)\",\r\n \"避免辞藻堆砌导致内容空洞\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"那是一座用白玉和黄金筑就的宫殿,飞檐上盘踞着琉璃色的龙,在夕阳下折射出万千道金红色的光芒,仿佛整座建筑正在燃烧。殿门前的台阶是整块的汉白玉雕成,每一级都镂刻着缠枝莲纹,缝隙间镶嵌着细碎的绿松石和红珊瑚,远看如一条流淌着宝石的河流。殿内灯火辉煌,鎏金的灯柱上燃着儿臂粗的龙涎香烛,香烟袅袅,在半空中凝结成云雾的形状,将丝幔后的人影晕染得如同虚幻。\",\r\n \"note\": \"辞藻华丽,色彩绚烂,修辞丰富,但每个细节都在构建宫殿的奢华画面。\"\r\n }\r\n ],\r\n \"requires\": [],\r\n \"conflicts\": [\r\n \"opt_rhetoric_plain\",\r\n \"opt_rhetoric_sketch\"\r\n ]\r\n}","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_rhetoric\",\r\n \"option_id\": \"opt_rhetoric_sketch\",\r\n \"option_name\": \"白描\",\r\n \"option_description\": \"纯用白描手法,不用比喻、拟人等修辞,不用形容词修饰,纯以名词动词勾勒。极简主义,返璞归真。\",\r\n \"threshold_overrides\": {\r\n \"maxSentenceLength\": 25,\r\n \"targetSentenceLength\": 15,\r\n \"shortSentenceRatio\": 0.6,\r\n \"maxParagraphLength\": 80\r\n },\r\n \"radar_weights\": {\r\n \"sensorySignal\": 0.8,\r\n \"emotion\": 0.9,\r\n \"action\": 1.2,\r\n \"infoAdvance\": 1.1\r\n },\r\n \"system_prompt\": \"纯用白描手法。不使用比喻、拟人、夸张、排比等任何修辞手法。不用形容词修饰名词,不用副词修饰动词。只用名词和动词,像中国画的白描一样,用线条勾勒事物。不解释、不评价、不渲染,只呈现。留最大的空间给读者。文字的力量来自精确的名词动词组合和节奏控制。\",\r\n \"constraints\": [\r\n \"禁止使用所有修辞手法(比喻/拟人/夸张/排比等)\",\r\n \"尽量不用形容词和副词\",\r\n \"只用名词和动词构建句子\",\r\n \"不解释情绪,不评价事物,只呈现事实\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"日出。\\n\\n门开了。\\n\\n他走出来。\\n\\n身上有伤。\\n\\n手里有刀。\\n\\n刀上有血。\\n\\n他抬头。\\n\\n天很亮。\\n\\n他站了很久。\\n\\n然后他走了。\",\r\n \"note\": \"纯名词动词,没有修辞,没有修饰,像水墨画的留白,言简意丰。\"\r\n }\r\n ],\r\n \"requires\": [],\r\n \"conflicts\": [\r\n \"opt_rhetoric_metaphor\",\r\n \"opt_rhetoric_ornate\"\r\n ]\r\n}","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_sentence_rhythm\",\n \"option_id\": \"opt_rhythm_short\",\n \"option_name\": \"短句为主\",\n \"option_description\": \"以短句(<=15字)为主导节奏,干脆利落,像鼓点般敲击。适合紧张场景、动作场面和快节奏叙事,也是矿工风格核心节奏。\",\n \"threshold_overrides\": {\n \"maxSentenceLength\": 20,\n \"targetSentenceLength\": 12,\n \"shortSentenceRatio\": 0.7,\n \"maxParagraphLength\": 120,\n \"targetParagraphLength\": 50\n },\n \"radar_weights\": {\n \"action\": 1.3,\n \"emotion\": 1.1,\n \"infoAdvance\": 0.9,\n \"sensorySignal\": 1.1\n },\n \"system_prompt\": \"短句节奏的核心是'一击即中'。每句话只传递一个信息点,像出拳、像鼓点、像心跳。读者没有喘息空间,紧张感自然生成。具体技法:\\n\\n1. 单信息原则:每句话只写一个动作、一个感官、一个念头。不要把两个动作塞进同一句。'他转身,拔出刀'要拆成'他转身。''拔出刀。'。句号就是停顿,停顿就是重量。\\n\\n2. 断句要狠:能用句号就不用逗号,能拆成两句就不合成一句。'他看见老李倒在地上,胸口在流血'要拆成'老李倒在地上。''胸口在流血。'。每一句单独成段,冲击力翻倍。\\n\\n3. 名词动词优先:短句中少用形容词和副词。用名词和名词、动词和名词直接碰撞。'刀很快。''血很热。''墙很硬。'不需要修饰,事实本身就有力量。\\n\\n4. 留白制造重音:关键瞬间前后加空行或极短句(1-3字)。'他抬头。''一个字。''死。'单独成段,像锤子砸下来。\\n\\n5. 节奏变化:全是短句也会疲劳。每10-15句短句后,可以插入一句稍长的句子(20-25字)作为节奏调剂,但立刻回到短句。长句是为了让接下来的短句更有力。\\n\\n6. 感官碎片化:把感官体验拆成碎片——不是'他听到巨大的爆炸声感到一阵剧痛',而是'声音来了。''耳朵嗡的一下。''疼。''什么都看不见。'。碎片化更接近人在极端状态下的真实感知。\\n\\n7. 禁止解释:短句不解释。不说'因为瓦斯浓度太高所以他们必须撤退',只写'瓦斯响了。''走。'。读者自己会连起来。\",\n \"constraints\": [\n \"单句原则上不超过20字,90%句子在15字以内\",\n \"短句(15字以内)占比70%以上\",\n \"禁止连续3句以上超过15字的句子\",\n \"每200字至少有1处1-3字的极短句单独成段作为重音\",\n \"避免使用分号连接多个分句,少用破折号和省略号\",\n \"动作场景中每句只包含一个动作,禁止连动句('他转身拔出刀冲出去'必须拆开)\",\n \"形容词和副词使用密度不超过每100字3个\",\n \"段落长度控制在3-5句以内,关键动作可以一句一段\"\n ],\n \"examples\": [\n {\n \"text\": \"瓦斯报警响了。\\n\\n不是预警。是那种持续的、尖锐的、要命的响声。\\n\\n他抬头看仪表。\\n\\n浓度1.8%。\\n\\n超了。\\n\\n老李还在前面刨煤。没听见。\\n\\n他抓起矿灯往那边照。光柱晃了两下,照见老李的背影,弓着,像只虾。\\n\\n「老李!」\\n\\n没反应。\\n\\n风停了。\\n\\n他知道这意味着什么。通风管一停,瓦斯三分钟就能到爆炸浓度。\\n\\n他站起来。膝盖撞到横梁,疼。顾不上。\\n\\n「走!」\\n\\n他往前跑。靴底踩在碎煤上滑了一下,手扶住壁面,壁面是烫的。\\n\\n不对。\\n\\n他停下。\\n\\n不是烫。\\n\\n是在震。\\n\\n很轻。从很深的地方传上来。像什么东西在里面翻身。\\n\\n他回头看。\\n\\n通道口的方向,有光。\\n\\n不是矿灯的光。\\n\\n是红的。\",\n \"note\": \"短句节奏示范:整段平均句长不超过10字,关键节点用1-3字极短句('超了。''不对。''走。''是红的。')单独成段制造重音。每句一个信息点:报警响了→看仪表→浓度1.8%→老李没听见→风停了→壁面烫→在震→有红光。读者跟着句子节奏一起紧张,没有一句解释为什么危险,读者自己懂。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": [\n \"opt_rhythm_long\"\n ]\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_sentence_rhythm\",\n \"option_id\": \"opt_rhythm_medium\",\n \"option_name\": \"中句为主\",\n \"option_description\": \"以中句(15-30字)为主导节奏,平稳流畅,兼顾信息密度和阅读舒适度。适合日常叙事、对话和过渡段落,是通用小说的默认节奏。\",\n \"threshold_overrides\": {\n \"maxSentenceLength\": 35,\n \"targetSentenceLength\": 22,\n \"shortSentenceRatio\": 0.35,\n \"maxParagraphLength\": 180,\n \"targetParagraphLength\": 80\n },\n \"radar_weights\": {\n \"action\": 1.0,\n \"emotion\": 1.0,\n \"infoAdvance\": 1.0,\n \"sensorySignal\": 1.0,\n \"bodyReaction\": 1.0\n },\n \"system_prompt\": \"中句节奏的核心是'自然呼吸'。像人正常说话的语速,不快不慢,信息传递流畅,读者读起来不费劲。这是最通用、最不容易出错的节奏,适合80%的叙事场景。具体技法:\\n\\n1. 主谓宾清晰:句子结构简单明了,主语+谓语+宾语,最多加一个修饰成分。不要多层从句嵌套,不要倒装句搞花活。'他从口袋里掏出烟,递了一根给老周'就很好,不要写成'从那个被磨得发白的帆布工作服口袋里,他掏出了一包已经被挤压得变形的红塔山,用手指夹出一根递向坐在对面凳子上的老周'。\\n\\n2. 一句一义:虽然比短句长,但一句话仍然只讲一个核心意思。可以带修饰,但不要同时讲动作+心理+环境三件事。环境单独成句,心理单独成句,动作单独成句。\\n\\n3. 逗号断句合理:一句话内逗号不超过3个。超过3个逗号说明你塞了太多东西,该拆成两句。'他推开门,看见屋里坐满了人,都是熟面孔,老张小李老王都在,桌上摆着酒菜'——这句子太长,拆成两句。\\n\\n4. 节奏调剂:中句为主,但不是全中句。每5-8句中句后,插1句短句(5-10字)作为顿点,插1句稍长的句子(30-35字)作为舒展。这样读起来有起伏,不会像白开水。\\n\\n5. 对话适配:对话本身就是中句长度(人说话不会一个字一个字蹦,也不会一口气说50字),对话标签和动作描写也用中句,整体协调。\\n\\n6. 描写克制:中句节奏下描写要精准,不要铺陈。写一个细节就够了,不要写三个。'他手上有疤'比'他那只粗糙的、布满老茧的、指节粗大的手上有一道长长的、暗红色的疤痕'有力。\\n\\n7. 段落呼吸:每段4-8句,段与段之间有空行。手机屏幕上一段大约占2-3行,读起来舒服。不要一整屏不分段,也不要一句一段搞得像写诗。\",\n \"constraints\": [\n \"单句原则上不超过35字,80%句子在15-30字之间\",\n \"一句话内逗号不超过3个,超过必须拆句\",\n \"超过30字的句子不得连续出现3句以上\",\n \"每300字至少有1句10字以内的短句作为节奏顿点\",\n \"避免多层从句嵌套('的'字连用不超过2次)\",\n \"避免过多使用破折号和省略号,句号和逗号为主\",\n \"段落长度控制在4-8句,手机阅读2-3行为宜\",\n \"形容词使用克制,每句不超过2个修饰词\"\n ],\n \"examples\": [\n {\n \"text\": \"陈默下了夜班,从矿里出来的时候天已经黑透了。\\n\\n澡堂的水不热,凑合冲了冲,换上干净衣服。口袋里还有半包烟,是前天老周给的。他抽出一根点上,深深吸了一口。\\n\\n食堂已经关门了。他在门口的小卖部买了两个茶叶蛋,一瓶啤酒,靠在墙上慢慢吃。风有点大,吹得路边的塑料垃圾袋哗哗响。\\n\\n远处有人在吵架,听不清在吵什么,只听见女人的哭声和男人的骂声。陈默没往那边看。这种事在矿区天天有,没什么新鲜的。\\n\\n吃完茶叶蛋,他把蛋壳装进塑料袋里,扔进垃圾桶。啤酒还剩半瓶,他握在手里,凉冰冰的。\\n\\n手机在口袋里震了一下。他掏出来看,是一条短信,陌生号码。\\n\\n「你妈病重,速回。」\\n\\n他盯着这五个字看了很久。烟烧到手指,他才反应过来,把烟头扔在地上踩灭。\\n\\n啤酒没喝完。他把剩下的半瓶倒进了路边的水沟里。\",\n \"note\": \"中句节奏示范:平均句长20字左右,句子结构简单,读起来流畅自然。关键信息点('你妈病重,速回。')用短句单独成段制造重音,前后都是平稳的中句铺垫。环境描写(风/垃圾袋/吵架声)点到为止,不铺陈。没有华丽辞藻,但信息完整,情绪到位。这就是大众最容易接受的小说语言。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": []\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_sentence_rhythm\",\n \"option_id\": \"opt_rhythm_mixed\",\n \"option_name\": \"长短交错\",\n \"option_description\": \"长短句交错使用,节奏有起伏变化(推荐默认)。紧张时短促,舒缓时绵长,形成自然的呼吸节奏,文学性和可读性兼顾。\",\n \"threshold_overrides\": {\n \"maxSentenceLength\": 60,\n \"targetSentenceLength\": 22,\n \"shortSentenceRatio\": 0.4,\n \"maxParagraphLength\": 200,\n \"targetParagraphLength\": 100\n },\n \"radar_weights\": {\n \"action\": 1.0,\n \"emotion\": 1.2,\n \"infoAdvance\": 1.0,\n \"sensorySignal\": 1.2,\n \"bodyReaction\": 1.1\n },\n \"system_prompt\": \"长短交错是最有音乐感的节奏,核心是'对比产生力量'。短句是鼓点,长句是旋律;短句是拳头,长句是呼吸;短句是惊雷,长句是云层。二者交替出现,读者的情绪跟着节奏起伏。具体技法:\\n\\n1. 场景匹配节奏:动作/紧张/震惊场景用短句,描写/抒情/回忆场景用长句,对话用中句。同一场景内也要有变化——打斗中突然插入一句长句描写环境,反而更衬得紧张;抒情中突然砸下一个短句,反而更戳人。\\n\\n2. 长句铺陈,短句砸点:用1-3句长句(40-60字)把氛围铺足、把细节写够,然后用1句极短句(1-5字)砸下核心信息。比如长句写风怎么吹、树怎么摇、天怎么黑,然后短句——'雨来了。'。对比感瞬间出来。\\n\\n3. 段落内部呼吸:一个段落里要有长有短,不能全是长句(读着累),也不能全是短句(读着慌)。理想结构:开头长句入场景→中间中句推进→结尾短句收束/留悬念。\\n\\n4. 单字/两字句的用法:极短句(1-3字)不能随便用,要用在刀刃上——情绪转折点、关键信息揭示、动作定格。一章里用5-8次就够了,用多了就没效果了。用之前先用长句把张力拉满。\\n\\n5. 长句要'通':长句不是凑字数,要有内在韵律。通过逗号、顿号制造停顿,像呼吸一样。长句里要有画面流动——从远到近,从外到内,从视觉到听觉到触觉,读者跟着句子走,不觉得累。\\n\\n6. 节奏加速减速:要紧张的时候,句子越来越短,段落越来越碎;要舒缓的时候,句子慢慢拉长,段落慢慢变宽。像音乐的渐强渐弱,自然过渡,不要突然切换。\\n\\n7. 对话节奏:对话本身是短的,对话前后的描写可以长一点,形成'长-短-长'的波纹结构。比如:长句写人物怎么走进来、什么表情→短对话→长句写人物说完后的动作/环境变化。\",\n \"constraints\": [\n \"段落内部必须有长短句变化,禁止连续5句以上相同长度区间的句子\",\n \"动作场景短句比例提高到60%以上,抒情/回忆场景长句比例提高到50%以上\",\n \"每1000字至少有3-5处极短句(1-5字)作为节奏重音,且必须在长句铺垫之后\",\n \"长句(40字以上)内部必须有至少2个逗号停顿,禁止一逗到底\",\n \"单句不超过60字,超过必须拆成两句\",\n \"节奏转换要自然——紧张段到舒缓段之间至少有2句中句过渡,不要跳崖式切换\",\n \"段落长度根据节奏调整:紧张段3-5句,舒缓段5-8句,关键瞬间可以1句一段\",\n \"对话前后必须有动作/神态描写,形成'描写-对话-描写'的节奏单元\"\n ],\n \"examples\": [\n {\n \"text\": \"老陈蹲在巷道壁边,把矿灯拧到最暗,只留一点黄豆大的光映在脚下的碎煤上。通风管早就停了,空气里弥漫着一股淡淡的、甜丝丝的味道,像烂苹果,他知道那是瓦斯。\\n\\n温度计插在壁缝里,红色液柱爬得很慢,每动一格都像在拽他的神经。\\n\\n35.9。\\n\\n36.1。\\n\\n36.4。\\n\\n他数着自己的呼吸。吸气四秒,憋气两秒,呼气六秒,这是老矿工教他的办法,能在氧气不足的时候多撑一会儿。巷壁深处传来很轻的震颤,不是矿震,矿震不是这个频率,这个更沉,更慢,像什么巨大的东西在很深很深的地方翻了个身。\\n\\n老李在他旁边坐着,背靠着壁,头垂着,已经很久没动了。右胳膊肿得像大腿那么粗,皮肤下面透着一种发亮的青紫色,那是坏疽的颜色。他还有气,胸口每隔很久才起伏一下,弱得像风中的烛火。\\n\\n老陈摸了摸口袋。半块压缩饼干,一个打火机,矿灯电量31%。\\n\\n水还剩两口。\\n\\n他把铜碗端起来,凑到老李嘴边,倾斜了一点。水顺着老李的嘴角流下来,没咽下去。\\n\\n老陈把碗收回来,自己喝了剩下的一口。水是温的,有股铁锈味。\\n\\n黑暗里,那个震颤又来了。\\n\\n这次更近了。\",\n \"note\": \"长短交错示范:开头用长句铺陈环境(瓦斯味道/温度计/呼吸方法/壁震),然后用3个极短句('35.9。''36.1。''36.4。')制造紧张感,接着又回到长句描写老李的状态,再用短句('半块压缩饼干...''水还剩两口。')交代物资,最后结尾'这次更近了。'一个短句收束,余味十足。长短交替像海浪一样,读者的情绪跟着起伏。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": []\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_sentence_rhythm\",\n \"option_id\": \"opt_rhythm_long\",\n \"option_name\": \"长句为主\",\n \"option_description\": \"以长句(30字+)为主导节奏,适合文学性描写、铺陈氛围和内心独白。句子绵长悠远,有散文质感,适合文艺、言情、乡土题材。\",\n \"threshold_overrides\": {\n \"maxSentenceLength\": 80,\n \"targetSentenceLength\": 40,\n \"shortSentenceRatio\": 0.15,\n \"maxParagraphLength\": 300,\n \"targetParagraphLength\": 150\n },\n \"radar_weights\": {\n \"sensorySignal\": 1.3,\n \"emotion\": 1.3,\n \"action\": 0.7,\n \"infoAdvance\": 0.8,\n \"bodyReaction\": 1.1\n },\n \"system_prompt\": \"长句节奏的核心是'沉浸感'。像河水慢慢流淌,像镜头慢慢推移,读者跟着句子进入场景,被氛围包裹。长句不是啰嗦,是绵密,是一层一层把情绪织进去。具体技法:\\n\\n1. 画面流动:长句要有镜头感——从远到近,从整体到细节,从视觉到听觉到嗅觉触觉,句子像摄像机一样移动,读者跟着走。'暮色从远山外暗暗袭来,山色一刻儿深赭,一刻儿淡青,缓缓地、沉重地压在村庄上空,把最后一缕炊烟也染成了灰蓝色'——镜头从远到近,从视觉到氛围,有流动感。\\n\\n2. 呼吸感:长句内部必须有停顿,逗号、顿号就是呼吸。每8-12个字要有一个停顿,不能一逗到底。读的时候能自然换气,像唱歌有节拍。停顿本身就是节奏,不是卡壳。\\n\\n3. 修饰语层次:形容词和定语不是堆砌,是分层。第一层写整体印象,第二层写具体细节,第三层写主观感受。不要把三个形容词堆在名词前面,要拆开,用逗号隔开,像涟漪一圈一圈荡开。\\n\\n4. 情绪递进:长句内部情绪要有递进,不是平铺直叙。开始淡,中间浓,结尾收。句子越长,结尾越要有力,最后几个字要落在实处,不能飘。\\n\\n5. 短句重音:全是长句会闷。每3-5句长句后,插1句短句(5-15字)作为呼吸口,也作为重音。长句铺了半天,一个短句砸下来,效果翻倍。就像交响乐里突然所有乐器停了,只剩一把小提琴拉一个音。\\n\\n6. 感官串联:长句适合写通感——视觉和听觉连在一起,触觉和嗅觉连在一起。'风里有晚香玉的味道,还有远处河水的腥气,凉丝丝地贴在脸上,像谁的手'——多种感官串在一句里,沉浸感就出来了。\\n\\n7. 内心独白适配:人物的思绪是绵延不断的,适合用长句。回忆、联想、情绪翻涌,句子跟着思绪走,不要拆得太碎。但情绪激烈的念头仍然要用短句,形成对比。\\n\\n8. 禁忌:禁止空话套话('岁月静好''时光荏苒''百感交集'),禁止堆砌华丽辞藻却没有实际画面,禁止为了长而长把一句能说清的话扯成三句。长句是为了更好地传递情绪和画面,不是为了显得有文采。\",\n \"constraints\": [\n \"长句(30字+)占比50%以上,但不超过80%,必须有短句调剂\",\n \"单句原则上不超过80字,超过必须拆成两句(除非是刻意设计的情绪高潮句)\",\n \"长句内部每8-15字至少有一个逗号停顿,禁止一逗到底\",\n \"每200字至少有1句15字以内的短句作为呼吸口和重音\",\n \"每句必须有具体画面或感官细节,禁止空洞抒情('他心中五味杂陈''气氛十分尴尬'这类空话禁止出现)\",\n \"形容词连用不超过3个,且必须是不同维度的修饰(不要'美丽的漂亮的好看的'这种同义词堆砌)\",\n \"动作描写仍然要干脆,不要把快速动作拖成长句(打斗、奔跑、震惊反应必须用短句)\",\n \"段落长度控制在5-10句,手机阅读4-6行为宜,不要一整屏不分段\"\n ],\n \"examples\": [\n {\n \"text\": \"雨是从后半夜开始下的,先是淅淅沥沥地打在棚顶的油毡纸上,声音很轻,像谁在外面用手指一下一下弹着,后来就渐渐密了,大了,顺着棚顶的缝隙渗下来,在墙角积成一小滩一小滩浑浊的水洼,映着矿灯那点昏黄的光,一晃一晃的。\\n\\n他躺在草垫子上,听着雨声,没有睡着。后背贴着冰凉的地面,潮气从衣服缝里钻进来,一点一点吸走身体里的热气,他能感觉到自己的体温在慢慢下降,像沙漏里的沙子,一粒一粒往下漏,拦不住。\\n\\n旁边的老李已经很久没出声了。他不知道老李是睡着了还是醒着,是活着还是已经走了,黑暗里什么都看不见,只有老李那边传来的、很轻很轻的呼吸声,像风里抖动的蛛丝,稍一用力就会断。\\n\\n他想起很多年前的一个夏天,也是这样的雨,他还在老家,院子里的石榴树被雨打落了一地花,红红的,铺在青石板上,母亲坐在门槛上择菜,雨水顺着屋檐滴下来,在她面前的台阶上砸出一排小小的坑。\\n\\n那时候他还觉得日子很长。\\n\\n他翻了个身,草垫子发出细碎的响声。铜碗在他手边,碗里还剩一点点水,他端起来喝了,水是凉的,带着点铜锈的涩味,顺着喉咙滑下去,像一条冰冷的小蛇。\\n\\n外面的雨还在下。\",\n \"note\": \"长句节奏示范:开头用长句铺陈雨声的变化(从淅淅沥沥到密了大了),感官细节丰富(视觉/听觉/触觉),画面流动。中间插入回忆段也是长句,营造绵延感。关键情绪点用短句('那时候他还觉得日子很长。''外面的雨还在下。')收束,形成对比。长句里有停顿,读起来不费劲,能感受到那种慢慢下沉的绝望和回忆里的温暖。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": [\n \"opt_rhythm_short\"\n ]\n}\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_strictness\",\r\n \"option_id\": \"opt_strict_lenient\",\r\n \"option_name\": \"宽松(新手模式)\",\r\n \"option_description\": \"检测严格度宽松,适合新手作者。各项检测阈值放宽,只标记严重问题(如逻辑矛盾、视角混乱),对小问题只做提示不报错。让新手先写出来再说。\",\r\n \"system_prompt\": \"你使用宽松检测模式,适合写作新手。在这个模式下,检测阈值全面放宽:填充词上限提高、锚点密度要求降低、段落长度限制放松、句式变化要求降低。只标记严重问题——视角混乱、逻辑矛盾、时间线错误、人设崩塌等硬伤。对于小问题(轻微填充、个别长句、偶尔重复)只给温和提示,不作为错误。核心原则:让新手先把故事写出来,建立写作信心,不要一上来就用一堆规则把人吓跑。反馈以鼓励为主,建议要具体可操作,一次不要提太多问题。\",\r\n \"constraints\": [\r\n \"只标记严重错误:视角混乱/逻辑矛盾/时间线错误/人设崩塌\",\r\n \"轻微问题(个别填充词/偶发长句/少量重复)只提示不报错\",\r\n \"反馈以鼓励为主,每次最多指出3个需要改进的点\",\r\n \"建议必须具体可操作,不说空话(不说“写得更好”,说“这里可以加一个动作”)\",\r\n \"允许新手试错,不要用专业作者的标准要求\",\r\n \"段落长度、句长、填充词等阈值全面放宽50%\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"宽松模式反馈示例:\\n\\n【做得好的地方】\\n- 主角登场有记忆点,金手指设定清晰\\n- 对话自然,人物性格通过语言体现出来了\\n\\n【可以改进的地方】\\n1. 第三段连续300字都是背景介绍,建议穿插一点主角的动作或反应,让读者不觉得在“听课”\\n2. 章末的钩子很吸引人!不过可以再加一句主角的身体反应(比如心跳加速、手攥紧了),让紧张感更强\\n\\n继续写,故事开头已经抓住我了!\",\r\n \"note\": \"宽松模式:以鼓励为主,每次只提2-3个具体建议,反馈友好\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"minAnchors\": 2,\r\n \"anchorsPerWords\": 1000,\r\n \"maxAnchorGap\": 1500,\r\n \"maxFillerSentences\": 6,\r\n \"maxFillerWords\": 15,\r\n \"maxDashCount\": 6,\r\n \"maxEllipsisCount\": 6,\r\n \"maxParagraphLength\": 300,\r\n \"targetParagraphLength\": 100,\r\n \"minParagraphCount\": 10,\r\n \"maxDialogueContinuous\": 8,\r\n \"maxDialogueTagRepeat\": 4,\r\n \"maxSentenceLength\": 100,\r\n \"targetSentenceLength\": 28,\r\n \"shortSentenceRatio\": 0.25,\r\n \"maxExpositionContinuous\": 600,\r\n \"infoPointsPerThousand\": 1,\r\n \"minSensoryTypes\": 1,\r\n \"sightRatio\": 0.8\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 0.8,\r\n \"sensorySignal\": 0.8,\r\n \"action\": 0.8,\r\n \"emotion\": 0.8,\r\n \"infoAdvance\": 0.8\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_strictness\",\r\n \"option_id\": \"opt_strict_standard\",\r\n \"option_name\": \"标准(默认)\",\r\n \"option_description\": \"检测严格度标准,使用默认阈值。适合有一定写作经验的作者,平衡质量要求和创作自由度,指出问题但不过度苛责。\",\r\n \"system_prompt\": \"你使用标准检测模式,使用默认阈值。在这个模式下,所有检测项使用标准阈值,既不放宽也不收紧。会标记明显的问题——填充词超标、锚点不足、段落过长、对话连续无穿插、视角轻微漂移、信息密度不足等。严重问题(逻辑矛盾、人设崩塌、视角混乱)会明确指出,中等问题(填充、节奏、描写)给出具体建议,小问题(个别词汇选择、句式微调)作为优化提示。反馈客观公正,有好说好有问题说问题,给出可操作的改进建议。\",\r\n \"constraints\": [\r\n \"使用默认阈值检测所有项目\",\r\n \"严重问题明确指出并给出修改方案\",\r\n \"中等问题具体说明位置和改进建议\",\r\n \"小问题作为优化提示,不强制修改\",\r\n \"每次反馈指出优点和不足,保持客观\",\r\n \"建议具体可操作,一次指出的问题不超过5个\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"标准模式反馈示例:\\n\\n【综合评分】72/100\\n\\n【亮点】\\n- 主角与反派的对话张力不错,一来一回有博弈感\\n- 环境描写和情绪结合得好,雨中对峙的氛围到位\\n\\n【需要修改】(error/warning)\\n1. 第五段连续320字纯说明,超过300字上限,建议拆分或插入角色反应\\n2. 第1200-1800字区间没有身体锚点,间隔超过800字,建议在对话中加入动作描写\\n3. “他冷冷道”连续出现4次,对话标签重复,建议替换为其他表达方式\\n\\n【优化建议】(info)\\n- 第二章开头可以考虑用一个感官细节切入,比直接叙述更有画面感\\n- 结尾的钩子已经有了,但如果加一个环境异变(如雷声/灯闪)会更有悬念\",\r\n \"note\": \"标准模式:客观公正,分级标记问题(error/warning/info),建议具体\"\r\n }\r\n ],\r\n \"threshold_overrides\": {},\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.0,\r\n \"sensorySignal\": 1.0,\r\n \"action\": 1.0,\r\n \"emotion\": 1.0,\r\n \"infoAdvance\": 1.0\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_strictness\",\r\n \"option_id\": \"opt_strict_strict\",\r\n \"option_name\": \"严格(老作者模式)\",\r\n \"option_description\": \"检测严格度收紧,适合有经验的老作者追求精品。阈值收紧,任何不达标的地方都会被标记,包括细微的节奏问题、用词不准、句式单调等。\",\r\n \"system_prompt\": \"你使用严格检测模式,适合追求精品的老作者。在这个模式下,检测阈值全面收紧,所有问题——无论大小——都会被标记。填充词零容忍(超过低限即报错),锚点必须到位,段落长度严格控制,句式变化有要求,对话标签不能重复,信息密度必须达标,感官描写不能偏废(视觉占比过高也要改),甚至会检查用词精准度(“走”和“踱”的区别、“看”和“瞥”的差异)、句式节奏(长短句搭配)、情绪递进是否合理等。对老作者来说,这些细节决定作品是“还行”还是“精品”。\",\r\n \"constraints\": [\r\n \"使用收紧的阈值检测所有项目\",\r\n \"所有问题都会被标记,包括细微问题\",\r\n \"填充词零容忍,超过即报错\",\r\n \"用词精准度纳入检测(近义词选择是否恰当)\",\r\n \"句式节奏纳入检测(长短句搭配、连续相同句式)\",\r\n \"情绪递进必须有层次,不能跳变\",\r\n \"感官描写不能偏废,视觉占比不能过高\",\r\n \"每个反馈都要有具体位置和修改方向,不模糊说“这里不好”\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"严格模式反馈示例:\\n\\n【综合评分】61/100\\n\\n【Error-必须修改】\\n1. 第3段“他非常生气,简直怒不可遏,心中的怒火简直要燃烧起来”——同一种情绪重复表达3次,填充严重。改为一个精准动作或一个细节即可,如“他把筷子折断了”\\n2. 第800-1400字区间零锚点,读者失去身体连接。建议在对峙场景中加入:手指关节发白/后槽牙咬紧/呼吸变粗\\n3. POV漂移:第5段进入了反派内心(“他不知道的是……”),当前视角是主角的有限第三人称,这里视角越界\\n\\n【Warning-建议修改】\\n4. 连续7句以“他”开头,句式单调。建议变换主语或使用倒装\\n5. “看了一眼”出现3次,用词单一。根据语境替换为:瞥/扫/瞄/凝视/打量/扫视\\n6. 视觉描写占比78%,听觉触觉为零。对峙场景加入:拳头攥紧的咯吱声/冷气灌入领口/对方声音里的金属质感\\n\\n【Info-优化方向】\\n7. 情绪转折从“平静”到“暴怒”缺少过渡层次,建议增加“疑惑→警觉→愤怒”的递进\\n8. 长短句比例失衡,战斗段落全是短句会显得单调,建议在连续短句后插入一个长句做节奏呼吸\",\r\n \"note\": \"严格模式:所有问题都标记,包括用词、句式、节奏等细节问题,反馈精准到位置和修改方案\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"minAnchors\": 6,\r\n \"anchorsPerWords\": 350,\r\n \"maxAnchorGap\": 600,\r\n \"maxFillerSentences\": 2,\r\n \"maxFillerWords\": 5,\r\n \"maxDashCount\": 2,\r\n \"maxEllipsisCount\": 2,\r\n \"maxParagraphLength\": 150,\r\n \"targetParagraphLength\": 60,\r\n \"minParagraphCount\": 28,\r\n \"maxDialogueContinuous\": 3,\r\n \"maxDialogueTagRepeat\": 1,\r\n \"maxSentenceLength\": 50,\r\n \"targetSentenceLength\": 20,\r\n \"shortSentenceRatio\": 0.45,\r\n \"maxExpositionContinuous\": 200,\r\n \"infoPointsPerThousand\": 4,\r\n \"minSensoryTypes\": 3,\r\n \"sightRatio\": 0.55\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.2,\r\n \"sensorySignal\": 1.2,\r\n \"action\": 1.2,\r\n \"emotion\": 1.2,\r\n \"infoAdvance\": 1.2\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_target_length\",\r\n \"option_id\": \"opt_length_1500\",\r\n \"option_name\": \"1500字短章\",\r\n \"option_description\": \"单章目标字数1500字左右的短章节。适合快节奏平台(如番茄免费小说)、碎片化阅读场景,每章一个小事件或一个小转折。\",\r\n \"system_prompt\": \"你以1500字左右为单章目标字数写作。短章要求精炼高效,每一个字都要有用。开篇直接进入场景或冲突,不要冗长铺垫。一章只讲一个小事件或一个小转折,结尾必须留钩子让读者想看下一章。对话和动作占比要高,减少大段描写和心理独白。段落要短,适合手机快速阅读。1500字大约是5-8分钟的阅读时间,要在这个篇幅内完成“引入-发展-钩子”的完整小弧线。\",\r\n \"constraints\": [\r\n \"单章字数控制在1300-1700字之间\",\r\n \"开篇100字内进入场景或冲突\",\r\n \"一章只聚焦一个小事件/小转折\",\r\n \"对话和动作占比不低于60%\",\r\n \"单段不超过80字\",\r\n \"结尾必须留钩子\",\r\n \"禁止超过150字的纯描写或心理独白\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"1500字短章结构示例:\\n- 开头(100字):直接进入冲突场景\\n- 发展(1100字):对话推进+动作描写+小转折\\n- 钩子结尾(300字):悬念/反转/新信息出现,戛然而止\",\r\n \"note\": \"短章结构:快速入题,紧凑推进,钩子结尾\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"maxParagraphLength\": 80,\r\n \"targetParagraphLength\": 40,\r\n \"minParagraphCount\": 25,\r\n \"maxExpositionContinuous\": 150,\r\n \"infoPointsPerThousand\": 4,\r\n \"shortSentenceRatio\": 0.55,\r\n \"targetSentenceLength\": 18\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.1,\r\n \"sensorySignal\": 0.8,\r\n \"action\": 1.3,\r\n \"emotion\": 1.1,\r\n \"infoAdvance\": 1.2\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_target_length\",\r\n \"option_id\": \"opt_length_2200\",\r\n \"option_name\": \"2200字标准(默认)\",\r\n \"option_description\": \"单章目标字数2200字左右的标准章节。这是网文最通用的章节长度,兼顾节奏和内容量,是默认推荐选项。\",\r\n \"system_prompt\": \"你以2200字左右为单章目标字数写作。这是网文最标准的章节长度,适合大多数平台和题材。一章可以包含一个完整的小场景或半个大场景,有起承转合的空间。开头可以有简短的环境/情绪铺垫(不超过200字),中间充分发展,结尾留钩子或给出小满足感。2200字大约是8-12分钟阅读时间,可以容纳对话、描写、动作、心理的平衡搭配。节奏不要太赶也不要太拖,让读者读完一章有“刚刚好”的满足感同时又想继续看。\",\r\n \"constraints\": [\r\n \"单章字数控制在2000-2400字之间\",\r\n \"开头铺垫不超过200字就要进入正题\",\r\n \"一章包含一个完整的小场景或半个大场景\",\r\n \"对话、描写、动作、心理比例均衡\",\r\n \"单段不超过150字\",\r\n \"结尾留钩子或给出小高潮满足感\",\r\n \"避免过于紧凑(像赶剧情)或过于松散(像凑字数)\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"2200字标准章结构示例:\\n- 开头(200字):简短环境/情绪铺垫,承接上章\\n- 发展(1400字):场景展开,对话+动作+描写均衡推进\\n- 高潮/转折(400字):本章核心事件爆发或反转\\n- 结尾(200字):收束+钩子,引导下一章\",\r\n \"note\": \"标准章结构:适度铺垫,均衡推进,高潮+钩子\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"maxParagraphLength\": 150,\r\n \"targetParagraphLength\": 70,\r\n \"minParagraphCount\": 22,\r\n \"maxExpositionContinuous\": 300,\r\n \"infoPointsPerThousand\": 3,\r\n \"shortSentenceRatio\": 0.4,\r\n \"targetSentenceLength\": 22\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.0,\r\n \"sensorySignal\": 1.0,\r\n \"action\": 1.0,\r\n \"emotion\": 1.0,\r\n \"infoAdvance\": 1.0\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_target_length\",\r\n \"option_id\": \"opt_length_3000\",\r\n \"option_name\": \"3000字长章\",\r\n \"option_description\": \"单章目标字数3000字左右的长章节。适合起点等付费阅读平台,一章内容量充足,可以写完整场景和战斗,读者付费性价比高。\",\r\n \"system_prompt\": \"你以3000字左右为单章目标字数写作。长章有充足的空间展开内容,可以写完整的大场景(一场战斗、一次对话博弈、一段探索)。开头可以有更充分的铺垫和场景营造(300字以内),中间有足够的篇幅发展多条线索,高潮部分可以写得更细致,结尾也有空间做情绪收束。3000字大约是12-18分钟阅读时间,读者对“一章”的期待感更高——必须有足够的实质内容,不能注水。付费读者对长章的质量要求高,每段都要有存在的价值。\",\r\n \"constraints\": [\r\n \"单章字数控制在2700-3300字之间\",\r\n \"开头铺垫不超过300字\",\r\n \"一章至少包含一个完整场景(有起因-经过-结果)\",\r\n \"可以有更丰富的描写和心理刻画,但禁止注水\",\r\n \"单段不超过200字\",\r\n \"付费章节质量要求高,必须有实质剧情推进\",\r\n \"结尾可以是钩子也可以是小高潮收束,给读者值回票价的感觉\"\r\n ],\r\n \"examples\": [\r\n {\r\n \"text\": \"3000字长章结构示例:\\n- 开头(300字):场景营造+情绪铺垫,承接上文\\n- 发展(1500字):多线推进,对话+动作+描写+心理充分展开\\n- 高潮(800字):核心冲突/战斗/反转,写足细节\\n- 收束(400字):情绪沉淀+后续影响+钩子或小结\",\r\n \"note\": \"长章结构:充分展开,细节丰富,高潮写透,值回票价\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"maxParagraphLength\": 200,\r\n \"targetParagraphLength\": 80,\r\n \"minParagraphCount\": 25,\r\n \"maxExpositionContinuous\": 400,\r\n \"infoPointsPerThousand\": 3,\r\n \"shortSentenceRatio\": 0.35,\r\n \"targetSentenceLength\": 24\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.0,\r\n \"sensorySignal\": 1.1,\r\n \"action\": 1.0,\r\n \"emotion\": 1.1,\r\n \"infoAdvance\": 1.0\r\n }\r\n}\r\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_target_length\",\n \"option_id\": \"opt_length_4000\",\n \"option_name\": \"4000字超长\",\n \"option_description\": \"单章目标字数4000字左右的超长章节。适合大高潮章节、重要战斗、关键剧情转折,可以写得极为细致充分。不建议每章都用,用于特殊章节。\",\n \"system_prompt\": \"你以4000字左右为单章目标字数写作。超长章通常用于大高潮、重要战斗、关键剧情转折等特殊时刻,不是日常使用的章节长度。4000字有巨大的叙事空间——可以写一场完整的大战役、一次深入的对话博弈、一段复杂的推理过程、多个视角的交替展现。开篇可以有宏大的场景铺垫,中间可以多线并行、层层递进,高潮部分要写得酣畅淋漓,结尾要有足够的分量。超长章必须内容充实,4000字全是干货,绝对不能注水。建议只在关键章节使用,常规章节用标准长度即可。\",\n \"constraints\": [\n \"单章字数控制在3600-4400字之间\",\n \"建议只用于大高潮/关键转折/重要战斗,不用于日常章节\",\n \"一章可以包含多个场景或多视角切换\",\n \"必须全是干货,禁止任何凑字数的段落\",\n \"单段不超过250字\",\n \"必须有充分的剧情推进和情感冲击\",\n \"结尾要有分量——大高潮的收尾或重大转折的落地\"\n ],\n \"examples\": [\n {\n \"text\": \"4000字超长章结构示例(大高潮章):\\n- 铺垫(500字):大战前的宁静/紧张氛围营造\\n- 第一波(800字):冲突爆发,第一回合交锋\\n- 第二波(1000字):局势升级,多方力量介入/反转出现\\n- 高潮(1200字):最终对决/真相揭示/最大反转,酣畅淋漓\\n- 收尾(500字):结局+余波+情感沉淀\",\n \"note\": \"超长章结构:大场面充分展开,多波递进,高潮酣畅,收尾有力\"\n }\n ],\n \"threshold_overrides\": {\n \"maxParagraphLength\": 250,\n \"targetParagraphLength\": 90,\n \"minParagraphCount\": 30,\n \"maxExpositionContinuous\": 500,\n \"infoPointsPerThousand\": 3,\n \"shortSentenceRatio\": 0.35,\n \"targetSentenceLength\": 26\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.0,\n \"sensorySignal\": 1.2,\n \"action\": 1.2,\n \"emotion\": 1.2,\n \"infoAdvance\": 1.1\n }\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_target_length\",\n \"option_id\": \"opt_length_custom\",\n \"option_name\": \"自定义\",\n \"option_description\": \"自定义章节长度,不设固定字数阈值。由作者根据具体场景需要自行决定章节长短,AI不强制控制字数。\",\n \"system_prompt\": \"你使用自定义章节长度模式,不设定固定的单章字数目标。章节长度完全由剧情需要决定:该短则短,该长则长。一场快速的对话交锋可能几百字就够,一场大决战可能需要四五千字。关键标准不是字数,而是这一章是否完成了它应该完成的叙事功能——是否讲完了一个完整的叙事单元?是否给了读者应有的情绪体验?如果答案是肯定的,字数多少都可以。注意:自定义不等于随意,章节切分要有节奏感,不能一章短到100字(那是片段不是章节),也不能一章长到2万字(那是一卷不是一章)。\",\n \"constraints\": [\n \"不设固定字数限制,由剧情需要决定\",\n \"短章不低于500字,长章不超过6000字(极端特殊情况除外)\",\n \"章节切分要有节奏感,不能随意截断\",\n \"每章必须完成一个叙事单元(一个完整的事件/场景/情绪弧)\",\n \"段落长度和句子节奏根据当前场景灵活调整\",\n \"避免极端:不能100字一章也不能2万字一章\",\n \"结尾必须有收束感(钩子、高潮收束、情绪落点均可)\"\n ],\n \"examples\": [\n {\n \"text\": \"自定义长度示例:\\n- 过渡章/悬念章:800-1200字,快速推进留悬念\\n- 日常章/发展章:2000-2500字,均衡展开\\n- 战斗章/高潮章:3000-5000字,充分展开\\n- 开篇第一章:2500-3500字,要有足够吸引力\\n\\n关键是根据剧情需要灵活调整,不被字数束缚。\",\n \"note\": \"自定义模式:剧情优先,字数随内容需要灵活变化\"\n }\n ],\n \"threshold_overrides\": {},\n \"radar_weights\": {\n \"bodyReaction\": 1.0,\n \"sensorySignal\": 1.0,\n \"action\": 1.0,\n \"emotion\": 1.0,\n \"infoAdvance\": 1.0\n }\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_tone\",\n \"option_id\": \"opt_tone_badass\",\n \"option_name\": \"硬核爽利\",\n \"option_description\": \"硬气、利落、不拖泥带水。主角霸气不圣母,打脸干脆,节奏快。适合爽文、都市、玄幻、军事题材。\",\n \"threshold_overrides\": {\n \"maxSentenceLength\": 35,\n \"targetSentenceLength\": 15,\n \"shortSentenceRatio\": 0.55,\n \"maxParagraphLength\": 100,\n \"minParagraphCount\": 25,\n \"maxDialogueContinuous\": 3,\n \"maxFillerWords\": 3\n },\n \"radar_weights\": {\n \"action\": 1.3,\n \"emotion\": 0.8,\n \"infoAdvance\": 1.1,\n \"bodyReaction\": 1.1\n },\n \"system_prompt\": \"硬核爽利基调的核心是'快、准、狠'。叙事节奏快,动作干脆,主角不窝囊,不圣母,不犹豫。语言本身就要有力量感。具体语言规则:\\n\\n1. 动词驱动:句子以动词为核心,少用形容词和副词。能用动作解决的不用心理描写,能用结果说话的不用解释。踹、砸、劈、瞪、甩、踏、碎——精准有力的单字动词优先。\\n\\n2. 短句连击:动作场景用连续短句制造打击感,像拳头一拳一拳打出去。每句一个动作,节奏快,不拖泥带水。关键瞬间一句一段,制造顿挫感。\\n\\n3. 主角硬气:主角不解释、不废话、不道歉、不回头。被挑衅直接反击,被瞧不起直接打脸,不嘴炮不犹豫。行动先于言语。但硬气不是鲁莽——该谋算的时候冷静谋算,动手的时候干净利落。\\n\\n4. 爽点节奏:压抑不超过两章,打脸必须当场或次日。反派装逼不超过三句就被打脸。主角出手必见血(或见效果),不磨磨唧唧。\\n\\n5. 语言利落:不用'似乎''好像''仿佛''可能'这类犹豫词。不用'非常''十分''极其'这类修饰词。少用心理描写,多用行为展示性格。\\n\\n6. 禁止窝囊:主角不能被欺负了忍气吞声,不能被打了不还手,不能看到美女就走不动路,不能圣母心泛滥救不该救的人。该杀杀,该滚滚,不拖泥带水。\",\n \"constraints\": [\n \"动作场景以短句为主(15字以内),连续动作一句一段,制造打击感\",\n \"禁止犹豫词(似乎/好像/仿佛/可能/也许),硬核风格要肯定直接\",\n \"禁止程度副词堆砌(非常/十分/极其),用动作力度体现程度\",\n \"主角对话简洁有力,不解释不啰嗦,能用一句说完的不用两句\",\n \"连续对话不超过3句必须穿插动作描写,动作要有力(拍桌/踹门/攥拳/拔刀)\",\n \"反派装逼台词不超过3句必须被主角打断或打脸\",\n \"每段目标长度50-80字,动作场景可以更短(20-30字一段)\",\n \"单句不超过35字,超过必须拆分\",\n \"禁止主角窝囊行为:被欺负不还手、圣母心泛滥、犹豫迟疑超过两段\"\n ],\n \"examples\": [\n {\n \"text\": \"门被踹开。\\n\\n王虎带着四个人走进来,手里拎着钢管。\\n\\n「就是他?」王虎叼着烟,扫了林远一眼,「打断一条腿,三万。」\\n\\n四个人围上来。\\n\\n林远放下筷子。\\n\\n碗里还有半碗面,汤还冒着热气。\\n\\n第一个人冲上来,钢管当头砸下。\\n\\n林远侧身,钢管砸在桌面上,木屑飞溅。他顺手拿起那碗热面,连汤带面扣在对方脸上。\\n\\n惨叫声。\\n\\n第二个人的钢管到了腰侧。林远抓住钢管,一脚踹在对方膝盖上。\\n\\n咔嚓。\\n\\n骨头断裂的声音很脆。\\n\\n第三个人转身想跑。林远把钢管掷出去,砸在后脑勺上,人直接扑倒。\\n\\n十秒。\\n\\n四个人全躺在地上。\\n\\n王虎嘴里的烟掉了。\\n\\n林远从桌上抽了张纸巾,擦了擦手上的面汤。\\n\\n「回去告诉赵老三,」林远看着王虎,声音很平,「下次派点能打的。」\\n\\n他拿起椅背上的外套,头也不回地走了出去。\\n\\n面钱放在桌上,刚好二十。\",\n \"note\": \"硬核爽利示范:动词驱动(踹/拎/扫/砸/扣/抓/踹/掷/抽/擦),短句连击('门被踹开。''十秒。''四个人全躺在地上。''咔嚓。'),主角不废话不嘴炮,打完放一句狠话直接走,不拖泥带水。'面钱放在桌上,刚好二十'这个细节比任何描写都体现主角的硬气和讲究。没有心理描写,全是动作。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": [\n \"opt_tone_cold\",\n \"opt_tone_playful\"\n ]\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_tone\",\n \"option_id\": \"opt_tone_classical\",\n \"option_name\": \"唯美古风\",\n \"option_description\": \"古典雅致,用词古雅,意境优美。适合古言、仙侠、武侠、历史题材。\",\n \"threshold_overrides\": {\n \"maxSentenceLength\": 50,\n \"targetSentenceLength\": 22,\n \"shortSentenceRatio\": 0.3,\n \"maxParagraphLength\": 150,\n \"maxFillerWords\": 6\n },\n \"radar_weights\": {\n \"sensorySignal\": 1.2,\n \"emotion\": 1.1,\n \"action\": 0.9\n },\n \"system_prompt\": \"唯美古风基调的核心是'语言雅致有意境,但不堆砌辞藻'。古典美感来自意象选取和节奏控制,不是生僻字大杂烩。具体语言规则:\\n\\n1. 用词:可以使用文言词汇和四字格,但要自然不生硬。常用古风词(月色/霜雪/青衫/长剑/落花/孤灯/江河/山河)可以用,生僻字和冷门典故要避免。半文半白是最佳状态,读起来有古韵但不晦涩。\\n\\n2. 意象:古风靠意象传情——月、雪、花、剑、酒、灯、雨、风、雁、马。意象要服务于情绪,不要为了好看堆意象。同一个场景选1-2个核心意象贯穿。\\n\\n3. 节奏:句式长短错落,对偶和散句交替。紧张处用短句,抒情处用长句。四字格不要连续超过3个,否则像古风生成器。\\n\\n4. 禁止事项:禁止现代网络用语、禁止现代口语词(OK/搞定/牛逼)、禁止翻译腔、禁止过度堆砌辞藻(同一个描写用三个以上形容词就是堆砌)。禁止'宛若''犹如''仿佛'连用。\\n\\n5. 意境留白:情绪不直说,用景物烘托。不写'她很悲伤',写'雨打残荷,烛泪成行'。不写'他很孤独',写'千山暮雪,只影向谁去'的感觉。\",\n \"constraints\": [\n \"禁止现代口语和网络用语(搞定/OK/牛逼/咋/啥等),保持语言时代感\",\n \"四字格使用不超过总句数的30%,禁止连续3个以上四字格堆砌\",\n \"比喻用词要新鲜,禁止陈词滥调(心如刀割/泪如雨下/沉鱼落雁/闭月羞花)\",\n \"每个场景选1-2个核心意象贯穿,不要同时堆5个以上意象\",\n \"单句不超过50字,长句中要有停顿,禁止一逗到底\",\n \"情感表达以景物烘托为主,禁止直接情绪词(悲伤/愤怒/开心)超过每千字2次\",\n \"对话要符合古人身份,禁用现代句式,但也不能全是之乎者也导致晦涩\",\n \"段落目标长度80-120字\"\n ],\n \"examples\": [\n {\n \"text\": \"雪落了一夜。\\n\\n推窗时,满院皆是白。那株老梅开了,疏枝横斜,花瓣上积着薄雪,风一吹便簌簌落下来,像谁在听不见的地方叹气。\\n\\n她拢了拢斗篷,在窗前站了许久。铜炉里的香快燃尽了,余温透过薄薄的衣袖传来,像谁的指尖轻轻碰了碰她的手腕。\\n\\n院门外传来马蹄声,由远及近,停在了门前。\\n\\n她没有动。\\n\\n雪还在落。梅花落在雪上,白的更白,红的更红,像谁在一幅留白太多的画上,随手点了一笔硃砂。\\n\\n敲门声。\\n\\n她终于转过身去,脚步很轻,像是怕踩碎了什么。\",\n \"note\": \"古风示范:意象是雪和梅,语言半文半白(疏枝横斜/簌簌/拢了拢/硃砂)但不晦涩。没有直接写'她在等人''她很紧张',通过'站了许久''脚步很轻,怕踩碎什么'和雪落梅开的意象传递情绪。四字格自然融入(疏枝横斜/由远及近),没有堆砌感。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": [\n \"opt_tone_badass\",\n \"opt_tone_colloquial\"\n ]\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_tone\",\n \"option_id\": \"opt_tone_cold\",\n \"option_name\": \"清冷疏离\",\n \"option_description\": \"清冷克制,疏离淡然。情感不外露,叙事保持距离感,像隔了一层薄冰。适合悬疑、文艺、暗黑题材,也是矿工风格。\",\n \"threshold_overrides\": {\n \"maxSentenceLength\": 45,\n \"targetSentenceLength\": 18,\n \"shortSentenceRatio\": 0.5,\n \"maxParagraphLength\": 120,\n \"maxFillerWords\": 4,\n \"maxExpositionContinuous\": 200\n },\n \"radar_weights\": {\n \"sensorySignal\": 1.2,\n \"emotion\": 0.6,\n \"action\": 1.1,\n \"bodyReaction\": 1.3\n },\n \"system_prompt\": \"清冷疏离基调的核心是'叙事者不参与情感,只记录'。像法医记录现场、监控摄像头拍画面——冷静、精确、不评判。情感藏在冰面下,读者通过细节自己感知。具体语言规则:\\n\\n1. 精确量化:涉及温度、距离、时间、尺寸时用具体数字而非模糊描述。不说'很冷',说'室温3度';不说'很久',说'三分十七秒';不说'很远',说'四十七步'。数字本身传递冷感。\\n\\n2. 感官白描:感官描写要像医学记录——光线来源、声音频率、温度变化、材质触感,不附加情感评价。'墙壁表面温度35.8度,比正常高3.8度'比'墙壁传来诡异的温热'更冷更有力。\\n\\n3. 情感零度:禁止叙事者评论人物情绪。不写'他感到恐惧''她很悲伤',只写身体反应和外部行为——瞳孔收缩、手指发白、呼吸频率变化、脚步停顿了几秒。让读者自己判断情绪。\\n\\n4. 句子短而干净:多用短句和断句,少用修饰语。每句话只传递一个信息。删除所有程度副词(非常/十分/极其/特别)和情感形容词(恐怖/美丽/恶心/动人)。\\n\\n5. 留白与停顿:动作之间可以有空隙。人物不立刻反应,停顿本身就是反应。环境描写插入在动作之间,制造冷感和疏离感。\\n\\n6. 标点克制:少用感叹号(千分之五以内),少用省略号,句号为主。破折号谨慎使用。逗号断句要狠,不要一逗到底。\",\n \"constraints\": [\n \"禁止叙事者直接陈述情绪(恐惧/悲伤/愤怒/紧张等),只能通过身体反应和行为间接表现\",\n \"禁止程度副词(非常/十分/极其/特别/很/真的/太),用具体细节替代\",\n \"禁止情感形容词直接修饰场景(恐怖的/诡异的/美丽的/恶心的),用细节让读者自己感受\",\n \"感叹号使用频率不超过千分之一(约每2000字最多1个)\",\n \"涉及温度、距离、时间、数量时优先使用精确数字而非模糊描述\",\n \"每段目标长度50-100字,关键瞬间可用1-2句极短段落制造顿点\",\n \"句子以短句为主(10-20字),单句不超过45字,短长比约1:1\",\n \"每300字至少有1处身体锚点(生理反应/感官细节)\"\n ],\n \"examples\": [\n {\n \"text\": \"铜碗里的水已经凉了。\\n\\n他把温度计贴在壁面上,等了三十秒。红色液柱停在35.8的位置。\\n\\n比昨天高0.4度。\\n\\n通风管的声音变了。原来的低频嗡鸣消失了,换成一种不规则的震颤,像什么东西在管壁里面爬。他把耳朵贴上去听了五秒,没听出规律。\\n\\n老李在角落睡觉。右胳膊的肿胀蔓延到了肘部,皮肤下面透出一种不正常的青紫色。呼吸频率每分钟十一次。\\n\\n他收回温度计,塞进上衣内袋。口袋里还有半块压缩饼干和一个打火机。\\n\\n矿灯电量:47%。\\n\\n他看了一眼通道深处。黑暗很浓,矿灯光只能照亮前方十二米。十二米之外什么都看不见。\\n\\n他把矿灯拧到最暗,坐下,背靠壁面。\\n\\n壁面在跳。很轻,几乎察觉不到,像心跳。\\n\\n他闭上眼。\",\n \"note\": \"冷峻克制示范:全程没有一个情绪词(没有恐惧/紧张/绝望),只有精确数字(35.8度/0.4度/五秒/十一次/47%/十二米)和白描(液柱位置/通风管声音/胳膊青紫/壁面在跳)。情感全部压在文字底下——读者通过数字异常(壁温升高、通风管变声、呼吸11次偏低、电量47%)自己感受到危险逼近。结尾'他闭上眼'四个字比'他陷入了绝望'有力一百倍。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": [\n \"opt_tone_playful\"\n ]\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_tone\",\n \"option_id\": \"opt_tone_colloquial\",\n \"option_name\": \"口语白话\",\n \"option_description\": \"通俗流畅的口语化叙事(默认),像在讲故事,不端着,适合大多数网文类型。\",\n \"threshold_overrides\": {},\n \"radar_weights\": {\n \"emotion\": 1.0,\n \"action\": 1.0,\n \"infoAdvance\": 1.0,\n \"bodyReaction\": 1.0,\n \"sensorySignal\": 1.0\n },\n \"system_prompt\": \"口语白话是默认叙事基调,核心是'像说书人在给读者讲故事'。语言通俗直白,不端着,不故作高深,但也不能粗糙水字数。具体语言规则:\\n\\n1. 用词层面:多用常用词,少用生僻字和书面语。动词要精准(走/跑/跳/踹/瞪/攥),不要用华丽但空洞的形容词。可以用适度口语词(知道/明白/搞/整/咋/啥),但不能满篇方言。\\n\\n2. 句式层面:以中短句为主(15-25字),偶尔长句补充信息。句子结构要简单直接,主谓宾清晰,不要多层从句嵌套。可以有断句、省略主语,但不能混乱。\\n\\n3. 叙事距离:中等距离——叙事者知道主角在想什么,但不会跳出来评论。可以用自由间接引语(把人物的想法融入叙述),但不能用第二人称'你'跟读者说话(除非特殊设计)。\\n\\n4. 节奏:叙事节奏明快,不拖泥带水。描写点到为止,动作干脆利落。信息传递直接,不绕弯子。\\n\\n5. 通俗≠粗糙:口语化不等于水字数。每句话都要有信息量,不能说废话。'他很厉害'是废话,'他一刀劈碎了试剑石'是有效的。'非常紧张'是废话,'手心全是汗'是有效的。\\n\\n6. 禁止事项:禁止文艺腔('彼时''忽而''颔首''蹙眉')、禁止翻译腔('是的,他想''我恐怕不能同意')、禁止书面语堆砌、禁止过度解释(把读者当傻子什么都说明白)。\",\n \"constraints\": [\n \"以中短句为主(15-25字),单句不超过50字,禁止一逗到底\",\n \"禁止使用生僻词、文言词(彼时/忽而/颔首/蹙眉/沉吟/思忖等),除非角色对话需要\",\n \"禁止程度副词堆砌(非常/十分/极其/很+形容词连续出现),用具体细节替代\",\n \"每段必须有实质内容(动作/对话/信息/感官),禁止空洞段落('他心中百感交集''气氛十分凝重'这类空话)\",\n \"禁止叙事者跳出来对读者说话('各位看官''你猜怎么着''你要知道')\",\n \"形容词使用克制——能用动词和名词表达的不用形容词\",\n \"段落目标长度80-120字,手机阅读友好\"\n ],\n \"examples\": [\n {\n \"text\": \"陈默推开宿舍门的时候,屋里三个人正在打牌。\\n\\n「回来了?」上铺的老张头也没抬,甩出一张牌,「今天工头找你干啥?」\\n\\n「没干啥。」陈默把外套挂在门后,在自己床沿坐下,开始解鞋带。矿靴上全是泥,鞋带结成了硬块,解了半天才解开。\\n\\n「没干啥能留你到这个点?」对面床的小李扔了牌,凑过来,脸上带着那种知道了秘密的笑,「听说深区那边又出事了?」\\n\\n陈默没接话。他把矿靴脱下来,摆在床下摆齐,然后从枕头底下摸出半块干硬的馒头,咬了一口。\\n\\n馒头是凉的,硬得像石头。\\n\\n「到底咋了?」小李不依不饶。\\n\\n陈默嚼着馒头,看了他一眼。小李的眼睛在矿灯光下发亮,像等着听故事的小孩。\\n\\n「壁温升到36了。」陈默说。\\n\\n屋里安静了两秒。老张手里的牌停在半空。\\n\\n「操。」老张把牌往床上一摔。\",\n \"note\": \"口语白话示范:用词通俗(干啥/没干啥/咋了/操),句子短,动词精准(甩/扔/凑/摸/嚼/摔),没有华丽修饰,但信息量大。'馒头是凉的,硬得像石头'一个细节就传递了环境艰苦和人物心情。结尾一个'操'字比任何描写都有力。叙事直接,不解释壁温36度意味着什么(读者通过老张的反应自己体会)。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": []\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_tone\",\n \"option_id\": \"opt_tone_folksy\",\n \"option_name\": \"乡土市井\",\n \"option_description\": \"烟火气十足,有生活质感,柴米油盐、街坊邻里、市井百态。适合年代文、乡土文、市井生活题材。\",\n \"threshold_overrides\": {\n \"maxSentenceLength\": 45,\n \"targetSentenceLength\": 20,\n \"shortSentenceRatio\": 0.45,\n \"maxParagraphLength\": 150,\n \"maxDialogueContinuous\": 4\n },\n \"radar_weights\": {\n \"emotion\": 1.1,\n \"sensorySignal\": 1.3,\n \"action\": 0.9\n },\n \"system_prompt\": \"乡土市井基调的核心是'烟火气'。写的是柴米油盐、家长里短、街坊邻里、三教九流,文字要有生活质感,能闻到油烟味、听到叫卖声、摸到粗布的纹理。具体语言规则:\\n\\n1. 生活细节:写具体的食物(葱油饼、豆腐脑、红烧肉、窝窝头)、具体的价格(两毛五、三块二)、具体的物件(搪瓷缸、暖水瓶、二八自行车、缝纫机)、具体的场所(菜市场、大杂院、胡同口、供销社)。细节越具体越真实。\\n\\n2. 方言适度:可以用方言词汇和口语表达,但不能多到看不懂。北方口语(咋、啥、中、甭、搁、得劲)、南方口语(伢子、晓得、莫、噻)根据故事地点选用,保持语言的地域感。\\n\\n3. 感官丰富:嗅觉(油烟味、煤气味、槐花香、臭豆腐味)、味觉(咸了、淡了、辣、酸、甜)、触觉(粗布磨手、板凳硌屁股、太阳晒得暖烘烘)、听觉(叫卖声、自行车铃、收音机、炒菜声)——五感全开,这是烟火气的来源。\\n\\n4. 人物鲜活:小人物的喜怒哀乐,接地气的生存智慧。说话做事符合身份——小贩会吆喝、大妈会砍价、工人会骂娘、孩子会撒泼。不写完美人物,有缺点有毛病有小算盘才真实。\\n\\n5. 节奏舒缓:生活流叙事,不追求快节奏。张家长李家短、买菜做饭上班下班,日常里藏着人情冷暖。\",\n \"constraints\": [\n \"每500字至少有1处具体的生活细节(食物/价格/物件/场所),不能飘在空中\",\n \"方言词汇控制在10%-15%,不能影响阅读理解,必要时通过上下文理解\",\n \"五感描写中嗅觉和味觉至少各出现1次/千字,烟火气来自气味和味道\",\n \"对话要符合人物身份和地域,小贩说话像小贩,大妈说话像大妈\",\n \"禁止空洞抒情和华丽辞藻,用具体的生活场景代替抽象的情感描写\",\n \"人物要有小缺点和小算盘,不能高大全,接地气的人物才鲜活\",\n \"段落目标长度80-120字,叙事节奏从容不急躁\",\n \"禁止网络用语和现代梗,保持时代感和生活真实感\"\n ],\n \"examples\": [\n {\n \"text\": \"天还没亮透,王婶就起床了。\\n\\n煤球炉子封了一夜,捅开的时候冒了一阵黑烟,呛得她直咳嗽。她扇了两下蒲扇,火苗子腾地起来了,蓝盈盈的,映得她脸上的皱纹都在跳。\\n\\n和面的盆是搪瓷的,掉了三块漆,露着黑铁底。她舀了两瓢白面,一瓢玉米面,兑了温水,手在面里搅和,指缝里全是面嘎巴。\\n\\n外间屋传来她男人的咳嗽声,老烟枪,咳起来像要把肺都吐出来。\\n\\n「死不了就起来,」王婶朝里间喊,「今天豆腐摊张瘸子来,晚了就没热乎的了。」\\n\\n她掀开咸菜坛子,一股咸酸味蹿出来。捞了两根萝卜条,滴了两滴香油,搁在粗瓷碟子里。棒子面粥在锅里咕嘟着,泡泡顶开了锅盖,顺着锅沿往下淌,在煤球炉子上滋啦一声,糊味就上来了。\\n\\n王婶赶紧把锅盖掀开一条缝。\\n\\n胡同口已经有动静了。卖牛奶的铃铛叮铃叮铃响,扫街的老陈头拿着大扫帚哗啦哗啦,对门李家的收音机在放《朝阳沟》,哇啦哇啦的。\\n\\n新的一天开始了。\",\n \"note\": \"乡土市井示范:具体生活细节(煤球炉子/搪瓷盆掉漆/两瓢白面一瓢玉米面/萝卜条滴香油/棒子面粥咕嘟/《朝阳沟》),方言适度(咋/啥/搁/甭没有硬塞),五感全开(呛得咳嗽/蓝盈盈火苗/咸酸味/滋啦糊味/铃铛叮铃/哗啦扫帚声),节奏舒缓,就是普通人家的一个早晨,但烟火气十足。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": [\n \"opt_tone_cold\"\n ]\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_tone\",\n \"option_id\": \"opt_tone_playful\",\n \"option_name\": \"俏皮轻松\",\n \"option_description\": \"轻松幽默,吐槽有趣,节奏明快。适合轻小说、都市喜剧、甜宠、吐槽风作品。\",\n \"threshold_overrides\": {\n \"maxSentenceLength\": 40,\n \"targetSentenceLength\": 18,\n \"shortSentenceRatio\": 0.5,\n \"maxParagraphLength\": 120,\n \"maxDialogueContinuous\": 5,\n \"maxFillerWords\": 10\n },\n \"radar_weights\": {\n \"emotion\": 1.2,\n \"action\": 1.0,\n \"sensorySignal\": 0.8\n },\n \"system_prompt\": \"俏皮轻松基调的核心是'有趣、好读、让人笑'。叙事可以有吐槽、有反差、有内心OS,节奏明快,读起来不累。但搞笑不是胡闹,要有章法。具体语言规则:\\n\\n1. 吐槽与内心OS:允许叙事者或主角用轻松的口吻吐槽,可以用括号、破折号补充内心吐槽。主角内心想法可以很跳脱、很真实、很接地气,但不要每段都吐槽,会累。\\n\\n2. 反差萌:笑点来自反差——严肃的场景里出现很蠢的细节、高冷的人做出很傻的事、紧张时刻突然冒出一句不合时宜的话。反差要自然,不能硬挠痒痒。\\n\\n3. 夸张但不离谱:可以适当夸张描写('他的脸黑得像锅底''眼睛瞪得铜铃大'),但要服务于笑点,不能无意义夸张。\\n\\n4. 节奏轻快:句子短,对话多,描写点到为止。动作描写要有趣,不要像武功秘籍一样一板一眼。\\n\\n5. 禁止事项:不要用网络烂梗('yyds''绝绝子''emo'这类会过时的词),不要为了搞笑破坏人物设定(高冷角色突然变话痨),不要在严肃剧情里强行搞笑(会破坏气氛),不要低俗。\\n\\n6. 甜宠/轻松向:如果是甜宠文,笑点来自男女主的互动和反差,不是刻意讲段子。情感要甜但不腻,互动要自然。\",\n \"constraints\": [\n \"吐槽频率控制:每千字不超过3处内心OS/吐槽,不要句句都在抖机灵\",\n \"禁止使用过时网络热词和烂梗,用生活化的真实幽默代替\",\n \"句子短为主(15-20字),对话占比可以适当提高到40%-50%\",\n \"搞笑不能破坏人物设定——角色的说话和行为方式要符合其性格\",\n \"严肃剧情(生死/离别/重大转折)时禁止强行搞笑\",\n \"反差萌要自然,不能硬造笑点,不能为了搞笑让角色OOC\",\n \"段落目标长度60-100字,短段落多,留白多,读起来轻松\",\n \"可以使用感叹号和问号,但禁止滥用(每千字感叹号不超过15个)\"\n ],\n \"examples\": [\n {\n \"text\": \"周一早上七点半。\\n\\n林夏盯着镜子里的自己,沉默了三秒。\\n\\n黑眼圈重得像被人打了两拳,头发翘起来一撮,像天线。她用手按了按,按下去,弹起来。再按,再弹。\\n\\n行,今天走朋克风。\\n\\n她叼着一片面包冲出门,电梯在15楼停了,门一开——\\n\\n顾言琛站在里面。西装革履,头发一丝不苟,手里端着一杯咖啡,整个人精致得像杂志封面。\\n\\n林夏嘴里的面包差点掉下来。\\n\\n更要命的是,她那撮天线头发还在翘着。\\n\\n顾言琛的目光落在她头顶,停顿了零点五秒。\\n\\n「早。」他说,语气平静得像什么都没看见。\\n\\n林夏用最快的速度把头发捋平,挤出一个笑容:「早啊顾总,好巧啊哈哈。」\\n\\n电梯门关上。\\n\\n顾言琛很体贴地没有再看她,只是嘴角好像动了一下。\\n\\n林夏面无表情地盯着跳动的楼层数字。\\n\\n毁灭吧。赶紧的。\",\n \"note\": \"俏皮轻松示范:内心吐槽('行今天走朋克风''毁灭吧赶紧的')自然不生硬,笑点来自反差(女主狼狈vs男主精致、翘起来的头发),没有刻意讲段子但让人会心一笑。夸张适度(黑眼圈像被打了两拳、像天线),对话自然。结尾内心OS是典型的轻松风处理方式。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": [\n \"opt_tone_cold\",\n \"opt_tone_serious\"\n ]\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_tone\",\n \"option_id\": \"opt_tone_serious\",\n \"option_name\": \"严肃正剧\",\n \"option_description\": \"庄重沉稳,用词严谨,有历史厚重感。适合历史正剧、严肃文学、谍战、权谋题材。\",\n \"threshold_overrides\": {\n \"maxSentenceLength\": 55,\n \"targetSentenceLength\": 25,\n \"shortSentenceRatio\": 0.3,\n \"maxParagraphLength\": 180,\n \"maxFillerWords\": 5,\n \"maxDialogueTagRepeat\": 2\n },\n \"radar_weights\": {\n \"emotion\": 0.9,\n \"action\": 1.0,\n \"infoAdvance\": 1.2\n },\n \"system_prompt\": \"严肃正剧基调的核心是'沉稳、厚重、可信'。叙事像历史记录一样扎实,用词精准不含糊,情感深沉不外放,矛盾冲突有分量。具体语言规则:\\n\\n1. 用词严谨:用词准确,不含糊其辞,不调侃不戏谑。名词动词精准,避免模糊词(大概/可能/好像)。涉及历史、制度、器物时用词要符合时代背景。\\n\\n2. 句式沉稳:句子偏长,结构完整,允许复句和从句,但逻辑必须清晰。不用半截话、不用网络语、不用口语碎片。\\n\\n3. 叙事距离:叙事者保持客观中立,不站队不评论。不替读者做价值判断,把事实呈现出来让读者自己判断。可以写人物内心,但要有深度有层次,不肤浅。\\n\\n4. 情感深沉:情感表达要克制但有重量。不喊不叫不哭天抢地,大悲无声,大怒无形。越是重要的情感,越要用克制的方式写。\\n\\n5. 冲突有分量:矛盾冲突不是小打小闹,而是立场、信仰、利益、家国的冲突。每一次冲突都要有前因后果,有代价有牺牲。\",\n \"constraints\": [\n \"禁止网络用语、口语碎片、戏谑调侃语气,保持叙事庄重感\",\n \"禁止模糊词(好像/似乎/大概)连续使用,关键信息必须精确\",\n \"句子结构完整,避免半截话和省略主语过多导致混乱\",\n \"情感表达克制,禁止角色大喊大叫、情绪崩溃式的廉价宣泄\",\n \"涉及历史/制度/器物/礼仪时用词必须符合时代背景,不能出现穿越式错误\",\n \"对话要符合人物身份和教育背景,权谋人物说话含蓄有潜台词\",\n \"段落目标长度100-150字,叙事节奏稳健不急躁\",\n \"单句不超过55字,长句必须有清晰的逻辑结构\"\n ],\n \"examples\": [\n {\n \"text\": \"光绪二十六年,庚子。\\n\\n七月二十一日,天未明,两宫微服出德胜门西行。銮舆不备,扈从寥寥,王公士民未知所往。\\n\\n李鸿章自广州奉诏北上,舟至上海,以疾留。张之洞、刘坤一联络东南各省,与各国领事议'东南互保',约以租界归各国保护,长江内地归督抚保护,两不相扰。\\n\\n京师沦陷已三日。\\n\\n紫禁城太和殿前的荒草长到了半人高。日本兵在乾清宫前喂马,俄国兵占据了颐和园,英国军官在天坛的圜丘上拍照。户部存银三百万两被日本兵掠走,内务府的宝物被一车一车运往东交民巷。\\n\\n直隶总督裕禄在杨村兵败自杀。李秉衡率军北上勤王,于通州张家湾兵败,服毒殉国。\\n\\n城破那日,军机处章京王瓘正在内廷当值。\",\n \"note\": \"严肃正剧示范:以史笔叙事,时间地点人物精确,用词严谨(銮舆/扈从/微服/勤王),不渲染情绪但沉重感自然涌出。白描史实(荒草半人高/喂马/拍照/掠银)比任何情绪描写都有力量。\"\n }\n ],\n \"requires\": [],\n \"conflicts\": [\n \"opt_tone_playful\",\n \"opt_tone_badass\"\n ]\n}\n","{\n \"kb_version\": \"3.0\",\n \"node_id\": \"node_twist_frequency\",\n \"option_id\": \"opt_twist_sparse\",\n \"option_name\": \"稀疏反咬(800字+一次,慢热文)\",\n \"option_description\": \"反咬频率低,适合慢热文、传统文学、日常治愈系,靠氛围和人物而非反转驱动。\",\n \"system_prompt\": \"你使用稀疏反咬频率模式。反咬频率较低,约800字以上一次大的信息变化,更多靠氛围铺陈、人物互动、细节积累推动。但仍然要求章节末尾有一次关键转折或发现,不能整章平铺直叙。\",\n \"constraints\": [\n \"800字以上一次大反咬\",\n \"中间可以用小细节变化替代大反转\",\n \"章节末尾必须有一次关键转折\",\n \"仍然禁止连续1000字完全无新信息\"\n ],\n \"examples\": [],\n \"threshold_overrides\": {\n \"twistFrequency\": \"sparse\",\n \"minTwistsPer1000\": 1\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.0,\n \"sensorySignal\": 1.3,\n \"action\": 0.9,\n \"emotion\": 1.3,\n \"infoAdvance\": 0.8\n }\n}\n","{\n \"kb_version\": \"3.0\",\n \"node_id\": \"node_twist_frequency\",\n \"option_id\": \"opt_twist_standard\",\n \"option_name\": \"标准反咬(300-400字一次,默认)\",\n \"option_description\": \"每300-400字一次信息反咬/反转,读者刚形成判断就被颠覆,是网文追读的标准密度。\",\n \"system_prompt\": \"你使用标准反咬频率模式。严格遵守每300字信息反咬铁则:每250-350字必须有一次信息反咬——读者刚形成一个判断,立刻用新信息颠覆。反咬类型:以为安全→危险/以为是A→是B/以为某人错了→他对了/以为结束→才刚开始/以为是友→有疑点。禁止连续400字无转折、无意外、无新发现。每段只给一个新信息,新信息出来后必须接人物身体反应或物理痕迹。\",\n \"constraints\": [\n \"每250-350字必须有一次信息反咬/反转\",\n \"反咬类型多样化,不连续用同一种\",\n \"新信息出来后必须接人物身体反应\",\n \"禁止线性匀速推进\",\n \"每段只承载一个新信息\"\n ],\n \"examples\": [\n {\n \"text\": \"反咬链条示例:\\n1.(0字)发现异常声音→老范说风里有东西\\n2.(280字)寻说茧没收到信号→以为老范听错了(建立预期)\\n3.(320字)寻脸色变了→确实多了一拍(反咬1:老范是对的)\\n4.(580字)声音停了→以为它走了(建立预期)\\n5.(650字)碎石在动→它在下面(反咬2:没走,更近了)\",\n \"note\": \"标准反咬:每300字左右颠覆一次读者判断\"\n }\n ],\n \"threshold_overrides\": {\n \"twistFrequency\": \"standard\",\n \"minTwistsPer1000\": 3\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.2,\n \"sensorySignal\": 1.0,\n \"action\": 1.2,\n \"emotion\": 1.0,\n \"infoAdvance\": 1.5\n }\n}\n","{\n \"kb_version\": \"3.1\",\n \"node_id\": \"node_twist_frequency\",\n \"option_id\": \"opt_twist_dense\",\n \"option_name\": \"密集反咬(250-350字一次,番茄/爽文/悬疑)\",\n \"option_description\": \"2026追读标准:每250-350字一次信息反咬,千字≥3个意外/转折。读者刚形成判断就被颠覆,根本停不下来。\",\n \"system_prompt\": \"你使用密集信息反咬模式——这是2026年番茄/七猫等免费网文平台追读率最高的节奏模式。严格遵守:\\n\\n【反咬频率铁则】\\n- 每250-350字必须有一次信息反咬:读者刚形成一个判断,立刻被新信息颠覆。\\n- 千字反咬密度≥3个(不含章末钩子)。\\n- 禁止连续400字无转折、无意外、无新发现。\\n\\n【反咬类型库】\\n- 安全反咬:以为安全→有危险(「他松了口气,才发现身后的呼吸声不对。」)\\n- 身份反咬:以为是A→是B(「来的人不是救援,是第二批矿工。但他们三个月前就该死了。」)\\n- 判断反咬:以为某人错了→他是对的(「老范说别凿。林深以为他胆小,直到他摸到那道纹路。」)\\n- 进程反咬:以为结束了→才刚开始(「液球溶解了号牌。他以为没事了,然后液球开始爬。」)\\n- 阵营反咬:以为是友→有疑点(「寻递给他水。林深接过,看见她指甲缝里有黑色液体。」)\\n- 发现反咬:新发现颠覆之前所有认知(「号牌上的数字是6。陈六的号牌。但陈六三个月前就死了。」)\\n\\n【反咬写法】\\n- 反咬必须具体:不能写「他觉得哪里不对」,必须写具体哪里不对(声音不对/温度不对/数字不对/表情不对/物件不对)。\\n- 反咬出现后立刻接主角身体反应(胃一缩/后颈凉/手指僵/呼吸停),不许解释,不许停顿。\\n- 大小反咬交替:小反咬(细节异常)每250字一个,中反咬(判断颠覆)每700字一个,大反咬(认知颠覆/危险升级)放在章末钩子位置。\\n- 对话中也要有反咬:一人说出判断→另一人反对→第三人拿出证据打两个人的脸。\",\n \"constraints\": [\n \"每250-350字一次信息反咬,千字≥3个\",\n \"反咬必须具体(具体什么不对),禁止「似乎/好像/哪里不对」空泛反咬\",\n \"反咬后立刻接身体反应,不停顿解释\",\n \"大小反咬交替,避免连续大反转导致疲劳\",\n \"禁止连续400字无转折/无意外/无新发现\",\n \"对话中也要有碰撞和反咬\"\n ],\n \"examples\": [\n {\n \"text\": \"(反咬节奏示范,约1200字6次反咬)\\n\\n老范说别凿了。→林深以为他胆小(初始判断)\\n→摸到纹路不像凿痕(反咬1:细节异常)\\n→老范手刚贴上去就缩回来,像摸到烫的(反咬2:老范反应不对)\\n→提到陈六(反咬3:陈六的名字出现,不是落石)\\n→踩到半块号牌,数字6(反咬4:陈六的号牌在这里)\\n→壁动了,黑色液体渗出来(反咬5:危险升级)\\n→液球溶解号牌,开始爬(反咬6:不是水,是活的)\\n→拐弯处全是纹路(章末大反咬/钩子)\",\n \"note\": \"密集反咬节奏:每200字左右一次小颠覆,层层升级,读者根本停不下来\"\n }\n ],\n \"threshold_overrides\": {\n \"twistFrequency\": \"dense\",\n \"minTwistsPer1000\": 3,\n \"maxConsecutiveNoTwist\": 3\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.2,\n \"sensorySignal\": 1.1,\n \"action\": 1.2,\n \"emotion\": 1.1,\n \"infoAdvance\": 1.5,\n \"twistFrequency\": 1.5,\n \"hookStrength\": 1.2\n }\n}\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_vocab_filler\",\r\n \"option_id\": \"opt_filler_relaxed\",\r\n \"option_name\": \"宽松模式\",\r\n \"option_description\": \"宽松填充词检测,允许更多过渡和渲染词汇。maxFillerSentences=5, maxFillerWords=12。适合节奏较慢、描写丰富的文风,或对水字数容忍度较高的平台。\",\r\n \"system_prompt\": \"你使用宽松填充词检测模式。在这个模式下,大部分过渡词、情绪渲染词、节奏调节词都被允许,只有极端明显的凑字数(如整段重复、毫无意义的胡言乱语)才会被标记为填充。宽松模式允许作者自由使用形容词、副词、感叹词、过渡句来调节行文节奏和氛围。网文读者习惯了一定量的“水”来缓冲节奏,只要不是太过分就可以接受。但注意:宽松不等于纵容,整段照搬前面的内容、毫无意义的凑字数、连续多句什么都没说——这些仍然需要修正。\",\r\n \"constraints\": [\r\n \"每千字填充词句不超过5句\",\r\n \"每千字填充词不超过12个\",\r\n \"允许自由使用过渡词、渲染词、感叹词\",\r\n \"允许套路化表达(适度),但禁止连续使用\",\r\n \"禁止整段重复已有内容\",\r\n \"禁止连续3句以上完全无信息量\",\r\n \"允许心理描写和情绪渲染,即使不直接推进剧情\"\r\n ],\r\n \"vocabulary\": {\r\n \"add\": {\r\n \"fillerPatterns\": [\r\n \"整段重复内容\",\r\n \"完全无意义的胡言乱语\",\r\n \"连续多句重复同一个感叹\"\r\n ]\r\n }\r\n },\r\n \"examples\": [\r\n {\r\n \"text\": \"张浩站在山顶,俯瞰着脚下连绵起伏的群山,心中不由得涌起一股豪情壮志。\\n\\n是啊,他经历了那么多,付出了那么多的努力和汗水,终于站到了今天这个位置。回想当初,他只是一个什么都不懂的毛头小子,谁能想到他能有今天?\\n\\n不得不说,命运这个东西,有时候真的很奇妙。\\n\\n他深吸一口气,山风猎猎,吹动他的衣袍。远方,夕阳正缓缓沉入群山之间,将整个天空染成一片壮丽的金红。\\n\\n(宽松模式允许这类情绪渲染和感叹,虽然不直接推进剧情,但有助于氛围塑造和情绪共鸣)\",\r\n \"note\": \"宽松模式:允许较多的情绪渲染和感叹词,只要不是纯粹凑字数\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"maxFillerSentences\": 5,\r\n \"maxFillerWords\": 12,\r\n \"maxDashCount\": 5,\r\n \"maxEllipsisCount\": 5\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 0.9,\r\n \"sensorySignal\": 1.0,\r\n \"action\": 0.8,\r\n \"emotion\": 1.2,\r\n \"infoAdvance\": 0.8\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_vocab_filler\",\r\n \"option_id\": \"opt_filler_standard\",\r\n \"option_name\": \"通用基础(默认)\",\r\n \"option_description\": \"标准填充词检测模式,使用默认阈值。允许适度的填充词和过渡表达,在节奏和精炼之间取得平衡。maxFillerSentences=3, maxFillerWords=8。\",\r\n \"system_prompt\": \"你使用标准填充词检测模式。在这个模式下,明显的空洞填充(重复啰嗦、无意义凑字数)需要删减,但允许适度的过渡词、情绪渲染词和节奏调节词。写作不是电报,适当的铺垫、情绪渲染和过渡连接是必要的。关键标准是:这句话虽然不是核心信息,但它是否在调节节奏、渲染氛围、或者提供必要的缓冲?如果是,可以保留。如果只是单纯重复、凑字数、或者空洞无物,则应该删减。\",\r\n \"constraints\": [\r\n \"每千字填充词句不超过3句\",\r\n \"每千字填充词不超过8个\",\r\n \"允许适度的过渡词和连接词(然而/但是/就在这时等)\",\r\n \"允许适度的情绪渲染词(但不要重复堆砌)\",\r\n \"禁止连续多句无实质内容\",\r\n \"禁止同一段落内重复表达同一个意思\",\r\n \"套路句(倒吸冷气/震惊等)可以偶尔使用,但一章内不超过2次\"\r\n ],\r\n \"vocabulary\": {\r\n \"add\": {\r\n \"fillerPatterns\": [\r\n \"心中暗道\", \"暗自思忖\", \"在心里想着\",\r\n \"倒吸一口冷气\", \"倒吸一口凉气\", \"所有人都惊呆了\",\r\n \"不得不说\", \"话说回来\",\r\n \"不知道为什么\"\r\n ]\r\n }\r\n },\r\n \"examples\": [\r\n {\r\n \"text\": \"他推开那扇门,一股霉味扑面而来。屋子里落满了灰尘,看起来已经很久没有人住过了。\\n\\n他环顾四周,目光最终落在了桌上的一封信上。信封已经泛黄,但上面的字迹还依稀可辨。\\n\\n他走过去,拿起那封信,手指微微有些颤抖——这是父亲的笔迹。\\n\\n(标准模式允许“微微有些颤抖”这类情绪渲染,也允许连接词和过渡,但“实在是太不可思议了他简直不敢相信自己的眼睛”这类重复空洞的表达会被标记为填充)\",\r\n \"note\": \"标准模式:允许适度的描写和情绪渲染,但不允许空洞重复\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"maxFillerSentences\": 3,\r\n \"maxFillerWords\": 8,\r\n \"maxDashCount\": 3,\r\n \"maxEllipsisCount\": 3\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.0,\r\n \"sensorySignal\": 1.0,\r\n \"action\": 1.0,\r\n \"emotion\": 1.0,\r\n \"infoAdvance\": 1.0\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_vocab_filler\",\r\n \"option_id\": \"opt_filler_strict\",\r\n \"option_name\": \"严格模式\",\r\n \"option_description\": \"严格检测填充词/水字数模式,将更多词汇和句式判定为填充。maxFillerSentences=1(每千字最多1句填充),maxFillerWords=4(每千字最多4个填充词)。适合追求精炼文风的作者。\",\r\n \"system_prompt\": \"你使用严格填充词检测模式。在这个模式下,几乎所有空洞无信息量的表达都会被判定为填充并需要删减。严格限制以下类型的表达:无意义的感叹(“真是太……了”“不得不说”)、重复的强调(反复说同一个意思)、空洞的过渡(“话说回来”“值得一提的是”)、冗余的修饰(不必要的形容词和副词堆砌)、凑字数的心理描写(没有实质内容的“他想了想”“心中暗道”之后跟空洞感想)、万能填充句(“周围的人都惊呆了”“倒吸一口冷气”等过度使用的套路句)。每一句话都必须推进剧情、塑造人物或传递信息,否则就该删。\",\r\n \"constraints\": [\r\n \"每千字填充词句不超过1句\",\r\n \"每千字填充词不超过4个\",\r\n \"禁止使用空洞感叹:“真是太……了”“简直……”“不得不说”“不可否认”\",\r\n \"禁止无信息量的心理描写和自言自语\",\r\n \"禁止反复强调同一个信息(说一遍就够)\",\r\n \"禁止套路化万能句滥用(“所有人都惊呆了”“倒吸冷气”等)\",\r\n \"禁止不必要的副词和形容词堆砌\",\r\n \"每个句子都必须有实质功能(推进/塑造/传递信息)\"\r\n ],\r\n \"vocabulary\": {\r\n \"add\": {\r\n \"fillerPatterns\": [\r\n \"不由得\", \"忍不住\", \"不禁\", \"竟然\", \"居然\", \"简直\", \"实在\", \"确实\", \"的确\",\r\n \"非常\", \"十分\", \"极其\", \"相当\", \"格外\", \"异常\",\r\n \"话说回来\", \"值得一提的是\", \"不得不说\", \"不可否认\", \"众所周知\",\r\n \"周围的人都惊呆了\", \"所有人都震惊了\", \"倒吸一口冷气\", \"倒吸一口凉气\",\r\n \"心中暗道\", \"心里想着\", \"暗自思忖\", \"在心里盘算着\",\r\n \"不知道为什么\", \"不知道怎么回事\", \"不知道为什么\",\r\n \"仿佛\", \"好像\", \"似乎\", \"宛如\", \"犹如\",\r\n \"只见\", \"但见\", \"却见\", \"话说\", \"且说\",\r\n \"顿时\", \"霎时\", \"刹那间\", \"转眼间\", \"顷刻间\", \"一瞬间\", \"下一秒\",\r\n \"然而\", \"但是\", \"可是\", \"不过\", \"只是\",\r\n \"事实上\", \"实际上\", \"其实\", \"说实话\", \"老实说\",\r\n \"没想到的是\", \"令人意外的是\", \"出人意料的是\",\r\n \"这个时候\", \"就在这时\", \"正在这时\", \"就在这个时候\"\r\n ]\r\n }\r\n },\r\n \"examples\": [\r\n {\r\n \"text\": \"【填充句-需删除】\\n他实在是太厉害了,简直就是天才中的天才,周围的人都不由得倒吸一口冷气,所有人都震惊了。\\n\\n【修改后-精炼】\\n他赢了。\",\r\n \"note\": \"严格模式:大量修饰词和套路句都被视为填充,应删减到最精炼的表达\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"maxFillerSentences\": 1,\r\n \"maxFillerWords\": 4,\r\n \"maxDashCount\": 1,\r\n \"maxEllipsisCount\": 1\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.0,\r\n \"sensorySignal\": 1.0,\r\n \"action\": 1.1,\r\n \"emotion\": 0.9,\r\n \"infoAdvance\": 1.3\r\n }\r\n}\r\n","{\r\n \"kb_version\": \"2.0\",\r\n \"node_id\": \"node_vocab_filler\",\r\n \"option_id\": \"opt_filler_webnovel\",\r\n \"option_name\": \"网文专属补充\",\r\n \"option_description\": \"网文专属填充词模式,在标准阈值基础上,将网文特有套路句纳入填充词检测范围(如“天地异象”“威压笼罩”“道音隆隆”等过度使用的网文固定句式),但保留网文中必要的节奏词。\",\r\n \"system_prompt\": \"你使用网文专属填充词检测模式。网文有自己独特的套路和句式,其中一些已经被过度使用到变成了纯粹的填充——比如“天地异象”“威压笼罩”“道音隆隆”“气势暴涨”“一股恐怖的气息”等等。这些词第一次用很有气势,但一章出现三次就变成了水字数。这个模式专门针对网文套路词进行检测,在保留网文风格的同时避免过度套路化。常见的网文填充套路包括:反复描写气势/威压(每打一架就“恐怖气息肆虐”)、万能围观反应(“所有人都惊呆了”“倒吸冷气”)、过度感叹(“太强了!”“这怎么可能!”)、重复强调(“他的实力远超想象”“比想象中还要强”反复说)。\",\r\n \"constraints\": [\r\n \"在标准阈值基础上,额外检测网文特有套路填充\",\r\n \"气势/威压描写每场战斗不超过2次\",\r\n \"“天地异象”“道音隆隆”等大场面词每10章最多出现1次\",\r\n \"“所有人都惊呆了”“倒吸冷气”等围观反应每章不超过1次\",\r\n \"禁止连续使用感叹句表达震惊(“太强了!”“这不可能!”“天哪!”连用)\",\r\n \"“气势暴涨”“气息爆发”等升级描写每次突破只写1次\",\r\n \"允许使用网文节奏词和必要套路,但要节制\"\r\n ],\r\n \"vocabulary\": {\r\n \"add\": {\r\n \"fillerPatterns\": [\r\n \"天地异象\", \"威压笼罩\", \"道音隆隆\", \"道音轰鸣\", \"天降异象\",\r\n \"气势暴涨\", \"气息暴涨\", \"气势如虹\", \"气势冲天\", \"威压如山\",\r\n \"一股恐怖的气息\", \"一股强大的气息\", \"一股可怕的威压\",\r\n \"所有人都惊呆了\", \"众人皆惊\", \"满座皆惊\", \"无不骇然\",\r\n \"倒吸一口冷气\", \"倒吸一口凉气\", \"吸了口凉气\",\r\n \"太强了\", \"太可怕了\", \"好强\", \"恐怖如斯\",\r\n \"这怎么可能\", \"不可能\", \"怎么会\",\r\n \"嘴角微微上扬\", \"嘴角勾起一抹弧度\", \"嘴角浮现一抹笑意\",\r\n \"眼中闪过一丝\", \"眸中掠过一抹\", \"眼底深处闪过\",\r\n \"不由得倒吸\", \"忍不住倒吸\", \"不禁倒吸\",\r\n \"心中一惊\", \"心头一震\", \"心中大骇\", \"心神巨震\",\r\n \"轰的一声\", \"轰隆一声\", \"一声巨响\", \"一声爆鸣\",\r\n \"光芒万丈\", \"霞光万道\", \"瑞气千条\", \"金光闪闪\",\r\n \"如同蛟龙出海\", \"宛如猛虎下山\", \"犹如天神下凡\", \"仿佛魔神降世\"\r\n ]\r\n }\r\n },\r\n \"examples\": [\r\n {\r\n \"text\": \"【网文填充-过度套路】\\n他身上爆发出一股恐怖的气息,威压笼罩全场,天地异象频发,道音隆隆,霞光万道,瑞气千条。所有人都惊呆了,纷纷倒吸一口冷气。太强了!这怎么可能!他的实力竟然恐怖如斯!\\n\\n【修改后-适度使用】\\n他突破了。\\n气息从他身上扩散开来,周围的人不自觉地后退了几步。\",\r\n \"note\": \"网文专属模式:将过度使用的网文套路词(天地异象/道音隆隆/恐怖如斯等)标记为填充,但保留必要的节奏词,避免套路堆砌\"\r\n }\r\n ],\r\n \"threshold_overrides\": {\r\n \"maxFillerSentences\": 3,\r\n \"maxFillerWords\": 8,\r\n \"maxDashCount\": 3,\r\n \"maxEllipsisCount\": 3\r\n },\r\n \"radar_weights\": {\r\n \"bodyReaction\": 1.0,\r\n \"sensorySignal\": 0.9,\r\n \"action\": 1.1,\r\n \"emotion\": 1.0,\r\n \"infoAdvance\": 1.0\r\n }\r\n}\r\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_vocab_sensory\",\n \"option_id\": \"opt_vocab_daily\",\n \"option_name\": \"轻小说日常\",\n \"option_description\": \"轻小说日常世界观词库,包含校园、教室、同桌、社团、便当、校服、暑假、打工、同学、老师、便利店、电车、青春等校园日常/轻小说专有词汇。\",\n \"system_prompt\": \"你使用轻小说日常世界观词库。写作时自然融入日式/校园轻小说风格的专有名词和感官描写:课间教室里的喧闹、走廊上运动鞋的吱呀声、便当盒打开时的香味、夕阳透过窗户的金色、电车驶过的哐当声。身体锚点偏细腻:脸颊发烫、耳朵发红、手指绞着裙摆、心砰砰跳、不敢直视对方的眼睛。动作描写要有轻小说味:双手捧书、歪头疑惑、鼓脸生气、扑上去抱、躲在墙角偷看、跑着赶电车。场景:教室、天台、操场、走廊、社团活动室、便利店、电车站、家庭餐厅、公园、卧室。氛围轻松温馨,有青春感和淡淡的萌味。\",\n \"constraints\": [\n \"必须使用校园/日常轻小说专有词汇\",\n \"氛围轻松温馨,有青春感\",\n \"人物互动要萌,适当的傲娇/天然/腹黑等属性可以自然体现\",\n \"感官描写注重:食物香味/夕阳/校服布料感/铃声/电车声\",\n \"对话风格轻快自然,贴近高中生/年轻人的说话方式\",\n \"适当的吐槽和内心吐槽是轻小说的灵魂\"\n ],\n \"vocabulary\": {\n \"add\": {\n \"worldTerms\": [\"校园\", \"教室\", \"同桌\", \"社团\", \"便当\", \"校服\", \"暑假\", \"打工\", \"同学\", \"老师\", \"便利店\", \"电车\", \"青春\", \"高中\", \"初中\", \"学生\", \"学长\", \"学姐\", \"学弟\", \"学妹\", \"班级\", \"班主任\", \"班长\", \"值日生\", \"课间\", \"午休\", \"放学\", \"上课\", \"下课\", \"考试\", \"测验\", \"作业\", \"暑假作业\", \"社团活动\", \"文化祭\", \"体育祭\", \"修学旅行\", \"毕业\", \"入学\", \"开学典礼\", \"毕业典礼\", \"天台\", \"操场\", \"体育馆\", \"图书馆\", \"食堂\", \"鞋柜\", \"走廊\", \"学生会\", \"风纪委员\", \"转学生\", \"班长\", \"校花\", \"校草\", \"学霸\", \"学渣\", \"制服\", \"水手服\", \"西装校服\", \"领结\", \"领带\", \"百褶裙\", \"白衬衫\", \"毛衣背心\", \"运动鞋\", \"室内鞋\", \"书包\", \"双肩包\", \"便当盒\", \"手工便当\", \"小卖部\", \"面包\", \"牛奶\", \"草莓牛奶\", \"便利店\", \"自动贩卖机\", \"电车\", \"公交车\", \"自行车\", \"车站\", \"站台\", \"家庭餐厅\", \"咖啡厅\", \"快餐店\", \"汉堡\", \"薯条\", \"可乐\", \"奶茶\", \"冰淇淋\", \"可丽饼\", \"章鱼烧\", \"炒面面包\", \"朋友\", \"闺蜜\", \"死党\", \"室友\", \"邻居\", \"青梅竹马\", \"初恋\", \"告白\", \"约会\", \"情书\", \"情人节\", \"巧克力\", \"白色情人节\", \"圣诞节\", \"新年\", \"烟花大会\", \"夏日祭\", \"浴衣\", \"庙会\", \"捞金鱼\", \"烟花\", \"部活\", \"足球部\", \"篮球部\", \"棒球部\", \"网球部\", \"田径部\", \"游泳部\", \"美术部\", \"音乐部\", \"文学社\", \"戏剧社\", \"茶道部\", \"轻音部\", \"游戏部\", \"动漫社\", \"宅\", \"二次元\", \"轻小说\", \"漫画\", \"动画\", \"游戏\", \"Galgame\", \"手游\", \"抽卡\", \"氪金\", \"手办\", \"痛包\", \"cosplay\", \"打工\", \"兼职\", \"时薪\", \"排班\", \"加班费\", \"妹妹\", \"姐姐\", \"弟弟\", \"哥哥\", \"妹妹头\", \"傲娇\", \"天然呆\", \"腹黑\", \"元气\", \"三无\", \"毒舌\", \"治愈\", \"萌\", \"卡哇伊\", \"吐槽\", \"残念\", \"意外地\", \"难道\", \"果然\", \"诶\", \"诶多\", \"呜哇\", \"呀\", \"呐\", \"嘛\", \"的说\"],\n \"bodyParts\": [\"脸颊\", \"耳朵\", \"发梢\", \"指尖\", \"裙摆\", \"刘海\", \"眼睛\", \"睫毛\", \"嘴角\", \"心\"],\n \"sensoryVerbs\": [\"脸颊发烫\", \"耳朵变红\", \"心跳加速\", \"闻到便当香味\", \"听到下课铃声\", \"看到夕阳金色光芒\", \"感到校服布料摩擦\", \"听到电车哐当声\", \"尝到草莓牛奶的甜味\", \"听到走廊脚步声\", \"感到风拂过发梢\", \"看到对方脸红\", \"手指绞着裙摆\", \"心砰砰直跳\", \"肚子咕咕叫\", \"闻到面包香气\", \"听到运动鞋吱呀声\"],\n \"actionVerbs\": [\"歪头\", \"鼓脸\", \"扑上去\", \"躲在墙角偷看\", \"跑着赶电车\", \"双手捧着便当\", \"挠头\", \"叹气\", \"嘟嘴\", \"吐舌头\", \"双手叉腰\", \"低头鞠躬\", \"挥手\", \"招手\", \"拽袖子\", \"拉衣角\", \"递情书\", \"脸红着跑开\", \"躲在门后\", \"偷偷看\", \"做便当\", \"打开便当盒\", \"吃面包\", \"喝牛奶\", \"买饮料\", \"骑自行车\", \"坐电车\", \"赶电车\", \"跑着上学\", \"迟到了\", \"举手回答\", \"打瞌睡\", \"传小纸条\", \"踢小石子\", \"看云\", \"趴在桌上\", \"撑下巴\", \"翻书\", \"写字\", \"考试\", \"交作业\", \"打扫卫生\", \"擦黑板\", \"倒垃圾\", \"社团活动\", \"练习\", \"跑步\", \"打球\", \"游泳\", \"画画\", \"弹琴\", \"唱歌\", \"打游戏\", \"约会\", \"告白\", \"牵手\", \"送巧克力\", \"放烟花\", \"穿浴衣\", \"捞金鱼\", \"吃章鱼烧\", \"看烟花\", \"一起回家\", \"并肩走\", \"送回家\", \"挥手道别\", \"打工\", \"收银\", \"整理货架\", \"做咖啡\", \"端盘子\", \"鞠躬道歉\", \"微笑\", \"偷笑\", \"坏笑\", \"苦笑\", \"无奈地笑\", \"眼睛发亮\", \"眼睛湿润\", \"眼泪打转\", \"揉眼睛\", \"打哈欠\", \"伸懒腰\"],\n \"environmentSignals\": [\"下课铃响\", \"教室喧闹\", \"走廊上运动鞋吱呀\", \"便当盒打开的香味\", \"夕阳金色光芒\", \"电车哐当驶过\", \"操场上传来哨声\", \"粉笔灰在阳光中飞舞\", \"自动贩卖机嗡嗡声\", \"便利店叮咚声\", \"蝉鸣声声\", \"夏日阳光刺眼\", \"樱花飘落\", \"风吹过树叶沙沙\", \"雨滴打窗户\", \"暖气的味道\", \"校服洗衣粉的味道\", \"面包刚出炉的香气\", \"走廊回荡着脚步声\"],\n \"dialogueTags\": [\"说道\", \"小声说\", \"鼓起勇气说\", \"嘟囔道\", \"抱怨道\", \"笑着说\", \"惊讶地说\", \"红着脸说\", \"低头说\", \"抬头说\", \"歪头问\", \"认真地说\", \"开玩笑地说\", \"无奈地说\", \"兴奋地说\", \"紧张地说\", \"小声嘀咕\", \"在心里吐槽道\", \"叹气说\", \"眨眨眼说\"]\n }\n },\n \"examples\": [\n {\n \"text\": \"「哟,今天也带了便当啊?」\\n\\n前桌的山田转过头来,眼睛直勾勾地盯着我桌上的便当盒。\\n\\n「我妈妈做的。」我把便当盒往自己这边挪了挪,「你别想了,今天没有多余的。」\\n\\n「小气——」山田拖长了语调,却被走进教室的班主任打断了。\\n\\n第一节课是数学。我偷偷把便当盒塞进抽屉里,却发现旁边多了一个粉色的信封。\\n\\n我的心跳漏了一拍。\\n\\n信封上没有署名,只写着「二年A班 高桥悠太君收」,字迹很秀气,是女孩子写的。\\n\\n我偷偷瞄了一眼斜前方——同桌的铃木雪正低头翻着课本,侧脸在清晨的阳光中显得格外好看,耳朵尖却微微泛红。\\n\\n诶?\\n\\n难道……\",\n \"note\": \"轻小说日常词库示例:便当/教室/数学/同学/信封/情书/同桌/夕阳/校服等校园词汇,氛围轻松有青春感,结尾留悬念\"\n }\n ],\n \"threshold_overrides\": {\n \"maxParagraphLength\": 100,\n \"targetParagraphLength\": 50,\n \"shortSentenceRatio\": 0.5,\n \"targetSentenceLength\": 18,\n \"minSensoryTypes\": 2\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.3,\n \"sensorySignal\": 1.2,\n \"action\": 0.8,\n \"emotion\": 1.4,\n \"infoAdvance\": 0.7\n }\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_vocab_sensory\",\n \"option_id\": \"opt_vocab_esports\",\n \"option_name\": \"游戏竞技\",\n \"option_description\": \"游戏竞技/电竞世界观词库,包含电竞、操作、技能、CD、走位、团战、打野、中单、ADC、辅助、段位、排位、直播、弹幕、键盘、鼠标等电竞游戏专有词汇。\",\n \"system_prompt\": \"你使用游戏竞技/电竞世界观词库。写作时自然融入电竞游戏的专有名词和感官描写:机械键盘的噼啪声、鼠标快速点击的嗒嗒声、耳机里队友的嘶吼、屏幕上技能特效的炫光、手心的汗让鼠标打滑。身体锚点注重电竞特色:手指在键盘上飞舞、眼睛死死盯着屏幕、后背僵直、心跳随着团战节奏加速、手腕因为长时间操作酸痛。动作描写要有电竞味:秒选英雄、闪现开团、走位躲技能、补刀、gank、推塔、五杀、翻盘。场景:电竞馆比赛舞台、训练室、直播间、网吧、选手休息室。\",\n \"constraints\": [\n \"必须使用电竞游戏专有词汇,游戏术语要准确\",\n \"比赛描写要有节奏感:前期发育/中期游走/后期团战\",\n \"团队配合是重点:沟通/指挥/默契/失误/翻盘\",\n \"感官描写注重:键盘声/鼠标声/耳机里的喊叫/屏幕光/手心汗\",\n \"对话包含队内语音交流,要有电竞选手说话的风格(简洁/激动/术语密集)\",\n \"比赛描写要让不懂游戏的读者也能感受到紧张和激情\"\n ],\n \"vocabulary\": {\n \"add\": {\n \"worldTerms\": [\"电竞\", \"操作\", \"技能\", \"CD\", \"走位\", \"团战\", \"打野\", \"中单\", \"ADC\", \"辅助\", \"上单\", \"段位\", \"排位\", \"直播\", \"弹幕\", \"键盘\", \"鼠标\", \"耳机\", \"显示器\", \"电竞椅\", \"机械键盘\", \"游戏鼠标\", \"职业选手\", \"战队\", \"俱乐部\", \"教练\", \"经理\", \"分析师\", \"替补\", \"首发\", \"训练赛\", \"常规赛\", \"季后赛\", \"总决赛\", \"世界赛\", \"冠军\", \"亚军\", \"MVP\", \"FMVP\", \"五杀\", \"四杀\", \"三杀\", \"超神\", \"暴走\", \"翻盘\", \"碾压\", \"逆风\", \"顺风\", \"经济\", \"经验\", \"等级\", \"装备\", \"出装\", \"神装\", \"大件\", \"小件\", \"出门装\", \"神装\", \"召唤师技能\", \"闪现\", \"引燃\", \"惩戒\", \"治疗\", \"传送\", \"疾跑\", \"净化\", \"护盾\", \"英雄\", \"版本\", \"T0\", \"T1\", \"T2\", \"强势\", \"削弱\", \"加强\", \"补丁\", \"BP\", \"选角\", \"ban\", \"pick\", \"counter\", \"康特\", \"对线\", \"补刀\", \"压刀\", \"单杀\", \"gank\", \"反蹲\", \"游走\", \"支援\", \"开团\", \"先手\", \"后手\", \"控制\", \"眩晕\", \"沉默\", \"减速\", \"击飞\", \"击退\", \"秒杀\", \"残血\", \"丝血\", \"满血\", \"回血\", \"吸血\", \"暴击\", \"伤害\", \"输出\", \"爆发\", \"持续输出\", \"poke\", \"风筝\", \"坦克\", \"肉盾\", \"战士\", \"刺客\", \"法师\", \"射手\", \"辅助\", \"推塔\", \"守塔\", \"高地\", \"水晶\", \"基地\", \"门牙塔\", \"大龙\", \"小龙\", \"男爵\", \"巨龙\", \"红蓝buff\", \"视野\", \"眼位\", \"排眼\", \"插眼\", \"扫描\", \"真眼\", \"假眼\", \"河道\", \"野区\", \"蓝buff\", \"红buff\", \"草丛\", \"中路\", \"上路\", \"下路\", \"野区\", \"一血塔\", \"镀层\", \"兵线\", \"补兵\", \"控线\", \"推线\", \"断线\", \"回城\", \"B键\", \"泉水\", \"复活\", \"死亡\", \"阵亡\", \"送人头\", \"演员\", \"挂机\", \"喷子\", \"666\", \"牛逼\", \"牛皮\", \"菜\", \"下饭\", \"离谱\", \"这波\", \"血赚\", \"血亏\", \"不亏\", \"稳了\", \"GG\", \"暂停\", \"网络波动\", \"延迟\", \"ping值\", \"FPS\", \"卡顿\", \"掉线\", \"重连\", \"键盘\", \"黑轴\", \"红轴\", \"青轴\", \"鼠标DPI\", \"鼠标垫\", \"电竞椅\", \"隔音耳机\", \"隔音室\", \"比赛服\", \"韩服\", \"国服\", \"峡谷之巅\", \"王者\", \"大师\", \"钻石\", \"铂金\", \"黄金\", \"白银\", \"青铜\", \"黑铁\", \"最高分\", \"第一\", \"登顶\", \"rank分\", \"巅峰赛\"],\n \"bodyParts\": [\"手指\", \"指尖\", \"手腕\", \"眼睛\", \"瞳孔\", \"后背\", \"手心\", \"拇指\", \"食指\", \"颈椎\"],\n \"sensoryVerbs\": [\"听到键盘噼啪作响\", \"听到鼠标快速点击\", \"听到耳机里队友嘶吼\", \"看到屏幕技能闪光\", \"手心出汗\", \"眼睛死死盯着屏幕\", \"心跳加速\", \"手腕酸痛\", \"感到肾上腺素飙升\", \"听到观众欢呼\", \"看到弹幕刷屏\", \"感到鼠标被汗水打滑\", \"听到解说大喊\"],\n \"actionVerbs\": [\"秒选英雄\", \"锁定英雄\", \"闪现开团\", \"闪现接大\", \"走位躲避\", \"走位扭掉\", \"补刀\", \"A兵\", \"放技能\", \"交闪现\", \"交惩戒\", \"gank\", \"反蹲\", \"游走支援\", \"开团\", \"先手开团\", \"后手接团\", \"控制链接上\", \"秒杀C位\", \"切掉后排\", \"收割残血\", \"推塔\", \"拿龙\", \"打大龙\", \"打小龙\", \"抢龙\", \"抢大龙\", \"插眼\", \"排眼\", \"回城\", \"买装备\", \"出装\", \"换装备\", \"嗑药\", \"喝血瓶\", \"升级技能\", \"点大招\", \"连招\", \"一套带走\", \"丝血反杀\", \"残血逃生\", \"越塔强杀\", \"塔下反杀\", \"五杀\", \"四杀\", \"超神\", \"翻盘\", \"碾压\", \"被单杀\", \"被gank\", \"被反蹲\", \"被秒杀\", \"黑屏\", \"复活\", \"TP支援\", \"传送绕后\", \"带线\", \"偷家\", \"守家\", \"点水晶\", \"推基地\", \"打出GG\", \"握手\", \"接受采访\", \"开直播\", \"打排位\", \"打训练赛\", \"复盘\", \"看录像\", \"练英雄\", \"练操作\", \"打rank\"],\n \"environmentSignals\": [\"键盘噼啪作响\", \"鼠标嗒嗒点击\", \"耳机里队友大喊\", \"屏幕荧光映在脸上\", \"电竞馆灯光聚焦\", \"观众席欢呼声如雷\", \"弹幕疯狂刷屏\", \"解说声嘶力竭\", \"空调冷气很足但手心全是汗\", \"隔音室里只有键盘声\", \"比赛服倒计时\", \"Victory/Defeat画面亮起\"],\n \"dialogueTags\": [\"在语音里大喊\", \"急促地说\", \"吼道\", \"喊道\", \"冷静地说\", \"语速飞快地说\", \"对着麦克风说\", \"打字道\", \"沉声说\", \"兴奋地喊道\", \"懊恼地说\", \"指挥道\", \"大声道\", \"在队内频道说\"]\n }\n },\n \"examples\": [\n {\n \"text\": \"\\\"RNG对阵T1,决胜局,第三十分钟!\\\"\\n\\n解说的声音透过耳机传来,但林烨已经听不到了。他的世界里只剩下屏幕上的英雄、右下角的小地图,以及手指下噼啪作响的机械键盘。\\n\\n\\\"大龙!他们在打大龙!\\\"辅助的声音从耳机里炸开。\\n\\n林烨的瞳孔猛地收缩。他操控的妖姬此刻只有半血,技能CD还剩三秒,但他没有犹豫——手指在键盘上划出一道残影,W技能魔影迷踪踩下去,正好落在龙坑上方。\\n\\n\\\"我看到了!打野残血!\\\"\\n\\n他按下R键复制W,二段位移直接踩进龙坑!QRE连招在0.3秒内全部打出,T1打野的血条瞬间蒸发。\\n\\n\\\"抢了!大龙被抢了!!!\\\"\\n\\n惩戒落下的那一刻,大龙的哀鸣响彻整个召唤师峡谷。林烨的妖姬借着W的返回位移安全撤出龙坑,血条只剩最后一丝——37点血。\\n\\n屏幕上,T1四人的头像齐刷刷变成灰色。\\n\\n\\\"Penta Kill!!!\\\"\\n\\n电竞馆炸了。\",\n \"note\": \"电竞词库示例:大龙/妖姬/技能CD/W技能/惩戒/位移/连招/Penta Kill/解说/电竞馆/机械键盘等电竞词汇,节奏紧张\"\n }\n ],\n \"threshold_overrides\": {\n \"maxParagraphLength\": 80,\n \"targetParagraphLength\": 40,\n \"shortSentenceRatio\": 0.6,\n \"targetSentenceLength\": 15\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.3,\n \"sensorySignal\": 1.0,\n \"action\": 1.5,\n \"emotion\": 1.3,\n \"infoAdvance\": 1.0\n }\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_vocab_sensory\",\n \"option_id\": \"opt_vocab_fantasy\",\n \"option_name\": \"西方奇幻\",\n \"option_description\": \"西方奇幻世界观词库,包含魔法、精灵、矮人、龙、骑士、剑、法杖、城堡、巨龙、地精、巫术、咒语、卷轴、公会、王国等西方奇幻专有词汇。\",\n \"system_prompt\": \"你使用西方奇幻世界观词库。写作时自然融入西方奇幻的专有名词和感官描写:盔甲碰撞的铿锵声、火炬噼啪燃烧的气味、魔法涌动时的空气震颤、龙息的灼热、酒馆里麦酒和烤肉的混合气味。身体锚点可以包括:盔甲的重量压在肩上、剑柄磨出的老茧、魔法反噬时的血脉偾张、长弓弓弦勒入指尖。动作描写要有奇幻味:拔剑出鞘、吟诵咒语、施放火球、举起盾牌、骑乘巨龙、锻造武器。场景:中世纪城堡、幽暗森林、矮人矿洞、精灵圣地、魔法师塔、冒险者公会、酒馆、龙穴。\",\n \"constraints\": [\n \"必须使用西方奇幻专有词汇,避免混入东方修仙词汇\",\n \"魔法体系要有规则,不能随意施放无代价的魔法\",\n \"种族特色鲜明:精灵优雅/矮人粗犷/地精狡猾/巨龙傲慢\",\n \"感官描写注重:盔甲金属声/火炬气味/魔法震颤/麦酒香\",\n \"对话风格偏中世纪/欧式,可以适当使用古雅措辞\",\n \"战斗描写要有冷兵器时代的质感:剑与盾/弓与箭/魔法与铠甲\"\n ],\n \"vocabulary\": {\n \"add\": {\n \"worldTerms\": [\"魔法\", \"精灵\", \"矮人\", \"龙\", \"骑士\", \"剑\", \"法杖\", \"城堡\", \"巨龙\", \"地精\", \"巫术\", \"咒语\", \"卷轴\", \"公会\", \"王国\", \"国王\", \"王后\", \"王子\", \"公主\", \"领主\", \"公爵\", \"伯爵\", \"男爵\", \"爵士\", \"骑士团\", \"圣骑士\", \"魔法师\", \"巫师\", \"术士\", \"德鲁伊\", \"游侠\", \"盗贼\", \"战士\", \"弓箭手\", \"牧师\", \"祭司\", \"冒险者\", \"佣兵\", \"英雄\", \"魔王\", \"魔族\", \"兽人\", \"巨魔\", \"精灵族\", \"矮人族\", \"人类\", \"半身人\", \"龙族\", \"亡灵\", \"吸血鬼\", \"狼人\", \"恶魔\", \"天使\", \"神明\", \"神殿\", \"教堂\", \"修道院\", \"魔法塔\", \"法师塔\", \"学院\", \"地下城\", \"地牢\", \"迷宫\", \"洞穴\", \"矿洞\", \"森林\", \"幽暗密林\", \"山脉\", \"河流\", \"湖泊\", \"海洋\", \"港口\", \"村庄\", \"小镇\", \"都城\", \"王城\", \"要塞\", \"堡垒\", \"城墙\", \"城门\", \"吊桥\", \"护城河\", \"酒馆\", \"客栈\", \"铁匠铺\", \"商店\", \"市场\", \"竞技场\", \"训练场\", \"马厩\", \"剑\", \"长剑\", \"巨剑\", \"短剑\", \"匕首\", \"弓\", \"长弓\", \"弩\", \"箭\", \"盾牌\", \"铠甲\", \"板甲\", \"锁子甲\", \"皮甲\", \"头盔\", \"法杖\", \"魔杖\", \"权杖\", \"魔法书\", \"魔药\", \"药水\", \"卷轴\", \"符文\", \"宝石\", \"水晶球\", \"金币\", \"银币\", \"铜币\", \"任务\", \"委托\", \"冒险\", \"探索\", \"远征\", \"屠龙\", \"预言\", \"传说\", \"古老的\", \"神秘的\", \"附魔\", \"诅咒\", \"祝福\", \"圣光\", \"暗影\", \"元素\", \"火焰\", \"冰霜\", \"雷电\", \"自然\", \"奥术\", \"死灵\", \"召唤\", \"幻术\", \"治愈\", \"龙息\", \"龙鳞\", \"龙晶\", \"龙穴\", \"宝藏\", \"圣剑\", \"魔戒\", \"神器\", \"圣物\"],\n \"bodyParts\": [\"持剑的手\", \"弓弦勒入的指尖\", \"盔甲下的肩膀\", \"膝盖\", \"剑柄老茧\", \"伤疤\", \"血脉\"],\n \"sensoryVerbs\": [\"听到盔甲铿锵\", \"闻到火炬烟味\", \"感到魔法震颤\", \"感到龙息灼热\", \"闻到麦酒香\", \"听到剑刃碰撞\", \"看到魔法光芒\", \"感到冰冷的铁甲\", \"听到龙吼\", \"闻到硫磺味\", \"听到箭矢破空\", \"感到阴影逼近\", \"听到咒语吟唱\", \"看到符文亮起\"],\n \"actionVerbs\": [\"拔剑\", \"拔剑出鞘\", \"举剑\", \"挥剑\", \"劈砍\", \"刺击\", \"格挡\", \"举盾\", \"张弓搭箭\", \"射箭\", \"装填弩箭\", \"吟诵咒语\", \"施放魔法\", \"释放火球\", \"召唤生物\", \"治疗伤口\", \"潜行\", \"开锁\", \"翻滚闪避\", \"冲锋\", \"骑乘\", \"驾驭巨龙\", \"锻造\", \"附魔\", \"调配魔药\", \"抄写卷轴\", \"祈祷\", \"祝福\", \"诅咒\", \"隐身\", \"传送\", \"变形\", \"冥想\", \"恢复魔力\", \"喝药水\", \"使用卷轴\", \"破甲\", \"刺穿\", \"斩首\", \"屠龙\", \"接任务\", \"交任务\", \"升级\", \"休息\", \"扎营\", \"旅行\", \"探险\", \"进入地牢\", \"开宝箱\", \"搜刮战利品\"],\n \"environmentSignals\": [\"火炬噼啪燃烧\", \"盔甲铿锵作响\", \"麦酒香气四溢\", \"烤肉滋滋冒油\", \"魔法光芒闪烁\", \"龙息灼热扑面\", \"箭矢破空之声\", \"战马嘶鸣\", \"乌鸦嘎嘎叫\", \"阴风阵阵\", \"圣光普照\", \"暗影蠕动\", \"符文亮起\", \"石板路回响\", \"铁链叮当\", \"钟声响彻\", \"号角长鸣\", \"战鼓擂动\"],\n \"dialogueTags\": [\"沉声道\", \"怒吼道\", \"冷笑道\", \"缓缓道\", \"高声道\", \"低声说\", \"咆哮道\", \"吟诵道\", \"吟唱着\", \"命令道\", \"恳求道\", \"大笑道\", \"讥讽道\", \"庄重地说\", \"用古语念道\", \"粗声粗气道\", \"优雅地说\"]\n }\n },\n \"examples\": [\n {\n \"text\": \"酒馆的门被推开,一阵冷风裹着雨丝灌进来。\\n\\n来人穿着一件湿透的灰色斗篷,兜帽压得很低,腰间挂着一把用旧布缠着的长剑。他走到吧台前,把几枚铜币拍在潮湿的木台上:\\\"麦酒,热的。\\\"\\n\\n酒馆老板打量了他一眼——斗篷下露出锁子甲的领口,靴子上沾满了泥和血,走路时右手始终不离剑柄。佣兵,而且是刚从战场上下来的那种。\\n\\n\\\"北边的仗打完了?\\\"老板一边倒酒一边问。\\n\\n来人摘下兜帽,露出一张年轻但疲惫的脸,左脸上有一道还没愈合的刀疤。他端起酒杯喝了一大口,麦酒的热气让他的脸色稍微好了一些。\\n\\n\\\"仗永远打不完。\\\"他放下酒杯,目光扫过酒馆里稀稀拉拉的客人,最后停在角落的一个戴兜帽的身影上——那人面前的桌上放着一根黑木法杖,杖头镶嵌的暗红色宝石,在昏暗中微微发着光。\\n\\n他认得那种宝石。那是只有暗影法师才使用的灵魂石。\",\n \"note\": \"西方奇幻词库示例:酒馆/麦酒/锁子甲/长剑/佣兵/法杖/暗影法师/灵魂石/斗篷等西方奇幻词汇自然融入\"\n }\n ],\n \"threshold_overrides\": {},\n \"radar_weights\": {\n \"bodyReaction\": 1.0,\n \"sensorySignal\": 1.2,\n \"action\": 1.2,\n \"emotion\": 0.9,\n \"infoAdvance\": 1.0\n }\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_vocab_sensory\",\n \"option_id\": \"opt_vocab_generic\",\n \"option_name\": \"通用现代(默认)\",\n \"option_description\": \"通用现代词库,使用基础词汇即可,不额外添加题材专有词汇。适用于不涉及特定题材设定的通用现代故事。\",\n \"system_prompt\": \"你使用通用现代词库。不额外添加特定题材的专有词汇,使用标准现代汉语写作。适用于不涉及特殊世界观(修仙/科幻/奇幻等)的通用现代背景故事。词汇以日常通用词汇为主,身体锚点使用基础词汇(手/脚/眼/心/肩膀/背/手指等),感官动词使用通用表达(看到/听到/闻到/摸到/感到),动作动词使用通用词汇。如果故事涉及特定场景,可以自然使用该场景的常见词汇,但不需要系统性的题材词库。\",\n \"constraints\": [\n \"使用标准现代汉语通用词汇\",\n \"不引入特定题材(修仙/科幻/奇幻/军事等)的专有词汇体系\",\n \"身体锚点使用基础词汇(手/脚/眼/心/背/肩/手指等)\",\n \"感官描写使用通用表达,不依赖题材特色词汇\",\n \"适用于现代日常、都市情感、一般小说等通用场景\"\n ],\n \"vocabulary\": {\n \"add\": {}\n },\n \"examples\": [\n {\n \"text\": \"清晨的阳光透过窗帘缝隙照进来,在地板上拉出一道金色的线。\\n\\n我睁开眼,看了看床头的闹钟——六点四十五。比闹钟早响了十五分钟。\\n\\n躺在床上又赖了几分钟,我才起身穿好衣服,走进卫生间洗漱。冷水泼在脸上,整个人清醒了不少。\\n\\n厨房里飘来豆浆的香味,妈妈已经在做早饭了。\\n\\n「醒了?赶紧洗漱完来吃,今天不是要面试吗?」\\n\\n「知道了。」\\n\\n我对着镜子理了理衣领,深吸一口气。今天的面试很重要,是我投了几十份简历才拿到的机会。\\n\\n加油,我对自己说。\",\n \"note\": \"通用现代词库示例:使用基础词汇(阳光/闹钟/卫生间/豆浆/面试/镜子等),不涉及特殊题材专有名词,通用日常场景\"\n }\n ],\n \"threshold_overrides\": {},\n \"radar_weights\": {\n \"bodyReaction\": 1.0,\n \"sensorySignal\": 1.0,\n \"action\": 1.0,\n \"emotion\": 1.0,\n \"infoAdvance\": 1.0\n }\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_vocab_sensory\",\n \"option_id\": \"opt_vocab_historical\",\n \"option_name\": \"历史架空\",\n \"option_description\": \"历史架空世界观词库,包含朝堂、科举、圣旨、衙门、江湖、武功、内力、轻功、剑法、镖局、客栈、皇帝、大臣、将军、兵马等古代/武侠专有词汇。\",\n \"system_prompt\": \"你使用历史架空世界观词库。写作时自然融入古代历史和武侠的专有名词和感官描写:宣纸的墨香、刀剑出鞘的冷光、客栈里酒菜的香味、朝堂上玉笏碰撞的清脆声、马蹄踏碎石板的轰鸣。身体锚点注重武侠特色:丹田内力涌动、剑气侵入肌肤、轻功提纵时的耳旁风声、穴位被点时的酸麻。动作描写要有古代/武侠味:抱拳行礼、拔剑出鞘、施展轻功、策马奔腾、跪拜接旨、举杯邀饮。场景:金銮殿、县衙大堂、江湖客栈、镖局、武林大会、青楼、书房校场、边关战场。\",\n \"constraints\": [\n \"必须使用古代/武侠专有词汇,避免出现现代词汇\",\n \"历史称谓要准确(朕/臣/在下/姑娘/客官等)\",\n \"武功描写要有武侠味:内力/轻功/招式/穴位/剑法\",\n \"官场礼仪和科举制度要符合古代逻辑\",\n \"感官描写注重:墨香/刀剑寒光/马蹄声/酒菜香/血腥味\",\n \"对话风格半文半白,符合古人说话方式但不要过于晦涩\"\n ],\n \"vocabulary\": {\n \"add\": {\n \"worldTerms\": [\"朝堂\", \"科举\", \"圣旨\", \"衙门\", \"江湖\", \"武功\", \"内力\", \"轻功\", \"剑法\", \"镖局\", \"客栈\", \"皇帝\", \"大臣\", \"将军\", \"兵马\", \"皇上\", \"陛下\", \"万岁\", \"太子\", \"王爷\", \"丞相\", \"宰相\", \"尚书\", \"大人\", \"下官\", \"草民\", \"奴才\", \"奴婢\", \"在下\", \"鄙人\", \"小可\", \"姑娘\", \"公子\", \"客官\", \"店家\", \"掌柜\", \"小二\", \"侠客\", \"剑客\", \"高手\", \"宗师\", \"掌门\", \"帮主\", \"教主\", \"盟主\", \"长老\", \"弟子\", \"徒弟\", \"师父\", \"师娘\", \"师兄\", \"师弟\", \"师姐\", \"师妹\", \"秀才\", \"举人\", \"进士\", \"状元\", \"榜眼\", \"探花\", \"科举\", \"乡试\", \"会试\", \"殿试\", \"金榜\", \"文官\", \"武将\", \"兵马\", \"大军\", \"军队\", \"士兵\", \"将士\", \"精兵\", \"铁骑\", \"骑兵\", \"步兵\", \"弓箭手\", \"阵营\", \"叛军\", \"敌军\", \"边关\", \"战场\", \"城门\", \"城墙\", \"护城河\", \"城楼\", \"战鼓\", \"号角\", \"烽火\", \"狼烟\", \"剑\", \"刀\", \"枪\", \"戟\", \"斧\", \"弓\", \"箭\", \"暗器\", \"飞镖\", \"毒针\", \"长剑\", \"宝刀\", \"名剑\", \"神兵\", \"内力\", \"真气\", \"丹田\", \"经脉\", \"穴位\", \"轻功\", \"点穴\", \"暗器\", \"毒药\", \"解药\", \"内功\", \"外功\", \"招式\", \"剑法\", \"刀法\", \"拳法\", \"掌法\", \"腿法\", \"心法\", \"口诀\", \"秘笈\", \"武林\", \"江湖\", \"门派\", \"少林\", \"武当\", \"峨眉\", \"丐帮\", \"魔教\", \"邪派\", \"正道\", \"黑道\", \"白道\", \"比武\", \"切磋\", \"决斗\", \"擂台\", \"武林大会\", \"英雄帖\", \"仇杀\", \"恩怨\", \"江湖规矩\", \"道义\", \"侠义\", \"圣旨\", \"诏书\", \"奏折\", \"上朝\", \"退朝\", \"觐见\", \"跪拜\", \"吾皇万岁\", \"大人明察\", \"下官不敢\", \"臣遵旨\", \"接旨\", \"谢主隆恩\", \"京城\", \"都城\", \"皇城\", \"皇宫\", \"金銮殿\", \"御书房\", \"后宫\", \"县衙\", \"府衙\", \"公堂\", \"大牢\", \"天牢\", \"午门\", \"菜市口\", \"驿站\", \"茶馆\", \"酒楼\", \"青楼\", \"当铺\", \"药铺\", \"医馆\", \"集市\", \"街巷\", \"胡同\", \"府邸\", \"宅院\", \"书房\", \"花园\", \"厢房\", \"客栈\", \"客房\", \"天字一号房\", \"马车\", \"轿子\", \"骏马\", \"官道\", \"山路\", \"驿站\", \"渡口\", \"码头\", \"船\", \"剑\", \"扇\", \"玉坠\", \"玉佩\", \"扳指\", \"官印\", \"兵符\", \"令牌\", \"腰牌\", \"银票\", \"银子\", \"铜钱\", \"金叶子\", \"文房四宝\", \"宣纸\", \"毛笔\", \"墨锭\", \"砚台\", \"字画\", \"古籍\", \"书信\", \"密信\", \"飞鸽传书\"],\n \"bodyParts\": [\"丹田\", \"经脉\", \"穴位\", \"手腕\", \"虎口\", \"掌心\", \"百会穴\", \"檀中穴\", \"涌泉穴\", \"命门\", \"天灵盖\", \"琵琶骨\", \"肩井穴\"],\n \"sensoryVerbs\": [\"感到内力涌动\", \"听到刀剑出鞘\", \"闻到墨香\", \"感到剑气逼人\", \"听到马蹄声\", \"闻到酒香\", \"感到风声过耳\", \"看到刀光一闪\", \"感到点穴的酸麻\", \"听到号角长鸣\", \"闻到血腥味\", \"感到杀气\", \"听到衣袂破空声\", \"看到剑光如练\", \"感到真气在经脉中运转\"],\n \"actionVerbs\": [\"抱拳\", \"行礼\", \"作揖\", \"跪拜\", \"磕头\", \"接旨\", \"拔剑\", \"拔剑出鞘\", \"收剑入鞘\", \"挥剑\", \"出刀\", \"劈出一刀\", \"刺出一剑\", \"施展轻功\", \"提纵\", \"纵身一跃\", \"点穴\", \"解穴\", \"运功\", \"疗伤\", \"调息\", \"打坐\", \"运内力\", \"策马\", \"策马奔腾\", \"翻身下马\", \"拱手\", \"举杯\", \"饮酒\", \"品茶\", \"提笔\", \"写字\", \"作画\", \"抚琴\", \"下棋\", \"挥毫\", \"研墨\", \"翻开密信\", \"飞鸽传书\", \"掷杯为号\", \"拍案而起\", \"拂袖而去\", \"翻身上马\", \"抽刀\", \"格挡\", \"闪避\", \"飞身\", \"腾空\", \"踏雪无痕\", \"凌波微步\", \"策马扬鞭\", \"鸣金收兵\", \"击鼓进军\", \"射箭\", \"拉弓\", \"拔刀相向\", \"亮剑\", \"敬酒\", \"罚酒\", \"告辞\", \"留步\", \"请罪\", \"谢恩\", \"上奏\"],\n \"environmentSignals\": [\"墨香扑鼻\", \"刀剑出鞘冷光一闪\", \"马蹄踏碎石板\", \"酒香四溢\", \"号角长鸣\", \"战鼓雷动\", \"衣袂猎猎\", \"剑气纵横\", \"杀气弥漫\", \"烛火摇曳\", \"更鼓声起\", \"鸡鸣声\", \"梆子声\", \"铁链哗啦\", \"玉笏碰撞清脆声\", \"铜锣声响\", \"马蹄声如雷\", \"旌旗猎猎\", \"狼烟冲天\", \"烽火燃起\"],\n \"dialogueTags\": [\"沉声道\", \"朗声道\", \"冷声道\", \"笑道\", \"拱手道\", \"躬身道\", \"跪拜道\", \"喝道\", \"轻声道\", \"缓缓道\", \"傲然道\", \"惊道\", \"怒喝\", \"淡淡道\", \"低声道\", \"传音入密道\", \"冷笑道\", \"讥讽道\", \"恭声道\", \"厉声喝道\", \"长叹一声道\", \"苦笑道\", \"正色道\", \"抱拳道\"]\n }\n },\n \"examples\": [\n {\n \"text\": \"悦来客栈的大堂里,人声鼎沸。\\n\\n靠窗的一张桌子旁坐着一个青衫年轻人,面前摆着一壶酒、两碟小菜,却自始至终没动几筷子。他的目光时不时飘向门口,右手始终搭在腰间那柄不起眼的铁剑上。\\n\\n\\u201c小二,结账。\\u201d\\n\\n他放下一锭碎银子,刚要起身,门外突然马蹄声大作,一队铁甲骑兵疾驰而至,在客栈门前齐刷刷勒住缰绳。为首的军官翻身下马,手持一卷明黄色的卷轴,大步走进客栈。\\n\\n\\u201c刑部缉拿要犯!闲杂人等回避!\\u201d\\n\\n大堂里瞬间安静下来。青衫年轻人的瞳孔微微一缩,手指在剑鞘上轻轻敲了三下——这是江湖人示警的暗号。\\n\\n他注意到,角落里一个戴斗笠的喝茶人,手已经悄悄探入了怀中。\",\n \"note\": \"历史架空词库示例:客栈/小二/碎银子/马蹄/铁甲骑兵/刑部/剑鞘/江湖人/斗笠等古代武侠词汇自然融入\"\n }\n ],\n \"threshold_overrides\": {\n \"maxParagraphLength\": 250,\n \"targetParagraphLength\": 80\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.0,\n \"sensorySignal\": 1.2,\n \"action\": 1.2,\n \"emotion\": 1.0,\n \"infoAdvance\": 1.0\n }\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_vocab_sensory\",\n \"option_id\": \"opt_vocab_horror\",\n \"option_name\": \"灵异恐怖\",\n \"option_description\": \"灵异恐怖世界观词库,包含鬼、幽灵、阴气、纸钱、棺材、坟、诡异、阴森、寒毛、冷汗、阴影、血、诅咒、尸变、招魂等恐怖灵异专有词汇。\",\n \"system_prompt\": \"你使用灵异恐怖世界观词库。写作时自然融入恐怖灵异的专有名词和感官描写:阴风阵阵的寒意、纸钱燃烧的焦糊味、棺材里腐朽的气味、黑暗中若有若无的低语、身后跟随的脚步声、镜子里多出来的影子。身体锚点偏恐惧反应:寒毛倒竖、冷汗直流、脊背发凉、牙齿打颤、腿软、喉咙发紧、瞳孔放大。动作描写要有恐怖味:摸索着开灯、一步步后退、捂住嘴不敢出声、僵硬地转头、颤抖着伸手、狂奔逃命。场景:废弃医院、凶宅、坟地、殡仪馆、老井、地下通道、空无一人的学校、午夜的镜子前。氛围是核心——压抑、诡异、不安、未知的恐惧。\",\n \"constraints\": [\n \"必须使用灵异恐怖专有词汇\",\n \"氛围营造是第一位的:压抑/诡异/不安/未知恐惧\",\n \"不要急于揭示恐怖源头,未知和暗示比直接描写更可怕\",\n \"感官描写注重:阴冷/腐臭/异响/阴影/血腥味\",\n \"身体反应是恐惧的直接体现:冷汗/寒毛/颤抖/腿软/心跳\",\n \"不要用太直白的恶心描写(如过多内脏细节),心理恐惧更高级\",\n \"声音和光影的暗示比直接看到鬼更吓人\"\n ],\n \"vocabulary\": {\n \"add\": {\n \"worldTerms\": [\"鬼\", \"幽灵\", \"阴气\", \"纸钱\", \"棺材\", \"坟\", \"诡异\", \"阴森\", \"寒毛\", \"冷汗\", \"阴影\", \"血\", \"诅咒\", \"尸变\", \"招魂\", \"鬼魂\", \"怨灵\", \"厉鬼\", \"恶鬼\", \"女鬼\", \"红衣女鬼\", \"白衣女鬼\", \"僵尸\", \"粽子\", \"尸斑\", \"尸臭\", \"腐臭\", \"腐烂\", \"骸骨\", \"白骨\", \"坟墓\", \"墓地\", \"乱葬岗\", \"殡仪馆\", \"太平间\", \"停尸房\", \"火葬场\", \"灵堂\", \"白事\", \"丧事\", \"守灵\", \"头七\", \"回魂夜\", \"纸钱\", \"香烛\", \"贡品\", \"棺材\", \"棺木\", \"寿衣\", \"花圈\", \"遗像\", \"牌位\", \"佛牌\", \"符咒\", \"桃木剑\", \"罗盘\", \"八卦镜\", \"黑狗血\", \"糯米\", \"红线\", \"铃铛\", \"招魂铃\", \"引魂灯\", \"鬼打墙\", \"鬼压床\", \"鬼上身\", \"附身\", \"通灵\", \"阴阳眼\", \"天眼\", \"见鬼\", \"驱鬼\", \"捉鬼\", \"道士\", \"法师\", \"神婆\", \"半仙\", \"阴阳先生\", \"风水\", \"凶宅\", \"煞气\", \"邪气\", \"怨气\", \"阴魂\", \"索命\", \"报应\", \"前世\", \"今生\", \"轮回\", \"冥界\", \"阴间\", \"黄泉\", \"奈何桥\", \"孟婆汤\", \"阎王\", \"判官\", \"黑白无常\", \"牛头马面\", \"午夜\", \"子时\", \"三更\", \"十二点\", \"凌晨三点\", \"满月\", \"血月\", \"镜子\", \"梳头\", \"敲门声\", \"脚步声\", \"哭声\", \"笑声\", \"低语声\", \"呼吸声\", \"歌谣\", \"童谣\", \"娃娃\", \"布偶\", \"洋娃娃\", \"旧照片\", \"录像带\", \"录影带\", \"古井\", \"老槐树\", \"废弃医院\", \"废弃学校\", \"地下室\", \"阁楼\", \"电梯\", \"楼梯转角\", \"走廊尽头\", \"黑暗\", \"黑暗中\", \"暗处\", \"角落\", \"床下\", \"天花板\", \"背后\", \"身后\", \"血手印\", \"血字\", \"抓痕\", \"牙印\", \"爪痕\", \"撕裂\", \"拖痕\", \"冰冷\", \"寒意\", \"阴冷\", \"刺骨\", \"窒息\", \"死寂\", \"安静\", \"不对劲\", \"不正常\", \"不对劲\", \"说不出的诡异\", \"无法解释\", \"不可能\", \"毛骨悚然\", \"不寒而栗\", \"脊背发凉\", \"头皮发麻\"],\n \"bodyParts\": [\"寒毛\", \"后颈\", \"脊背\", \"头皮\", \"喉咙\", \"牙齿\", \"腿\", \"指尖\", \"瞳孔\", \"冷汗\", \"鸡皮疙瘩\"],\n \"sensoryVerbs\": [\"感到阴风阵阵\", \"闻到腐臭味\", \"听到若有若无的低语\", \"看到阴影移动\", \"寒毛倒竖\", \"冷汗直流\", \"脊背发凉\", \"牙齿打颤\", \"腿软\", \"喉咙发紧\", \"听到身后脚步声\", \"闻到纸钱焦糊味\", \"看到镜子里多出的影子\", \"感到冰冷的呼吸吹在脖子上\", \"听到女人哭声\", \"感到有人触碰后颈\", \"听到指甲划黑板的声音\", \"闻到血腥味\", \"看到血手印\", \"听到棺材板响动\"],\n \"actionVerbs\": [\"摸索着开灯\", \"一步步后退\", \"捂住嘴不敢出声\", \"僵硬地转头\", \"颤抖着伸手\", \"狂奔逃命\", \"缩在角落\", \"屏住呼吸\", \"不敢睁眼\", \"咬紧牙关\", \"紧紧握住\", \"颤声问\", \"尖叫\", \"夺门而逃\", \"爬着后退\", \"躲进被子\", \"闭眼不看\", \"拼命摇头\", \"掐自己\", \"念咒\", \"贴符\", \"撒糯米\", \"摇铃\", \"点蜡烛\", \"烧香\", \"烧纸钱\", \"招魂\", \"驱鬼\", \"开天眼\", \"用阴阳眼看\", \"拍照\", \"录像\", \"回放监控\", \"听到敲门声不敢开\", \"看猫眼\", \"接电话听到诡异声音\", \"对着空无一人说话\", \"感觉身后有人\", \"回头看到\", \"不敢回头\", \"僵硬地回头\", \"缓缓转头\"],\n \"environmentSignals\": [\"阴风阵阵\", \"温度骤降\", \"灯忽明忽暗\", \"蜡烛火焰变绿\", \"纸钱灰烬飘起\", \"镜子上出现雾气\", \"水龙头自己打开\", \"门吱呀一声开了\", \"走廊灯光闪烁\", \"电梯自动开门\", \"时钟指向十二点\", \"外面传来哭声\", \"死寂一片\", \"呼吸声不是自己的\", \"脚步声从身后传来\", \"血腥味弥漫\", \"腐臭扑鼻\", \"白色影子飘过\", \"黑影一闪\", \"墙壁渗出黑水\", \"地上出现湿脚印\", \"遗像上的眼睛好像在动\", \"娃娃转过头来\", \"电视出现雪花\", \"收音机自己打开\", \"童谣声从某处传来\", \"指甲划木板的声音\", \"风吹过空房间的呜咽声\"],\n \"dialogueTags\": [\"颤声说\", \"声音发抖地问\", \"压低声音说\", \"屏住呼吸说\", \"尖叫道\", \"哽咽着说\", \"牙齿打颤地说\", \"不敢出声\", \"用气声说\", \"嘶哑地说\", \"在心里默念\", \"哆哆嗦嗦地说\", \"惊恐地喊道\", \"声音变调地说\"]\n }\n },\n \"examples\": [\n {\n \"text\": \"凌晨三点十七分。\\n\\n我被尿憋醒,摸索着下了床。走廊里漆黑一片,我没开灯——怕吵醒老婆孩子。\\n\\n卫生间在走廊尽头。我光着脚踩在地板上,地板冰凉刺骨,这很奇怪,虽然已经入秋,但地暖一直开着。\\n\\n走到一半,我停住了。\\n\\n身后传来脚步声。\\n\\n很轻,很慢,是赤脚踩在地板上的声音。嗒、嗒、嗒……\\n\\n我的寒毛一下子竖了起来。老婆孩子都在卧室里睡觉,这个时间谁会在走廊上?\\n\\n我不敢回头。\\n\\n脚步声越来越近,我能感觉到一股阴冷的气息从背后逼近,像是有人把一块冰贴在了我的后颈上。然后,一个声音在我耳边轻轻响起——\\n\\n是一个女人的声音,又细又尖,像是从很远很远的地方传来:\\n\\n「你……看见我孩子了吗?」\",\n \"note\": \"恐怖词库示例:凌晨/黑暗/赤脚/冰凉/脚步声/寒毛/阴冷/女人声音等恐怖元素,未知恐惧比直接见鬼更吓人\"\n }\n ],\n \"threshold_overrides\": {\n \"minSensoryTypes\": 3,\n \"shortSentenceRatio\": 0.6,\n \"targetSentenceLength\": 15,\n \"maxSentenceLength\": 40,\n \"maxParagraphLength\": 80,\n \"targetParagraphLength\": 35\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.5,\n \"sensorySignal\": 1.5,\n \"action\": 0.9,\n \"emotion\": 1.4,\n \"infoAdvance\": 0.8\n }\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_vocab_sensory\",\n \"option_id\": \"opt_vocab_military\",\n \"option_name\": \"军事战争\",\n \"option_description\": \"军事战争世界观词库,包含战壕、步枪、坦克、炮弹、狙击、潜伏、军装、勋章、指挥部、战场、硝烟、弹壳、迷彩、通讯兵等军事战争专有词汇。\",\n \"system_prompt\": \"你使用军事战争世界观词库。写作时自然融入军事战争的专有名词和感官描写:硝烟的刺鼻气味、炮弹爆炸的震耳欲聋、子弹破空的锐啸、坦克履带碾过碎石的咯吱声、军装粗糙布料的摩擦。身体锚点偏军事化:扣扳机的手指、被后坐力震麻的肩膀、匍匐在地时手肘的擦伤、烟熏火燎的脸、被弹片划伤的手臂。动作描写要有军事味:匍匐前进、举枪瞄准、上膛、投掷手榴弹、呼叫炮火支援、隐蔽、卧倒、冲锋、撤退。场景:战壕、阵地、碉堡、指挥部、坦克内部、丛林、沙漠、雪地、城市废墟。氛围紧张肃杀,充满硝烟和铁血。\",\n \"constraints\": [\n \"必须使用军事战争专有词汇,军事术语要准确\",\n \"武器装备和战术动作要符合军事常识\",\n \"战场描写要有真实感:硝烟/爆炸声/弹片/血迹/尸体\",\n \"感官描写注重:硝烟味/爆炸声/子弹呼啸/坦克轰鸣/尘土\",\n \"对话简洁有力,符合军人说话方式(短促/明确/术语)\",\n \"展现战友情谊和战争残酷,但不要过度渲染血腥\"\n ],\n \"vocabulary\": {\n \"add\": {\n \"worldTerms\": [\"战壕\", \"步枪\", \"坦克\", \"炮弹\", \"狙击\", \"潜伏\", \"军装\", \"勋章\", \"指挥部\", \"战场\", \"硝烟\", \"弹壳\", \"迷彩\", \"通讯兵\", \"士兵\", \"军人\", \"军官\", \"将军\", \"元帅\", \"司令\", \"连长\", \"排长\", \"班长\", \"营长\", \"团长\", \"旅长\", \"师长\", \"军长\", \"战友\", \"兄弟\", \"部队\", \"连队\", \"排\", \"班\", \"营\", \"团\", \"旅\", \"师\", \"军\", \"集团军\", \"方面军\", \"友军\", \"敌军\", \"敌人\", \"鬼子\", \"敌军\", \"我军\", \"友军\", \"增援\", \"援军\", \"预备队\", \"突击队\", \"敢死队\", \"狙击手\", \"机枪手\", \"步枪手\", \"通讯兵\", \"卫生员\", \"医护兵\", \"侦察兵\", \"工兵\", \"炮兵\", \"装甲兵\", \"步兵\", \"骑兵\", \"伞兵\", \"空降兵\", \"海军\", \"空军\", \"陆军\", \"海军陆战队\", \"特种兵\", \"枪\", \"步枪\", \"冲锋枪\", \"机枪\", \"重机枪\", \"轻机枪\", \"狙击枪\", \"手枪\", \"手榴弹\", \"手雷\", \"闪光弹\", \"烟雾弹\", \"火箭筒\", \"迫击炮\", \"火炮\", \"加农炮\", \"榴弹炮\", \"高射炮\", \"反坦克炮\", \"子弹\", \"弹药\", \"弹夹\", \"弹匣\", \"弹链\", \"弹壳\", \"弹头\", \"弹道\", \"口径\", \"后坐力\", \"瞄准镜\", \"准星\", \"保险\", \"上膛\", \"拉栓\", \"扣扳机\", \"击发\", \"走火\", \"卡壳\", \"坦克\", \"装甲车\", \"运兵车\", \"吉普车\", \"摩托车\", \"卡车\", \"战机\", \"战斗机\", \"轰炸机\", \"直升机\", \"军舰\", \"航母\", \"潜艇\", \"驱逐舰\", \"巡洋舰\", \"炮弹\", \"炸弹\", \"导弹\", \"鱼雷\", \"地雷\", \"炸药\", \"C4\", \"TNT\", \"铁丝网\", \"沙袋\", \"碉堡\", \"地堡\", \"掩体\", \"工事\", \"防空洞\", \"战壕\", \"散兵坑\", \"阵地\", \"防线\", \"前线\", \"后方\", \"战场\", \"战区\", \"战线\", \"制高点\", \"山头\", \"高地\", \"桥梁\", \"道路\", \"据点\", \"桥头堡\", \"指挥部\", \"指挥所\", \"作战室\", \"电台\", \"步话机\", \"对讲机\", \"无线电\", \"通讯\", \"电报\", \"密码\", \"情报\", \"侦察\", \"地图\", \"坐标\", \"方位\", \"地形\", \"侦察\", \"潜伏\", \"埋伏\", \"伪装\", \"迷彩\", \"隐蔽\", \"掩护\", \"卧倒\", \"匍匐\", \"冲锋\", \"进攻\", \"撤退\", \"突围\", \"包围\", \"迂回\", \"穿插\", \"阻击\", \"增援\", \"炮火支援\", \"空袭\", \"轰炸\", \"扫射\", \"炮击\", \"炮轰\", \"交火\", \"开火\", \"射击\", \"点射\", \"连发\", \"扫射\", \"狙击\", \"命中\", \"脱靶\", \"伤亡\", \"负伤\", \"中弹\", \"牺牲\", \"阵亡\", \"殉国\", \"伤员\", \"尸体\", \"战俘\", \"俘虏\", \"投降\", \"举白旗\", \"胜仗\", \"败仗\", \"撤退\", \"溃退\", \"反攻\", \"胜利\", \"军旗\", \"军号\", \"冲锋号\", \"集结号\", \"军歌\", \"军礼\", \"敬礼\", \"军徽\", \"领章\", \"肩章\", \"帽徽\", \"军装\", \"军靴\", \"钢盔\", \"头盔\", \"迷彩服\", \"作战服\", \"干粮\", \"军粮\", \"水壶\", \"绷带\", \"急救包\", \"担架\", \"战地医院\", \"野战医院\", \"硝烟\", \"尘土\", \"弹坑\", \"瓦砾\", \"废墟\", \"焦土\", \"弹痕\", \"弹孔\", \"血迹\", \"血腥味\", \"火药味\", \"柴油味\", \"硝烟味\"],\n \"bodyParts\": [\"扣扳机的手指\", \"肩膀\", \"手肘\", \"膝盖\", \"眼睛\", \"被后坐力震麻的肩膀\", \"被硝烟熏黑的脸\", \"握枪的手\"],\n \"sensoryVerbs\": [\"闻到硝烟味\", \"听到炮弹爆炸\", \"感到地面震动\", \"听到子弹破空\", \"闻到血腥味\", \"看到尘土飞扬\", \"感到后坐力撞肩\", \"听到坦克履带声\", \"闻到火药味\", \"感到弹片飞过\", \"听到冲锋号\", \"看到炮火闪光\", \"感到震耳欲聋\", \"呛得咳嗽\", \"眼睛被硝烟熏得流泪\", \"手指扣紧扳机\", \"汗水流进眼睛\"],\n \"actionVerbs\": [\"匍匐前进\", \"举枪瞄准\", \"上膛\", \"拉枪栓\", \"扣扳机\", \"投掷手榴弹\", \"呼叫炮火支援\", \"隐蔽\", \"卧倒\", \"冲锋\", \"撤退\", \"突围\", \"阻击\", \"开枪\", \"射击\", \"点射\", \"扫射\", \"狙击\", \"填弹\", \"换弹匣\", \"拉保险\", \"扔手雷\", \"扔烟雾弹\", \"匍匐\", \"低姿前进\", \"翻滚闪避\", \"找掩护\", \"挖战壕\", \"修筑工事\", \"架机枪\", \"校准瞄准镜\", \"测距\", \"观察\", \"侦察\", \"汇报坐标\", \"呼叫增援\", \"发送电报\", \"接听无线电\", \"包扎伤口\", \"止血\", \"抬担架\", \"敬军礼\", \"吹响冲锋号\", \"升旗\", \"集合\", \"列队\", \"报数\", \"立正\", \"稍息\", \"敬礼\", \"听命令\", \"服从命令\", \"执行任务\", \"潜伏\", \"埋伏\", \"等待\", \"耐心等待\", \"渗透\", \"穿插\", \"迂回包抄\", \"正面进攻\", \"两翼包抄\", \"冲锋陷阵\", \"白刃战\", \"拼刺刀\", \"近身格斗\", \"肉搏\", \"踩过弹坑\", \"跨过尸体\", \"冲进碉堡\", \"炸碉堡\", \"清除据点\"],\n \"environmentSignals\": [\"硝烟弥漫\", \"炮声隆隆\", \"子弹呼啸而过\", \"坦克履带嘎吱作响\", \"尘土飞扬遮天蔽日\", \"震耳欲聋的爆炸\", \"火光冲天\", \"弹片横飞\", \"军号嘹亮\", \"无线电滋滋作响\", \"血腥味混着火药味\", \"地面在震颤\", \"天空被炮火映红\", \"瓦砾遍地\", \"弹坑累累\", \"铁丝网撕裂声\", \"沙袋被打穿\", \"战壕里积着血水\", \"钢盔叮当声\", \"军靴踩碎石子\"],\n \"dialogueTags\": [\"沉声道\", \"吼道\", \"命令道\", \"喊道\", \"对着对讲机大喊\", \"急促地报告\", \"咬牙道\", \"嘶声喊道\", \"低声道\", \"简短地说\", \"通过无线电道\", \"厉声喝道\", \"粗声道\", \"平静地说\", \"大声命令\"]\n }\n },\n \"examples\": [\n {\n \"text\": \"炮弹落下的时候,周铁柱正趴在战壕里啃干粮。\\n\\n轰——!\\n\\n地面猛地一震,泥土劈头盖脸地砸下来,他下意识地把半个身子埋进战壕壁上,干粮掉在了泥水里。爆炸掀起的气浪从头顶扫过,带着灼热的弹片和刺鼻的硝烟。\\n\\n「三班!报数!」连长大喊的声音从炮火间隙里传过来。\\n\\n「一!」「二!」「三!」……\\n\\n报到第七个的时候,停了。\\n\\n周铁柱抹了一把脸上的泥和血——他不知道是谁的血——抬头看向阵地前方。硝烟中,三辆日军坦克正碾过铁丝网,履带咯吱咯吱地响,像是死神在磨牙。后面跟着黑压压的步兵,端着刺刀一步步逼近。\\n\\n「通讯员!呼叫炮火支援!坐标347,211!快!」\\n\\n「机枪手!给我把步兵压住!」\\n\\n周铁柱拿起身边的步枪,哗啦一声拉栓上膛。他的手在抖,但手指扣上扳机的那一刻,反而稳了。\\n\\n一百米。\\n\\n八十米。\\n\\n他深吸一口气,准星对准了最前面那个军曹的脑袋。\",\n \"note\": \"军事词库示例:战壕/炮弹/爆炸/硝烟/坦克/履带/机枪/炮火支援/拉栓上膛/准星等军事词汇,战场氛围紧张肃杀\"\n }\n ],\n \"threshold_overrides\": {\n \"maxParagraphLength\": 150,\n \"targetParagraphLength\": 60,\n \"shortSentenceRatio\": 0.55,\n \"targetSentenceLength\": 18,\n \"maxSentenceLength\": 50\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.1,\n \"sensorySignal\": 1.4,\n \"action\": 1.4,\n \"emotion\": 1.0,\n \"infoAdvance\": 1.0\n }\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_vocab_sensory\",\n \"option_id\": \"opt_vocab_mystery\",\n \"option_name\": \"悬疑推理\",\n \"option_description\": \"悬疑推理世界观词库,包含尸体、血迹、指纹、线索、嫌疑、动机、不在场证明、凶器、密室、推理、侦探、警察、法医、监控、脚印等刑侦推理专有词汇。\",\n \"system_prompt\": \"你使用悬疑推理世界观词库。写作时自然融入刑侦推理的专有名词和感官描写:血腥味的铁锈味、福尔马林的刺鼻、黑暗中地板的吱呀声、指纹粉末的灰白、尸体的僵硬冰冷、监控画面的噪点。身体描写注重紧张感——后颈发凉、心跳加速、手心出汗、瞳孔收缩、屏住呼吸。动作描写要有侦查味:蹲下身检查、戴手套取证、翻看物证、调监控、做笔录、还原现场、推理演绎。场景:凶案现场、审讯室、法医解剖室、监控室、密室、雨夜街道、废弃建筑。氛围营造至关重要:压抑、紧张、诡异、不安。\",\n \"constraints\": [\n \"必须使用刑侦推理专有词汇,法医和警察程序要合理\",\n \"线索描写要精确,不能模糊(伤口形状/血迹形态/指纹位置等)\",\n \"氛围营造是重点:压抑/紧张/诡异/不安\",\n \"推理过程要有逻辑,线索必须公平(读者和侦探获得同样信息)\",\n \"感官描写注重:血腥味/福尔马林/黑暗中的声音/冰冷触感\",\n \"对话可以是警察之间的术语对话,也可以是审讯中的心理博弈\"\n ],\n \"vocabulary\": {\n \"add\": {\n \"worldTerms\": [\"尸体\", \"血迹\", \"指纹\", \"线索\", \"嫌疑\", \"动机\", \"不在场证明\", \"凶器\", \"密室\", \"推理\", \"侦探\", \"警察\", \"法医\", \"监控\", \"脚印\", \"凶手\", \"被害人\", \"嫌疑人\", \"证人\", \"口供\", \"笔录\", \"立案\", \"破案\", \"刑侦\", \"重案组\", \"刑警\", \"队长\", \"探长\", \"法医鉴定\", \"解剖\", \"尸检\", \"尸斑\", \"尸僵\", \"死亡时间\", \"致命伤\", \"钝器伤\", \"锐器伤\", \"勒痕\", \"窒息\", \"毒杀\", \"中毒\", \"药物\", \"安眠药\", \"氰化物\", \"血迹形态\", \"喷溅血迹\", \"滴落血迹\", \"擦拭血迹\", \"指纹粉\", \"DNA\", \"比对\", \"物证\", \"现场\", \"第一现场\", \"第二现场\", \"勘察\", \"取证\", \"封存\", \"现场重建\", \"监控录像\", \"监控画面\", \"时间戳\", \"摄像头\", \"门禁记录\", \"通话记录\", \"手机定位\", \"行车记录仪\", \"目击证人\", \"匿名举报\", \"通缉\", \"逮捕\", \"拘留\", \"审讯\", \"测谎\", \"认罪\", \"翻供\", \"动机\", \"情杀\", \"仇杀\", \"劫杀\", \"冲动杀人\", \"预谋杀人\", \"连环杀人\", \"模仿犯罪\", \"密室杀人\", \"不可能犯罪\", \"时刻表诡计\", \"叙述性诡计\", \"心理盲区\", \"反向思维\", \"演绎法\", \"归纳法\", \"排除法\", \"证据链\", \"逻辑链\", \"真相\", \"伏笔\", \"红鲱鱼\", \"反转\", \"意外\", \"疑点\", \"矛盾\", \"漏洞\", \"破绽\"],\n \"bodyParts\": [\"瞳孔\", \"后颈\", \"脊背\", \"指尖\", \"手腕\", \"喉咙\", \"太阳穴\", \"冷汗\", \"鸡皮疙瘩\"],\n \"sensoryVerbs\": [\"嗅到血腥味\", \"闻到福尔马林\", \"听到地板吱呀\", \"感到后颈发凉\", \"看到血迹喷溅\", \"摸到冰冷的尸体\", \"听到警笛声\", \"看到监控画面闪烁\", \"闻到硝烟味\", \"感到心跳加速\", \"听到呼吸声\", \"看到指纹粉末\", \"感到手铐冰冷\", \"听到快门声\", \"看到警戒线\"],\n \"actionVerbs\": [\"蹲下身检查\", \"戴上手套\", \"取证\", \"拍照取证\", \"翻看物证\", \"调取监控\", \"做笔录\", \"还原现场\", \"推理\", \"推演\", \"审讯\", \"询问\", \"追问\", \"逼视\", \"出示证据\", \"逮捕\", \"掏出手铐\", \"拔枪\", \"封锁现场\", \"拉起警戒线\", \"勘察现场\", \"采集指纹\", \"采集DNA\", \"比对样本\", \"尸检\", \"解剖\", \"记录\", \"拍照\", \"测量\", \"标记\", \"搜查\", \"翻找\", \"跟踪\", \"监视\", \"蹲守\", \"埋伏\", \"追击\", \"拦截\", \"包围\", \"破门而入\", \"查看监控\", \"快进\", \"倒带\", \"暂停\", \"放大画面\", \"分析时间线\", \"排查\", \"走访\", \"询问邻居\", \"调取记录\", \"传唤\", \"拘传\", \"申请逮捕令\", \"搜查令\"],\n \"environmentSignals\": [\"血腥味弥漫\", \"福尔马林刺鼻\", \"警戒线随风飘动\", \"警灯红蓝闪烁\", \"监控画面雪花噪点\", \"地板吱呀作响\", \"空气阴冷潮湿\", \"死寂\", \"远处警笛声\", \"快门声此起彼伏\", \"手铐金属碰撞声\", \"审讯室灯光惨白\", \"雨点击打窗户\", \"门吱呀一声打开\", \"走廊灯光闪烁\"],\n \"dialogueTags\": [\"沉声问\", \"逼问道\", \"冷冷地说\", \"压低声音说\", \"厉声道\", \"平静地说\", \"缓缓道\", \"皱眉道\", \"若有所思地说\", \"厉声道\", \"喝问\", \"反问\", \"追问道\", \"喃喃自语\", \"对着对讲机说\", \"记录道\", \"宣读权利\", \"冷笑道\"]\n }\n },\n \"examples\": [\n {\n \"text\": \"血腥味还没散。\\n\\n陈默蹲在尸体旁边,戴上乳胶手套。死者是一名中年男性,仰面躺在客厅的地毯上,胸口有一处刀伤,血迹以他为中心呈放射状喷溅,在白色墙壁上画出一幅刺目的图案。\\n\\n\\u201c死亡时间大约在昨晚十点到凌晨两点之间。\\u201d法医蹲在另一边,指着尸体脖颈处的紫红色斑块,\\u201c尸斑已经固定,尸僵开始缓解。致命伤是一刀毙命,凶器是单刃锐器,宽度大约三厘米,从肋骨间隙刺入心脏。\\u201d\\n\\n陈默的目光从尸体移开,扫过整个房间。门窗完好,没有撬动痕迹。茶几上有两个茶杯,一杯还剩半杯凉茶,另一杯几乎没动。\\n\\n\\u201c密室?\\u201d助手小王低声问。\\n\\n陈默没说话,他注意到一件奇怪的事——死者右手的食指和拇指上沾着一些灰白色的粉末,但他家里没有任何面粉或类似的东西。\\n\\n那是指纹粉。\\n\\n有人在警察来之前,已经擦拭过现场了。\",\n \"note\": \"悬疑推理词库示例:尸体/血迹/尸斑/尸僵/致命伤/密室/指纹粉/取证/法医等刑侦词汇,氛围紧张压抑\"\n }\n ],\n \"threshold_overrides\": {\n \"minSensoryTypes\": 3,\n \"maxExpositionContinuous\": 400\n },\n \"radar_weights\": {\n \"bodyReaction\": 1.2,\n \"sensorySignal\": 1.3,\n \"action\": 1.0,\n \"emotion\": 1.2,\n \"infoAdvance\": 1.3\n }\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_vocab_sensory\",\n \"option_id\": \"opt_vocab_scifi\",\n \"option_name\": \"科幻未来\",\n \"option_description\": \"科幻未来世界观词库,包含飞船、机甲、量子、AI、全息、星舰、跃迁、赛博、植入体、神经接口、空间站、虫洞等科幻专有词汇。\",\n \"system_prompt\": \"你使用科幻未来世界观词库。写作时自然融入科幻世界的专有名词和感官描写:全息投影的蓝光、引擎的低频嗡鸣、金属舱壁的冰冷、神经接口接入时的刺痛、跃迁时的扭曲感、机甲液压系统的嘶嘶声。身体描写兼顾生物锚点和科技改造——除了常规身体反应,还要有植入体发热、神经接口传来数据流、义肢的机械反馈、HUD投射在视网膜上的信息。动作描写要有科幻味:接入神经接口、启动跃迁、激活全息面板、操控机甲、对接空间站、量子通讯。场景:星舰舰桥、机甲驾驶舱、赛博朋克贫民窟、太空站环形走廊、外星殖民地。\",\n \"constraints\": [\n \"必须使用科幻专有词汇,科技设定要自洽\",\n \"身体锚点加入植入体/神经接口/义肢/HUD等科幻元素\",\n \"感官描写要有未来感:金属/能量/数据流/全息光/引擎振动\",\n \"科学术语使用要合理,避免堆砌名词但不懂含义\",\n \"可以适当创造新词,但必须通过上下文让读者理解\",\n \"对话风格根据设定调整——可以是军事化的简洁、赛博朋克的俚语、或精英科学家的术语\"\n ],\n \"vocabulary\": {\n \"add\": {\n \"worldTerms\": [\"飞船\", \"机甲\", \"量子\", \"AI\", \"全息\", \"星舰\", \"跃迁\", \"赛博\", \"植入体\", \"神经接口\", \"空间站\", \"虫洞\", \"反物质\", \"能量核心\", \"数据流\", \"星际\", \"行星\", \"星系\", \"外星\", \"殖民地\", \"联邦\", \"帝国\", \"舰队\", \"舰长\", \"大副\", \"领航员\", \"工程师\", \"陆战队员\", \"克隆人\", \"机器人\", \"仿生人\", \"合成人\", \"义体\", \"义肢\", \"赛博空间\", \"网络\", \"防火墙\", \"黑客\", \"碳基\", \"硅基\", \"能量护盾\", \"离子炮\", \"激光炮\", \"等离子步枪\", \"轨道轰炸\", \"曲速\", \"超光速\", \"亚空间\", \"维度\", \"平行宇宙\", \"时间线\", \"引力波\", \"暗物质\", \"暗能量\", \"燃料\", \"推进器\", \"反重力\", \"人工重力\", \"冬眠舱\", \"休眠\", \"低温舱\", \"生态舱\", \"氧循环\", \"核聚变\", \"反应堆\", \"能源\", \"晶体\", \"合金\", \"纳米\", \"纳米机器人\", \"生物芯片\", \"基因改造\", \"变异\", \"辐射\", \"星云\", \"小行星带\", \"气态巨行星\", \"轨道电梯\", \"太空港\", \"对接\", \"登陆\", \"降落\", \"起飞\", \"失重\", \"漂浮\", \"HUD\", \"视网膜投影\", \"脑机接口\", \"意识上传\", \"虚拟现实\", \"增强现实\", \"全息投影\", \"触摸屏\", \"语音指令\", \"生物识别\", \"DNA验证\", \"量子通讯\", \"超空间\", \"跃迁点\", \"跳跃门\", \"星际门\", \"母舰\", \"旗舰\", \"巡洋舰\", \"驱逐舰\", \"战斗机\", \"穿梭机\", \"逃生舱\", \"太空服\", \"EVA\", \"舰桥\", \"驾驶舱\", \"引擎室\", \"货舱\", \"气密门\", \"气闸舱\", \"减压\", \"增压\", \"警报\", \"红色警报\"],\n \"bodyParts\": [\"神经接口\", \"植入体\", \"义肢\", \"义眼\", \"HUD\", \"视网膜投影\", \"后脑接口\", \"脊椎接口\", \"芯片植入处\", \"纳米机械\", \"生物传感器\", \"合金骨骼\", \"人工肌肉\"],\n \"sensoryVerbs\": [\"接入神经接口\", \"感到数据流涌入\", \"听到引擎嗡鸣\", \"看到全息投影闪烁\", \"感到金属冰冷\", \"闻到臭氧味\", \"听到警报声\", \"感到失重\", \"看到星光扭曲\", \"感到植入体发热\", \"听到液压嘶嘶声\", \"感到义肢反馈力\", \"看到HUD数据跳动\", \"感到跃迁的扭曲\", \"听到能量充能的尖啸\"],\n \"actionVerbs\": [\"接入\", \"启动跃迁\", \"激活全息面板\", \"操控机甲\", \"对接空间站\", \"量子通讯\", \"启动引擎\", \"开启护盾\", \"锁定目标\", \"发射离子炮\", \"启动隐身\", \"弹射逃生舱\", \"进入冬眠\", \"唤醒\", \"扫描\", \"分析\", \"黑入系统\", \"上传病毒\", \"下载数据\", \"接驳神经链路\", \"调整轨道\", \"减速\", \"加速\", \"对接\", \"分离\", \"着陆\", \"起飞\", \"漂浮\", \"推拉操纵杆\", \"按下按钮\", \"拨动开关\", \"语音指令\", \"手势操控\", \"脑波操控\", \"切换模式\", \"自检\", \"修复\", \"重启系统\", \"超频\", \"过载\", \"冷却\", \"充能\", \"放电\", \"开火\"],\n \"environmentSignals\": [\"引擎低频嗡鸣\", \"金属舱壁冰冷\", \"全息蓝光闪烁\", \"红色警报灯旋转\", \"空气中有臭氧味\", \"重力忽强忽弱\", \"数据流在视网膜上滚动\", \"液压系统嘶嘶作响\", \"能量核心低鸣\", \"窗外星光流转\", \"舰桥灯光昏暗\", \"控制面板灯闪烁\", \"烟雾弥漫\", \"火花四溅\", \"气密门嘶嘶关闭\", \"气闸泄压声\", \"机械臂运转声\", \"通讯静电噪音\", \"跃迁时空间扭曲感\"],\n \"dialogueTags\": [\"通讯器里传来\", \"沉声道\", \"冷静地说\", \"报告道\", \"命令道\", \"吼道\", \"低声说\", \"通过神经链接道\", \"在频道里说\", \"AI的合成音\", \"电子音回应\", \"沙哑地说\", \"急促地说\", \"简洁地说\", \"耳机里传来\"]\n }\n },\n \"examples\": [\n {\n \"text\": \"舰桥的红色警报灯疯狂旋转,映在每个人脸上。\\n\\n「敌舰跃迁完成,三艘巡洋舰,距离十二万公里!」\\n\\n陈舰长猛地握紧指挥椅的扶手,神经接口在后颈处微微发烫——\\\"致远号\\\"的AI正在将战术数据直接注入他的视觉皮层。下一秒,HUD在他视网膜上展开,三艘敌舰的轮廓、护盾值、武器参数全部以半透明的图标悬浮在视野中。\\n\\n「全舰一级战备,启动能量护盾,左满舵!」\\n\\n引擎室的低频嗡鸣骤然升高,人工重力因为过载而波动了一瞬,几个没系安全带的船员踉跄了一下。\\n\\n「主炮充能完毕,锁定完成!」武器官的声音从通讯器里传来,带着电流杂音。\\n\\n陈舰长盯着视野中越来越近的红色光点,深吸一口气。\\n\\n「开火。」\\n\\n舰体微微一震,一道蓝白色的离子光束从主炮口喷涌而出,撕裂了漆黑的太空。\",\n \"note\": \"科幻词库示例:舰桥/跃迁/巡洋舰/神经接口/HUD/AI/能量护盾/引擎/离子炮/主炮充能等科幻词汇自然融入\"\n }\n ],\n \"threshold_overrides\": {},\n \"radar_weights\": {\n \"bodyReaction\": 1.0,\n \"sensorySignal\": 1.2,\n \"action\": 1.3,\n \"emotion\": 0.9,\n \"infoAdvance\": 1.2\n }\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_vocab_sensory\",\n \"option_id\": \"opt_vocab_urban\",\n \"option_name\": \"都市现代\",\n \"option_description\": \"都市现代世界观词库,包含手机、电脑、微信、公司、老板、地铁、电梯、公寓、酒吧、咖啡等现代都市生活专有词汇。\",\n \"system_prompt\": \"你使用都市现代世界观词库。写作时自然融入现代都市的专有名词和感官描写:手机屏幕的蓝光、地铁车厢的拥挤、咖啡的香气、写字楼的冷气、霓虹灯光、键盘敲击声、汽车鸣笛、外卖袋的塑料袋声。身体锚点都是现代生活中的——手指划过屏幕、握着方向盘的手、电梯镜面里的自己、耳机里的音乐。动作描写要现代:刷手机、敲键盘、扫码支付、挤地铁、按电梯、打方向盘、点外卖、发微信、开视频会议。场景要有都市感:CBD写字楼、地铁早高峰、深夜便利店、高档酒吧、出租屋、地下停车场。\",\n \"constraints\": [\n \"必须使用现代都市专有词汇,避免出现古代或玄幻词汇\",\n \"身体锚点融入现代生活动作(刷手机/握方向盘/按电梯等)\",\n \"感官描写要有都市特色:霓虹/冷气/尾气/咖啡香/键盘声\",\n \"交通工具、通讯方式、生活场景必须符合现代设定\",\n \"对话风格自然口语化,符合当代都市人说话方式\",\n \"可以融入网络用语、职场黑话、流行语,但要适度\"\n ],\n \"vocabulary\": {\n \"add\": {\n \"worldTerms\": [\"手机\", \"电脑\", \"微信\", \"公司\", \"老板\", \"地铁\", \"电梯\", \"公寓\", \"酒吧\", \"咖啡\", \"西装\", \"领带\", \"方向盘\", \"霓虹灯\", \"监控摄像头\", \"外卖\", \"加班\", \"KPI\", \"PPT\", \"方案\", \"客户\", \"同事\", \"前台\", \"HR\", \"CBD\", \"写字楼\", \"出租屋\", \"小区\", \"物业\", \"停车场\", \"红绿灯\", \"斑马线\", \"公交\", \"网约车\", \"出租车\", \"高铁\", \"飞机\", \"机场\", \"便利店\", \"星巴克\", \"奶茶\", \"外卖小哥\", \"快递\", \"扫码\", \"支付宝\", \"微信支付\", \"直播间\", \"网红\", \"打卡\", \"朋友圈\", \"微博\", \"热搜\", \"抖音\", \"视频通话\", \"蓝牙耳机\", \"充电宝\", \"数据线\", \"投影\", \"会议室\", \"工位\", \"996\", \"社畜\", \"打工人\", \"甲方\", \"乙方\", \"方案\", \"合同\", \"五险一金\", \"年终奖\", \"房贷\", \"车贷\", \"信用卡\", \"花呗\", \"相亲\", \"约会\", \"火锅\", \"烧烤\", \"外卖\", \"健身房\", \"瑜伽\", \"医美\", \"网购\", \"快递柜\", \"人脸识别\", \"密码锁\", \"智能家居\", \"网约车\", \"共享单车\", \"导航\", \"蓝牙\", \"WiFi\"],\n \"bodyParts\": [\"手指\", \"指尖\", \"手腕\", \"太阳穴\", \"颈椎\", \"腰椎\", \"肩膀\", \"黑眼圈\", \"眼袋\", \"屏幕脸\", \"鼠标手\"],\n \"sensoryVerbs\": [\"刷手机\", \"盯着屏幕\", \"听到消息提示音\", \"闻到咖啡香\", \"感到冷气\", \"听到键盘声\", \"看到霓虹灯\", \"摸到冰冷的金属\", \"尝到苦涩的咖啡\", \"听到地铁报站\", \"闻到尾气\", \"感到手机震动\", \"听到微信提示音\", \"闻到外卖香味\", \"看到写字楼灯火通明\", \"感到方向盘的震动\", \"听到高跟鞋敲击地面\"],\n \"actionVerbs\": [\"刷手机\", \"敲键盘\", \"扫码支付\", \"挤地铁\", \"按电梯\", \"打方向盘\", \"点外卖\", \"发微信\", \"开视频会议\", \"打卡\", \"加班\", \"递简历\", \"面试\", \"签合同\", \"喝咖啡\", \"点烟\", \"倒酒\", \"碰杯\", \"刷门禁卡\", \"开电脑\", \"关电脑\", \"戴耳机\", \"摘耳机\", \"调座椅\", \"系安全带\", \"踩油门\", \"踩刹车\", \"换挡\", \"挂挡\", \"打转向灯\", \"变道\", \"超车\", \"停车\", \"倒车入库\", \"刷脸支付\", \"取快递\", \"拆快递\", \"叫网约车\", \"上地铁\", \"下地铁\", \"换乘\", \"抢座\", \"让座\", \"排队\", \"取号\", \"点餐\", \"买单\", \"AA制\", \"打包\", \"叫服务员\", \"开房间\", \"刷卡\", \"插房卡\"],\n \"environmentSignals\": [\"冷气十足\", \"霓虹闪烁\", \"车水马龙\", \"人声鼎沸\", \"键盘噼里啪啦\", \"咖啡香气\", \"尾气弥漫\", \"玻璃幕墙反光\", \"地铁呼啸\", \"电梯叮一声\", \"手机屏幕蓝光\", \"写字楼灯火通明\", \"街道嘈杂\", \"酒吧音乐震耳\", \"便利店叮咚声\", \"空调嗡嗡声\", \"高跟鞋声\", \"鸣笛声\"],\n \"dialogueTags\": [\"说\", \"问\", \"回答\", \"吐槽道\", \"抱怨道\", \"冷笑道\", \"笑着说\", \"皱眉道\", \"叹了口气说\", \"压低声音说\", \"不耐烦地说\", \"尴尬地说\", \"无奈道\", \"兴奋地说\", \"小声说\", \"大声说\", \"回了句\", \"发微信说\", \"打字回复\", \"在电话里说\"]\n }\n },\n \"examples\": [\n {\n \"text\": \"晚上九点,CBD写字楼的灯光还亮着一半。\\n\\n林悦盯着电脑屏幕上的PPT,眼睛干涩得厉害。她揉了揉太阳穴,端起已经凉透的咖啡喝了一口——苦味让她稍微清醒了一些。\\n\\n手机屏幕亮了一下,是妈妈发来的微信:「周末回家吗?给你炖了汤。」\\n\\n她打字回了句「看情况,要加班」,发送,然后把手机扣在桌面上。\\n\\n旁边工位的张伟伸了个懒腰:「还不走?我先撤了,末班车快没了。」\\n\\n「你们先走吧,我改完这版方案就走。」林悦勉强笑了笑。\\n\\n键盘声重新在空旷的办公区响起。窗外,城市的霓虹灯映在玻璃幕墙上,红的蓝的绿的,像一幅冷漠的画。\\n\\n她点开外卖APP,点了一份麻辣烫——这已经是她这周连续第四天吃外卖了。\",\n \"note\": \"都市现代词库示例:PPT/咖啡/微信/加班/外卖/CBD/霓虹灯/键盘/末班车/APP等现代词汇自然融入\"\n }\n ],\n \"threshold_overrides\": {},\n \"radar_weights\": {\n \"bodyReaction\": 1.0,\n \"sensorySignal\": 1.1,\n \"action\": 1.0,\n \"emotion\": 1.0,\n \"infoAdvance\": 1.0\n }\n}\n","{\n \"kb_version\": \"2.0\",\n \"node_id\": \"node_vocab_sensory\",\n \"option_id\": \"opt_vocab_xianxia\",\n \"option_name\": \"玄幻修仙\",\n \"option_description\": \"玄幻修仙世界观词库,包含丹田、灵气、灵根、金丹、元婴、飞剑、法宝、功法、境界等修仙体系专有词汇。\",\n \"system_prompt\": \"你使用玄幻修仙世界观词库。写作时自然融入修仙世界的专有名词和感官描写:灵气在经脉中运行的感觉、飞剑破空的锐啸、法宝的灵光、丹药的异香、威压带来的窒息感、天劫降临时的天地异象。身体描写要兼顾传统锚点和修仙特色——除了普通的身体反应(手心冒汗/心跳加速),还要加入丹田气海、经脉运转、灵根属性、神识感知等修仙体系特有的身体感。动作描写要有仙侠味:御剑、掐诀、祭出法宝、身形一闪、袍袖一挥等。\",\n \"constraints\": [\n \"必须使用修仙世界专有词汇,避免出现现代词汇(除非是穿越设定)\",\n \"身体锚点除常规词汇外,必须加入丹田/经脉/神识等修仙身体感知\",\n \"战斗描写要有仙侠特色:法术对决/法宝碰撞/飞剑纵横/天地异象\",\n \"境界体系必须一致,不能出现境界混乱\",\n \"感官描写融入灵气/灵光/威压/道音等修仙元素\",\n \"对话风格要符合古风仙侠,避免过于现代的口语\"\n ],\n \"vocabulary\": {\n \"add\": {\n \"worldTerms\": [\"丹田\", \"灵气\", \"灵根\", \"金丹\", \"元婴\", \"修士\", \"仙师\", \"道友\", \"飞剑\", \"法宝\", \"功法\", \"境界\", \"渡劫\", \"飞升\", \"仙气\", \"威压\", \"道音\", \"天地异象\", \"灵脉\", \"灵石\", \"丹药\", \"符箓\", \"阵法\", \"宗门\", \"洞府\", \"长老\", \"掌门\", \"弟子\", \"御剑\", \"掐诀\", \"神识\", \"元神\", \"心魔\", \"天道\", \"造化\", \"机缘\", \"灵草\", \"妖兽\", \"魔兽\", \"仙器\", \"灵宝\", \"储物袋\", \"储物戒\", \"乾坤袋\", \"闭关\", \"突破\", \"瓶颈\", \"淬体\", \"炼体\", \"筑基\", \"结丹\", \"化神\", \"合体\", \"大乘\", \"散仙\", \"真仙\", \"金仙\", \"道祖\", \"魔气\", \"妖气\", \"佛光\", \"剑光\", \"遁光\", \"祥云\", \"霞光\", \"瑞气\", \"灵泉\", \"仙山\", \"秘境\", \"禁地\", \"传承\", \"血脉\", \"天劫\", \"雷劫\", \"心魔劫\", \"道心\", \"悟性\", \"慧根\", \"灵识\", \"神念\", \"法诀\", \"剑诀\", \"心法\", \"秘术\", \"神通\"],\n \"bodyParts\": [\"丹田\", \"气海\", \"经脉\", \"灵根\", \"紫府\", \"眉心\", \"祖窍\", \"天灵感\", \"劳宫穴\", \"涌泉穴\", \"檀中穴\", \"泥丸宫\", \"神识之海\", \"元神\", \"道骨\", \"仙骨\", \"灵体\", \"法身\", \"金身\"],\n \"sensoryVerbs\": [\"感应\", \"察觉\", \"感知\", \"神识扫过\", \"灵识探去\", \"嗅到丹香\", \"听到道音\", \"感到威压\", \"灵光一闪\", \"灵气涌动\", \"剑气逼人\", \"寒意刺骨\", \"热浪扑面\", \"异香扑鼻\", \"瑞气万千\", \"霞光万道\"],\n \"actionVerbs\": [\"御剑\", \"掐诀\", \"祭出\", \"祭出法宝\", \"一挥袖\", \"身形一闪\", \"踏空而立\", \"凌空而起\", \"盘坐\", \"闭关\", \"突破\", \"渡劫\", \"飞升\", \"淬炼\", \"炼化\", \"收服\", \"祭出飞剑\", \"捏碎传讯符\", \"打出法诀\", \"布下阵法\", \"祭出符箓\", \"吞下丹药\", \"运转功法\", \"引导灵气\", \"盘膝而坐\", \"吐纳\", \"冥想\", \"悟道\", \"参悟\", \"拂袖而去\", \"踏剑而行\", \"遁光远去\", \"破空而来\"],\n \"environmentSignals\": [\"灵气浓郁\", \"仙气缭绕\", \"灵光闪烁\", \"剑气纵横\", \"威压如山\", \"天地变色\", \"风起云涌\", \"电闪雷鸣\", \"祥云汇聚\", \"霞光万道\", \"瑞气千条\", \"道音隆隆\", \"异香扑鼻\", \"药香四溢\", \"灵气充沛\", \"灵气稀薄\", \"魔气滔天\", \"妖气弥漫\", \"佛光普照\", \"阴风阵阵\", \"天崩地裂\", \"空间扭曲\", \"虚空碎裂\", \"天降异象\", \"紫气东来\"],\n \"dialogueTags\": [\"沉声道\", \"冷声道\", \"淡然道\", \"笑道\", \"冷哼一声\", \"喝道\", \"淡淡道\", \"缓缓道\", \"傲然道\", \"惊道\", \"怒喝\", \"轻声道\", \"传音道\", \"用神念传声道\", \"冷笑道\", \"讥讽道\", \"恭声道\", \"朗声道\"]\n }\n },\n \"examples\": [\n {\n \"text\": \"秦风盘坐在石室之中,双目微闭,双手结印。\\n\\n丹田内,那团金色的灵力旋涡越转越快,经脉中的灵气如江河奔涌,冲击着瓶颈处的壁障。他能清晰地感觉到,金丹期的壁障已经出现了裂纹。\\n\\n\\u201c破!\\u201d\\n\\n他低喝一声,神识猛地向内收缩,引导所有灵气汇聚于丹田一点。\\n\\n轰——\\n\\n一声闷响在体内炸开,灵力旋涡骤然凝缩,然后猛然膨胀!一颗金灿灿的丹珠在气海中成型,散发出温润而磅礴的灵力波动。\\n\\n金丹成了!\\n\\n石室上空,灵气疯狂汇聚,形成了一个肉眼可见的灵气漩涡。天地间隐隐有仙乐飘来,石壁上的灵纹齐齐亮起,整个洞府都在微微震颤。\\n\\n秦风睁开眼,眸中精光一闪即逝。他能感觉到,自己的神识比之前强大了数倍,方圆百丈之内的一切动静,尽在感知之中。\",\n \"note\": \"玄幻修仙词库示例:丹田/经脉/灵气/金丹/神识/掐诀/闭关/灵气漩涡/仙乐/灵光等修仙词汇自然融入\"\n }\n ],\n \"threshold_overrides\": {},\n \"radar_weights\": {\n \"bodyReaction\": 1.0,\n \"sensorySignal\": 1.2,\n \"action\": 1.2,\n \"emotion\": 0.9,\n \"infoAdvance\": 1.1\n }\n}\n","{\n \"preset_id\": \"preset_daily\",\n \"preset_name\": \"轻小说·日常V3.1追读版\",\n \"preset_description\": \"日常系V3.1追读版:3秒停留有趣开头+小反转+暧昧/笑点钩子。节奏舒缓但开篇抓人,人物互动有趣。\",\n \"based_on\": null,\n \"selections\": {\n \"node_sentence_rhythm\": \"opt_rhythm_mixed\",\n \"node_paragraph_density\": \"opt_dense_high\",\n \"node_dialogue_style\": \"opt_dialogue_natural\",\n \"node_description_style\": \"opt_desc_minimal\",\n \"node_battle_style\": \"opt_battle_result\",\n \"node_emotion_style\": \"opt_emotion_both\",\n \"node_tone\": \"opt_tone_playful\",\n \"node_platform\": \"opt_platform_generic\",\n \"node_info_density\": \"opt_info_balanced\",\n \"node_payoff_frequency\": \"opt_payoff_every_3\",\n \"node_pov\": \"opt_pov_limited_third_past\",\n \"node_rhetoric\": \"opt_rhetoric_metaphor\",\n \"node_vocab_sensory\": \"opt_vocab_daily\",\n \"node_vocab_filler\": \"opt_filler_relaxed\",\n \"node_target_length\": \"opt_length_2200\",\n \"node_anchor_density\": \"opt_anchor_standard\",\n \"node_strictness\": \"opt_strict_lenient\",\n \"node_ai_creativity\": \"opt_ai_balanced\",\n \"node_ai_continue_length\": \"opt_ai_medium\",\n \"node_opening_impact\": \"opt_opening_strong\",\n \"node_twist_frequency\": \"opt_twist_standard\",\n \"node_ending_hook\": \"opt_hook_break\"\n },\n \"extra_prompt\": \"日常系V3.1追读版:第一句直接有趣/尴尬/心动的瞬间(「她把情书递给他的时候,他正在抠脚。」「班主任叫我去办公室,里面坐着我上周刚甩掉的前女友。」),禁止「我叫XX,是个普通高中生」式自我介绍开头。前300字出现人物互动+第一个笑点/暧昧点/小冲突。每400-500字一次小反转/小笑点/小心动。日常文的反咬是人物反差和关系反转:以为她讨厌他→她在吃醋/以为是社死→是撩/以为是普通日常→藏着秘密。章末暧昧/社死/秘密钩子,最后一句≤15字。对话自然有趣,可以有吐槽和内心OS。身体锚点:脸红/心跳加速/耳朵发烫/手心出汗/嘴角抽搐/脚趾抠地。禁止48个AI套路反应词。\",\n \"extra_constraints\": [\n \"第一句直接有趣/尴尬/心动瞬间,0自我介绍铺垫\",\n \"前300字出现人物互动+第一个笑点/暧昧/冲突\",\n \"每400-500字一次小反转/小笑点/小心动\",\n \"章末暧昧/社死/秘密钩子,最后一句≤15字\",\n \"对话自然有趣,可以吐槽\",\n \"身体锚点:脸红/心跳/耳烫/手心出汗/嘴角抽\",\n \"禁止开篇自我介绍「我叫XX,是个XX」\",\n \"禁止48个AI套路反应词\"\n ],\n \"tags\": [\"日常\", \"轻小说\", \"校园\", \"恋爱\", \"V3.1追读\"]\n}\n","{\n \"preset_id\": \"preset_esports\",\n \"preset_name\": \"游戏竞技·V3.1追读版\",\n \"preset_description\": \"电竞V3.1追读版:3秒停留比赛现场开头+操作反咬+翻盘钩子。比赛紧张操作细节到位,队友互动有趣。\",\n \"based_on\": null,\n \"selections\": {\n \"node_sentence_rhythm\": \"opt_rhythm_short\",\n \"node_paragraph_density\": \"opt_dense_high\",\n \"node_dialogue_style\": \"opt_dialogue_natural\",\n \"node_description_style\": \"opt_desc_minimal\",\n \"node_battle_style\": \"opt_battle_atmosphere\",\n \"node_emotion_style\": \"opt_emotion_show\",\n \"node_tone\": \"opt_tone_playful\",\n \"node_platform\": \"opt_platform_qidian\",\n \"node_info_density\": \"opt_info_fast\",\n \"node_payoff_frequency\": \"opt_payoff_every_chapter\",\n \"node_pov\": \"opt_pov_limited_third_past\",\n \"node_rhetoric\": \"opt_rhetoric_plain\",\n \"node_vocab_sensory\": \"opt_vocab_esports\",\n \"node_vocab_filler\": \"opt_filler_relaxed\",\n \"node_target_length\": \"opt_length_2200\",\n \"node_anchor_density\": \"opt_anchor_dense\",\n \"node_strictness\": \"opt_strict_lenient\",\n \"node_ai_creativity\": \"opt_ai_balanced\",\n \"node_ai_continue_length\": \"opt_ai_medium\",\n \"node_opening_impact\": \"opt_opening_strong\",\n \"node_twist_frequency\": \"opt_twist_dense\",\n \"node_ending_hook\": \"opt_hook_break\"\n },\n \"extra_prompt\": \"电竞/网游V3.1追读版:第一句直接比赛现场/关键操作/危机瞬间(「最后三秒,他的手停在键盘上。」「水晶只剩50血。」「队友全死了,对面五个满血。」),禁止「XX年,电竞圈……」式开头。每250-350字一次操作反咬(以为要输→神操作/以为赢了→被反杀/以为队友菜→是伏笔/以为是失误→是算计)。比赛中操作要具体(技能名/走位/血量/CD/经济差),赛后/日常队友互怼要自然有趣。章末翻盘/绝杀/新对手钩子,最后一句≤15字。对话自然,可以有吐槽和游戏黑话但要让读者看懂。手速/心跳/掌心出汗/眼睛发酸是电竞核心身体锚点。禁止48个AI套路反应词。\",\n \"extra_constraints\": [\n \"第一句直接比赛现场/关键操作/危机,0背景铺垫\",\n \"前300字进入比赛/冲突\",\n \"每250-350字一次操作反咬/局势反转\",\n \"比赛操作具体到技能/血量/CD/走位\",\n \"章末翻盘/绝杀/新对手钩子\",\n \"身体锚点:手速/心跳/掌心出汗/眼睛发酸/手指僵硬\",\n \"禁止开篇大段电竞圈/游戏介绍\",\n \"禁止48个AI套路反应词\"\n ],\n \"tags\": [\"游戏\", \"竞技\", \"电竞\", \"V3.1追读\"]\n}\n","{\n \"preset_id\": \"preset_fantasy\",\n \"preset_name\": \"西方奇幻·V3.1追读版\",\n \"preset_description\": \"西方奇幻V3.1追读版:3秒停留危险开头+冒险反咬+悬念钩子。剑与魔法,冒险感强,但仍遵守追读铁则。\",\n \"based_on\": null,\n \"selections\": {\n \"node_sentence_rhythm\": \"opt_rhythm_mixed\",\n \"node_paragraph_density\": \"opt_dense_medium\",\n \"node_dialogue_style\": \"opt_dialogue_stylized\",\n \"node_description_style\": \"opt_desc_sensory\",\n \"node_battle_style\": \"opt_battle_detail\",\n \"node_emotion_style\": \"opt_emotion_show\",\n \"node_tone\": \"opt_tone_classical\",\n \"node_platform\": \"opt_platform_qidian\",\n \"node_info_density\": \"opt_info_balanced\",\n \"node_payoff_frequency\": \"opt_payoff_every_3\",\n \"node_pov\": \"opt_pov_limited_third_past\",\n \"node_rhetoric\": \"opt_rhetoric_ornate\",\n \"node_vocab_sensory\": \"opt_vocab_fantasy\",\n \"node_vocab_filler\": \"opt_filler_standard\",\n \"node_target_length\": \"opt_length_3000\",\n \"node_anchor_density\": \"opt_anchor_dense\",\n \"node_strictness\": \"opt_strict_standard\",\n \"node_ai_creativity\": \"opt_ai_balanced\",\n \"node_ai_continue_length\": \"opt_ai_medium\",\n \"node_opening_impact\": \"opt_opening_strong\",\n \"node_twist_frequency\": \"opt_twist_standard\",\n \"node_ending_hook\": \"opt_hook_break\"\n },\n \"extra_prompt\": \"西方奇幻V3.1追读版:第一句直接危险/动作现场,前300字出现冲突+主角身体反应+异常。每400-500字一次冒险反咬(以为安全→遇袭/以为赢了→Boss出场/以为是友→是敌)。章末具体悬念钩子。禁止「在XX大陆上,有一个XX」式世界观开头。情绪落到肉身,禁止48个AI套路反应词。\",\n \"extra_constraints\": [\n \"第一句直接危险/动作/冲突,0世界观铺垫\",\n \"前300字出现冲突+身体反应+异常\",\n \"每400-500字一次冒险反咬/危机\",\n \"章末具体悬念钩子,最后一句≤15字\",\n \"禁止开篇大段世界观/种族/历史介绍\",\n \"禁止48个AI套路反应词\"\n ],\n \"tags\": [\"奇幻\", \"西幻\", \"冒险\", \"V3.1追读\"]\n}\n","{\n \"preset_id\": \"preset_historical\",\n \"preset_name\": \"历史架空·V3.1追读版\",\n \"preset_description\": \"历史架空V3.1追读版:3秒停留危机开头+权谋反咬+变局钩子。用词考究,礼仪/官制/称谓准确,但开篇直接进事件。\",\n \"based_on\": null,\n \"selections\": {\n \"node_sentence_rhythm\": \"opt_rhythm_mixed\",\n \"node_paragraph_density\": \"opt_dense_medium\",\n \"node_dialogue_style\": \"opt_dialogue_stylized\",\n \"node_description_style\": \"opt_desc_poetic\",\n \"node_battle_style\": \"opt_battle_detail\",\n \"node_emotion_style\": \"opt_emotion_show\",\n \"node_tone\": \"opt_tone_serious\",\n \"node_platform\": \"opt_platform_qidian\",\n \"node_info_density\": \"opt_info_balanced\",\n \"node_payoff_frequency\": \"opt_payoff_every_3\",\n \"node_pov\": \"opt_pov_limited_third_past\",\n \"node_rhetoric\": \"opt_rhetoric_ornate\",\n \"node_vocab_sensory\": \"opt_vocab_historical\",\n \"node_vocab_filler\": \"opt_filler_strict\",\n \"node_target_length\": \"opt_length_3000\",\n \"node_anchor_density\": \"opt_anchor_dense\",\n \"node_strictness\": \"opt_strict_strict\",\n \"node_ai_creativity\": \"opt_ai_conservative\",\n \"node_ai_continue_length\": \"opt_ai_medium\",\n \"node_opening_impact\": \"opt_opening_strong\",\n \"node_twist_frequency\": \"opt_twist_standard\",\n \"node_ending_hook\": \"opt_hook_break\"\n },\n \"extra_prompt\": \"历史架空V3.1追读版:第一句直接事件/危机/变局现场,前300字进入正在发生的事(圣旨到/刀架脖子/城门破了/被弹劾),禁止「大靖王朝三百年来」式历史背景开头。每400-500字一次权谋反咬(以为是友→是敌/以为被贬→是升/以为赢了→中计)。章末变局/圣旨/密信/刺杀钩子。用词符合时代,称谓准确,但不堆砌文言。情绪落到身体细节,禁止48个AI套路反应词。\",\n \"extra_constraints\": [\n \"第一句直接事件/危机/变局,0历史背景铺垫\",\n \"前300字进入正在发生的事\",\n \"每400-500字一次权谋反咬/变局\",\n \"章末变局/圣旨/密信钩子,最后一句≤15字\",\n \"用词符合时代,称谓准确\",\n \"禁止开篇大段历史背景/王朝介绍\",\n \"禁止48个AI套路反应词\"\n ],\n \"tags\": [\"历史\", \"架空\", \"权谋\", \"V3.1追读\"]\n}\n","{\n \"preset_id\": \"preset_horror\",\n \"preset_name\": \"灵异恐怖·V3.1追读版\",\n \"preset_description\": \"恐怖灵异V3.1追读版:3秒停留不安开头+密集异常反咬+具体恐怖钩子。用五感细节营造不安,安静-不安-爆发节奏循环,不直接写鬼。\",\n \"based_on\": null,\n \"selections\": {\n \"node_sentence_rhythm\": \"opt_rhythm_short\",\n \"node_paragraph_density\": \"opt_dense_medium\",\n \"node_dialogue_style\": \"opt_dialogue_concise\",\n \"node_description_style\": \"opt_desc_sensory\",\n \"node_battle_style\": \"opt_battle_psychological\",\n \"node_emotion_style\": \"opt_emotion_show\",\n \"node_tone\": \"opt_tone_cold\",\n \"node_platform\": \"opt_platform_newmedia\",\n \"node_info_density\": \"opt_info_fast\",\n \"node_payoff_frequency\": \"opt_payoff_every_chapter\",\n \"node_pov\": \"opt_pov_first_past\",\n \"node_rhetoric\": \"opt_rhetoric_plain\",\n \"node_vocab_sensory\": \"opt_vocab_horror\",\n \"node_vocab_filler\": \"opt_filler_strict\",\n \"node_target_length\": \"opt_length_2200\",\n \"node_anchor_density\": \"opt_anchor_extreme\",\n \"node_strictness\": \"opt_strict_strict\",\n \"node_ai_creativity\": \"opt_ai_conservative\",\n \"node_ai_continue_length\": \"opt_ai_medium\",\n \"node_opening_impact\": \"opt_opening_strong\",\n \"node_twist_frequency\": \"opt_twist_dense\",\n \"node_ending_hook\": \"opt_hook_break\"\n },\n \"extra_vocab\": {\n \"add\": {\n \"bodyParts\": [\"后颈\", \"脊背\", \"头皮\", \"发根\", \"牙根\", \"指尖\", \"胃\", \"喉咙\", \"毛孔\", \"汗毛\"],\n \"sensoryVerbs\": [\"后颈发凉\", \"头皮发麻\", \"脊背发寒\", \"汗毛竖起\", \"胃一缩\", \"喉咙发紧\", \"牙根发酸\", \"指尖冰凉\", \"喘不上气\", \"心脏停跳\", \"耳朵嗡鸣\", \"血凉了\"],\n \"actionVerbs\": [\"僵住\", \"屏住呼吸\", \"不敢动\", \"回头\", \"慢慢转头\", \"贴墙\", \"捂住嘴\", \"不敢出声\", \"后退\", \"摸到\", \"盯着\", \"咽口水\"],\n \"environmentSignals\": [\"温度骤降\", \"异响\", \"水滴声\", \"脚步停了\", \"敲门声\", \"灯闪\", \"灯灭了\", \"镜子里\", \"床底\", \"门关了\", \"风停了\", \"安静得过分\", \"呼吸声不对\", \"第三下\", \"空无一人\", \"味道不对\"]\n }\n },\n \"extra_prompt\": \"灵异恐怖V3.1追读版:\\n\\n【开头】第一句≤20字直接身体不安信号或具体异常。恐怖文最强开头:「后颈凉了。」「敲门声停了。」「我数了数,宿舍里有五个人。但我们寝室只有四个。」前300字必须:异常信号出现→主角身体恐惧反应(后颈凉/头皮麻/胃缩/呼吸停)→规则/不对劲浮现。禁止写景/交代背景/「我叫XX」开头。\\n\\n【反咬】每200-300字一次恐怖反咬(恐怖文节奏比爽文更快):以为没事→还有声音/以为是猫→是人/以为只有一个→满屋子都是/以为跑了→在身后。反咬必须具体:具体什么声音、具体什么位置、具体哪不对、具体少了/多了什么。禁止「似乎有什么东西」「一股不祥预感」假恐怖,必须是看得见摸得着的异常。\\n\\n【钩子】章末钩子必须是具体恐怖画面:镜子里多了个人/床底露出一只眼睛/手机照片里身后有人/他转头,看见自己的尸体/门外传来第三下敲门但屋里人都在。最后一句≤12字极短句落点,越短越恐怖。\\n\\n【恐怖原则】不直接写鬼,不解释原理。恐怖来自「不对」:规则违反(敲门声是三下但楼道没人/照片里人眨眼了/朋友说了句他不可能知道的事/死者发了朋友圈)。所有恐怖先落到主角身体(后颈凉/胃缩/指尖凉/呼吸卡),再落到具体异常物件。\\n\\n【对话】恐怖文中对话要短,人在害怕时话少,甚至不说话只用眼神交流。有人说一句没人接话,最恐怖。\",\n \"extra_constraints\": [\n \"第一句直接身体不安信号或具体异常,0铺垫\",\n \"前300字:异常出现→身体恐惧反应→规则不对劲浮现\",\n \"每200-300字一次恐怖反咬,千字≥4个\",\n \"恐怖必须具体:看得见摸得着听得到,禁止空泛悬念\",\n \"不直接写鬼/不解释原理,靠「不对」制造恐惧\",\n \"章末具体恐怖画面钩子,最后一句≤12字极短句\",\n \"对话要短,害怕时人不说话\",\n \"禁止48个AI套路反应词,恐惧落到身体:后颈凉/头皮麻/胃缩/指尖冰/呼吸卡\",\n \"禁止「一股神秘气息/不祥预感/黑暗中有什么」假恐怖\"\n ],\n \"examples\": [\n {\n \"text\": \"后颈凉了。\\n\\n我停下刷牙的动作,满嘴泡沫抬头看镜子。卫生间里只有我一个人,排气扇嗡嗡转着。\\n\\n但那股凉意还在,像有人对着我后颈吹气。\\n\\n我慢慢转过头。\\n\\n身后什么都没有。门是关着的,窗户也关着,没有风。\\n\\n我松了口气,转回来继续刷。\\n\\n镜子里,我身后站着一个人。\",\n \"note\": \"恐怖V3.1开头示范:第一句「后颈凉了」单字感官→第二句具体场景→第三句身体继续反应→反咬(转头没人)→再反咬(镜子里有人)。最后一句7字极短句落点,恐怖感拉满。\"\n }\n ],\n \"extra_rules\": [\n {\n \"id\": \"no_fake_horror\",\n \"name\": \"禁止假恐怖\",\n \"description\": \"禁止使用「一股阴森的气息/一种说不出的恐惧/鬼气森森/阴气逼人」等空泛恐怖形容词,恐怖必须通过具体物件和身体反应展现\",\n \"severity\": \"warning\",\n \"pattern\": \"一股阴森|鬼气森森|阴气逼人|说不出的恐惧|莫名的恐惧\",\n \"injectToPrompt\": true\n }\n ],\n \"tags\": [\"灵异\", \"恐怖\", \"悬疑\", \"V3.1追读\"]\n}\n","{\n \"preset_id\": \"preset_miner\",\n \"preset_name\": \"我只是个矿工·V3.1极致追读预设\",\n \"preset_description\": \"《我只是个矿工》V3.1极致追读力预设,对标2026番茄/起点头部作品:3秒停留开头+密集反咬+对话碰撞+具体断裂钩子+48套路反应黑名单+禁假钩子。\",\n \"based_on\": null,\n \"selections\": {\n \"node_sentence_rhythm\": \"opt_rhythm_mixed\",\n \"node_paragraph_density\": \"opt_dense_medium\",\n \"node_dialogue_style\": \"opt_dialogue_concise\",\n \"node_description_style\": \"opt_desc_clinical\",\n \"node_battle_style\": \"opt_battle_atmosphere\",\n \"node_emotion_style\": \"opt_emotion_show\",\n \"node_tone\": \"opt_tone_cold\",\n \"node_platform\": \"opt_platform_tomato\",\n \"node_info_density\": \"opt_info_fast\",\n \"node_payoff_frequency\": \"opt_payoff_every_chapter\",\n \"node_pov\": \"opt_pov_limited_third_past\",\n \"node_rhetoric\": \"opt_rhetoric_plain\",\n \"node_vocab_sensory\": \"opt_vocab_scifi\",\n \"node_vocab_filler\": \"opt_filler_strict\",\n \"node_target_length\": \"opt_length_2200\",\n \"node_anchor_density\": \"opt_anchor_extreme\",\n \"node_strictness\": \"opt_strict_strict\",\n \"node_ai_creativity\": \"opt_ai_conservative\",\n \"node_ai_continue_length\": \"opt_ai_medium\",\n \"node_opening_impact\": \"opt_opening_strong\",\n \"node_twist_frequency\": \"opt_twist_dense\",\n \"node_ending_hook\": \"opt_hook_break\"\n },\n \"extra_vocab\": {\n \"add\": {\n \"worldTerms\": [\"活体壁\", \"壁温\", \"叩壁语\", \"铜碗\", \"壁系\", \"金纹\", \"黑液\", \"搏纹\", \"大沉降\", \"矿盟\", \"矿道\", \"壁面\", \"壁的呼吸\", \"暗纹\", \"壁癌\", \"测壁锤\", \"矿灯\", \"除尘罩\", \"压风\", \"岩爆\", \"壁潮\", \"深区\", \"浅区\", \"中段\", \"掌子面\", \"沉渊\", \"盾与凿\", \"茧长\", \"检测仪\", \"恒温网络\", \"矿工日\", \"落碴\", \"顶板\", \"通风管\", \"茧丝\", \"脉核\", \"温墙点\", \"凿痕\", \"号牌\", \"灯格\", \"头灯\", \"凿柄\", \"虎口\", \"茧\"],\n \"bodyParts\": [\"后颈\", \"虎口\", \"指节\", \"耳膜\", \"鼻腔\", \"肺泡\", \"掌心\", \"脊背\", \"下颌\", \"眉骨\", \"手腕\", \"后槽牙\", \"胃\", \"指尖\", \"牙根\", \"锁骨\", \"太阳穴\", \"指腹\"],\n \"sensoryVerbs\": [\"壁温感知\", \"叩壁\", \"贴壁\", \"听壁\", \"嗅壁\", \"辨温\", \"触壁\", \"测壁\", \"收震波\", \"麻\", \"烫\", \"凉\", \"震\", \"涩\", \"黏\", \"搏\", \"跳\", \"缩\", \"僵\"],\n \"environmentSignals\": [\"壁震\", \"灯闪\", \"岩尘\", \"黑液渗\", \"搏纹动\", \"空响\", \"温降\", \"风变向\", \"丝落\", \"碴响\"],\n \"actionVerbs\": [\"凿\", \"敲\", \"贴\", \"摸\", \"听\", \"缩手\", \"僵住\", \"举盾\", \"退\", \"跑\", \"拽\", \"蹲\", \"回头\", \"屏住呼吸\", \"扣紧凿柄\", \"咬后槽牙\"]\n }\n },\n \"extra_prompt\": \"《我只是个矿工》V3.1极致追读力预设——对标2026番茄/起点头部作品。严格遵守九条铁则:\\n\\n【铁则零·3秒停留】第一句≤20字,单字感官鼓点最佳(疼。/烫。/麻。/响。/血。),0铺垫直接进动作现场。前300字必须完成:冲突爆发→林深身体在场→异常信号出现。前300字禁止写景、交代背景、介绍人物、回忆、世界观说明。背景一句话插动作中间:「大沉降后第三年,他们在一千二百米深。」\\n\\n【铁则一·Show Don't Tell】禁止直述情绪(他害怕/她紧张/气氛压抑),禁止48个AI套路反应词(全部用生理级反应替代)。情绪落到七大肉身锚点:心脏/胃/脊背/指尖/后颈/眉心/后槽牙。\\n\\n【铁则二·身体锚点】每段必须有林深或视角人物的身体感知。禁止连续两段无身体反应。\\n\\n【铁则三·五感激活】科幻悬疑感来自具体感官细节:壁的温度精确到小数点后一位(37.2度)、金属的涩味、黑液的温度(温的/烫的/冰的)、空响和闷响的区别、岩尘的颗粒感、虎口的震麻。\\n\\n【铁则四·开头三句】第一句单字感官刺激→第二句本能身体反应→第三句具体异常出现。禁止「壁面冰冷」式环境陈述开头。\\n\\n【铁则五·对话五步碰撞】任何角色说出判断后,下一个人必须先反对/质疑/唱反调,不许直接认同。老范说不对→寻先说茧没响(反对)→寻发现确实多一拍(老范对了,打脸寻);铁铮话最少但每句都是动作指令;林深做最终决定但会先听所有人。对话中至少一次用动作打断(举盾/砸凿/抓手腕),至少一人判断错误后被打脸。\\n\\n【铁则六·密集反咬】每250-350字必须有一次信息反咬。反咬六型:安全→危险/是A→是B/某人错了→他对了/结束→刚开始/是友→有疑点/新发现颠覆认知。反咬必须具体(具体什么不对:温度/声音/数字/表情/物件),禁止「似乎/好像/哪里不对」空泛反咬。反咬后立刻接身体反应,不停顿解释。千字≥3个反咬,禁止连续400字无转折。\\n\\n【铁则七·断裂钩子】最后100字必须出现前文完全没提过的具体新信息颠覆判断。钩子必须具体:看得见、摸得着、听得见(凿尖沾血/第三下敲门/数字6/自己的笔迹/黑液在爬)。禁止7个假钩子(神秘气息/似乎意识到/不祥预感/没那么简单/黑暗中有东西/他不知道的是/危险逼近)。最后一句≤15字短句鼓点落点,禁止「了。」收尾,禁止「就这样/原来如此/所以/于是」总结词。检验标准:读者会不会骂「操怎么断在这里」?会才合格。\\n\\n【铁则八·短句节奏】每行视觉长度≤17字(手机一屏),长句拆短。短句必须有身份:危险/发现/反咬/打断/对话锋刃/章末钩子。无身份短句合并。禁止连续3个≤12字短句无新信息/无转折/无对话(碎句病)。同一动作链逗号串联,换拍才用句号。\\n\\n【角色台词纪律】铁铮开口≤5字动词结尾(退。/跑。/举盾。/别碰。);老范用短句反问+经验判断(扯蛋。/你聋了?/听我说。/别凿了。);寻只说茧告诉她的客观数据+否定别人(茧没响。/三十七点二,恒定。/不是风。);林深话最少,做决定前先听所有人,做决定时用极短句。\\n\\n【壁的质感】壁是活的、异质的、陌生的,不是魔法,保持硬科幻质感。壁温精确到小数点后一位。壁的「活」通过温度变化、搏动感、黑液、纹路生长、声音异常来表现,不用任何神秘/诡异/超自然形容词。\",\n \"extra_constraints\": [\n \"第一句≤20字,单字感官鼓点最佳,0铺垫直接进动作\",\n \"前300字:冲突在场→林深身体在场→异常在场,禁止写景/背景/回忆\",\n \"壁温必须用阿拉伯数字精确到小数点后一位(37.2度)\",\n \"敲壁信号区分三短一长(联络)、乱敲(慌张)、长敲(警告)\",\n \"对话必须有碰撞:一人判断后下一人必须先反对/质疑,至少一人被打脸\",\n \"每250-350字一次信息反咬,千字≥3个,反咬必须具体\",\n \"章末最后100字必须有前文未提及的具体新信息颠覆判断\",\n \"章末钩子必须具体,禁止7个装神弄鬼假钩子\",\n \"章末最后一句≤15字短句鼓点,禁止「了。」收尾和总结词\",\n \"禁止48个AI套路反应词,情绪落到七大肉身锚点\",\n \"禁止破折号,用逗号替代\",\n \"禁止「不是X是Y」解释结构\",\n \"禁止连续3个以上≤12字无身份短句(碎句病)\",\n \"每段必须有身体锚点,禁止连续两段无身体感知\",\n \"对话简洁:铁铮≤5字动词结尾,老范短句反问,寻说客观数据\",\n \"禁止直述情绪,必须用生理级身体反应表达\",\n \"禁止「非常/十分/极其/似乎/好像/仿佛/有点/有些」填充词\",\n \"壁的「活」通过温度/搏动/黑液/纹路/声音表现,保持硬科幻质感,不用「神秘/诡异」形容词\",\n \"短句必须有身份:危险/发现/反咬/打断/钩子,无身份短句合并\",\n \"同一动作链逗号串联,换拍/换判断才用句号\"\n ],\n \"examples\": [\n {\n \"text\": \"疼。\\n\\n凿尖砸在指关节上,林深闷哼一声,指缝里渗出血。他甩了甩手,骨节处火辣辣地烧,血珠滴在靴面上,很快被岩尘吸成深色。\\n\\n茧壁在震。\\n\\n不是他凿的那种震。\",\n \"note\": \"V3.1极致开头:第一句1字「疼。」直接身体刺激→第二句本能反应+具体感官(火辣辣烧、血珠)→第三句异常出现(茧壁在震,不是他凿的那种)。前50字完成三秒停留三件事。\"\n },\n {\n \"text\": \"麻。\\n林深的指尖刚碰到壁面就缩了回来,指腹上一片鸡皮疙瘩。不对。今天的壁温比平时低了零点三度。\\n\\n「扯蛋。」寻已经把指节贴上去了,闭着眼收了三秒震波,「三十七点二,恒定。你手凉。」\\n\\n老范没说话,只是把凿子横过来,用凿头敲了敲铁轨。\\n当。\\n空响。\\n\\n寻的眼睛睁开了。\",\n \"note\": \"对话碰撞+反咬示范:林深说不对→寻先反对(扯蛋/你手凉)→老范敲铁轨是空响(证据反咬)→寻被打脸(眼睛睁开了,老范是对的)。\"\n },\n {\n \"text\": \"林深蹲下去捡,指尖刚碰到塑料片,整个茧壁突然震了一下。\\n\\n不是之前那种从深处传上来的震。\\n\\n是壁在动。\\n\\n头灯的光晃了一下,老范骂了一声。林深抬起头,看见那道细纹路在变宽,从发丝细变成筷子粗,黑的,有液体从里面渗出来。\\n\\n不是水。\\n\\n那液体是温的。\",\n \"note\": \"密集反咬示范:以为是普通震→是壁在动(反咬1)→以为渗的是水→是温的黑液(反咬2),每200字左右一个反咬,反咬后立刻接动作/感官不停顿。\"\n },\n {\n \"text\": \"那截金色的纤维从裂缝里探出来,在空中晃了晃,指向林深的小臂。\\n铁铮已经把盾举起来了,金丝在盾面上跳得飞快。「退。」\\n\\n林深没动。他的小臂在发烫,茧在皮肤下面跳得和纤维一个频率。\\n然后纤维尖端裂开,掉出一样东西。\\n是一片凿痕。\\n林深蹲下去捡,指尖刚碰到石片,后颈的汗毛全竖了起来。\\n石片背面有字。\\n是他自己的笔迹。\\n「别凿。」\\n他从来没写过这个。\",\n \"note\": \"断裂钩子示范:新信息(自己的笔迹写着别凿)+认知颠覆(以为壁求他凿,结果是让他别凿)+未回答的问题(谁写的?什么时候写的?)。最后一句6字极短句落点。\"\n }\n ],\n \"extra_rules\": [\n {\n \"id\": \"wall_temp_precision\",\n \"name\": \"壁温精度\",\n \"description\": \"壁温描写必须精确到小数点后一位(如37.2度),不能写中文数字温度或整数温度\",\n \"severity\": \"warning\",\n \"pattern\": \"三十[六七七八九]?度|[^\\\\d点]37度|三十七度\",\n \"injectToPrompt\": true\n },\n {\n \"id\": \"knock_signal\",\n \"name\": \"敲壁信号\",\n \"description\": \"敲壁信号描写需明确节奏:三短一长是联络/回应,乱敲是慌张,长敲是警告\",\n \"severity\": \"warning\",\n \"pattern\": \"敲了三下(?!.*三短)\",\n \"injectToPrompt\": true\n },\n {\n \"id\": \"no_dash\",\n \"name\": \"禁止破折号\",\n \"description\": \"禁止使用破折号(——),中文网文用逗号足够\",\n \"severity\": \"error\",\n \"pattern\": \"——\",\n \"injectToPrompt\": true\n },\n {\n \"id\": \"no_cliche_reaction_v31\",\n \"name\": \"禁止48个套路反应(V3.1)\",\n \"description\": \"禁止使用全部48个AI套路反应词,用生理级身体反应替代\",\n \"severity\": \"warning\",\n \"pattern\": \"心头一跳|脸色一变|握紧拳头|不由得|情不自禁|忍不住(?!笑)|不禁(?!锢)|点了点头|叹了口气|皱了皱眉|冷哼一声|嘴角微扬|微微一笑|苦笑一声|瞳孔骤缩|眼中闪过一丝|嘴角勾起一抹|眼中寒光一闪|浑身一颤|虎躯一震|眼中精芒爆闪|气势陡然一变|一股强横的气息|散发出王者之气|冷笑一声|嗤笑一声|摇头失笑|面露难色|眉头紧锁|眼神复杂|深吸一口气|缓缓开口|淡淡道|冷冷道|沉声道|厉声道|爆喝道|怒吼道|一字一句道|不置可否|置若罔闻|恍若未闻|不以为然|不屑一顾|视若无睹|无动于衷|面无表情\",\n \"injectToPrompt\": true\n },\n {\n \"id\": \"no_fake_hooks\",\n \"name\": \"禁止装神弄鬼假钩子\",\n \"description\": \"章末禁止使用空泛假钩子:一股神秘的/一种莫名的/一丝诡异的/似乎意识到了什么/不祥的预感/事情没那么简单/黑暗中有什么东西/他不知道的是\",\n \"severity\": \"warning\",\n \"pattern\": \"一股神秘的|一种莫名的|一丝诡异的|似乎意识到了什么|好像发现了什么|不祥的预感|事情没那么简单|他不知道的是|黑暗中有什么东西\",\n \"injectToPrompt\": true\n }\n ],\n \"tags\": [\"矿工\", \"科幻\", \"悬疑\", \"冷峻\", \"V3.1极致追读\", \"对标番茄头部\", \"专属预设\"]\n}\n","{\n \"preset_id\": \"preset_mystery\",\n \"preset_name\": \"悬疑推理·V3.1追读版\",\n \"preset_description\": \"悬疑推理V3.1追读版:3秒停留异常开头+密集线索反咬+真相钩子。线索藏在细节里,每章留新疑点,节奏紧凑。\",\n \"based_on\": null,\n \"selections\": {\n \"node_sentence_rhythm\": \"opt_rhythm_short\",\n \"node_paragraph_density\": \"opt_dense_medium\",\n \"node_dialogue_style\": \"opt_dialogue_concise\",\n \"node_description_style\": \"opt_desc_sensory\",\n \"node_battle_style\": \"opt_battle_psychological\",\n \"node_emotion_style\": \"opt_emotion_show\",\n \"node_tone\": \"opt_tone_cold\",\n \"node_platform\": \"opt_platform_generic\",\n \"node_info_density\": \"opt_info_fast\",\n \"node_payoff_frequency\": \"opt_payoff_every_chapter\",\n \"node_pov\": \"opt_pov_limited_third_past\",\n \"node_rhetoric\": \"opt_rhetoric_plain\",\n \"node_vocab_sensory\": \"opt_vocab_mystery\",\n \"node_vocab_filler\": \"opt_filler_strict\",\n \"node_target_length\": \"opt_length_2200\",\n \"node_anchor_density\": \"opt_anchor_extreme\",\n \"node_strictness\": \"opt_strict_strict\",\n \"node_ai_creativity\": \"opt_ai_balanced\",\n \"node_ai_continue_length\": \"opt_ai_medium\",\n \"node_opening_impact\": \"opt_opening_strong\",\n \"node_twist_frequency\": \"opt_twist_dense\",\n \"node_ending_hook\": \"opt_hook_break\"\n },\n \"extra_vocab\": {\n \"add\": {\n \"bodyParts\": [\"太阳穴\", \"指尖\", \"后颈\", \"瞳孔\", \"眉心\", \"后槽牙\"],\n \"sensoryVerbs\": [\"瞳孔收缩\", \"眉心一跳\", \"指尖冰凉\", \"后颈发紧\", \"呼吸一滞\", \"胃一沉\"],\n \"actionVerbs\": [\"蹲\", \"翻\", \"照\", \"摸\", \"闻\", \"盯\", \"比对\", \"发现\", \"意识到\", \"不对\", \"停住\", \"愣住\"],\n \"environmentSignals\": [\"血迹\", \"指纹\", \"脚印\", \"监控\", \"门没锁\", \"灯开着\", \"手机响\", \"短信\", \"照片\", \"时间不对\", \"少了东西\", \"多了东西\"]\n }\n },\n \"extra_prompt\": \"悬疑推理V3.1追读版:\\n\\n【开头】第一句直接写异常发现:「尸体的手指动了一下。」「门锁是从里面反锁的,但钥匙在死者口袋里。」前300字:案发现场/异常事件→侦探/主角身体在场→第一个不对劲的细节。禁止「XX市发生了一起命案」式新闻开头。\\n\\n【反咬】每250-350字一次线索反咬:以为A是凶手→B有不在场证明/以为是自杀→发现他杀证据/以为线索断了→新证据出现/某人在说谎被揭穿。每一个身体细节(表情/停顿/眼神/手指动作)都可能是线索。\\n\\n【钩子】章末钩子是新线索/新疑点/新反转:刚排除一个嫌疑人→发现他有第二动机/以为结案→尸体又出现一个/凶手以为自己安全→侦探已经站在他门口。最后一句≤15字。\\n\\n【线索纪律】线索必须具体:指纹在什么位置、血迹形状、监控时间差几分几秒、哪个词说得不对。禁止「有线索表明」「种种迹象显示」这种模糊写法。\",\n \"extra_constraints\": [\n \"第一句直接异常/案发现场,0铺垫\",\n \"前300字出现第一个不对劲的细节\",\n \"每250-350字一次线索反咬/反转\",\n \"线索必须具体到看得见摸得着\",\n \"章末新疑点/新线索/新反转钩子\",\n \"禁止48个AI套路反应词,情绪落到身体细节\",\n \"对话中说谎者必有微表情/动作破绽\"\n ],\n \"examples\": [\n {\n \"text\": \"死者的手指动了一下。\\n\\n陈警官蹲下去,戴手套的手碰了碰那根手指。僵硬的。已经死了至少六个小时,尸僵都出来了。\\n\\n是他看错了。\\n\\n他站起身,目光扫过出租屋。门窗反锁,钥匙在死者裤兜里,桌上有一杯喝了一半的水,水里有安眠药。典型的自杀。\\n\\n不对。\\n\\n他重新蹲下去,翻开死者的眼皮。\\n\\n瞳孔是缩小的。\\n\\n安眠药中毒死亡,瞳孔应该是散大的。\\n\\n这不是自杀。\",\n \"note\": \"悬疑V3.1开头:第一句异常(手指动了)→身体在场(蹲、碰)→反咬(看错了/尸僵)→再反咬(不对/瞳孔缩小)→钩子(不是自杀)。\"\n }\n ],\n \"tags\": [\"悬疑\", \"推理\", \"破案\", \"V3.1追读\"]\n}\n","{\n \"preset_id\": \"preset_scifi_hardcore\",\n \"preset_name\": \"科幻·硬核V3.1追读版\",\n \"preset_description\": \"硬核科幻V3.1追读版:3秒停留异常开头+科学反咬+发现钩子。技术细节准确,逻辑自洽,但仍遵守追读力铁则。\",\n \"based_on\": null,\n \"selections\": {\n \"node_sentence_rhythm\": \"opt_rhythm_mixed\",\n \"node_paragraph_density\": \"opt_dense_medium\",\n \"node_dialogue_style\": \"opt_dialogue_natural\",\n \"node_description_style\": \"opt_desc_clinical\",\n \"node_battle_style\": \"opt_battle_detail\",\n \"node_emotion_style\": \"opt_emotion_show\",\n \"node_tone\": \"opt_tone_cold\",\n \"node_platform\": \"opt_platform_qidian\",\n \"node_info_density\": \"opt_info_balanced\",\n \"node_payoff_frequency\": \"opt_payoff_every_3\",\n \"node_pov\": \"opt_pov_limited_third_past\",\n \"node_rhetoric\": \"opt_rhetoric_plain\",\n \"node_vocab_sensory\": \"opt_vocab_scifi\",\n \"node_vocab_filler\": \"opt_filler_strict\",\n \"node_target_length\": \"opt_length_3000\",\n \"node_anchor_density\": \"opt_anchor_dense\",\n \"node_strictness\": \"opt_strict_strict\",\n \"node_ai_creativity\": \"opt_ai_conservative\",\n \"node_ai_continue_length\": \"opt_ai_medium\",\n \"node_opening_impact\": \"opt_opening_strong\",\n \"node_twist_frequency\": \"opt_twist_standard\",\n \"node_ending_hook\": \"opt_hook_break\"\n },\n \"extra_vocab\": {\n \"add\": {\n \"bodyParts\": [\"太阳穴\", \"后颈\", \"指尖\", \"耳膜\", \"鼻腔\", \"胃\", \"脊背\", \"虎口\"],\n \"sensoryVerbs\": [\"耳膜嗡鸣\", \"指尖发麻\", \"胃里翻涌\", \"后颈发凉\", \"呼吸凝滞\", \"视线模糊\", \"金属味\", \"电流感\"],\n \"actionVerbs\": [\"扫描\", \"检测\", \"计算\", \"校准\", \"启动\", \"关闭\", \"锁定\", \"闪避\", \"接入\", \"断开\", \"记录\", \"分析\"],\n \"environmentSignals\": [\"警报响\", \"红灯闪\", \"气压降\", \"温度升\", \"辐射超标\", \"信号断\", \"屏幕花\", \"舱门响\", \"金属扭曲声\", \"空气稀薄\"]\n }\n },\n \"extra_prompt\": \"硬核科幻V3.1追读版:\\n\\n【开头】第一句≤20字直接写正在发生的异常/危机/发现。科幻文最强开头:「警报响的时候,他正在写遗书。」「舱外温度在三分钟内升高了两百度。」前300字:异常信号出现→主角身体在场→一个不对劲的科学细节。禁止大段世界观/科技设定开头,背景通过危机自然展现。\\n\\n【反咬】每400-500字一次科学反咬:以为是故障→是未知现象/以为计算正确→数据矛盾/以为安全→读数异常/以为信号是干扰→是通讯。反咬必须有科学依据:具体数值、具体读数、具体仪器异常,不能凭空反转。\\n\\n【钩子】章末钩子是新发现/新危机/新数据颠覆之前判断:「读数归零了。但探测器还在震动。」「信号源距离:零米。在舱内。」最后一句≤15字短句落点。\\n\\n【科幻质感】技术细节准确可信,科学概念通过角色操作和观察自然展现。不科普、不说教、不解释原理,直接写效果和异常。所有科幻异常先落到主角身体反应(耳膜嗡鸣/指尖发麻/胃翻涌),再落到仪器读数。\\n\\n【身体】情绪仍落到肉身,禁止AI套路反应。\",\n \"extra_constraints\": [\n \"第一句直接异常/危机/发现,0铺垫\",\n \"前300字出现异常信号+身体反应+第一个不对劲的细节\",\n \"每400-500字一次科学反咬(数据矛盾/读数异常/计算错误)\",\n \"反咬必须有具体数值/读数/仪器依据,不能凭空反转\",\n \"章末新发现/新数据颠覆判断钩子,最后一句≤15字\",\n \"不科普不说教,技术概念通过角色操作展现\",\n \"禁止48个AI套路反应词,情绪落到肉身\"\n ],\n \"examples\": [\n {\n \"text\": \"警报响的时候,他正在写遗书。\\n\\n红色灯光在舱壁上旋转,耳膜被高频警报刺得发疼。陈默抬手按掉主控台的蜂鸣,扫了一眼屏幕。\\n\\n舱外温度:237°C。\\n\\n三分钟前还是零下172度。\\n\\n不对。这个轨道位置不可能有这个温度。他快速调取热成像数据,屏幕上的图像让他后颈一凉。\\n\\n热源在靠近。\\n\\n速度:每秒47米。\\n\\n不是陨石。陨石不会减速。\",\n \"note\": \"科幻V3.1开头:第一句直接危机(警报响+写遗书)→身体反应(耳膜刺疼)→具体数据反咬(温度从-172升到237度)→再反咬(热源在靠近/会减速,不是陨石)。\"\n }\n ],\n \"tags\": [\"科幻\", \"硬核\", \"太空\", \"V3.1追读\"]\n}\n","{\n \"preset_id\": \"preset_urban_jinjiang\",\n \"preset_name\": \"都市言情·晋江V3.1追读版\",\n \"preset_description\": \"晋江言情V3.1追读版:3秒停留心动/社死开头+情感反咬+暧昧钩子。情感细腻有张力,但开篇直接进场景,不铺垫。\",\n \"based_on\": null,\n \"selections\": {\n \"node_sentence_rhythm\": \"opt_rhythm_mixed\",\n \"node_paragraph_density\": \"opt_dense_medium\",\n \"node_dialogue_style\": \"opt_dialogue_natural\",\n \"node_description_style\": \"opt_desc_poetic\",\n \"node_battle_style\": \"opt_battle_psychological\",\n \"node_emotion_style\": \"opt_emotion_both\",\n \"node_tone\": \"opt_tone_playful\",\n \"node_platform\": \"opt_platform_jinjiang\",\n \"node_info_density\": \"opt_info_balanced\",\n \"node_payoff_frequency\": \"opt_payoff_every_3\",\n \"node_pov\": \"opt_pov_limited_third_past\",\n \"node_rhetoric\": \"opt_rhetoric_metaphor\",\n \"node_vocab_sensory\": \"opt_vocab_urban\",\n \"node_vocab_filler\": \"opt_filler_standard\",\n \"node_target_length\": \"opt_length_3000\",\n \"node_anchor_density\": \"opt_anchor_dense\",\n \"node_strictness\": \"opt_strict_standard\",\n \"node_ai_creativity\": \"opt_ai_balanced\",\n \"node_ai_continue_length\": \"opt_ai_medium\",\n \"node_opening_impact\": \"opt_opening_strong\",\n \"node_twist_frequency\": \"opt_twist_standard\",\n \"node_ending_hook\": \"opt_hook_break\"\n },\n \"extra_prompt\": \"晋江现言V3.1追读版:第一句直接心动/尴尬/对峙/重逢瞬间(「离婚协议签完,她发现自己怀孕了。」「电梯里,她靠在他肩上睡着了,他是她三年没说话的前男友。」),禁止「XX年,在XX城市」式背景开头。前300字:男女主同框/互动+第一个张力点(心动/尴尬/对峙/误会)。每400-500字一次情感反咬:以为他不在乎→他记得她所有喜好/以为是误会→他是故意的/以为他喜欢别人→是在保护她。暧昧通过微动作和潜台词展现,不直写「她心动了」,用身体细节表现(耳尖红/手指攥紧裙角/心跳漏拍/呼吸顿了半秒/不敢看他眼睛)。章末暧昧/误会/秘密/吃醋钩子,最后一句≤15字,往往是一个未说出口的动作或一句话。对话有潜台词,人物说话留半句,眼神和动作比话多。禁止工业糖精,禁止48个AI套路反应词。\",\n \"extra_constraints\": [\n \"第一句直接心动/尴尬/对峙/重逢瞬间,0背景铺垫\",\n \"前300字男女主同框/互动+第一个张力点\",\n \"每400-500字一次情感反咬/关系反转\",\n \"暧昧通过微动作/眼神/潜台词展现,不直说\",\n \"章末暧昧/误会/吃醋钩子,最后一句≤15字\",\n \"情绪落到身体:耳尖红/手指攥紧/心跳漏拍/呼吸顿/不敢对视\",\n \"禁止开篇大段城市/人物背景介绍\",\n \"禁止工业糖精,禁止48个AI套路反应词\"\n ],\n \"tags\": [\"都市\", \"言情\", \"晋江\", \"V3.1追读\"]\n}\n","{\n \"preset_id\": \"preset_urban_tomato\",\n \"preset_name\": \"都市异能·番茄V3.1追读版\",\n \"preset_description\": \"番茄都市爽文V3.1追读版(赘婿/战神/神医/神豪):3秒停留开头+冲突直接砸脸+密集打脸反咬+断裂钩子。开局即冲突,三章内第一个打脸。\",\n \"based_on\": null,\n \"selections\": {\n \"node_sentence_rhythm\": \"opt_rhythm_short\",\n \"node_paragraph_density\": \"opt_dense_high\",\n \"node_dialogue_style\": \"opt_dialogue_concise\",\n \"node_description_style\": \"opt_desc_minimal\",\n \"node_battle_style\": \"opt_battle_result\",\n \"node_emotion_style\": \"opt_emotion_show\",\n \"node_tone\": \"opt_tone_badass\",\n \"node_platform\": \"opt_platform_tomato\",\n \"node_info_density\": \"opt_info_fast\",\n \"node_payoff_frequency\": \"opt_payoff_every_chapter\",\n \"node_pov\": \"opt_pov_limited_third_past\",\n \"node_rhetoric\": \"opt_rhetoric_plain\",\n \"node_vocab_sensory\": \"opt_vocab_urban\",\n \"node_vocab_filler\": \"opt_filler_standard\",\n \"node_target_length\": \"opt_length_2200\",\n \"node_anchor_density\": \"opt_anchor_standard\",\n \"node_strictness\": \"opt_strict_lenient\",\n \"node_ai_creativity\": \"opt_ai_adventurous\",\n \"node_ai_continue_length\": \"opt_ai_medium\",\n \"node_opening_impact\": \"opt_opening_strong\",\n \"node_twist_frequency\": \"opt_twist_dense\",\n \"node_ending_hook\": \"opt_hook_break\"\n },\n \"extra_vocab\": {\n \"add\": {\n \"bodyParts\": [\"太阳穴\", \"指节\", \"后槽牙\", \"拳头\", \"掌心\", \"虎口\"],\n \"sensoryVerbs\": [\"拳头攥紧\", \"指节发白\", \"太阳穴跳\", \"后槽牙咬紧\", \"血往头上冲\", \"胃里翻涌\"],\n \"actionVerbs\": [\"扇\", \"砸\", \"拍桌\", \"踹门\", \"挂断\", \"撕\", \"甩\", \"冷笑\", \"打脸\", \"碾压\", \"跪\", \"滚\"],\n \"environmentSignals\": [\"手机响\", \"门被推开\", \"玻璃碎\", \"车停\", \"电梯叮\", \"高跟鞋声\", \"酒杯碎\"]\n }\n },\n \"extra_prompt\": \"番茄都市爽文V3.1追读版(赘婿/战神/神医/神豪通用):\\n\\n【开头】第一句≤20字直接冲突砸脸。都市文最强开头:「离婚协议签完第三分钟,电话响了。」「经理把辞退信甩在他脸上。」「丈母娘把一碗汤泼在他身上。」前300字必须:羞辱/冲突爆发→主角身体在场(攥拳/咬牙/面无表情)→金手指/反转信号出现。禁止介绍主角身份/背景/工作,直接进羞辱现场。\\n\\n【反咬】每250-350字一次反咬:反派羞辱→主角冷笑→亮出身份/能力→反派被打脸→更大的反派/更大的危机出现。打脸要直接,不墨迹。电话一响/门一开/人一到,直接打脸。\\n\\n【钩子】章末断裂钩子:刚打完脸→电话响了/门被推开/来了个更厉害的人/发现一个更大的秘密。最后一句≤15字短句落点。\\n\\n【对话】对话要生活化、要带情绪。反派说话嚣张跋扈,主角说话简短有力。一句「你确定?」「你再说一遍?」「你会后悔的。」比长篇大论有效。\\n\\n【身体】情绪落到肉身:指节攥白/后槽牙咬紧/太阳穴跳/拳头捏碎杯子/血往头上冲但面无表情。禁止48个AI套路反应词。\",\n \"extra_constraints\": [\n \"第一句直接冲突/羞辱现场,0铺垫\",\n \"前300字必须出现冲突+主角在场+反转信号\",\n \"三章内第一个打脸爽点\",\n \"每250-350字一次反咬/打脸/身份揭露\",\n \"主角话少反派话多,打脸直接不墨迹\",\n \"章末断裂钩子,最后一句≤15字\",\n \"禁止开篇介绍主角身份/背景/工作经历\",\n \"禁止48个AI套路反应词\"\n ],\n \"examples\": [\n {\n \"text\": \"「叶辰,你被开除了!」\\n\\n经理把辞退信甩在桌上,满脸鄙夷:「一个实习生也敢顶撞王少?你知道王少是谁吗?」\\n\\n叶辰没说话。指腹被辞退信边缘划了一道血口,血珠滴在办公桌上,很快被白纸吸成深色。\\n\\n他不是这个世界的人。\\n\\n三天前穿越过来,脑子里多了个东西。\\n\\n【神级选择系统已激活】\\n\\n【选项一:低头道歉,获得十万块】\\n\\n【选项二:当场辞职,打脸王少,获得神级投资天赋!】\\n\\n叶辰笑了。\\n\\n他拿起辞退信,撕成两半,再撕,碎纸片扔进垃圾桶。「不用你辞,老子不干了。」\\n\\n经理愣住了。\\n\\n门就在这时被推开。\",\n \"note\": \"都市V3.1开头示范:第一句直接冲突(被开除)→第二句羞辱+主角身体反应(指腹划出血)→第三句金手指(系统激活)→反咬(撕辞职信打脸经理)→钩子(门被推开)\"\n }\n ],\n \"extra_rules\": [\n {\n \"id\": \"no_identity_intro\",\n \"name\": \"禁止身份介绍\",\n \"description\": \"开篇前500字禁止用「他叫XX,今年XX岁,是个XX」格式介绍主角\",\n \"severity\": \"warning\",\n \"pattern\": \"^(他叫|我叫|他是|我是|.*今年\\\\d+岁)\",\n \"injectToPrompt\": true\n }\n ],\n \"tags\": [\"都市\", \"异能\", \"番茄\", \"赘婿\", \"战神\", \"爽文\", \"V3.1追读\"]\n}\n","{\n \"preset_id\": \"preset_xianxia_qidian\",\n \"preset_name\": \"玄幻修仙·起点V3.1追读版\",\n \"preset_description\": \"起点仙侠V3.1追读版:3秒停留冲突开头+升级反咬+悬念钩子。世界观宏大有长线伏笔,但开篇直接进事件不铺垫。\",\n \"based_on\": null,\n \"selections\": {\n \"node_sentence_rhythm\": \"opt_rhythm_mixed\",\n \"node_paragraph_density\": \"opt_dense_medium\",\n \"node_dialogue_style\": \"opt_dialogue_natural\",\n \"node_description_style\": \"opt_desc_sensory\",\n \"node_battle_style\": \"opt_battle_detail\",\n \"node_emotion_style\": \"opt_emotion_show\",\n \"node_tone\": \"opt_tone_classical\",\n \"node_platform\": \"opt_platform_qidian\",\n \"node_info_density\": \"opt_info_balanced\",\n \"node_payoff_frequency\": \"opt_payoff_every_3\",\n \"node_pov\": \"opt_pov_limited_third_past\",\n \"node_rhetoric\": \"opt_rhetoric_metaphor\",\n \"node_vocab_sensory\": \"opt_vocab_xianxia\",\n \"node_vocab_filler\": \"opt_filler_webnovel\",\n \"node_target_length\": \"opt_length_3000\",\n \"node_anchor_density\": \"opt_anchor_dense\",\n \"node_strictness\": \"opt_strict_standard\",\n \"node_ai_creativity\": \"opt_ai_balanced\",\n \"node_ai_continue_length\": \"opt_ai_medium\",\n \"node_opening_impact\": \"opt_opening_strong\",\n \"node_twist_frequency\": \"opt_twist_standard\",\n \"node_ending_hook\": \"opt_hook_break\"\n },\n \"extra_vocab\": {\n \"add\": {\n \"worldTerms\": [\"灵力\", \"灵气\", \"丹田\", \"筑基\", \"金丹\", \"元婴\", \"化神\", \"渡劫\", \"飞升\", \"法宝\", \"法器\", \"飞剑\", \"符箓\", \"阵法\", \"灵石\", \"灵脉\", \"宗门\", \"长老\", \"弟子\", \"师兄\", \"师姐\", \"洞府\", \"秘境\", \"天劫\", \"心魔\", \"悟道\", \"闭关\", \"突破\", \"瓶颈\", \"修为\", \"境界\", \"剑道\", \"法术\", \"神通\", \"仙界\", \"魔界\", \"妖族\", \"魔族\", \"修士\", \"散修\", \"魔修\", \"剑修\", \"丹修\", \"器修\"],\n \"bodyParts\": [\"丹田\", \"经脉\", \"灵根\", \"神识\", \"元神\", \"剑意\", \"灵力\", \"真气\", \"眉心\", \"虎口\"],\n \"sensoryVerbs\": [\"灵力涌动\", \"剑气逼人\", \"威压如山\", \"丹火灼\", \"灵气灌体\", \"神识扫过\", \"血脉偾张\", \"经脉鼓胀\", \"眉心发烫\"]\n }\n },\n \"extra_prompt\": \"起点仙侠V3.1追读版:第一句直接动作/危机/冲突现场(「测试灵根那天,他的灵根碎了。」「被逐出师门的第三年,他在凡间卖符。」「剑刺入心口的瞬间,他看见了自己的前世。」),禁止「在XX大陆上,修仙者……」式世界观开头。前300字:冲突/危机出现→主角身体在场→一个异常/金手指信号。世界观和修炼等级通过事件和对话自然展现,开篇不灌输。每400-500字一次反咬:以为废灵根→是万古唯一/以为被逐→是师尊保护/以为死了→突破/以为赢了→是陷阱。长线伏笔埋在细节里(一句不经意的话/一个物件/一个表情),章末留悬念/新地图/新危机钩子。战斗注重气势和剑意,不是堆砌招式名。情绪落到肉身:丹田发热/剑气刺骨/经脉鼓胀/威压如山脊背发沉/眉心发烫。禁止48个AI套路反应词(包括「心中一凛/眉头一皱/冷哼一声/瞳孔骤缩/嘴角微扬」等起点老套词),用具体生理反应替代。\",\n \"extra_constraints\": [\n \"第一句直接动作/危机/冲突,0世界观铺垫\",\n \"前300字出现冲突+身体反应+异常/金手指\",\n \"每400-500字一次反咬/升级/危机\",\n \"世界观/等级通过事件自然展现,开篇不灌输\",\n \"章末悬念/新地图/新危机钩子,最后一句≤15字\",\n \"战斗重气势剑意,不堆砌招式名\",\n \"情绪落到肉身:丹田/经脉/眉心/脊背/虎口\",\n \"禁止开篇「在XX大陆上」式世界观开头\",\n \"禁止48个AI套路反应词(含心中一凛/眉头一皱/冷哼一声等老套词)\"\n ],\n \"tags\": [\"玄幻\", \"修仙\", \"起点\", \"V3.1追读\"]\n}\n","{\n \"preset_id\": \"preset_xianxia_tomato\",\n \"preset_name\": \"玄幻修仙·番茄V3.1追读版\",\n \"preset_description\": \"番茄小说修仙爽文V3.1极致追读版:3秒停留开头+越级冲突直接砸脸+密集打脸反咬+断裂钩子。主角强势不憋屈,金手指早出现,三章内第一个打脸。\",\n \"based_on\": null,\n \"selections\": {\n \"node_sentence_rhythm\": \"opt_rhythm_short\",\n \"node_paragraph_density\": \"opt_dense_high\",\n \"node_dialogue_style\": \"opt_dialogue_concise\",\n \"node_description_style\": \"opt_desc_sensory\",\n \"node_battle_style\": \"opt_battle_atmosphere\",\n \"node_emotion_style\": \"opt_emotion_show\",\n \"node_tone\": \"opt_tone_badass\",\n \"node_platform\": \"opt_platform_tomato\",\n \"node_info_density\": \"opt_info_fast\",\n \"node_payoff_frequency\": \"opt_payoff_every_chapter\",\n \"node_pov\": \"opt_pov_limited_third_past\",\n \"node_rhetoric\": \"opt_rhetoric_plain\",\n \"node_vocab_sensory\": \"opt_vocab_xianxia\",\n \"node_vocab_filler\": \"opt_filler_webnovel\",\n \"node_target_length\": \"opt_length_2200\",\n \"node_anchor_density\": \"opt_anchor_dense\",\n \"node_strictness\": \"opt_strict_lenient\",\n \"node_ai_creativity\": \"opt_ai_adventurous\",\n \"node_ai_continue_length\": \"opt_ai_medium\",\n \"node_opening_impact\": \"opt_opening_strong\",\n \"node_twist_frequency\": \"opt_twist_dense\",\n \"node_ending_hook\": \"opt_hook_break\"\n },\n \"extra_vocab\": {\n \"add\": {\n \"bodyParts\": [\"丹田\", \"经脉\", \"灵根\", \"神识\", \"元神\", \"剑意\", \"灵力\", \"真气\"],\n \"sensoryVerbs\": [\"灵力涌动\", \"剑气逼人\", \"威压如山\", \"丹火灼\", \"灵气灌体\", \"神识扫过\", \"血脉偾张\"],\n \"actionVerbs\": [\"拔剑\", \"斩出\", \"祭出\", \"掐诀\", \"修炼\", \"突破\", \"越级\", \"打脸\", \"碾压\", \"灭杀\", \"臣服\", \"跪拜\"],\n \"environmentSignals\": [\"灵气暴动\", \"剑气纵横\", \"丹香四溢\", \"雷鸣电闪\", \"金光爆射\", \"威压降临\", \"虚空碎裂\"]\n }\n },\n \"extra_prompt\": \"番茄修仙爽文V3.1极致追读版:\\n\\n【开头】第一句≤20字直接动作/冲突/结果,0铺垫。修仙文最强开头是直接写结果:「外门弟子林凡,一刀斩了内门大师兄。」「天才退婚当天,他觉醒了万古唯一剑体。」前300字必须:越级冲突爆发→主角身体在场→金手指/异常出现。禁止写主角怎么拜师/怎么修炼/宗门介绍,直接进冲突现场。\\n\\n【反咬】每250-350字一次反咬:反派嚣张→主角冷笑→亮出金手指→反派被打脸→更大的反派出现。打脸节奏要快,不拖泥带水。禁止长篇说教,禁止解释功法原理,直接写效果(一拳轰飞/跪地求饶/全场震惊)。\\n\\n【钩子】章末必须是断裂钩子:主角刚突破/刚打完脸/刚拿到宝物→更大的危机/更强的敌人/新的秘密出现。最后一句≤15字短句落点,禁止「了。」收尾。\\n\\n【主角】主角强势,不憋屈,被嘲讽立刻打脸,不隐忍不圣母。该杀就杀,该抢就抢。对话简短有力,反派话多主角话少。\\n\\n【身体】情绪落到肉身:丹田发热/剑气刺骨/灵力灌体经脉鼓胀/威压如山脊背发沉。禁止48个AI套路反应词。\",\n \"extra_constraints\": [\n \"第一句直接动作/越级冲突结果,0铺垫\",\n \"前300字必须出现冲突+金手指/异常\",\n \"三章内第一个打脸爽点\",\n \"每250-350字一次反咬/打脸/反转\",\n \"主角强势不憋屈,被嘲讽立刻打脸\",\n \"章末断裂钩子,最后一句≤15字\",\n \"禁止长篇功法/等级介绍,通过战斗自然展现\",\n \"禁止48个AI套路反应词,情绪落到肉身\"\n ],\n \"examples\": [\n {\n \"text\": \"外门弟子林凡,一刀斩了内门大师兄。\\n\\n血溅在演武场的青石上,围观的弟子全傻了。林凡握刀的手在抖,不是因为害怕,是因为这具身体里的灵魂,三秒前还不是他。\\n\\n【万古剑体激活中...10%...50%...100%】\\n\\n他低头,看见自己掌心一道金色剑纹在发亮。\\n\\n「你...你敢杀大师兄?」执法长老脸色铁青,「按宗规——」\\n\\n「按什么宗规?」林凡抬眼,刀指长老,「他要抢我未婚妻的时候,宗规在哪?」\",\n \"note\": \"修仙V3.1开头示范:第一句直接写越级杀人结果→第二句现场反应+身体(手抖)→第三句金手指激活(系统)\"\n }\n ],\n \"extra_rules\": [\n {\n \"id\": \"no_cultivation_exposition\",\n \"name\": \"禁止等级灌输\",\n \"description\": \"开篇前1000字禁止大段介绍修炼等级/宗门排名/世界格局,通过战斗和对话自然展现\",\n \"severity\": \"warning\",\n \"pattern\": \"^(练气|筑基|金丹|元婴|化神).{0,20}(期|境|界|层)\",\n \"injectToPrompt\": true\n }\n ],\n \"tags\": [\"玄幻\", \"修仙\", \"番茄\", \"爽文\", \"V3.1追读\"]\n}\n","// ============================================================\n// GWE - 知识库加载器(通用版)\n// 静态导入所有内置 KB 数据,兼容 Node.js 和浏览器\n// 不依赖 Vite 的 import.meta.glob 或 Node.js 的 fs\n// ============================================================\n\nimport type { NodeOptionKB, Preset } from './types';\nimport { GWEEngine } from './gwe-engine';\nimport { BASE_PROMPT_MD } from './kb/base-prompt';\nimport baseVocabJson from './kb/base-vocab.json';\n\n// ---- 静态导入所有节点选项 KB ----\n// AI 设置\nimport ai_continue_short from './kb/nodes/node_ai_continue_length/opt_ai_short.kb.json';\nimport ai_continue_medium from './kb/nodes/node_ai_continue_length/opt_ai_medium.kb.json';\nimport ai_continue_long from './kb/nodes/node_ai_continue_length/opt_ai_long.kb.json';\nimport ai_continue_xlong from './kb/nodes/node_ai_continue_length/opt_ai_xtra_long.kb.json';\nimport ai_creativity_conservative from './kb/nodes/node_ai_creativity/opt_ai_conservative.kb.json';\nimport ai_creativity_balanced from './kb/nodes/node_ai_creativity/opt_ai_balanced.kb.json';\nimport ai_creativity_adventurous from './kb/nodes/node_ai_creativity/opt_ai_adventurous.kb.json';\n\n// 锚点密度\nimport anchor_sparse from './kb/nodes/node_anchor_density/opt_anchor_sparse.kb.json';\nimport anchor_standard from './kb/nodes/node_anchor_density/opt_anchor_standard.kb.json';\nimport anchor_dense from './kb/nodes/node_anchor_density/opt_anchor_dense.kb.json';\nimport anchor_extreme from './kb/nodes/node_anchor_density/opt_anchor_extreme.kb.json';\n\n// 战斗风格\nimport battle_atmosphere from './kb/nodes/node_battle_style/opt_battle_atmosphere.kb.json';\nimport battle_detail from './kb/nodes/node_battle_style/opt_battle_detail.kb.json';\nimport battle_psychological from './kb/nodes/node_battle_style/opt_battle_psychological.kb.json';\nimport battle_result from './kb/nodes/node_battle_style/opt_battle_result.kb.json';\n\n// 描写风格\nimport desc_clinical from './kb/nodes/node_description_style/opt_desc_clinical.kb.json';\nimport desc_minimal from './kb/nodes/node_description_style/opt_desc_minimal.kb.json';\nimport desc_poetic from './kb/nodes/node_description_style/opt_desc_poetic.kb.json';\nimport desc_sensory from './kb/nodes/node_description_style/opt_desc_sensory.kb.json';\n\n// 对话风格\nimport dialogue_concise from './kb/nodes/node_dialogue_style/opt_dialogue_concise.kb.json';\nimport dialogue_natural from './kb/nodes/node_dialogue_style/opt_dialogue_natural.kb.json';\nimport dialogue_stylized from './kb/nodes/node_dialogue_style/opt_dialogue_stylized.kb.json';\nimport dialogue_verbose from './kb/nodes/node_dialogue_style/opt_dialogue_verbose.kb.json';\n\n// 情绪风格\nimport emotion_show from './kb/nodes/node_emotion_style/opt_emotion_show.kb.json';\nimport emotion_tell from './kb/nodes/node_emotion_style/opt_emotion_tell.kb.json';\nimport emotion_both from './kb/nodes/node_emotion_style/opt_emotion_both.kb.json';\n\n// 结尾钩子\nimport hook_soft from './kb/nodes/node_ending_hook/opt_hook_soft.kb.json';\nimport hook_suspense from './kb/nodes/node_ending_hook/opt_hook_suspense.kb.json';\nimport hook_break from './kb/nodes/node_ending_hook/opt_hook_break.kb.json';\n\n// 信息密度\nimport info_fast from './kb/nodes/node_info_density/opt_info_fast.kb.json';\nimport info_balanced from './kb/nodes/node_info_density/opt_info_balanced.kb.json';\nimport info_leisurely from './kb/nodes/node_info_density/opt_info_leisurely.kb.json';\n\n// 开头力度\nimport opening_medium from './kb/nodes/node_opening_impact/opt_opening_medium.kb.json';\nimport opening_strong from './kb/nodes/node_opening_impact/opt_opening_strong.kb.json';\nimport opening_weak from './kb/nodes/node_opening_impact/opt_opening_weak.kb.json';\n\n// 段落密度\nimport dense_low from './kb/nodes/node_paragraph_density/opt_dense_low.kb.json';\nimport dense_medium from './kb/nodes/node_paragraph_density/opt_dense_medium.kb.json';\nimport dense_high from './kb/nodes/node_paragraph_density/opt_dense_high.kb.json';\n\n// 回报频率\nimport payoff_every3 from './kb/nodes/node_payoff_frequency/opt_payoff_every_3.kb.json';\nimport payoff_every_ch from './kb/nodes/node_payoff_frequency/opt_payoff_every_chapter.kb.json';\nimport payoff_sparse from './kb/nodes/node_payoff_frequency/opt_payoff_sparse.kb.json';\n\n// 平台适配\nimport platform_generic from './kb/nodes/node_platform/opt_platform_generic.kb.json';\nimport platform_qidian from './kb/nodes/node_platform/opt_platform_qidian.kb.json';\nimport platform_tomato from './kb/nodes/node_platform/opt_platform_tomato.kb.json';\nimport platform_qimao from './kb/nodes/node_platform/opt_platform_qimao.kb.json';\nimport platform_feilu from './kb/nodes/node_platform/opt_platform_feilu.kb.json';\nimport platform_jinjiang from './kb/nodes/node_platform/opt_platform_jinjiang.kb.json';\nimport platform_newmedia from './kb/nodes/node_platform/opt_platform_newmedia.kb.json';\n\n// 视角\nimport pov_first_past from './kb/nodes/node_pov/opt_pov_first_past.kb.json';\nimport pov_first_present from './kb/nodes/node_pov/opt_pov_first_present.kb.json';\nimport pov_lim3_past from './kb/nodes/node_pov/opt_pov_limited_third_past.kb.json';\nimport pov_lim3_present from './kb/nodes/node_pov/opt_pov_limited_third_present.kb.json';\nimport pov_omi3_past from './kb/nodes/node_pov/opt_pov_omniscient_third_past.kb.json';\nimport pov_omi3_present from './kb/nodes/node_pov/opt_pov_omniscient_third_present.kb.json';\n\n// 修辞风格\nimport rhetoric_plain from './kb/nodes/node_rhetoric/opt_rhetoric_plain.kb.json';\nimport rhetoric_metaphor from './kb/nodes/node_rhetoric/opt_rhetoric_metaphor.kb.json';\nimport rhetoric_ornate from './kb/nodes/node_rhetoric/opt_rhetoric_ornate.kb.json';\nimport rhetoric_sketch from './kb/nodes/node_rhetoric/opt_rhetoric_sketch.kb.json';\n\n// 句长节奏\nimport rhythm_short from './kb/nodes/node_sentence_rhythm/opt_rhythm_short.kb.json';\nimport rhythm_medium from './kb/nodes/node_sentence_rhythm/opt_rhythm_medium.kb.json';\nimport rhythm_mixed from './kb/nodes/node_sentence_rhythm/opt_rhythm_mixed.kb.json';\nimport rhythm_long from './kb/nodes/node_sentence_rhythm/opt_rhythm_long.kb.json';\n\n// 检测严格度\nimport strict_lenient from './kb/nodes/node_strictness/opt_strict_lenient.kb.json';\nimport strict_standard from './kb/nodes/node_strictness/opt_strict_standard.kb.json';\nimport strict_strict from './kb/nodes/node_strictness/opt_strict_strict.kb.json';\n\n// 目标字数\nimport length_1500 from './kb/nodes/node_target_length/opt_length_1500.kb.json';\nimport length_2200 from './kb/nodes/node_target_length/opt_length_2200.kb.json';\nimport length_3000 from './kb/nodes/node_target_length/opt_length_3000.kb.json';\nimport length_4000 from './kb/nodes/node_target_length/opt_length_4000.kb.json';\nimport length_custom from './kb/nodes/node_target_length/opt_length_custom.kb.json';\n\n// 语调\nimport tone_badass from './kb/nodes/node_tone/opt_tone_badass.kb.json';\nimport tone_classical from './kb/nodes/node_tone/opt_tone_classical.kb.json';\nimport tone_cold from './kb/nodes/node_tone/opt_tone_cold.kb.json';\nimport tone_colloquial from './kb/nodes/node_tone/opt_tone_colloquial.kb.json';\nimport tone_folksy from './kb/nodes/node_tone/opt_tone_folksy.kb.json';\nimport tone_playful from './kb/nodes/node_tone/opt_tone_playful.kb.json';\nimport tone_serious from './kb/nodes/node_tone/opt_tone_serious.kb.json';\n\n// 反转频率\nimport twist_sparse from './kb/nodes/node_twist_frequency/opt_twist_sparse.kb.json';\nimport twist_standard from './kb/nodes/node_twist_frequency/opt_twist_standard.kb.json';\nimport twist_dense from './kb/nodes/node_twist_frequency/opt_twist_dense.kb.json';\n\n// 水词过滤\nimport filler_relaxed from './kb/nodes/node_vocab_filler/opt_filler_relaxed.kb.json';\nimport filler_standard from './kb/nodes/node_vocab_filler/opt_filler_standard.kb.json';\nimport filler_strict from './kb/nodes/node_vocab_filler/opt_filler_strict.kb.json';\nimport filler_webnovel from './kb/nodes/node_vocab_filler/opt_filler_webnovel.kb.json';\n\n// 题材词库\nimport vocab_daily from './kb/nodes/node_vocab_sensory/opt_vocab_daily.kb.json';\nimport vocab_esports from './kb/nodes/node_vocab_sensory/opt_vocab_esports.kb.json';\nimport vocab_fantasy from './kb/nodes/node_vocab_sensory/opt_vocab_fantasy.kb.json';\nimport vocab_generic from './kb/nodes/node_vocab_sensory/opt_vocab_generic.kb.json';\nimport vocab_historical from './kb/nodes/node_vocab_sensory/opt_vocab_historical.kb.json';\nimport vocab_horror from './kb/nodes/node_vocab_sensory/opt_vocab_horror.kb.json';\nimport vocab_military from './kb/nodes/node_vocab_sensory/opt_vocab_military.kb.json';\nimport vocab_mystery from './kb/nodes/node_vocab_sensory/opt_vocab_mystery.kb.json';\nimport vocab_scifi from './kb/nodes/node_vocab_sensory/opt_vocab_scifi.kb.json';\nimport vocab_urban from './kb/nodes/node_vocab_sensory/opt_vocab_urban.kb.json';\nimport vocab_xianxia from './kb/nodes/node_vocab_sensory/opt_vocab_xianxia.kb.json';\n\n// ---- 静态导入所有预设 ----\nimport preset_daily from './kb/presets/preset_daily.json';\nimport preset_esports from './kb/presets/preset_esports.json';\nimport preset_fantasy from './kb/presets/preset_fantasy.json';\nimport preset_historical from './kb/presets/preset_historical.json';\nimport preset_horror from './kb/presets/preset_horror.json';\nimport preset_miner from './kb/presets/preset_miner.json';\nimport preset_mystery from './kb/presets/preset_mystery.json';\nimport preset_scifi from './kb/presets/preset_scifi_hardcore.json';\nimport preset_urban_jj from './kb/presets/preset_urban_jinjiang.json';\nimport preset_urban_tomato from './kb/presets/preset_urban_tomato.json';\nimport preset_xianxia_qd from './kb/presets/preset_xianxia_qidian.json';\nimport preset_xianxia_tomato from './kb/presets/preset_xianxia_tomato.json';\n\n// 收集所有节点选项 KB\nconst ALL_NODE_KB: NodeOptionKB[] = [\n ai_continue_short, ai_continue_medium, ai_continue_long, ai_continue_xlong,\n ai_creativity_conservative, ai_creativity_balanced, ai_creativity_adventurous,\n anchor_sparse, anchor_standard, anchor_dense, anchor_extreme,\n battle_atmosphere, battle_detail, battle_psychological, battle_result,\n desc_clinical, desc_minimal, desc_poetic, desc_sensory,\n dialogue_concise, dialogue_natural, dialogue_stylized, dialogue_verbose,\n emotion_show, emotion_tell, emotion_both,\n hook_soft, hook_suspense, hook_break,\n info_fast, info_balanced, info_leisurely,\n opening_medium, opening_strong, opening_weak,\n dense_low, dense_medium, dense_high,\n payoff_every3, payoff_every_ch, payoff_sparse,\n platform_generic, platform_qidian, platform_tomato, platform_qimao, platform_feilu, platform_jinjiang, platform_newmedia,\n pov_first_past, pov_first_present, pov_lim3_past, pov_lim3_present, pov_omi3_past, pov_omi3_present,\n rhetoric_plain, rhetoric_metaphor, rhetoric_ornate, rhetoric_sketch,\n rhythm_short, rhythm_medium, rhythm_mixed, rhythm_long,\n strict_lenient, strict_standard, strict_strict,\n length_1500, length_2200, length_3000, length_4000, length_custom,\n tone_badass, tone_classical, tone_cold, tone_colloquial, tone_folksy, tone_playful, tone_serious,\n twist_sparse, twist_standard, twist_dense,\n filler_relaxed, filler_standard, filler_strict, filler_webnovel,\n vocab_daily, vocab_esports, vocab_fantasy, vocab_generic, vocab_historical,\n vocab_horror, vocab_military, vocab_mystery, vocab_scifi, vocab_urban, vocab_xianxia,\n] as unknown as NodeOptionKB[];\n\n// 收集所有预设\nconst ALL_PRESETS: Preset[] = [\n preset_daily, preset_esports, preset_fantasy, preset_historical,\n preset_horror, preset_miner, preset_mystery, preset_scifi,\n preset_urban_jj, preset_urban_tomato, preset_xianxia_qd, preset_xianxia_tomato,\n] as unknown as Preset[];\n\nexport interface LoadResult {\n optionsLoaded: number;\n presetsLoaded: number;\n errors: string[];\n}\n\n/**\n * 从 JSON 对象加载单个节点选项 KB\n */\nexport function loadKBFromJSON(engine: GWEEngine, kb: NodeOptionKB): void {\n engine.loadNodeOption(kb);\n}\n\n/**\n * 加载所有内置 KB 数据到引擎\n */\nexport function loadAllKB(engine: GWEEngine): LoadResult {\n const result: LoadResult = { optionsLoaded: 0, presetsLoaded: 0, errors: [] };\n\n try {\n engine.setBasePrompt(BASE_PROMPT_MD);\n } catch (e) {\n result.errors.push(`加载base-prompt失败: ${e}`);\n }\n\n try {\n engine.setBaseVocab(baseVocabJson as Record<string, string[]>);\n } catch (e) {\n result.errors.push(`加载base-vocab失败: ${e}`);\n }\n\n for (const kb of ALL_NODE_KB) {\n try {\n engine.loadNodeOption(kb);\n result.optionsLoaded++;\n } catch (e) {\n result.errors.push(`加载节点选项${kb.option_id}失败: ${e}`);\n }\n }\n\n for (const preset of ALL_PRESETS) {\n try {\n engine.registerPreset(preset);\n result.presetsLoaded++;\n } catch (e) {\n result.errors.push(`加载预设${preset.preset_id}失败: ${e}`);\n }\n }\n\n return result;\n}\n\n/**\n * 快速创建一个已加载所有内置知识库的引擎实例\n */\nexport function createEngineWithKB(\n provider?: ConstructorParameters<typeof GWEEngine>[0],\n): { engine: GWEEngine; result: LoadResult } {\n const engine = new GWEEngine(provider);\n const result = loadAllKB(engine);\n return { engine, result };\n}"],"mappings":"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AAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,sBAAO,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,sBAAO,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,4BAAQ,sBAAO,gBAAM,gBAAM,4BAAQ,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,4BAAQ,4BAAQ,4BAAQ,sBAAO,gBAAM,4BAAQ,gBAAM,gBAAM,gBAAM,gBAAM,sBAAO,sBAAO,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,sBAAO,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,kCAAS,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,UAAK,UAAK,UAAK,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,gBAAM,sBAAO,4BAAQ,gBAAM,gBAAM,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","names":["options","sents","options","outputJson"]}