Passer au contenu principal
H

dsh-novel-forge

huangziyuan-general/dsh-novel-forge

Garde-fous d'écriture de romans : 20 outils novel_* appliquent la cohérence du grand livre factuel, les portes de phase et de chapitre, l'audit automatique avec des métriques déterministes, et des révisions en proposition uniquement ; un atelier du panneau de droite couvre la lecture, la lecture TTS, le polissage, la relecture, les vérifications de continuité et la rédaction par lots, et un moteur de contournement exécute les étapes internes hors de la conversation principale.

Installer

dsh plugin --profile web add github:huangziyuan-general/dsh-novel-forge

README

dsh-novel-forge · 小说锻炉

release license tests

DeepSeek Harness(DSH)的小说创作插件。设计主线只有一条:

代码强制 > 提示词自觉。 凡是"靠模型自觉"的约束都会失效—— 一致性、门禁、审计必须是工具层/数据层的硬约束。

AI 长篇写作的通病不是玄学,每一个都有对应的工程解法。本插件把其中"有明确对错"的部分做进代码:

AI 写作通病本插件的硬约束落点
设定/战力崩坏事实账本:同章改值=冲突拒绝;世界书关键词自动注入novel_ledger / novel_worldbook
模型"看不见前文"写前简报按预算组装上下文包(细纲→人物卡→账本→伏笔→世界书→上章结尾)novel_briefing
口头跳阶段阶段门禁:细纲未批准,novel_write_chapter 直接拒绝novel_outline approve
跨章复读/水文8 字 shingle 与前文重复检测,超阈值拒绝保存novel_write_chapter 机审
章节字数失控机审门槛默认 2000–4000 字(网文连载单章标准,目标 3000);写前简报带「本章字数目标」段novel_write_chapter / novel_briefing
章末无钩子章末钩子启发式(问句/悬念/省略/感叹),缺了给警告novel_audit
AI 味六维结构性扫描:模板句/库存词密度/情绪直写/句式模板/段落节奏方差/信息稀释(纯本地,零模型费用)novel_noai_scan
偷偷覆盖正文提案制:修订走提案→用户确认→生成新版本,旧版永不覆盖novel_propose
审稿放水机审与模型审分离:审计产出确定性数字,模型审稿必须引用证据novel_audit
悬念提前泄底场景契约:隐藏人物档案不进上下文(连账本/摘要里的痕迹也擦掉),正文出现其名=内容门禁拦下novel_scene
写偏/漏写细纲细纲契约段(必写场景 / 禁止偏离项)由代码算覆盖率与偏离度,命中禁项拒绝落盘novel_write_chapter
多角色千人一腔语言基因卡结构化注入(句长/逻辑/口头禅/绝不说/小动作/语域),审稿核对禁忌词novel_character voice
长篇上下文爆炸契约在场时只注入本章出场人物的卡,世界书按白名单取novel_briefing
设定没定就想写大纲九阶段状态机:每阶段入场条件由代码判定,缺什么直接列出来novel_project phase
同一章反复写不对熔断:同章连续驳回 3 次即拒写(不是提醒),改完细纲/契约自动解除novel_write_chapter
不合平台口味平台审稿两张表:起点看结构/章末钩子/移动端段长,番茄看前 1000 字爽点/打脸/憋屈时长novel_audit platform
踩平台红线敏感自查七类,命中给行号与改法novel_audit censor
内部工序占满主对话旁路直调:润色/校对/打标/起草走独立流,不占主对话、不写会话记录;结果只出提案lib/engine.js
批量起草绕过门禁并发生成、串行提交:每章仍过同一道门禁,单章失败不回滚整批draft-batch
写到百章后"看不见前文"本地检索索引:按记忆碎片把段落找回来(中文手工二元切分,零依赖)novel_search

界面一览

右侧栏「锻炉」面板实机截图(演示书目为演示新建的虚构内容):

项目列表
详情 · 基本信息
章节听书
阅读卡

快速开始(约 5 分钟)

前提:已安装 DeepSeek Harness(DSH)并跑通模型;Node ≥ 22(22.19+ / 24+ 可启用检索索引,否则自动降级,不影响其他功能)。

第 1 步 · 安装插件(任选其一):

# 从插件商店(GitHub 公开仓库,推荐)
dsh plugin --profile web add github:huangziyuan-general/dsh-novel-forge

# 从 npm(发包后启用——当前未发布,此路暂不可用)
# dsh plugin --profile web add npm:@huangziyuan-general/dsh-novel-forge

# 本地开发(符号链接,改码即生效)
dsh plugin --profile web add link:/path/to/dsh-novel-forge

第 2 步 · 重启 DSH web,然后浏览器硬刷新(客户端 bundle 在进程启动时快照,不重启等于没装)。

第 3 步 · 验证安装:右侧栏出现「🔨 锻炉」独立 tab;在会话里让模型「列出小说工具」,应能看到 20 个 novel_* 工具。同时 agent 预设「小说锻炉」已自动部署到 ~/.dsh/.agent-presets/novel-forge/(已存在则跳过,永不覆盖;DSH_NOVEL_FORGE_REDEPLOY=1 强制重铺,DSH_NOVEL_FORGE_SKIP_DEPLOY=1 关闭)。

第 4 步 · 建第一本书:在会话里直接对模型说,例如:

用 novel_project init 建一本玄幻书《示例书名》,一句话立意是「废柴觉醒了不该属于他的力量」。

第 5 步 · 跟着九阶段走:模型会按 立意→设定→人物→大纲→分卷→细纲→正文 的顺序引导,每个阶段缺什么、插件会直接列出来。写章前必须先 novel_outline approve 批准该章细纲——这是设计,不是故障。

第 6 步 · 到面板收结果:右侧栏「锻炉」tab 里阅读/听书、点润色/校对(产物是提案,你在面板点「应用」才生效)、跑全书体检、导出整本。

宿主版本要求与依赖面清单见 COMPATIBILITY.md

会话与面板的分工

  • 会话里(模型 + novel_* 工具):一切创作动作——建书、大纲、细纲、写章、账本、审计。写章必须走会话(简报 + 多道落盘门禁是多轮闭环)。
  • 面板(右侧栏「锻炉」):阅读与听书、润色/校对(旁路引擎,产物为提案)、全书体检、黄金三章诊断、批量起草、提案审批(应用/丢弃)、书卡管理(改名/删除/克隆)。

典型会话流:

novel_project init → novel_project phase(看九阶段看板,按提示补齐入场条件)
→ novel_outline save_book → novel_character save(建语言基因卡)
→ novel_worldbook add(固化核心设定)→ novel_project phase stage:outline/volume(分卷)
→ 循环:
    novel_outline save_chapter + approve
    → novel_briefing(拿上下文包;有场景契约就按契约裁剪)
    → 按细纲成稿 → novel_write_chapter(门禁/机审/账本/内容门禁/契约指标/熔断/落盘)
    → novel_noai_scan + novel_audit(证据)→ 你自己(或让模型引用证据)审稿
    → 发书前:novel_audit platform:qidian|fanqie + novel_audit censor:true
    → 修订:novel_propose propose → 用户在面板确认 → 生成 v2(旧版永不覆盖)

面板功能一览

功能入口说明
项目列表「🔨 锻炉」tab会话过滤(项目跟会话走);改名/删除/克隆;>8 本出筛选框
认领旧书列表底部0.5.0 之前建的无归属书,一键认领到当前会话
📋 基本信息详情页档案/大纲/角色卡/时间线总览;读章(📖 阅读卡)、保存、导出黄金三章诊断
🎧 章节听书详情页目录 + 语音连播(暂停/继续/停止、读完自动接下一章);每行 📖 阅读 / ▶ 朗读,看听独立
一键润色 / 机械校对章节走旁路引擎,产物是提案,不直接改正文;校对守卫更严(篇幅上限 1.06)
全书体检详情页死人复活/账本矛盾/伏笔超期/章号断档/人物卡缺失,零 token
黄金三章诊断基本信息卡钩子/开场/冲突/灌输四维数字 + 总评,纯词表零 token
批量起草详情页并发生成、串行提交;逐章成败摊开;并发上限 4、默认 1
提案审批详情页查看提案全文 → 应用(生成新版本)/ 丢弃;旧版永不覆盖

20 个工具

工具职责硬约束
novel_projectinit / status / phase(九阶段看板与入场判定) / set_stage / repair / check / promise防重复创建;阶段入场由代码判定;越级记 skipped;repair 索引-磁盘对账
novel_outline全书大纲 / 第N章细纲 / 批准写章门禁的钥匙
novel_character人物卡 + 语言基因卡(voice:句长/逻辑/口头禅/绝不说/小动作/语域,结构化存储)写章单独注入成区块;audit voice:true 核对禁忌词
novel_worldbook世界书条目(add/update/list/remove + import/export)设定只认这里;update 保 id
novel_scene场景契约(save/get/list/delete):本章场景/出场人物/隐藏人物/世界书白名单/禁项隐藏人物档案不进上下文且正文不许出现其名;契约外人物不注入(省 token)
novel_briefing写前上下文包(细纲→承诺书→场景契约→人物卡→语言基因卡→账本→伏笔→世界书→上章结尾→锚段)一致性供给侧;按契约裁剪 cast 与世界书
novel_write_chapter写章落盘门禁→机审→账本→内容门禁(六维)细纲契约指标→版本化;契约指标落盘到章节索引
novel_ledger事实账本(含 note)+ 时点推演status_at 第 n 章快照 / timeline 演化线)+ 伏笔埋/收/改期同章改值拒绝;章号超前拒绝;超期伏笔告警;补录不改历史
novel_noai_scan六维去 AI 味扫描纯本地零费用
novel_audit确定性章节审计 + 契约指标 + continuity 全书一致性 + voice 语言基因核对 + platform 起点/番茄双平台审稿 + censor 敏感自查七类机审证据;平台体检表给出可执行改法
novel_style文笔六维基线(μ±σ 带)+ 氛围光谱 12 轴:build 建基线 / check 对照(含主导氛围漂移)纯本地零费用;只报数不贴标签
novel_propose提案 / 列表修订走提案,用户在面板应用;旧版永不覆盖
novel_import本地书籍导入(preview/import/backfill 门禁回补纯函数切分章节;建书+版本化落盘
novel_export导出整本(md/txt + stats)按版本顺序拼装,写 导出/
novel_diagnose黄金三章四维诊断(钩子/开场/冲突/灌输)确定性数字,机审与模型审分离
novel_polish段落级病灶定位 + 润色提案提交润色也走提案制,永不覆盖旧稿
novel_search长篇检索(build / query / annotate / status):返回章号+摘录+命中比例索引是派生物书/.novel/index.db),删了重跑即得;无 sqlite 自动退化
novel_library书库饲料(import/list/read/analyze/delete):拆对标作品的结构画像——章长曲线/对话密度/段落节奏/章末钩子率/高频意象;compare_book 与自己的书并排给数零 token 全本地;只读饲料,不参与本书一致性判定;delete 只移索引
novel_glossary术语表(add/remove/list)随上下文包注入,防专有名词乱译
novel_clone_project整书克隆为模板阶段重置、提案与熔断计数清空;人物卡/世界书/账本/伏笔/术语表/场景契约/语言基因一并带走

参数刻意只用了标量(字符串/整数/布尔),结构化数据用分隔行表达 (如账本更新 实体|键|值[|备注])——对量化小模型也友好。

数据布局(一本书 = 会话工作区里的一个目录)

我的书/
├─ novel.json            # 机器状态:九阶段/批准/章节索引/cast/提案索引/熔断计数
├─ 大纲/全书大纲.md
├─ 大纲/细纲/第3章.md
├─ 人物/林晚.md           # 人物卡(Markdown,briefing 原文注入)
├─ 设定/世界书.json        # [{id, keywords[], content, always, priority}]
├─ 设定/术语表.json        # [{term, definition}]
├─ 设定/场景契约.json      # 按章的出场/隐藏人物、世界书白名单、禁项
├─ 设定/语言基因.json      # 按人物:句长/逻辑/口头禅/绝不说/小动作/语域
├─ 正文/第3章-雨夜来客-v2.md   # 版本化,永不覆盖
├─ 账本/facts.json        # [{entity, key, value, chapter, note}]
├─ 账本/伏笔.json          # [{id, setup, chapter, plan, payoffChapter}]
└─ .novel/
   ├─ audit.jsonl         # 全动作审计(谁在哪章做了什么、何时被拒)
   ├─ index.db            # 检索索引(派生物:删了重跑 novel_search build 即得)
   └─ proposals/P3-xxx.json

工作区根下还可以有一个与各书目平级书库/——外部小说饲料,多本书共享 (library.json + 原文 txt;不进上下文包、不参与本书一致性判定)。

全部文件都在会话工作区内、走宿主 ctx.fs(受沙箱与审批策略约束),可直接进 Git / Obsidian。 卸载插件不影响任何书稿数据。

配置(cordis.patch.yml)

默认说明
minChapterChars2000单章下限(机审拒绝线,网文连载单章标准)
maxChapterChars4000单章上限(超了提示拆章)
contextBudgetChars6000写前简报上下文包预算
scanTopK8扫描报告每维最多列出的问题数
repetitionWindow10跨章重复检测的滑动窗口(与前 N 章比对)
skipPresetDeployfalse跳过预设部署
engine.channels.*继承当前路由旁路通道(polish/proofread/annotate/draft)按通道覆盖;长文通道(polish/proofread/draft)timeoutMs 默认 600000
engine.channels.*.maxTokens00=不传,继承宿主按模型校准的上限(推荐保持默认);显式设小会被推理模型的思考+整章重写烧穿(报 OUTPUT_TRUNCATED
engine.retries2旁路调用的指数退避重试次数
engine.attachSessionfalse旁路流是否写进会话记录;默认不写(这才是"不占主对话")

engine 整块都可省略——省略即「用当前路由、重试 2 次、不写会话」,最省心的默认。 宿主没有模型服务时插件照常装载,只有真正调用旁路通道时才返回可读错误。

MCP 双通道(宿主外复用)

同一套 novel_* 工具(门禁/账本/审计/基线全在工具层)也可通过 stdio MCP 暴露给 Claude Desktop / Cursor 等任意 MCP 客户端——工作区根取 NOVEL_FORGE_ROOT (缺省为进程 cwd),一本小说 = 工作区里的一个目录:

{
  "mcpServers": {
    "novel-forge": {
      "command": "node",
      "args": ["/path/to/dsh-novel-forge/mcp/server.mjs"],
      "env": { "NOVEL_FORGE_ROOT": "/你的小说工作区" }
    }
  }
}

零依赖实现(原生 JSON-RPC 2.0 over stdio);宿主外的 fs 后端带同样的 containment 与版本守卫语义。

排障 FAQ

症状处理
右侧栏没有「🔨 锻炉」tab重启 DSH web(bundle 进程启动时快照)→ 浏览器硬刷新。console 应有 [novel-forge] client apply v…
面板按钮点了没反应先硬刷新;console 看 [novel-forge] 日志。开发者可跑 npm run preview 的按钮扫射定位
润色/校对报 503 引擎未就绪当前 dsh 进程没有可用的模型服务:确认模型路由已配置、插件是最新构建并已重启生效
润色/校对报 NO_PARENT_AGENT插件会先按「书归属会话」候选自动物化;仍失败时,到拥有这本书的会话里发一条消息(让会话 agent 驻留),再回面板重试
润色报 OUTPUT_TRUNCATED模型输出被上限截断。保持 engine.channels.*.maxTokens 默认 0(继承宿主校准值),不要显式设小
写章被拒「细纲未批准」novel_outline approve。确要跳过用 force(记审计),不建议
写章被拒「第N章熔断中」同章连续驳回 3 次触发。回去改细纲或场景契约,改完计数自动清零
机审说「章末钩子未检出」但明明有章末最后一个字符必须是裸 / / ……——后跟闭引号(" / 」)会漏检
机审说「对话占比 0」正文对话请用中文弯引号 "",直角引号不识别
细纲覆盖率 0% 但场景写了覆盖率按细纲「必写场景」标题词面匹配(启发式),把场景标题措辞对齐细纲条目即可
「一键写章」按钮 501设计如此:写章要走 briefing + 多道落盘门禁,只能在会话里做

开发与测试

npm run setup-dev   # 把 DSH checkout 的宿主 SDK 真包 symlink 进本地 node_modules
npm run build       # src/client/ → lib/client.js(改客户端源码后必须跑;npm test 会自动跑)
npm run audit       # 静态自检:① 调用了但没导入/声明 ② 孤儿 dataset.X 读取(npm test 前置也跑)
npm run preview     # 生成可交互 UI 预览 preview/forge-ui.html(内联真产物 + 宿主真 token,离线可开)
npm test            # node --test 全量用例(纯逻辑单测 + 假 fs 全链路冒烟 + REST 行为测试 + 真校验器输出契约 + headless 行为测试;条数见顶部 tests 徽章)
node scripts/demo.mjs   # 端到端演示:init→细纲→写章→账本→扫描→提案 全流程

开发约定(纯逻辑与 io 分离、output.schema 逐字段一致、peerDependencies、客户端源码/产物分离、 面板入口三步契约等)见 AGENTS.md

已知边界

  • 去 AI 味词库与阈值是启发式,只能抓显性病,不承诺"根治"——结构性指标(节奏方差/信息稀释)是它比纯词库强的地方。
  • novel_audit 只产出确定性证据,「模型审」在会话里进行;旁路引擎只服务内部工序(润色/校对/打标/起草),不改变「审计工具不调模型」这条线。
  • 批量起草并发上限 4(默认 1;书里没有场景契约时强制降为 1);并发只作用于起草,提交始终串行。
  • novel_search词法检索 + LLM 标签增强,不是 embedding 语义检索;索引单文件 sqlite,十万块级超大书未压测;annotate 产生真实 token 成本(默认每次最多 20 块)。
  • 跨章重复检测是滑动窗口(默认前 10 章,可调)——超出窗口的复读抓不到;世界书递归激活限 2 轮。
  • 面板听书用 Web Speech 合成,正文切块防 Chrome 长文本停摆;无语音引擎的环境给可读报错。

License

LICENSE

Plugins associés