novel_sentence_config
写作助手开关的查看与修改。读取即返回「总开关 + 18 个工具开关 + 9 个功能开关 + 系统提示词档位、场景与精简工作流 + 风格基线容差 + 原创模式设定 + 语义引擎状态」的生效值;action: "set" 时把传入字段增量写入状态文件并强制回读。开关落在 ~/.dsh/dsh-novel-writer/state.json,与 Web GUI 侧边栏读写同一文件(GUI 走插件自带的 POST /api/dsh-novel-writer/state 路由)。本工具自身禁止被关闭。
参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
action | string | 否 | 枚举 get / set。默认 get:实现为 args.action === "set" ? "set" : "get",任何非 "set" 的值(含省略)都按查看处理。 |
enabled | boolean | 否 | 写作助手功能总开关。仅布尔值参与写入,非布尔值静默忽略。 |
autoAnalyze | boolean | 否 | 分析作品时是否主动使用句式分析。仅布尔值参与写入。 |
systemPromptMode | string | 否 | 系统提示词档位:枚举 off(不注入) / brief(精简) / full(完整)。非枚举值静默忽略(不报错、不改盘)。 |
promptScene | string | 否 | 系统提示词场景:枚举 general / writing / revising / auditing / setup。仅 full 档生效;非枚举值静默忽略。general 是合法取值,用于把场景改回通用档。详见下文「提示词档位与场景」。 |
leanWorkflow | boolean | 否 | 系统提示词精简工作流(v5.1.0 新增,英文标签 Lean workflow):打开后注入 LEAN_TEXT,且优先于档位与场景。默认 false。只有真正的布尔值被采用,非法值(字符串 "true" / 1 / null …)静默忽略——与 promptScene 同一套「非法即丢弃、不报错不回显」的口径。详见下文「提示词档位与场景」。 |
tools | object | 否 | 各工具开关,形如 { novel_plot: false }。键必须在 ALL_TOOLS 的 18 个名字内,值必须是布尔,其余静默忽略;novel_sentence_config 自身的键会被强制剔除。与现有值浅合并。 |
features | object | 否 | 功能开关。合法键仅 9 个(见下表),其余键静默忽略;与现有值浅合并。 |
styleTolerance | object | 否 | 风格基线容差,每维 { low, high }(low 为负、high 为正)。low 钳到 [-99, 0],high 钳到 [0, 99],两者须同时为数字且 low ≤ high,否则该维被整体丢弃。传 {} 或 null 表示清除(恢复推荐值)。 |
creationProfile | object | 否 | 全局原创模式设定,六个字符串键:worldview / characters / forbidden / mainConflict / genre / extra。留空项省略。传 {} 或 null 表示清除。 |
creationProfiles | object | 否 | 按书专属原创设定,键 = 书名,值结构同上。与现有条目合并(同键覆盖);某书的值传 null 表示删除该书条目;传 {} 表示清除全部书的设定。 |
book 与 root。本工具是全局开关表,没有书库作用域;参数 schema 声明为 additionalProperties: false,即 schema 之外不存在任何可传字段。唯一的书库相关字段是只读回显的 creationProfiles(键为书名)。
tools 与 features 只挑白名单内的键写入,拼错的键名既不报错也不出现在回显里。判断某个键是否被接受,只能读返回体的 tools / features,不能读 updated——只要同一批里有一个合法字段生效,updated 就是 true。
输出结构
契约必返字段(output.schema.required):file、enabled、autoAnalyze、tools、features、embedding、styleTolerance、creationProfile。实现中还会恒定返回 source、updated、systemPromptMode、promptScene、leanWorkflow、creationProfiles。
| 字段 | 类型 | 内容 |
|---|---|---|
file | string | 状态文件的绝对路径,由 stateFilePath() 给出 |
enabled | boolean | 生效的总开关(写后回读的结果,非传入值) |
autoAnalyze | boolean | 生效的自动分析开关 |
systemPromptMode | string | 写后回读的提示词档位:off / brief / full(盘上的非法值已在读取侧回退为默认 brief) |
promptScene | string | 写后回读的提示词场景:general / writing / revising / auditing / setup(非法值已回退为默认 general)。回读值与你要写入的值不一致 = 该参数被判为非法而静默丢弃,这是比 updated 可靠的校验方式 |
leanWorkflow | boolean | 写后回读的精简工作流开关(v5.1.0 新增);盘上非布尔值已在读取侧回退为 false。老状态文件缺该键时同样为 false——即行为与 5.0.0 完全相同 |
source | string | 生效值来源:state 文件(GUI 开关) / v0.4.0 兼容文件 novel-writer.json / 插件 config / 默认值 |
updated | boolean | 本次 set 是否发生了实际写入(patch 为空则为 false) |
tools | object | 18 个 novel_* 工具名到当前开关的映射,逐个由 toolEnabled 求值 |
features | object | 9 个功能键到当前开关的映射,逐个由 featureEnabled 求值——恒有 9 个键,与文件里实际存了几个无关 |
embedding | object | { available, loaded, error },语义引擎状态,见下文 |
styleTolerance | object | 用户自定义容差;未设置为 {}(语义:使用推荐值),不是 null |
creationProfile | object | 全局原创设定;未设置为 {} |
creationProfiles | object | 按书设定;未设置为 {} |
additionalProperties: false,不含 brief;渲染层也没有精简分支。渲染文本是一份固定格式的开关清单(<path> / <type>novel-sentence-config</type> / <content>),逐行列出总开关、autoAnalyze、提示词档位与场景(系统提示词: 档位=X 场景=Y,full 档 + 非 general 场景时追加「(按场景注入)」)、来源、18 个工具开关与全部功能开关,体积由开关数量决定,不可再压缩。这里的 brief 指工具自身的精简输出参数,与提示词档位 systemPromptMode: "brief" 是两回事;也与 leanWorkflow 是两回事——后者只让 novel_style_report / novel_sentence_analysis 在未显式传 brief 时默认精简,本工具的渲染不受它影响。
计算原理
1 · 状态文件与读取回退
exists 是读取侧由文件是否存在推导出的派生字段,不落盘(写盘前被显式剔除)。磁盘上真实的 state.json 字段为 enabled、autoAnalyze、systemPromptMode、promptScene、leanWorkflow、tools、features、styleTolerance、creationProfile、creationProfiles、lastRoot。readSentenceStateSync(系统提示词回调用的同步版)对这些字段做同样的回退,因此老状态文件在两条读取路径下都落到 brief + general + leanWorkflow:false。
2 · 生效值的优先级
返回体里的 enabled / autoAnalyze 不是文件原值,而是 effectiveSentenceAnalysis 的结果:
set 创建(writeSentenceState 一律整份落盘),因此「配了 config.sentenceAnalysis 却不生效」是预期行为,不是配置写错。
3 · 工具开关(tools)
18 个 ALL_TOOLS 条目:novel_books、novel_chapters、novel_read、novel_keywords、novel_new_chapter、novel_chapter_brief、novel_import、novel_sentence_analysis、novel_sentence_config、novel_style_check、novel_fix_plan、novel_plot、novel_settings、novel_summary、novel_continuity_check、novel_semantic_search、novel_style_report、novel_outline。
关闭一个工具的后果并不统一:18 个工具的 execute 首行各自调用 assertToolEnabled,关闭时抛错(硬拒绝)。两类例外走软降级——novel_sentence_analysis 在总开关 enabled === false 时返回禁用桩(enabled:false、totalChars:0、totalSentences:0 加一段 message);novel_semantic_search 在 semanticSearch 关闭或引擎不可用时返回 available:false 加 message 的对象。前者的关闭还会让 novel_style_check 直接报错拒绝执行。
4 · 功能开关(features,9 键)
| 键 | 默认 | 作用 |
|---|---|---|
emotionCaveat | true | 情感净化预警 |
genreTheme | true | 题材与流派检测 |
emotionComplexity | true | 情感复杂度量化 |
semanticEmbedding | true | 本地语义增强总闸;关闭后三个 semantic* 子开关一并失效 |
semanticSearch | true | 语义检索(novel_semantic_search) |
semanticStyle | true | 衔接检查里的语义距离一路 |
semanticImplicit | true | 隐性情感的语义检测 |
rawWriting | false | 非净化直白模式;默认关闭,是唯一默认 false 的键 |
webnovelVibe | true | 网文信号检测 |
三个 semantic* 子开关与总闸是与关系(semanticFeatureEnabled 先看 semanticEmbedding 再查子键)。
5 · styleTolerance 与六个维度
合法维度键为 METRIC_ORDER 六项:complexity(句法复杂度)、modifierDensity(修饰密度)、abstractDensity(抽象度)、actionDensity(动作密度)、hedgeDensity(不确定性)、gapIndex(留白指数)。写侧不校验键名,未知维度会落盘但没有任何消费点;读取侧未设置时返回 {}。
推荐容差底取「含目标章的全书每维 recTol」(约作者自身波动 1.5σ,四舍五入到 5 的倍数、下限 10、上限 100),用户自定义只覆盖被点名的维度,未配置的维度不受「排除目标章后样本变少」影响。
6 · 写入路径
set 成功后强制重读状态文件再计算生效值与 source,避免首写时返回写前快照(旧版曾出现盘上 enabled:false 而返回值仍是 config 的 true)。若本次 patch 含 creationProfiles,还会同步 novels/创作资料/<书名>/ 下 创作设定.md 与 主要人物设定.md 的用户段(含空壳目录清理);同步失败不影响设定保存。
7 · rawWriting 的语义与写入位置
RAW_WRITING_PROMPT 的文本为「非净化模式已开启(用户已确认)」加四条要求:照原文的细节密度与露骨程度描写血腥 / 暴力 / 成人场景、不回避不委婉化、保持原文用词与动作细节、仅限用户个人创作。GUI 中开启该开关需经过双重确认与承诺输入;通过本工具直接传 { features: { rawWriting: true } } 会跳过这套确认流程,因此只应在用户明确要求时使用。
与之相邻但属于独立维度的是系统提示词档位 systemPromptMode(off / brief / full)与场景 promptScene(general / writing / revising / auditing / setup):两者同样落在状态文件里,但只影响「小说写作助手」这一段提示词的注入,与工具能力无关。详见下一节。
8 · 语义引擎状态(embedding)
available: true 不等于「推理可用」。它只表示开关打开且模型文件在位(或已加载)。真正完成 ONNX 会话加载要看 loaded;加载失败时 error 为失败原因的前 300 字,且有 30 秒冷却后自动重试。
提示词档位与场景
本版把系统提示词的注入拆成三个正交维度:档位(systemPromptMode)决定「注入多少」,场景(promptScene)决定「注入什么」,精简工作流(leanWorkflow)决定「要不要催促动作」。它们都只影响「小说写作助手」这一段插件系统提示词,不改变任何工具的能力、参数、返回值或开关生效状态。
| 维度 | 取值 | 含义 |
|---|---|---|
systemPromptMode(档位) | off | 不注入。promptTextFor 返回空串,DSH 侧过滤掉空段落,等于该段完全不存在。 |
brief | 精简档(默认):只说明「已挂载 novel_* 工具、详细规范见 novel-writing 技能」,几乎不占上下文。该档与场景无关——不论 promptScene 取什么值,注入的都是同一段 BRIEF_TEXT。 | |
full | 完整档:按场景注入对应的那一套工作流文本(见下表)。 | |
promptScene(场景) | general | 通用写作工作流(默认):章节库约定、分析方法、续写流程、导入整理、工具链提示等全量约定。这段文本来自 4.x 的 WORKFLOW_TEXT——结构逐字沿用,但 v5.1.0 把其中的「必做」改成了「按需」:基线由开写包 / 建章直接附带,不必专门去调 novel_style_report;写完建议跑一次 novel_style_check,只有偏离明显时才修正(详见下方「出带不等于必改」)。 |
writing | 写新章:先取材料(开写包)→ 简述计划 → 读锚段校准语感 → 遵守禁用清单 → 建章节 → 建议跑一次自检(偏离明显才修)→ 收尾按需(不必每章全套)。 | |
revising | 改稿:先取改稿清单 → 分批改(同段落 / 同类型合并成一次修改,一轮只处理最严重的 3~5 条,只改问题处、不整章重写)→ 不要逐条 mark,也不要反复 verify(一轮改完只跑一次 verify)。 | |
auditing | 审计:只体检、只报告,不改正文、不写章节、不登记设定;结构 / 风格 / 手法三层各自的工具与「候选而非结论」的输出要求。 | |
setup | 建资料:只维护创作资料与设定表,不写正文;初始化骨架、登记五张表、登记伏笔、扫描已有正文,最后用结构视图自查。 | |
leanWorkflow(精简工作流) | false | 默认:按上面两个维度选择文本,与 5.0.0 行为一致。 |
true | 注入 LEAN_TEXT(380 字符),且优先于档位与场景——档位与场景取什么值都不改变这一结果。该文本不再罗列流程,只保留最短的必要提醒,用来抑制模型「按流程逐项打勾」的冲动:不再催促每章都做完整套收尾、也不再要求把每条待办都标记一遍或反复复测。任何时候都能切换(不受 full 档限制)。另有两处联动:novel_style_report 与 novel_sentence_analysis 在调用方未显式指定 brief 时,默认走精简输出。 |
场景只在 full 档下生效。off 档恒为空串、brief 档恒为 BRIEF_TEXT,两者都会忽略 promptScene 的取值。反过来,full 档 + general 就是 4.x 的完整行为(v5.1.0 只把其中三处「必做」放宽成「按需」,见下)——因此「升级到 5.0.0」本身不会改变任何提示词内容,想按场景分流必须显式把 promptScene 改掉。
writing 原先要求建完章节立刻做一次风格自检、并把收尾固定成一套动作;revising 原先要求按 severity 一条一条过、每改一批就登记并复测;general 原先把「动笔前先出风格报告」与「每写完一章都做风格自检」写成硬性前提——现在分别改为「写完建议跑一次自检,只有相似度明显偏低或某维偏离超过 2 倍容差时才修正」「收尾按需,不必每章全套」「基线由开写包 / 建章直接附带,不必专门去调工具,建议跑一次自检、偏离明显时才修正」。
anchors 只用来校准语感,不要照 skeletons 造句、不要套句式模板(骨架仅在写不出该类型句子时参考)。leanWorkflow 是覆盖层,不是第四个档位。它不改变 systemPromptMode / promptScene 的磁盘值,也不参与「档位」的枚举;打开时只是在文本选择的最前面插一条命中分支。因此关掉它就能原样回到先前那套文本,不需要把档位与场景改回去。它同样不影响任何工具能力——「不要逐条 mark」是提示词对模型的约束,novel_fix_plan 的 mark 依然照常可用。revising 不会禁用章节工具,切到 auditing 也不会把工具变成只读——「不改正文」是提示词对模型的约束,不是插件的运行时限制。工具开关与总开关仍由上面的 tools / enabled 独立控制,两者互不影响。
promptScene 键的老状态文件落到 general,既有工作流不变。两条读取路径(异步 readSentenceState 与同步 readSentenceStateSync)都以 PROMPT_SCENES.includes(...) 校验,缺失或非法一律回退 general;general 映射到通用档的 WORKFLOW_TEXT(4.x 原文结构,本版在其中补入三条新工具的入口指引共 7 行,v5.1.0 又把三处「必做」放宽为「按需」)。写入侧同理:非枚举值被静默忽略(不写盘、不报错),而 general 是显式合法值,用于把场景从四套流程改回通用档。
leanWorkflow 键的老状态文件落到 false,行为与 5.0.0 相同。读取侧按「只有真正的布尔值被采用」处理:键缺失、为 null、为字符串 "true"、为数字 1 一律落到 false,且静默忽略(不写盘、不报错、不回显失败)——与 promptScene 的非法值口径一致。写入侧同样只接受布尔值。因此这个开关是纯增量的:不打开就等于 5.0.0 的提示词行为,升级本身不会改变任何注入文本。
写入渠道有两个:本工具的 action: "set"(systemPromptMode / promptScene / leanWorkflow 参数)与 Web GUI 侧边栏首页开关走的 POST /api/dsh-novel-writer/state(GET 响应里同样回显这三个字段)。两条路径最终都调用同一个 writeSentenceState,写入与校验口径一致。侧边栏「写作助手功能」面板里的精简工作流(英文标签 Lean workflow)一行位于「提示词档位」「提示词场景」下方,与它们并列,任何时候都能切换——不受 full 档限制,brief / off 档下同样可用。
约束与边界
- 本工具不能被关闭。两条写入路径都强制剔除该键:工具侧写入前
delete toolsPatch.novel_sentence_config,GUI 路由侧同样在写入前删除。因此它通常不出现在state.json的tools里,读取时按!== false判定为开。这一设计是为避免「关掉开关后连开启的工具都调不到」的死锁。 - 白名单之外的一切静默忽略。
tools只认 18 个工具名,features只认 9 个键,systemPromptMode/promptScene只认各自的枚举、leanWorkflow只认布尔;非布尔值、非对象、拼错的键都不会报错也不会回显。updated只表示「发生过写入」,不能用来确认某个具体键被接受——要确认请读返回体里对应字段的回读值。 - 非法容差维度是整体丢弃,不是钳到边界。
low > high、只给一侧、非数字都会让该维不写入(保持此前磁盘值或推荐值);low/high本身的越界值会被钳到[-99, 0]/[0, 99]。未知维度键会落盘但无消费点。 {}与null都是「清除」。styleTolerance/creationProfile传空对象或 null 即清空;creationProfiles传空对象或 null 表示清除全部书的设定(并触发创作资料里的用户段移除与空壳目录清理)。宿主的 JSON Schema 若不支持 null 类型,一律用{}。set是增量而非整份替换。未传字段保持原值;tools/features/creationProfiles为浅合并。creationProfiles不提供「只删某键但保留该书其余字段」的语义——按书整体替换,值传null是删除该书。- 生效值与磁盘值可能不同。
source反映的是生效值从哪来:state 文件一旦存在,插件config.sentenceAnalysis与 v0.4.0 兼容文件都不再影响enabled/autoAnalyze,但styleTolerance等其余字段本来也只从 state 文件读。 - 开关的关闭后果不统一。工具开关关闭 → 该工具
execute抛错(硬拒绝);总开关enabled=false→novel_sentence_analysis返回禁用桩、novel_style_check抛错;semanticSearch关闭 → 语义检索返回available:false的软降级对象。调用方不能假设「关闭 = 报错」或「关闭 = 空结果」。 autoAnalyze只影响提示词,不影响任何工具返回值。它被写进系统提示词第 4 条(false时要求「仅在用户明确要求时调用」句式分析);插件本身不据此改变输出。- 档位、场景与精简工作流是三个独立维度,且场景只在
full档生效。off恒不注入、brief恒注入精简文本,两者都忽略promptScene;只有full档下general/writing/revising/auditing/setup才有区别。full+general即 4.x 的原始行为。第三个维度leanWorkflow是覆盖层:为true时注入LEAN_TEXT并优先于前两个维度(与档位是否full无关,任何时候都能切换),为false时三个维度退回成上面的两维关系。三个字段都不改变工具能力,只换提示词文本。 - 提示词改动下一轮生效,无需重启。该 section 的
text是一个函数,在每轮组装系统提示词时现读状态文件;因此改完开关后当前这一轮仍用旧文本。状态读不到时回退精简档BRIEF_TEXT。 - 跨进程写入不是事务。写入串行化(
stateWriteChain)只在单个进程内生效。MCP 服务器是独立进程,它与 DSH 宿主内的 GUI 同时写同一文件时,读-合并-写可能互相覆盖;需要并发写入时应串行化调用而非并行。 - 写入失败与参数错误可区分。磁盘写不进去时抛出的错误带
code = "ENOVELWRITEFAIL",GUI 路由据此返回 500;其余写入异常在路由层返回 400。首次set的返回值取自写后重读,因此不会出现「返回值与盘上状态相反」。 - 无 brief / 精简模式。参数 schema 为
additionalProperties: false且不含brief;需要控制 token 时应减少调用频次,而不是指望该工具压缩输出。 - 跨版本差异。
systemPromptMode为 v4.0.0 引入的字段,更早的状态文件没有该键,读取侧按默认brief处理;promptScene为 v5.0.0 引入,老状态文件没有该键时按默认general处理——general即 v4.x 的通用工作流(本版仅在其第 3、7 节补入三条新工具的入口指引,共 +7 行;v5.1.0 又把其中三处「必做」放宽为「按需」),既有工作流不变;rawWriting在明确设置前按FEATURE_DEFAULTS的false处理(旧版曾把它误报为true);leanWorkflow为 v5.1.0 引入,老状态文件没有该键时按默认false处理,行为与 5.0.0 相同。
相关工具
- novel_sentence_analysis —— 受
enabled与autoAnalyze直接约束的分析工具;enabled=false时返回禁用桩。 - novel_style_check ——
styleTolerance的唯一消费点,逐维覆盖推荐容差后做基线判定。 - novel_style_report —— 六维基线与
recTol的来源;未自定义容差时本工具回显{},即使用该推荐值。
源码位置
- lib/index.js —— 工具注册与实现
registerNovelSentenceConfig:参数白名单(tools/features的合法键列表)、写入分支、source推导与返回体组装 - lib/prompts.js —— 系统提示词文本与选择逻辑:
RAW_WRITING_PROMPT、WORKFLOW_TEXT(general场景的文本)、BRIEF_TEXT、LEAN_TEXT(v5.1.0 新增的精简工作流文本,380 字符)、SCENE_TEXTS(writing/revising/auditing/setup四段)、PROMPT_SCENES(合法场景枚举)、promptTextFor(mode, scene)(档位 × 场景的选择器;leanWorkflow为真时优先返回LEAN_TEXT)。 - lib/client.js —— 侧边栏「写作助手功能」面板的渲染与提交:新增精简工作流(
Lean workflow)一行,位置在「提示词档位」「提示词场景」下方,与档位 / 场景并列且不受full档限制。 - lib/index.js ——
ctx.systemPrompt.section({ name: "novel-writing", order: 150 }):text回调读readSentenceStateSync()后调用promptTextFor;相邻的novel-writing:raw-writing(order 151)与档位/场景无关。 - lib/core.js ——
SENTENCE_ANALYSIS_DEFAULTS(含systemPromptMode/promptScene/leanWorkflow默认值)、ALL_TOOLS、FEATURE_DEFAULTS、featureEnabled、toolEnabled、assertToolEnabled、stateFilePath、readSentenceState/readSentenceStateSync、writeSentenceState、atomicWriteJson、clampStyleTolerance、effectiveSentenceAnalysis、makeStateRoutes(GUI 侧 GET/POST/api/dsh-novel-writer/state,GET 回显systemPromptMode/promptScene/leanWorkflow) - lib/style-metrics.js ——
METRIC_ORDER/METRIC_LABELS/computeBaselineFromPerChapter的recTol - lib/embedding.js ——
status/isAvailable(embedding字段的来源) - mcp/server.mjs —— MCP 侧只注入
root,不读写状态文件;因此 MCP 调用与本工具共享同一份state.json