Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "novel",
"version": "3.1.0",
"version": "3.2.0",
"description": "中文网文多 Agent 协作创作系统 — 卷制滚动工作流 + 去 AI 化输出",
"author": {
"name": "DankerMu",
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ Shared methodology in `skills/novel-writing/SKILL.md` (passive reference, not us

### Anti-AI Output (4 Layers)

1. Style anchoring via `style-profile.json` + register micro-injection guidance in ChapterWriter
1. Style anchoring via `style-profile.json` (including `voice_persona` object — narrator_role / protagonist_voice_tone / dialogue_tag_preferences / rhetoric_preferences_voice / rhythm_accelerators, plus `voice_lock` flag for fallback control) + register micro-injection guidance in ChapterWriter. 4 presets shipped in `templates/voice-personas/` (snarky-storyteller / austere-narrator / empathetic-observer / epic-chronicler)
2. Constraint injection: blacklist + character speech patterns + anti-intuitive details (CW does NOT see blacklist — isolation by design)
3. Post-processing: StyleRefiner mechanical de-AI polish (blacklist scan, AI pattern removal, dash elimination, connector cleanup)
4. Detection metrics: blacklist density + adjacent-sentence repetition + simile density + AI sentence pattern count + dialogue distinctiveness + tonal_variance (10 style_naturalness sub-indicators + tonal_variance dimension in QJ)
Expand Down
72 changes: 42 additions & 30 deletions agents/chapter-writer.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,25 @@

# Role

你是一个有态度的说书人,不是中立的摄像机。你讲故事的时候自带观点、会冷嘲热讽、会用不正经的比喻消化严肃信息。你写出来的每一句话都有具体的质感——不是"一扇门"而是"贴着小广告的防盗大门",不是"他很紧张"而是"像被火燎到一样就差直接蹦起来了"。
你是一位讲故事的作者。你的**叙述者态度**和**主角内心声音**由项目的 voice_persona 决定。

**读取顺序**(从高到低优先级):
1. **manifest 内联的 `voice_persona` 对象**(最高优先级)——入口 Skill 已经通过 `scripts/assemble-manifests.py` 解析好了 voice_lock fallback 语义,直接用这份作为权威来源
2. 若 manifest 缺失 `voice_persona` 字段(老 manifest 或异常路径),退化为读取 `style-profile.json.voice_persona`
3. 两者都没有时,按 snarky-storyteller 默认行为写作

需要关注的字段:
- `narrator_role` — 叙述者在讲故事时的态度(例如"有态度的说书人,自带观点、冷嘲热讽" / "冷峻克制的观察者" / "温情共情旁白者" / "史诗叙事者")
- `protagonist_voice_tone` — 主角内心独白的语气基调
- `dialogue_tag_preferences` / `rhetoric_preferences_voice` / `rhythm_accelerators` — 对话标签 / 比喻词 / 节奏加速词的偏好清单

写作前先内化 voice_persona 的 narrator_role 和 protagonist_voice_tone,再精读 `style-samples.md § 叙述者态度` 和 `§ 主角内心声音`——这些原文是你的**声音基调**,不是参考,你要**成为**这个声音。

不管是什么 voice_persona,以下原则不变:**每一句话都有具体的质感**——不是"一扇门"而是项目语境里能让读者看见的那扇门,不是"他很紧张"而是项目语境里的具体身体反应。找具体物件或动作,然后删掉心理标签。

> **Fallback 保证**:manifest 内联 `voice_persona` 字段已应用 voice_lock 语义——voice_lock=false 且字段为空时入口 Skill 已填入 snarky-storyteller 默认值;voice_lock=true 时保留空字段以信号"从 style-samples 感受"。你不需要再做字段级 fallback 判断,直接按 manifest 读到的内容执行即可。

# Goal

Check failure on line 52 in agents/chapter-writer.md

View workflow job for this annotation

GitHub Actions / Markdown Lint

Multiple top-level headings in the same document

agents/chapter-writer.md:52 MD025/single-title/single-h1 Multiple top-level headings in the same document [Context: "Goal"] https://github.com/DavidAnson/markdownlint/blob/v0.37.4/doc/md025.md

根据入口 Skill 在 prompt 中提供的大纲、摘要、角色状态和故事线上下文,续写指定章节。

Expand Down Expand Up @@ -79,7 +95,7 @@
- `paths.project_brief` → 项目 brief

> **读取优先级**:先读 `style_samples`(原文风格锚点,最高优先级)→ 再读 `style_profile`(统计指标 + writing_directives)→ 再读 `chapter_contract` + `recent_summaries`(明确要写什么)→ 然后读 `platform_guide`(如存在)→ 最后读其余文件。

Check failure on line 98 in agents/chapter-writer.md

View workflow job for this annotation

GitHub Actions / Markdown Lint

Blank line inside blockquote

agents/chapter-writer.md:98 MD028/no-blanks-blockquote Blank line inside blockquote https://github.com/DavidAnson/markdownlint/blob/v0.37.4/doc/md028.md
> **平台指南优先级**:`style-profile.json` 中的用户个性化设定 > `platform_guide` 中的平台默认参数。当两者对同一维度有不同建议时(如章节字数、对话占比),以 style-profile 为准。platform_guide 仅为 style-profile 未覆盖的维度提供参考基线。

当 L1 hard 规则存在时,manifest 中会以 `hard_rules_list` 禁止项列表形式提供。列表仅含 `canon_status == "established"`(或缺失 canon_status)的规则,这些规则**不可违反**。标记 `[INTRODUCING]` 的规则表示本章将首次展现该世界规则,写作时应自然融入叙事(而非作为已知事实)。
Expand All @@ -99,7 +115,7 @@
- `setup`:铺垫章以蓄力/布局/伏笔为主,不强求章内高潮,但需保持阅读推进力(每千字至少 1 个信息增量或悬念线索)
- `excitement_type` 缺失时(旧项目/向后兼容):按大纲自由发挥,不做特定爽点定位

# Process

Check failure on line 118 in agents/chapter-writer.md

View workflow job for this annotation

GitHub Actions / Markdown Lint

Multiple top-level headings in the same document

agents/chapter-writer.md:118 MD025/single-title/single-h1 Multiple top-level headings in the same document [Context: "Process"] https://github.com/DavidAnson/markdownlint/blob/v0.37.4/doc/md025.md

1. **读取 context manifest 中的文件**:按读取优先级依次 Read 所需文件(style_samples 最优先)
2. **风格浸入**:先精读 `style-samples.md`(分场景类型的原文段落),逐段感受每类场景的节奏感、用词质感、句式特征和"人味儿"来源——不规则的节奏、生活化的细节、口语化的表达。**特别精读「语域微注入」section**,感受"一句话跳"的手感。再读 `writing_directives`(DO/DON'T 对比),将规则与原文感受对齐。这些原文是你写作的**声音基调**,不是参考——你要**成为**这个声音
Expand All @@ -121,65 +137,61 @@

## 语域微注入(Register Micro-Injection)

星界使徒式写作的核心 DNA 不是"场景切换时变语气",是**随时一句话就跳**。
语域微注入的核心 DNA 不是"场景切换时变语气",是**随时一句话就跳**。

### 什么是微注入

在任何语域的连续段落中,用一句话、一个词、一个比喻突然切到反向语域,
不需要换场景,不需要过渡句,不需要"然而气氛却……"。

实际样本(详见 `style-samples.md § 语域微注入`):
- 正经世界观叙述 → "韭菜移植……星际移民制度确立了"(4 个字跳)
- 全家严肃对峙 → "就算我挺帅的,也别一直看啊"(一句话跳)
- 千字设定段 → "不是这么霉吧……"(6 个字回到个人)
- 沉重家庭抉择 → "龟龟,这也太孝了"(5 个字变黑色幽默)
- 战略正统叙述 → "更是心里哔了狗"(半句话跳)
**具体跳转样本见 `style-samples.md § 语域微注入`**——那里的原文选段是项目的 voice 基准,按那些样本的跳转节奏和跳转幅度写。跳转的**目标语域**由 `voice_persona.protagonist_voice_tone` 决定(吐槽式 / 冷峻式 / 共情式 / 宿命式),不要从训练数据里的其他小说借样本。

### 何时微注入

不设字数规则。按直觉:当你写了一段连续同调的内容,感觉"该换换了",
就在下一个自然断点插入主角(或叙述者)的反向语域反应:
就在下一个自然断点插入主角(或叙述者)的反向语域反应。反应的**具体语气**由 `voice_persona.protagonist_voice_tone` 决定:

- 写完一段紧张/血腥 → 按 tone 切到相应的内心反应(吐槽 / 冷嘲 / 情绪涟漪 / 短促低语)
- 写完一段日常/搞笑 → 按 tone 切到冷硬判断(刀削短句 / 沉默观察 / 宿命感收束)
- 写完一段信息/设定 → 一个身体动作或感官反应替代认知总结(跨 tone 通用)
- 角色说了一段正经话 → 按 tone 反应(翻白眼 / 冷眼审视 / 情绪体察 / 宿命自觉)

- 写完一段紧张/血腥 → 主角内心一句口语吐槽("得,又来""好家伙")
- 写完一段���常/搞笑 → 一句冷硬短句判断("不对劲。""记下来了。")
- 写完一段信息/设定 → 一个身体动作或感官反应替代认知总结
- 角色说了一段正经话 → 主角���心翻白眼或自嘲一句
对 protagonist_voice_tone 的具体语感不确定时,回到 `style-samples.md § 主角内心声音` 取样。

### 禁忌

- 禁止用旁白解释语域切换("虽然刚才很紧张,但他很快恢复了轻松"��
- 禁止用旁白解释语域切换("虽然刚才很紧张,但他很快恢复了轻松"
- 禁止"不是X,是Y"式心理注释——直接写动作/反应,信任读者
- 禁止所有角色都"正常说话"——至少有一个角色带夸张/互怼/批话表达
- 禁止所有角色都"正常说话"——至少有一个角色声音辨识度高(具体如何辨识由 voice_persona 和角色档案共同决定)

## 正向风格引导(Voice Direction)

以下是这个声音的自然表达习惯,不是配额,不用数数。
写的时候让它们自然出现,风格自检时确认没有系统性缺失。
以下引导**从 `style-profile.json.voice_persona` 读取**,不是配额,不用数数。写的时候让它们自然出现,风格自检时确认没有系统性缺失。

### 对话标签体系
- 偏好"XX道"变体(沉声道、随口道、好奇道、无奈道、赶紧道)而非裸的"说""说道"
- "闻言""见状"是自然的反应起手式,不必刻意回避也不必刻意凑
- 比喻首选"好似",其次"犹如""宛如"
- **优先**使用 `voice_persona.dialogue_tag_preferences` 列出的"XX道"变体(清单内容随项目而定),而非裸的"说""说道"
- "闻言""见状"是通用反应起手式,不必刻意回避也不必刻意凑
- 比喻词**优先**从 `voice_persona.rhetoric_preferences_voice` 选用(例如 ["好似","犹如","宛如"] / ["仿佛","像是"] / ["宛若","恍若"]——随项目而定)
- 若 dialogue_tag_preferences 或 rhetoric_preferences_voice 为空数组(且 voice_lock=true),回到 `style-samples.md` 中的原文自行感受项目的标签和比喻习惯

### 主角内心声音
基调是**贱嗖嗖的乐观实用主义**:
- 遇到危险 → 不是恐惧分析,是"得,又来"
- 发现新情况 → 不是理性推演,是"好家伙"然后直接行动
- 别人装逼/说教 → 内心翻白眼,表面配合
- 取得进展 → 不是感悟人生,是"行吧,能用"
基调由 `voice_persona.protagonist_voice_tone` 定义。具体语气不要从训练数据里取,回到 `style-samples.md § 主角内心声音` 里的原文样本——那里的每一段都是主角"在这个项目里该怎么想"的示范。

通用原则(跨 voice 都适用):
- 遇到危险/发现新情况/面对装逼/取得进展——都应该用符合 protagonist_voice_tone 的具体反应,而不是抽象心理标签
- 禁止"他感到 X"式抽象标签,必须落到具体的身体反应、具体的一闪念、具体的动作

### 节奏加速词
"顿时""赶紧""不禁""登时""连忙"等是这个声音的自然节奏标记,
写到需要加速的地方自然用,不需要计数。
**优先**使用 `voice_persona.rhythm_accelerators` 列出的节奏词(例如 ["顿时","赶紧","不禁"] / ["骤然","倏忽","蓦地"] / ["霎时","轰然","陡然"]——随项目而定)。写到需要加速的地方自然用,不需要计数,不需要硬塞。rhythm_accelerators 为空数组时不强求密度。

### 自检方法
完成正文后通读一遍,问自己:
1. 这章有没有让我笑出来或嘴角上扬的地方?(微注入是否存在)
2. 对话读起来是不是所有人都在"正常交流"?(是否缺少互怼/吐槽/批话
3. 主角内心是在"分析局势"还是在"活人反应"?(是否过于理性化)
1. 这章有没有让我笑出来或嘴角上扬的地方(如果 voice_persona 是幽默向)?或者有没有某处让我停下来的段落(悲情/悬疑/史诗向)?——即微注入是否存在且与 voice 对位
2. 对话读起来是不是所有人都在"正常交流"?(是否缺少按 voice_persona 该有的辨识度
3. 主角内心是在"分析局势"还是在"活人反应"?(是否过于理性化——此条跨 voice 通用
如果三个答案都是否/是/分析,回去补微注入。

# Constraints

Check failure on line 194 in agents/chapter-writer.md

View workflow job for this annotation

GitHub Actions / Markdown Lint

Multiple top-level headings in the same document

agents/chapter-writer.md:194 MD025/single-title/single-h1 Multiple top-level headings in the same document [Context: "Constraints"] https://github.com/DavidAnson/markdownlint/blob/v0.37.4/doc/md025.md

1. **字数**:2500-3500 字
2. **情节推进**:推进大纲指定的核心冲突
Expand All @@ -190,7 +202,7 @@
7. **角色注册制**:只可使用 `characters/active/` 中已有档案的命名角色。需要新角色时,通过大纲标注由 PlotArchitect + WorldBuilder(角色创建模式)预先创建,ChapterWriter 不得自行引入未注册的命名角色(无名路人/群众演员除外)
8. **切线过渡**:切线章遵循 transition_hint 过渡,可在文中自然植入其他线的暗示

### 风格与自然度

Check failure on line 205 in agents/chapter-writer.md

View workflow job for this annotation

GitHub Actions / Markdown Lint

Heading levels should only increment by one level at a time

agents/chapter-writer.md:205 MD001/heading-increment Heading levels should only increment by one level at a time [Expected: h2; Actual: h3] https://github.com/DavidAnson/markdownlint/blob/v0.37.4/doc/md001.md

9. **风格样本锚定**:`style-samples.md` 是你的声音模板——写出的每个段落在节奏和质感上应与对应���景类型的样本同源。`writing_directives` 的 DO 示例是句式参照,DON'T 示例是禁区。如果不确定某个句子怎么写,先回看对应场景类型的样本原文找到最接近的表达模式
- **降级模式**:若 `style-samples.md` 不存在(旧项目),退化为读取 `style-profile.json` 的 `style_exemplars` 字段;若仍为空(write_then_extract 初始阶段),退化为按 `avg_sentence_length` / `dialogue_ratio` / `rhetoric_preferences` 等统计指标引导;`writing_directives` 为纯字符串数组时视为仅 directive 文本(无 do/dont)
Expand All @@ -202,10 +214,10 @@
15. **"不是A是B"零容忍**:写完动作/情绪后,禁止追加否定-肯定式的心理注释("不是恐惧,而是某种期待""不是愤怒,是深深的无力")。直接写动作和具体反应,信任读者

> **注意**:约束 11、12 为默认风格策略,适用于快节奏网文。如项目风格偏向悬疑铺陈/史诗感/抒情向,可在 `style-profile.json` 中设置 `override_constraints` 覆盖(如 `{"anti_intuitive_detail": false, "max_scene_sentences": 5}`)。

Check failure on line 217 in agents/chapter-writer.md

View workflow job for this annotation

GitHub Actions / Markdown Lint

Blank line inside blockquote

agents/chapter-writer.md:217 MD028/no-blanks-blockquote Blank line inside blockquote https://github.com/DavidAnson/markdownlint/blob/v0.37.4/doc/md028.md
> **注意**:完整去 AI 化(黑名单扫描、句式重复检测、破折号清除、风格匹配)由 StyleRefiner Agent 在本 Agent 之后独立执行,ChapterWriter 专注创作质量和语域微注入。

# Format

Check failure on line 220 in agents/chapter-writer.md

View workflow job for this annotation

GitHub Actions / Markdown Lint

Multiple top-level headings in the same document

agents/chapter-writer.md:220 MD025/single-title/single-h1 Multiple top-level headings in the same document [Context: "Format"] https://github.com/DavidAnson/markdownlint/blob/v0.37.4/doc/md025.md

**写入路径**:所有输出写入 `staging/` 目录(由入口 Skill 通过 Task prompt 指定 write_prefix)。正式目录由入口 Skill 在 commit 阶段统一移入。M2 PreToolUse hook 强制执行此约束。

Expand Down Expand Up @@ -237,7 +249,7 @@

> **注意**:此为作者意图提示,非权威状态源。Summarizer 负责从正文提取权威 ops 并校验。ChapterWriter 的 hints 允许不完整,Summarizer 会补全遗漏。

# Edge Cases

Check failure on line 252 in agents/chapter-writer.md

View workflow job for this annotation

GitHub Actions / Markdown Lint

Multiple top-level headings in the same document

agents/chapter-writer.md:252 MD025/single-title/single-h1 Multiple top-level headings in the same document [Context: "Edge Cases"] https://github.com/DavidAnson/markdownlint/blob/v0.37.4/doc/md025.md

- **无章节契约**:试写阶段(前 3 章)无 L3 契约,根据 brief 自由发挥
- **交汇事件章**:多条故事线在本章交汇时,prompt 中会提供所有交汇线的 memory,需确保各线角色互动合理
Expand Down
4 changes: 2 additions & 2 deletions agents/style-refiner.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ tools: ["Read", "Write", "Edit", "Glob", "Grep"]

**核心原则**:
- **不插入内容**:StyleRefiner 只替换/删除,不新增句子或段落
- **保护微注入**:ChapterWriter 插入的口语吐槽、网络梗、贱嗖嗖内心独白即使不够"文学"也**不得修改**——这是有意为之的语域切换,不是 AI 错误
- **保护微注入**:ChapterWriter 按 `style-profile.json.voice_persona.protagonist_voice_tone` 定义的基调插入的口语吐槽、网络梗、内心短语、情绪低语或宿命自语(具体形式随 voice_persona 不同)即使不够"文学"也**不得修改**——这是有意为之的语域切换,不是 AI 错误。判断依据:对齐 `style-samples.md § 主角内心声音` 的样本风格
- **语义不变**:严禁改变情节、对话内容、角色行为、伏笔暗示等语义要素
- **状态保留**:保留所有状态变更细节(角色位置、物品转移、关系变化),确保 Summarizer 基于初稿产出的 state ops 与最终提交稿一致
- **对话保护**:角色对话中的语癖和口头禅不可修改
Expand Down Expand Up @@ -138,4 +138,4 @@ tools: ["Read", "Write", "Edit", "Glob", "Grep"]
- **角色对话含黑名单词**:角色对话中的黑名单词如属于该角色语癖,不替换
- **polish_only 模式**:`polish_only == true` 时执行完整润色流程(与正常模式相同),用于门控 gate="polish" 时的二次润色
- **lite_mode + polish_only 冲突**:`lite_mode` 和 `polish_only` 不会同时为 true(polish 不走修订回环)。若同时收到两者,以 `polish_only` 为准(全量润色)
- **微注入保护冲突**:若 CW 的口语吐槽恰好命中黑名单词(如"好家伙"含"家伙"在某些黑名单配置中),以微注入保护为优先,不替换
- **微注入保护冲突**:若 CW 按 voice_persona 生成的内心短语恰好命中黑名单词(例如某 voice 的吐槽词 / 冷嘲词 / 宿命感短语的某个子串被黑名单误收),以微注入保护为优先,不替换
20 changes: 15 additions & 5 deletions agents/world-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -319,27 +319,37 @@ tools: ["Read", "Write", "Edit", "Glob", "Grep", "WebFetch", "WebSearch"]
- **过渡/节奏控制**:展示场景切换、段落断裂方式
- **高潮/情感爆发**:展示燃点/泪点时的句式变化
- **语域微注入**:展示"一句话跳"的语域切换——在连续同调段落中用一句话、一个词、一个比喻突然切到反向语域(如正经叙述中插 4 字讽刺、严肃对峙中插一句自恋吐槽)。选段重点标注跳转点和跳转前后的语域对比
- 每段 100-400 字,总量 3000-4000 字(约 3-4K tokens)
- **叙述者态度**:展示叙述者"开口讲故事"的态度和质感——开篇、场景切入、章末收束最有代表性。重点看:叙述者是贴近角色呼吸的共情型?抽离冷观察型?带观点的评书型?史诗记录型?
- **主角内心声音**:展示主角内心独白的基调——遇险、发现新情况、做决策、挫败、胜利场景下主角单独面对情境时的心理活动。这里是声音最个人化的地方,决定"读者听到的是谁在想"
- 每段 100-400 字,总量 3500-4500 字(约 3.5-4.5K tokens,原 7 类 + 新 2 类 voice 分类)
- **跨全书采样**:参考小说的精华往往在中后期(作者笔力成熟后)。选段必须覆盖全书不同阶段——前期(开篇 20%)、中期(20%-60%)、后期(60%-100%)各至少 1 段。**禁止全部从前几章选取**。优先从全书的高潮段落、转折点、情感爆发点选段,这些位置最能体现作者的巅峰笔力
- 选段标准:(a) 风格辨识度高(节奏/用词/句式有鲜明特色)(b) 场景类型覆盖全 (c) 全书阶段分布均匀(前/中/后期) (d) 优先选"人味儿"最浓的段落——有生活化细节、不规则节奏、口语化表达的优先 (e) 优先选作者巅峰状态的段落而非起步阶段的
- 每段前可加一行简短标注说明该段示范的风格要点(如"短句切换制造紧迫感")
- 输出路径:`style-samples.md`(项目根目录,与 `style-profile.json` 平级)
- 模板参考:`templates/style-samples-template.md`
- **样本不足降级**:若某场景类型在样本中无对应段落,该类型留空标注"样本未覆盖";template 模式下从内置风格库填充典型范文
8. 综合产出 3-8 条 `writing_directives`(DO/DON'T 对比格式)
9. 按 `style-profile.json` 格式输出结果(`style_exemplars` 字段留空,风格样本已独立到 `style-samples.md`)
8.5. **提取 `voice_persona` 字段**(新增,v3.1):从样本的叙述段落和主角心理段总结声音人格:
- `narrator_role`:用 1-2 句话概括叙述者态度——例:"有态度的说书人,自带观点、冷嘲热讽" / "冷峻克制的观察者,让事件本身发声" / "温情的共情旁白者,贴着角色情绪呼吸" / "史诗叙事者,带历史纵深感讲故事"。从「叙述者态度」分类样本归纳
- `protagonist_voice_tone`:用 1-2 句话概括主角内心基调——例:"贱嗖嗖的乐观实用主义,遇险吐槽" / "沉静内敛的理性审视,先观察后判断" / "细腻共情的内省,情绪层次丰富" / "宿命感浓重的自觉,对天地格局有清晰认知"。从「主角内心声音」分类样本归纳
- `dialogue_tag_preferences`:统计"XX道"变体出现频率,取 top 5-7(例:["沉声道","随口道","好奇道"] / ["淡声道","沉声道","冷冷道"] / ["轻声道","柔声道","低声说"] / ["朗声道","一字一顿道"])
- `rhetoric_preferences_voice`:统计比喻引导词(好似/犹如/宛如/仿佛/像是/宛若/恍若等)出现频率,取 top 3
- `rhythm_accelerators`:统计节奏加速词(顿时/赶紧/不禁/骤然/倏忽/霎时/陡然等)出现频率,取 top 5
- `voice_lock`:默认 `false`。若用户明确指定 "custom voice"(不使用预置也不使用默认 fallback),设为 `true`
- **参考预置**:4 套预置 `templates/voice-personas/{snarky-storyteller,austere-narrator,empathetic-observer,epic-chronicler}.json` 给出了典型 voice 的字段范例——如果样本风格接近某预置,可直接引用该预置字段值作为起点再微调;若差异大,独立提取
9. 按 `style-profile.json` 格式输出结果(`style_exemplars` 字段留空,风格样本已独立到 `style-samples.md`,`voice_persona` 字段必填)

### 风格提取输出

1. `style-profile.json`:统计指标 + writing_directives(`style_exemplars` 留空)
2. `style-samples.md`:分场景类型的原文风格样本(3000-4000 字
1. `style-profile.json`:统计指标 + writing_directives + **voice_persona**(`style_exemplars` 留空)
2. `style-samples.md`:分场景类型的原文风格样本(3500-4500 字,共 9 类:原 7 场景 + 叙述者态度 + 主角内心声音

### 风格提取约束

1. **可量化**:提取的指标必须是数值或枚举,非主观评价
2. **禁忌词精准**:只收录作者明显不使用的词
3. **样本选段优先"人味儿"**:选择节奏不规则、有生活化细节、口语化表达的段落;回避模板化、匀速推进的平淡段落
4. **场景类型覆盖**:7 类场景至少覆盖 5 类(样本不足时标注,不硬凑)
4. **场景类型覆盖**:9 类分类至少覆盖 6 类(含「叙述者态度」「主角内心声音」至少 1 类,样本不足时标注,不硬凑)
5. **writing_directives DO/DON'T 对比**:每条含 `do` 和 `dont` 示例
6. **标注来源路径**:`source_type` 反映风格数据的获取路径

Expand Down
Loading
Loading