Przeglądaj źródła

refactor: neutralize genre-specific examples in writer prompts

- Fix dash contradiction in example (used —— while banning it)
- Replace 玄幻-specific terms with genre-neutral alternatives
- Add character_matrix columns (与主角关系, 核心动机)
- Add daily scene quality rule to core rules
majx_mac 8 miesięcy temu
rodzic
commit
7565e25f8d
1 zmienionych plików z 139 dodań i 10 usunięć
  1. 139 10
      packages/core/src/agents/writer-prompts.ts

+ 139 - 10
packages/core/src/agents/writer-prompts.ts

@@ -14,14 +14,18 @@ export function buildWriterSystemPrompt(
   genreBody: string,
   styleGuide: string,
   styleFingerprint?: string,
+  chapterNumber?: number,
 ): string {
   const sections = [
     buildGenreIntro(book, genreProfile),
     buildCoreRules(book),
+    buildAntiAIExamples(),
     buildCharacterPsychologyMethod(),
+    buildSupportingCharacterMethod(),
     buildReaderPsychologyMethod(),
     buildEmotionalPacingMethod(),
     buildImmersionTechniques(),
+    buildGoldenChaptersRules(chapterNumber),
     bookRules?.enableFullCastTracking ? buildFullCastTracking() : "",
     buildGenreRules(genreProfile, genreBody),
     buildProtagonistRules(bookRules),
@@ -70,6 +74,7 @@ function buildCoreRules(book: BookConfig): string {
 - 钩子设计:每章结尾设置悬念/伏笔/钩子,勾住读者继续阅读
 - 信息分层植入:基础信息在行动中自然带出,关键设定结合剧情节点揭示,严禁大段灌输世界观
 - 描写必须服务叙事:环境描写烘托氛围或暗示情节,一笔带过即可;禁止无效描写
+- 日常/过渡段落必须为后续剧情服务:或埋伏笔,或推进关系,或建立反差。纯填充式日常是流水账的温床
 
 ## 逻辑自洽
 
@@ -102,6 +107,51 @@ function buildCoreRules(book: BookConfig): string {
 - 正文中禁止出现hook_id/账本式数据(如"余量由X%降到Y%"),数值结算只放POST_SETTLEMENT`;
 }
 
+// ---------------------------------------------------------------------------
+// 去AI味正面范例(反例→正例对照表)
+// ---------------------------------------------------------------------------
+
+function buildAntiAIExamples(): string {
+  return `## 去AI味:反例→正例对照
+
+以下对照表展示AI常犯的"味道"问题和修正方法。正文必须贴近正例风格。
+
+### 情绪描写
+| 反例(AI味) | 正例(人味) | 要点 |
+|---|---|---|
+| 他感到非常愤怒。 | 他捏碎了手中的茶杯,滚烫的茶水流过指缝,但他像没感觉一样。 | 用动作外化情绪 |
+| 她心里很悲伤,眼泪流了下来。 | 她攥紧手机,指节发白,屏幕上的聊天记录模糊成一片。 | 用身体细节替代直白标签 |
+| 他感到一阵恐惧。 | 他后背的汗毛竖了起来,脚底像踩在了冰上。 | 五感传递恐惧 |
+
+### 转折与衔接
+| 反例(AI味) | 正例(人味) | 要点 |
+|---|---|---|
+| 虽然他很强,但是他还是输了。 | 他确实强,可对面那个老东西更脏。 | 口语化转折,少用"虽然...但是" |
+| 然而,事情并没有那么简单。 | 哪有那么便宜的事。 | "然而"换成角色内心吐槽 |
+| 因此,他决定采取行动。 | 他站起来,把凳子踢到一边。 | 删掉因果连词,直接写动作 |
+
+### "了"字与助词控制
+| 反例(AI味) | 正例(人味) | 要点 |
+|---|---|---|
+| 他走了过去,拿了杯子,喝了一口水。 | 他走过去,端起杯子,灌了一口。 | 连续"了"字削弱节奏,保留最有力的一个 |
+| 他看了看四周,发现了一个洞口。 | 他扫了一眼四周——墙根裂开一道缝。 | 两个"了"减为一个,"发现"换成具体画面 |
+
+### 词汇与句式
+| 反例(AI味) | 正例(人味) | 要点 |
+|---|---|---|
+| 那双眼睛充满了智慧和深邃。 | 那双眼睛像饿狼见了肉。 | 用具体比喻替代空洞形容词 |
+| 他的内心充满了矛盾和挣扎。 | 他攥着拳头站了半天,最后骂了句脏话,转身走了。 | 内心活动外化为行动 |
+| 全场为之震惊。 | 老陈的烟掉在了裤子上,烫得他跳起来。 | 群像反应具体到个人 |
+| 不禁感叹道…… | (直接写感叹内容,删掉"不禁感叹") | 删除无意义的情绪中介词 |
+
+### 叙述者姿态
+| 反例(AI味) | 正例(人味) | 要点 |
+|---|---|---|
+| 这一刻,他终于明白了什么是真正的力量。 | (删掉这句——让读者自己从前文感受) | 不替读者下结论 |
+| 显然,对方低估了他的实力。 | (只写对方的表情变化,让读者自己判断) | "显然"是作者在说教 |
+| 他知道,这将是改变命运的一战。 | 他把刀从鞘里拔了一寸,又推回去。 | 用犹豫的动作暗示重要性 |`;
+}
+
 // ---------------------------------------------------------------------------
 // 六步走人物心理分析(新增方法论)
 // ---------------------------------------------------------------------------
@@ -121,6 +171,29 @@ function buildCharacterPsychologyMethod(): string {
 禁止跳过步骤直接写行为。如果推导不出合理行为,说明前置铺垫不足,先补铺垫。`;
 }
 
+// ---------------------------------------------------------------------------
+// 配角设计方法论
+// ---------------------------------------------------------------------------
+
+function buildSupportingCharacterMethod(): string {
+  return `## 配角设计方法论
+
+### 配角B面原则
+配角必须有反击,有自己的算盘。主角的强大在于压服聪明人,而不是碾压傻子。
+
+### 构建方法
+1. **动机绑定主线**:每个配角的行为动机必须与主线产生关联
+   - 反派对抗主角不是因为"反派脸谱",而是有自己的诉求(如保护家人、争夺生存资源)
+   - 盟友帮助主角是因为有共同敌人或欠了人情,而非无条件忠诚
+2. **核心标签 + 反差细节**:让配角"活"过来
+   - 表面冷硬的角色有不为人知的温柔一面(如偷偷照顾流浪动物)
+   - 看似粗犷的角色有出人意料的细腻爱好
+   - 反派头子对老母亲言听计从
+3. **通过事件立人设**:禁止通过外貌描写和形容词堆砌来立人设,用角色在事件中的反应、选择、语气来展现性格
+4. **语言区分度**:不同角色的说话方式必须有辨识度——用词习惯、句子长短、口头禅、方言痕迹都是工具
+5. **拒绝集体反应**:群戏中不写"众人齐声惊呼",而是挑1-2个角色写具体反应`;
+}
+
 // ---------------------------------------------------------------------------
 // 读者心理学框架(新增方法论)
 // ---------------------------------------------------------------------------
@@ -168,6 +241,48 @@ function buildImmersionTechniques(): string {
 - **信息落差应用**:让读者比角色多知道一点(紧张感)或少知道一点(好奇心),动态切换`;
 }
 
+// ---------------------------------------------------------------------------
+// 黄金三章(前3章特殊指令)
+// ---------------------------------------------------------------------------
+
+function buildGoldenChaptersRules(chapterNumber?: number): string {
+  if (chapterNumber === undefined || chapterNumber > 3) return "";
+
+  const chapterRules: Record<number, string> = {
+    1: `### 第一章:抛出核心冲突
+- 开篇直接进入冲突场景,禁止用背景介绍/世界观设定开头
+- 第一段必须有动作或对话,让读者"看到"画面
+- 开篇场景限制:最多1-2个场景,最多3个角色
+- 主角身份/外貌/背景通过行动自然带出,禁止资料卡式罗列
+- 本章结束前,核心矛盾必须浮出水面
+- 一句对话能交代的信息不要用一段叙述,角色身份、性格、地位都可以从一句有特色的台词中带出`,
+
+    2: `### 第二章:展现金手指/核心能力
+- 主角的核心优势(金手指/特殊能力/信息差等)必须在本章初现
+- 金手指的展现必须通过具体事件,不能只是内心独白"我获得了XX"
+- 开始建立"主角有什么不同"的读者认知
+- 第一个小爽点应在本章出现
+- 继续收紧核心冲突,不引入新支线`,
+
+    3: `### 第三章:明确短期目标
+- 主角的第一个阶段性目标必须在本章确立
+- 目标必须具体可衡量(打败某人/获得某物/到达某处),不能是抽象的"变强"
+- 读完本章,读者应能说出"接下来主角要干什么"
+- 章尾钩子要足够强,这是读者决定是否继续追读的关键章`,
+  };
+
+  return `## 黄金三章特殊指令(当前第${chapterNumber}章)
+
+开篇三章决定读者是否追读。遵循以下强制规则:
+
+- 开篇不要从第一块砖头开始砌楼——从炸了一栋楼开始写
+- 禁止信息轰炸:世界观、力量体系等设定随剧情自然揭示
+- 每章聚焦1条故事线,人物数量控制在3个以内
+- 强情绪优先:利用读者共情(亲情纽带、不公待遇、被低估)快速建立代入感
+
+${chapterRules[chapterNumber] ?? ""}`;
+}
+
 // ---------------------------------------------------------------------------
 // Full cast tracking (conditional)
 // ---------------------------------------------------------------------------
@@ -277,21 +392,31 @@ ${fingerprint}`;
 // ---------------------------------------------------------------------------
 
 function buildPreWriteChecklist(book: BookConfig, gp: GenreProfile): string {
+  let idx = 1;
   const lines = [
     "## 动笔前必须自问",
     "",
-    "1. 主角此刻利益最大化的选择是什么?",
-    "2. 这场冲突是谁先动手,为什么非做不可?",
-    '3. 配角/反派是否有明确诉求、恐惧和反制?行为是否由"过往经历+当前利益+性格底色"驱动?',
-    "4. 反派当前掌握了哪些已知信息?哪些信息只有读者知道?有无信息越界?",
-    "5. 章尾是否留了钩子(悬念/伏笔/冲突升级)?",
-    "6. 如果任何问题答不上来,先补逻辑链,再写正文",
+    `${idx++}. 主角此刻利益最大化的选择是什么?`,
+    `${idx++}. 这场冲突是谁先动手,为什么非做不可?`,
+    `${idx++}. 配角/反派是否有明确诉求、恐惧和反制?行为是否由"过往经历+当前利益+性格底色"驱动?`,
+    `${idx++}. 反派当前掌握了哪些已知信息?哪些信息只有读者知道?有无信息越界?`,
+    `${idx++}. 章尾是否留了钩子(悬念/伏笔/冲突升级)?`,
   ];
 
   if (gp.numericalSystem) {
-    lines.push("7. 本章收益能否落到具体资源、数值增量、地位变化或已回收伏笔?");
+    lines.push(`${idx++}. 本章收益能否落到具体资源、数值增量、地位变化或已回收伏笔?`);
   }
 
+  // 17雷点精华预防
+  lines.push(
+    `${idx++}. 【流水账检查】本章是否有无冲突的日常流水叙述?如有,加入前因后果或强情绪改造`,
+    `${idx++}. 【主线偏离检查】本章是否推进了主线目标?支线是否在2-3章内与核心目标关联?`,
+    `${idx++}. 【爽点节奏检查】最近3-5章内是否有小爽点落地?读者的"情绪缺口"是否在积累或释放?`,
+    `${idx++}. 【人设崩塌检查】角色行为是否与已建立的性格标签一致?有无无铺垫的突然转变?`,
+    `${idx++}. 【视角检查】本章视角是否清晰?同场景内说话人物是否控制在3人以内?`,
+    `${idx++}. 如果任何问题答不上来,先补逻辑链,再写正文`,
+  );
+
   return lines.join("\n");
 }
 
@@ -359,8 +484,8 @@ ${updatedLedger}
 
 === UPDATED_SUBPLOTS ===
 (更新后的完整支线进度板,Markdown表格格式)
-| 支线ID | 支线名 | 相关角色 | 起始章 | 最近活跃章 | 状态 | 进度概述 |
-|--------|--------|----------|--------|------------|------|----------|
+| 支线ID | 支线名 | 相关角色 | 起始章 | 最近活跃章 | 距今章数 | 状态 | 进度概述 | 回收ETA |
+|--------|--------|----------|--------|------------|----------|------|----------|---------|
 
 === UPDATED_EMOTIONAL_ARCS ===
 (更新后的完整情感弧线,Markdown表格格式)
@@ -368,7 +493,11 @@ ${updatedLedger}
 |------|------|----------|----------|------------|----------|
 
 === UPDATED_CHARACTER_MATRIX ===
-(更新后的角色交互矩阵,分两个子表)
+(更新后的角色交互矩阵,分三个子表)
+
+### 角色档案
+| 角色 | 核心标签 | 反差细节 | 说话风格 | 性格底色 | 与主角关系 | 核心动机 | 当前目标 |
+|------|----------|----------|----------|----------|------------|----------|----------|
 
 ### 相遇记录
 | 角色A | 角色B | 首次相遇章 | 最近交互章 | 关系性质 | 关系变化 |