본문으로 건너뛰기
S

dsh-novel-craft

shiyan688/dsh-novel-craft

DeepSeek Harness용 소설 집필 워크벤치: 후보 문단에 좋아요나 싫어요를 표시하면 모델이 이를 짧은 선호 프로필로 증류해 이후 초안 작성 호출에 반영하며, 원고는 초안 작성 컨텍스트에 들어가지 않습니다. 챕터 보드, 챕터별 집필 팩, 주석 범위 수정(주석이 달린 문단만 다시 쓰고 나머지는 바이트 단위로 검증), 프로젝트 원장, 로컬 호흡 점검을 추가합니다.

설치

dsh plugin --profile web add github:shiyan688/dsh-novel-craft

README

dsh-novel-craft

English: docs/README.en.md(只放在仓库里,不进 npm 包——否则 npm 页面会显示英文版)

dsh-novel-craft 是一个跑在 DeepSeek Harness(dsh)上的开源 AI 小说写作插件(MIT 协议,npm 一行安装)。它解决的是「怎么让 AI 写出符合你个人文风的小说」——不用反复调提示词,也不用逐段写评语。

目的:让 AI 写出你觉得对味的文字。

方法:你只点赞、点踩,模型自己总结规律。

读候选稿时顺手点一下——好段落 👍、坏段落 👎。然后让模型把这批点选总结成几条能照着做的写法,写进一份档案。下一轮写稿带着这份档案,写完再点、再总结。它总结出来的东西长这样(我自己的档案):

## 已验证偏好(作者喜欢什么)
- 让在场群像先静默再爆响
- 危险降临先写器物异动,再写人的闷哼
## 避免的写法(作者不喜欢什么)
- 不要用比喻堆砌来写人群的恐惧
- 不要在施法后补旁白解释动机

这些不是我写的,是我点出来的。每条后面能点「🔍 证据」,看它当年是从哪几段原文里总结的;不认同的直接删掉。

**档案里只有规律,没有原文。**这是这个方法能成立的前提:原文一轮就几千字,带两轮上下文就满了,更别说一本书——带不动的东西,谈不上"持续"。规律是几百字节(我的是 714 字节),每一轮写稿都带得动;而且模型记住的是"怎么写",不是"这几句长什么样",前者能迁移到新章节,后者只会被抄。所以它能一轮轮跑下去,越用越对味。

可靠性信号:775 条断言 / 7 个测试文件,每个能力都有真数据用例;发版前请三个独立视角复审,四个高危问题先复现再修。详见「这东西靠谱吗」。


适合谁用 / 不适合谁用

适合:

  • 已经在用 DeepSeek Harness(dsh),想让它帮着写小说 / 网文
  • 长篇连载作者,需要十几万字不崩的设定与伏笔管理
  • 已经有明显个人文风,但说不清自己到底要什么
  • 刚开始写、还没形成固定风格 —— 点一轮,同时也是给自己标一次「我喜欢什么」
  • 愿意每轮花几分钟点一遍段落,换长期越用越准

不适合:

  • 没用过 dsh,也不打算装(本插件依赖 dsh)
  • 想让 AI 一键自动生成整本小说
  • 想要零投入全自动的

前置条件:Node 22 + DeepSeek Harness。dsh ≥ 0.1.5 在 Node 20 下起 dsh web 会静默退出(不打印、不监听端口),看起来特别像"插件不兼容",其实是环境问题。


它和别的做法有什么不一样

要让 AI 写出你的味道,常见有四条路。区别不在于谁更聪明,在于你要付出什么:

做法你要付出什么AI 学到的是什么能跑几轮
自己写提示词反复调,换个对话还得重来这一轮的指令一次
逐段写评语每轮读 8–10 篇、每篇两三千字,还得说清"哪里好"一些形容词一两轮就退化
上传风格样本 / 微调模型准备语料、等训练、结果不可控你的句子长什么样看语料量
dsh-novel-craft读的时候顺手点一下你的规律(怎么写)一轮轮持续

为什么要做这个

因为原来的两条路都太累。

自己写提示词。"别写那么用力"它听不懂,你得反复调;调好这一次,下次开个新对话又得重来。

逐段给它写评语。 一轮摊开八到十篇候选,每篇两三千字,读完还要说"哪里好"——说不出来,只会觉得"这篇有感觉"。勉强写下的那些"更细腻""节奏不错""有点刻意",翻译回写作等于没说,第三轮它还是同一个毛病,只是换了个说法。

说到底:**判断很好下,表达很难写。**点一下是一秒钟的事;让你把"我想要什么"讲清楚,你写得动十次,写不动一百次。所以别让你表达,让模型总结。


安装:一行命令

dsh plugin --profile web add dsh-novel-craft

装完重启一次 dsh(宿主半区在启动时装载)。侧栏底部会出现「🎴 抽卡工作台」。

不想装也能先看:把仓库里的 docs/preview.html 用浏览器打开,那是真实组件渲染出来的界面快照,七个页签都能点。


怎么用

一、点它一轮,它就学到一点

选一个放着候选稿的目录(选择器会推荐、记最近、也能浏览,不用记路径),然后读,按键盘:

j/k 换段 · G 标好 · B 标坏 · 空格 取消 · n/p 换篇

读完点「⚗️ 提炼规律」。它把这一批点选总结成条目,你逐条勾选,采纳的才进档案。不勾的不会进去——所以你永远能拦下它总结错的部分。

就这样,一轮一次。你不需要写一句话。

二、写新的一章(候选稿也让模型写)

「🗂 章节」页右上角有个「✍️ 开新章」,四步。

第一步,说清这一章要干什么。 章号、本章设定(目标、必须发生、禁止发生),要几个方向(默认 10 个)。

第二步,挑方向。让它先给一批"场景决策"方向——注意不是换十种形容词,是换怎么讲这个故事:

A 保守精修:以最小改动保留现有骨架,只在细节处收紧
B 配角识货:让同行配角先认出货色,主角的算计藏在他的沉默里
C 双层信息差:让掌柜也在算计,读者比主角先看出一层

方向不顺眼的改名、改说明、取消勾选,剩下的才写。这一步很重要:让它"写十个版本",你只会拿到十篇形容词不同、决策相同的稿子,挑等于没挑。

第三步,一篇篇写。 每写完一篇立刻落盘(第13章-A-保守精修.txt,沿用你的命名习惯)。看得见"第 3/10 篇",能中途停,单篇失败只影响那一篇。写完点「🎴 去抽卡选段」,它会顺手把当前卡池切成刚写出来的那个目录——接着就是回到第一步:读、点赞、点踩。

第四步,合并定稿。 你标了赞的段落按稿件顺序列出来,带上你写的那句"为什么用这一段",成为一张取用段落表。跨篇接不上的地方,它写成 〔此处需过渡〕 标记——不替你补写。那些位置正是"文不文、白不白"的来源,得你自己过。写入正文时原稿自动备份。

三、改稿:它只能改你标过的段落

读到哪儿不对,点那一段按 A 留一条批注(AI 腔 / 啰嗦 / 情绪直给 / 平 / 人物失真 / 逻辑账目 / 信息差 / 其他,外加一句话——注意这里可以写字,因为一处一处指点比逐段写总评省力得多,而且你是在说"这里不对",不是在解释"我要什么")。

点「按批注微调」,它只改被批注的那几段。两道防线:

  1. 交给模型时只有那几段,它碰不到别的段落;
  2. 改完逐字核对,没批注的段落差一个字、或者段落数变了,直接拒绝写回。

采纳前给你逐段前后对照,采纳时原稿先备份。以前那种"点三处、它重写一整章、语感全变了"的事,现在被堵住了。

四、看全局:它在本地算,不喂正文给模型

写到十几万字,"哪里塌了"靠记忆算不出来。「📈 情节」页给你:

  • 张力曲线 —— 可以自己点 1–5 标(实线),没标的才用正文估(虚线,每个点都写了估计依据)
  • 大纲偏移 —— 这一章该发生的事,在剧情总结里对上了吗
  • 伏笔欠账 —— 埋了几条、收了几条、哪条欠太久了
  • 字数失衡 / 事件密度 / 评分下滑

还有「🧭 全书」页:立项 → 设定 → 人物 → 大纲 → 逐章正文 → 修订 → 完本,每步该有什么产物、缺了哪样,一目了然,也能一键起草。


那条不能破的线:进写稿上下文的只有规律

这条线是上面"持续学习"的地基,不是洁癖:

  • 写稿、写候选、要方向的时候,模型只拿到一个写作包,包里除了上一章结尾(≤900 字,接续必须用,包内注明)之外没有任何正文。
  • 你标过的段落、证据摘录、批注,全都留在本地,你随时能回查——但写稿时不读。
  • 所以上下文里只有几百字节的规律 + 该有的前情与设定。这就是它能一轮轮带着你的口味跑下去的原因。

但我不想把话说大。有三处你亲手点下的按钮会触发一次辅助调用、带上原文,各有硬上限:

按钮带进去的上限
提炼规律你点过的段落≤40 段 × 240 字,总 ≤20KB
补齐来源证据摘录里的引文每条 160 字
按批注微调被批注的段落 + 前后段各 80 字每段 800 字,单次 ≤20 条

除此之外没有任何路径把正文送进模型。这条我以前写的是"原文不进模型上下文",属于说大了——"补来源"就会带引文,文案里没写。现在照实写,并把上限都列出来,因为承诺应该能被代码逐行验证。

写作包本身是写稿会话唯一该读的文件,十节:

① 本章任务(你写的)② 作者偏好档案(只有规律)③ 上一章结尾 ④ 前情提要(来自各章剧情总结,不重读正文) ⑤ 本章人物 ⑥ 道具与增益台账 ⑦ 情节节点 ⑧ 未兑现伏笔 ⑨ 禁 AI 腔清单 ⑩ 写作要求

每节都有上限,整包默认 9000 字预算。超了就按"先削补得回来的、后削没它写不了的"顺序削,削了谁、削了多少都写在预算表里。包尾固定列一段「不要读进上下文的东西」,把证据摘录、标注文件、批注、全书合并稿点名列为禁区。


它不做什么

诚实边界,先说清楚:

  • 不替你写正文。 它写候选和初稿,选和改是你的——这不是谦虚,是设计前提。
  • 不做"AI 通读全书"。 正文不进模型是上面那条线,所以情节体检是本地字符串统计,识别不了"语义上的重复"。
  • 不保证平台过审,也没有封面、排版、发布、数据抓取。
  • 不替你决定节奏。 张力曲线可以手工标,估计值只是虚线参考。

这东西靠谱吗

775 条断言 / 7 个测试文件,每个能力都有真数据用例(不需要浏览器、不需要起 dsh)。测的是"作者会怎么用它":微调用例会断言"只有被批注的那一段变了,其余段落逐字相同",开新章用例会验"写入正文前先备份原稿"。

发版前我请了三个独立视角,把宿主半区、浏览器半区、还有上面那句承诺各查了一遍。四个高危都先复现再修,复现脚本固化成了回归测试:

  • 分片请求会把中文正文里的字悄悄变成替换符(实测 4 万字每份 2 个坏字)
  • 按住 G 连标时,标注会互相覆盖(实测并发标 5 段只活下来 1 段)
  • 手写的偏好档案会被换成空骨架,规律全丢
  • 保存路径没校验,../../… 能写到作品目录外面

前两个都不报错,只是悄悄丢东西——这类最该怕,所以现在每个都有测试守着。

更多细节在 DEVELOPMENT.md(改这个仓库前先读)和 Commit 记录里。


常见问题

dsh-novel-craft 是什么? 一个跑在 DeepSeek Harness(dsh)上的开源 AI 小说写作插件,MIT 协议。核心能力是「偏好校准」:你读候选稿时点 👍/👎,模型把你的点选提炼成几条写作规律,下一轮写稿自动带上,越用越接近你的口味。

我需要先装什么才能用? Node 22 + DeepSeek Harness。装完插件必须重启一次 dsh(宿主半区在启动时装载)。dsh ≥ 0.1.5 用 Node 20 起 dsh web 会静默退出,看起来很像插件不兼容,其实是环境问题——兼容脚本会自己找 Node 22。

要写提示词吗? 不用。整个流程里你唯一要做的是点赞和点踩。这是它和"自己调提示词"最大的区别——判断很好下,表达很难写。

它记住的是我的文风吗?怎么做到的? 记住的是"规律",不是"句子"。偏好档案里只有规律,没有原文(作者自己那份 714 字节)。因为原文一轮就几千字,带两轮上下文就满了;规律几百字节,每一轮都带得动。而且模型学到的是"怎么写",能迁移到新章节——学到句子只会被抄。

写稿时它会把我的正文送给模型吗? 不会。写稿、写候选、要方向时,模型只拿到一个"写作包",除了上一章结尾(≤900 字)之外没有任何正文。三个例外全是你亲手点下的按钮:提炼规律(≤40 段 × 240 字,总 ≤20KB)、补齐来源(每条 160 字)、按批注微调(每段 800 字 + 前后段各 80 字)。这三个上限写在代码里,可以逐行验证。

和 Sudowrite、NovelAI、LAIKA 这类工具有什么区别? 那类工具的思路通常是"让 AI 模仿你的文本"——上传风格样本,或微调一个模型。dsh-novel-craft 的思路是"让 AI 学会你的判断"——你只点赞点踩,模型从中提炼出规律。前者学的是句子长什么样,后者学的是怎么写;前者要你准备语料,后者只要你点几下。

中文网文能写吗?英文呢? 为中文创作场景设计——界面是中文,禁 AI 腔清单针对中文文风。仓库提供英文 README,但清单本身是中文语境的。

写到几十万字会不会崩? 不会因为上下文爆炸而崩。正文不进模型是硬约束,进上下文的只有规律 + 前情提要(来自各章剧情总结,不重读正文)+ 本章设定,整包默认 9000 字预算,超了按明确顺序削减并记账。诚实说一个限制:情节体检是本地字符串统计,识别不了语义层面的重复。

免费吗? 插件本身 MIT 开源、免费。调用模型会消耗你 dsh 自己的额度——默认取 dsh 当前默认模型,想省钱可在设置里填 dsh-novel-craft 的 distillProvider / distillModel。

不想装插件能先看效果吗? 能。用浏览器打开仓库里的 docs/preview.html,那是真实组件渲染的界面快照,七个页签都能点。

我的数据存在哪? 全在本地,随作品走。标注存在作品自己的 .dsh-novel-craft/ 目录,不写全局配置。

它不能做什么? 不替你写正文;不做"AI 通读全书";不保证平台过审;没有封面、排版、发布、数据抓取;不替你决定节奏。

项目成熟度如何? 2026 年 9 月开源,还很新。可靠性信号:775 条断言 / 7 个测试文件;发版前三个独立视角复审;四个高危问题先复现再修,并固化成回归测试。


兼容性

dsh 是一组各自独立发版的包——同一个公开版本里,CLI 可能是 0.1.5-rc.2 而客户端运行时还是 0.1.1-rc.2。所以本插件不锁版本号,peer 依赖声明为 *,运行时从你的 profile 解析。

实测跑通的:0.1.0-rc.7(作者日常)、0.1.2-rc.1、0.1.5-rc.1(latest)、0.1.5-rc.2(next)、0.1.6-alpha.1。

一条命令自证:

node scripts/check-dsh-compat.mjs next    # 或 latest / alpha / 具体版本号

它会在临时目录里真装一份那个版本的 dsh、按 profile 的方式挂上插件、用独立 DSH_HOME 起服务,断言宿主路由可用、客户端半区进了启动清单、半区能正确下发。跑完自动清理,不影响你正在用的实例。

dsh ≥ 0.1.5 需要 Node 22。用 Node 20 起 dsh web 会静默退出(不打印、不监听端口),看起来特别像"插件不兼容"。兼容脚本会自己找 Node 22,找不到就把启动失败判成环境问题、跳过,而不是报兼容性失败。

两个写给插件作者的坑:行的 apply 可能早于服务挂载(同步 apply 里 ctx.get('webServer') 会是 undefined,本插件因此改成 ctx.inject 等就绪 + 超时兜底);客户端 bundle 的下发地址变了(新版是组合脚本 /plugins/??a/client.js,b/client.js&rev=…)。


出处与致谢

  • 禁 AI 腔六维度清单(skills/novel-writing)改编自 dsh-novel-solo(MIT, Copyright (c) 2026 Tkingxiao)
  • 运行平台 DeepSeek Harness(MIT):用它公开的插槽、客户端服务与 LLM 服务,未复制其源码;辅助模型调用的写法参考了平台内 dsh-session-title-llm 的公开实现
  • **"推理档位要关掉"**这条经验来自官方 Discussion #6857——我们在真机上踩过同一个坑:模型想了一堆、正文一个字都没留下
  • 包布局约定参考社区集合仓库 linxiecoder/deepseek-harness-plugins,让 dsh plugin add 直接可用

完整条目与许可证原文见 THIRD_PARTY_NOTICES.md。


给想深入的人:文件落点、接口、目录结构(点开)

文件都落在哪

文件是什么进上下文吗
写作包.md(在轮次目录里,没有就退到 .dsh-novel-craft/写作包/)写稿会话唯一该读的文件✅ 就该它进
.dsh-novel-craft/作者偏好档案.md只有规律✅
.dsh-novel-craft/证据摘录.md你标过的原文❌ 只有点「提炼」「补来源」时进那一次调用
.dsh-novel-craft/marks.json机器可读的好/坏❌ 同上
.dsh-novel-craft/批注/第N章.json你的改稿批注❌ 只有点「微调」时取被批注的那几段
.dsh-novel-craft/章节设定/第N章.md本章目标 / 禁止发生 / 出场人物✅ 作为写作包第 ① 节
.dsh-novel-craft/规则来源.json规律 → 证据的对应表❌ 只给界面反查
.dsh-novel-craft/微调/前后对照、待采纳改写、原稿备份❌ 给人看的
.dsh-novel-craft/取用理由.json好段的"为什么用这一段"❌
.dsh-novel-craft/workspace.json阶段进度、手工张力、章节状态❌
候选稿/、定稿候选/、筛选与合并记录.md开新章写出来的候选、合并稿、取用记录❌(只有写候选时喂写作包)

标注随作品走(存在作品自己的 .dsh-novel-craft/),不写全局配置。候选目录存在 dsh settings 的 dsh-novel-craft 命名空间里。

规律是怎么来的

作者点好/坏 → 落 marks.json → 「更新证据摘录」把原文收进 证据摘录.md → 「提炼规律」把待提炼的原文(≤40 段 × 240 字、总 ≤20KB)交给一次辅助模型调用,系统提示强制它只输出 喜欢: / 避免: 两节、禁止抄原文 → 结果不直接进档案,列出来让你逐条勾选,采纳的才写进规律区,提炼水位推到这批标注(下次不再送一遍)。

  • 用哪条模型路由:默认取 dsh 当前的默认模型;想省钱就在设置里填 dsh-novel-craft 的 distillProvider / distillModel
  • 不想让任何模型碰原文?跳过「提炼」这一步,把 证据摘录.md 交给你的 agent 也行——反正进档案的只有规律
  • 自动块(auto:begin/auto:end 之间)每次重写,那是账目;规律区是你的,永远不动
  • 你手写的内容会被完整渲染,不会被隐藏或覆盖

「抽卡」这条线里一些刻意的选择

  • 阅读优先,不是表格:候选稿按连续正文排版(字号 15.5 / 行高 1.95),标注状态用左侧 3px 色条 + 淡底色。大部分段落本来就不用标,所以标记按钮只在光标所在段或鼠标悬停的那段浮出
  • 手不用离开键盘:G/B 标完自动前进;键盘标记是幂等的(不会把刚标好的又切掉);在输入框里打字时快捷键自动让位
  • 一眼知道读到哪:底部写「第 7 / 28 段」+ 快捷键;候选条给的是短标签 + 字数 + 本篇标注数,同批目录共有的前缀(第9章-)会被剥掉,所以是 A · 1.2k字 · 标 3
  • 规律可以一条一条否决:每条后面有个 ✕,点了就删(自动块里的账目行不给删)
  • 第一次打开给一句三段式引导,标过任何一段之后就不再出现

宿主半区 HTTP API(只服务 127.0.0.1)

全部在 /novel-craft/api/ 下,enabled: false 时整体 503。共 23 条,挑几条主要的:

方法路径作用
GETstate候选稿段落 + 标注 + 档案 + 证据摘录情况 + 待提炼数 + 模型路由
POSTmarks / evidence / distill / rules / profile抽卡这条主线的写入
GETdiscover推荐目录(含篇数,5 秒短缓存)
GET/POSTproject认出 / 确认作品根(detect / set / clear)
GETworkspace章节看板(不带正文)
POSTchapter / setup单章详情、本章设定
POSTannotation批注加/改/删(同段同类型重复提交=更新)
POSTpack生成写作包(save:false 只预览)
POSTrevise / revise-apply按批注生成微调稿 / 采纳写回(先备份、核对不过就拒)
POSTtension / check手工标张力 / 账目+情节体检
POSTstage阶段状态 / 起草 / 写入产物
POSTnewchapter开新章:status / directions / draft / merge / finalize
GET/POSTrule-evidence规律来源表;action:'backfill' 补齐老档案

改代码后怎么生效

  • 浏览器半区:dsh 按请求现读文件下发(no-cache),刷新页面即生效
  • 宿主半区:dsh 启动时装载,必须重启 dsh

测试

npm install
npm test        # 7 个文件 775 条断言

跑单个:node test/workbench.test.mjs(0.2 的能力)、node test/ledger.test.mjs、node test/plot.test.mjs、node test/pipeline.test.mjs。

测试不依赖任何本机路径:作品目录由 test/fixtures.mjs 在临时目录里造,写操作全在临时目录,跑完就删。刚 clone 下来没装依赖时会打印「跳过」,不会甩一堆看不懂的红。

目录结构

dsh-novel-craft-plugin/
├── package.json         # dsh.bundle.patch + dsh.client.platform=web
├── cordis.patch.yml     # 安装时把插件行插进 profile 组合
├── lib/index.js         # 宿主半区:settings + 23 条回环路由 + 模型调用编排
├── lib/client.js        # 浏览器半区:工作台本体(七个页签,无 JSX)
├── lib/core/            # 十个模块,彼此只共享 text.js
│   ├── text.js          #   分段/字数/安全读写/章号解析 + 写队列与原子写
│   ├── workspace.js     #   作品根识别、章节看板、人物卡、轮次目录
│   ├── pack.js          #   写作包 + 上下文预算
│   ├── annotate.js      #   批注读写 + 微调拼装与逐字核对
│   ├── ledger.js        #   台账解析 + 账目体检
│   ├── plot.js          #   张力曲线 + 伏笔欠账 + 情节诊断
│   ├── pipeline.js      #   七阶段定义、产物检查、门禁、起草提示词
│   ├── provenance.js    #   规律 → 证据
│   ├── draft.js         #   开新章:方向、候选、合并、定稿归一化
│   └── llm.js           #   一次性模型调用(六个调用点共用)
├── test/                # 7 个测试文件
├── DEVELOPMENT.md       # 改这个仓库前先读(不进 npm 包)
└── LICENSE, THIRD_PARTY_NOTICES.md

관련 플러그인