佬友们好,今天我分享一个自己做的开源项目:NovelWriter —— 一个 AI辅助小说创作/续写工具。
NovWr支持 curl -fsSL 一键部署,BYOK,你的内容完全属于你。
为什么又造了个轮子
市面上的ai工具这么多,为什么我又重做了一个?我的项目有什么区别?
我看的工具,它们大多有着令人眼花缭乱的功能:大纲生成、角色卡、世界观模板、情节分析、风格迁移、一键拆书、多轮对话式创作…… 每个功能单独看都有道理,但堆在一起的结果是——我们花了大量时间在理解这些功能和学习使用它们上,而不是花在打磨写作作品上。
它们可能适合某些群体,但我觉得它们并不适合我
我自己写长篇的时候,真正的卡点不是写不出文章。自己写不出来,还不能靠大模型吗?几秒钟就能吐出几百字。真正的卡点是:这段写出来了,我到底要不要?它有没有偏离我的世界观?角色说的话是不是符合人设?写出来的风格是否一致?
而我认为要不要这个判断,本质上是审美判断——主观的、没法自动化的。因此工具唯一能做的,是把每次判断的成本压到足够低:生成足够快、足够便宜,你才敢毫不犹豫地说"不要,再来"。
所以 ,NovWr 的设计原则很简单:让你能快速生成、快速判断、快速丢弃,不断迭代直到满意。 其他一切功能,如果不是在加速这个循环,就不应该存在。
工作原理(可跳过)
核心思路很简单,一句话说就是:让代码和 LLM 各干各的事。
大多数 AI 写作工具喜欢让 LLM 做所有事情——先让 AI 分析剧情,再让 AI 规划走向,然后让 AI 评审质量,最后才让 AI 生成文本。一个续写调用 4-5 次大模型,又慢又贵,而且中间每一步都可能出错。
NovWr 反过来:
-
代码负责"理解":用 Aho-Corasick 算法从你的章节文本中检测相关实体,通过滑动窗口索引定位关联段落。不用向量数据库,不用 embedding,纯算法,快且确定。
-
LLM 只负责续写:每次续写只调用一次大模型。所有的世界观、角色设定、关系网络已经被代码提取好了,作为上下文直接注入 prompt。
-
用户决定取舍:AI 的输出永远是草稿。要还是不要,你说了算。不要就丢掉,再来一次,。
-
可闭环的迭代:在续写结果生成界面有注入摘要,你可以根据需要进行修改。比如说,AI 续写了一段文本,但你觉得李四这个角色说的话不太对人设。你可以直接在界面上修改李四的摘要(比如"李四:一个内向但心地善良的高中生,喜欢画画,不擅长社交"),然后再续写一次。因为代码已经把李四的设定提取好了,这次续写的时候就会用你修改后的设定来生成文本。
因为单次续写只有一次 LLM 调用,即能用 Gemini 3 Flash 之类的便宜又好用的模型,也可以用claude 4.6 opus等sota大模型。
NovWr背后的核心——世界模型
这是 NovWr 和其他工具最大的区别。AI 生成质量的上限,不取决于模型有多强,而取决于你喂给它的上下文有多精准。 大多数工具的思路是给 AI 更多信息——把整本书的设定、所有角色、全部章节一股脑丢进去。但信息不等于上下文。上下文是此刻此处相关的信息。一个 200 万字的小说里,续写当前这一段真正需要的可能只有三个角色的设定和两段前文。工具的职责是帮你做这个筛选——而不是把筛选也扔给 LLM。
在 AI 时代的创作,60% 的时间要花在维护上下文上,29% 的时间花在决定方向上,点续写生成长文却只占 1%——和传统大部分时间花在写作上完全相反。
世界模型的设计来自一个我高中学物理竞赛时印象最深的理念:普适的是美的。 当你需要处理太多特殊情况、写太多不适用声明,往往说明你还没找到正确的抽象。
基于这个理念,我砍掉了"角色卡"、"世界观模板"这些固定分类,不再区分角色、地点、概念。取而代之的是三个通用的基本定义:
-
体系:任何结构化的知识集合——势力格局、魔法体系、组织架构、时间线,随你定义
-
实体:世界中的任何具体事物——角色、地点、物品、概念,带有属性和别名
-
关系:实体之间的联系——人物关系、从属关系、因果关系
你还可以为体系添加规则约束(风格约束、世界观约束、称呼约束……),这些约束会在续写时自动注入。
世界模型的上限决定了生成质量的上限。 说实话,我作为这个想法的提出者,觉得自己远远没有发挥出它的上限。
减少摩擦感的方法
觉得世界模型从零搭建太麻烦?NovWr有两种可以让你尽可能快速起步的方式:如果你手上有写好的设定集,可以直接让 AI 帮你总结成结构化设定;如果你的小说比较热门,可以用"从章节提取实体关系"功能——代码通过共现分析找出高频实体对,LLM 基于自身的世界知识判断它们之间的关系。
续写的时候,NovWr 会自动扫描最近的章节文本和你的续写指令,找出其中提到了哪些已有的体系和实体,然后精准注入相关设定。核心设定始终注入,按需引用的设定和关系只在被提到时才加入。不是把整个世界观一股脑丢给 LLM(那会浪费 token 还可能干扰生成),而是精准匹配:这一章提到了张三和李四,那就只注入张三和李四的设定,以及他们之间的关系。
就算你的世界观有几百个角色、几十个势力,续写时 LLM 看到的永远是一份干净的、只包含当前相关信息的上下文。
一键部署
curl -fsSL https://raw.githubusercontent.com/Hurricane0698/novelwriter/master/install.sh | bash
安装脚本会自动:
- 安装
uv(若本机尚未安装) - 安装
novwrCLI - 初始化默认目录
~/.novwr - 拉取并启动官方 Docker 镜像
常用命令:
novwr init
novwr run
novwr doctor
novwr upgrade
novwr uninstall
默认安装目录为 ~/.novwr
数据存在 Docker volume 里,SQLite 数据库,升级版本的时候自动跑 migration,不会丢数据。
项目使用 AGPL v3.0 协议开源。选 AGPL 而不是 MIT:如果你拿 NovWr 的代码做了改进,希望这些改进也能回到开源社区里。
目前项目还在非常早期,很多地方还比较粗糙。如果你对 AI创作、AI 辅助写作感兴趣,欢迎试用并提反馈。不管是"这个地方不好用"还是"这个功能没必要"还是这里有bug,对我都很有价值。
佬友们有技术,架构上的选择(为什么不用 RAG、为什么不用向量数据库、为啥不设置ai对话框)都可以聊。
项目背后的一些思考(可跳过)
我是一个刚进入大学的 freshman。这个项目最初的开端,只是因为一个不起眼的愤怒:我喜欢的网络小说断更了。那种感觉大概每个追更人都懂——你在一个世界里住了几个月,突然发现大门焊死了,故事再也不会往前走…我不愿意,所以我想,我能不能自己把这扇门撬开?
于是我借助 AI 编程工具,在期末考前的几个星期加上整个假期,边构思边实现。不断重构,不断推翻自己,最终才有了现在这个样子。
回头看,最难的不是写代码,而是一些很基本的问题——我到底在做什么,给谁做,为什么要做。这些不是一开始就想好的,而是在做的过程中不断拷问自己,才渐渐想明白的。
我想做一个人人都能续写自己喜欢的小说、创作自己想要的故事的工具。
所以它必须容易上手,必须尽可能好理解。但要让生成结果好,有些复杂度又不能减少——那就由我这边付出努力,把复杂度消化掉,而不是把它扔给用户。
下面把一些做这个项目时的关键转折写下来,也算给自己理理思路。
一个被砍掉的 pipeline
NovWr 最早的版本长得完全不像现在这样。
那时候我设计了一个八节点的 pipeline——分析师、规划师、编辑、提取器……看起来很专业。每个节点都是一次 LLM 调用,从剧情分析到质量评审全部自动化。我还挺得意的,觉得这才是"正经的 AI 写作系统"。
然后我自己用了几次。如果 AI 写作是这样,那我情愿不要。
续写一章要跑完八个节点,等好几分钟。过程中我不断打断自己去做其他事情——刷短视频、回消息——完全没法进入心流状态。如果结果不满意,又要再等一轮。大部分时间不是在"写",而是在"等 AI 想明白"。
更烦人的是,当结果不对的时候,我根本不知道是哪个节点出了问题。是分析师误判了角色动机?还是规划师给了个离谱的方向?还是编辑画蛇添足改了不该改的?所有环节都藏在黑箱里,我只能看到最终输出,然后猜。
后来我意识到,这个错误的根源其实很简单:在 AI 时代,所有人包括我自己,都像是拿着一把名叫 AI 的锤子,看什么都像钉子,都想敲一敲。剧情分析?让 AI 敲。质量评审?让 AI 敲。情节规划?让 AI 敲。但写作过程中有些环节根本不是钉子——实体检测是确定性的字符串匹配问题,上下文筛选是集合运算问题,这些用代码做又快又准,根本不需要 AI。
而那些真正需要 AI 的环节——生成自然语言——其实只需要一次调用。我花了这么多精力让 AI "理解"我的故事,但最终做审美判断、作出决策的还是我。 我需要的不是一个替我思考的系统,而是一个让我能更快试错、更快迭代的系统。
想明白这件事的那天晚上,我把八个节点砍成了一个。用代码做上下文提取,LLM 只管写。续写时间从分钟变成秒。试错成本降了一个数量级。
砍完之后有一段时间很焦虑迷茫——大家都在往 pipeline 里加节点,我反而在拆?万一用户就是想要那些功能呢?但自己用了一阵子之后,焦虑慢慢消了。因为实际的体验确实好了很多:不用等了,不满意就再来一次,三五秒就有新结果,试几个版本选一个最好的,哪个地方有问题直接跳到相应界面修改。整个过程是流畅的。
这大概是我做这个项目最重要的一课:好的工具不一定是功能最多的,而是让你最快进入状态的。 你打开它,知道该干什么,干完就走,然后去做真正重要的事——生成,品味并修改你的故事。
做这个项目我想明白的几件事
回头看这三个月的开发过程,有些想法是写代码的时候逐渐结晶出来的,写在这里也算给自己理个思路。
能用代码解决的问题,不要交给概率。 Aho-Corasick 匹配实体、集合运算筛选上下文——这些事确定性算法做得又快又准。LLM 的强项是生成自然语言,不是做检索和逻辑判断。把确定性的事交给概率模型,就是用最贵的工具做最简单的活。
用户的注意力是最稀缺的资源,比 token 贵得多。 八节点 pipeline 浪费的不只是 API 费用,而是我等待时被打断的专注力。每一次"等 AI 想明白"都是一次心流中断。工具设计的第一优先级不是"能做什么",而是"用户的注意力花在哪"。
让想法变得廉价,决策才会变得大胆。 当续写成本是几分钟加几毛钱的时候,你会下意识地想"凑合用吧"。当成本是三秒加零点几分钱的时候,你会毫不犹豫地说"不够好,再来"。降低试错成本不是优化,是改变行为模式。
正确的抽象应该让特殊情况消失,而不是一个个处理它们。 “角色卡”、“世界观模板”、“势力图”——每多一个分类,就多一套 CRUD、多一种例外。当我把它们统一成"实体 + 关系 + 体系"之后,代码量反而少了,但表达力并没有降低。如果你在不断写 if type == 'character' 这样的分支,说明还没找到对的抽象。
关于作品的归属感
用 AI 写东西时间长了,会有一种微妙的不适感:你给了一句续写指令,AI 吐出三千字,读着还挺通顺的,你就直接采纳了。再来一次,又采纳了。几章之后你突然发现,故事的走向、角色的性格发展、甚至一些关键的转折点,都不是你主动选择的——是你懒得改,AI 替你决定的。故事是写完了,但它还是你的故事吗?
我不确定别人有没有这种感受,但它确实影响了 NovWr 的设计方向。我希望用这个工具写东西的人,始终知道自己在做什么:世界观是我搭的,方向是我定的,提示词是我好好打磨的,AI 写出来的草稿我看过了,这段留下那段扔掉,是我的判断。
有时候我会想一个可能不太恰当的比喻:好的写作工具应该像乐器,不像自动演奏机。自动演奏机能放出完美的曲子,但那不是你的音乐,你听完后只剩空虚。乐器有门槛,得练,但你演奏出来的每个音符都是你自己的——包括那些弹错的。
AI 没有情感,无法体验文字中的温度,这只能交给人来判断。你不可能既不说出自己想要什么,也不做该做的把控,却期待得到一个好的结果。
为什么选择开源
说实话,有很多高大上的理由,但是对我来说,最直接的原因是:假期结束了,我一个人做不完这个项目,可能也没有多少时间去维护了。假期里我几乎每天写到凌晨三四点,关掉电脑的时候常常想:如果只有我一个人用这个东西,那它的价值就被锁在我这个大一新生有限的认知里了。
接下来还有不少值得做的方向——基于代码的后检查、AI 建议、基于作品库的搜索(让 AI 从碎片化的知识中拼出世界的全貌,而不是一股脑把上下文喂给它),为此定义mcp。这些想法有一部分是从 Codex 的设计得到的灵感:搜索最小相关集,而不是力大砖飞地总结。
另一个原因是,我觉得 AI 辅助写作这个方向,目前没有人找到真正对的路。市面上的工具大多走同一条路线——更多功能、更多 AI 介入、更多自动化。我走了一条不太一样的路,可能对,也可能不对。
但如果把它开源出来,也许有人能在这个基础上,找到比我更好的答案。一个小屁孩能想到的事情总是有限的。
如果你读到了这里,谢谢你的耐心。目前这个项目就我一个人在做,如果你对这些想法有共鸣——或者觉得我哪里想错了——都欢迎来聊。不管是提 issue、贡献代码、还是纯粹讨论 AI 写作的可能性,对我来说都很有价值。
可能 NovWr 不是最终答案,但至少,我和它走了一条不太一样的路。
致谢
这个项目能做出来,离不开社区里很多人的帮助。一个大学生靠自己是烧不起大模型 API 的,感谢 Linux.do 社区的佬友们,列一些名字,列不全还请海涵:
-
感谢Wong 佬的公益站 / Any Router 公益——你们在项目初期和模型过渡期真的帮到我很多。
-
感谢xychatai——提供的 Codex 激活码和稳定中转,没有你们这个项目可能根本做不出来
-
感谢xiaviercode 中转站——提供的无限额度让我敢放手做大规模重构
-
感谢Trellis 开发团队——至今仍是我的开发主力框架,提供的工程化思路价值无法估量
-
最后,感谢始皇和 Linux.do 社区——能遇见这样热心的社区是我的荣幸




