Article
炼云小说工厂 v0.1:我想把 AI 写作做成一个生产系统
记录炼云小说工厂 v0.1 的开源过程,以及我对 AI 长篇写作、agent 工作流和可观察生产系统的一些想法。
最近把之前折腾的一个网文创作平台整理了一下,改名叫 炼云小说工厂,然后开源了。
项目地址是:https://github.com/larry-xue/lianyun-novel-factory
这个项目现在还很早期,说 v0.1 都有点勉强,但我还是想先把它放出来。原因也很简单,我最近一直在想一个问题:如果 AI 真的要参与长篇内容创作,它到底应该是一个更强的聊天框,还是应该是一个可以被观察、被调度、被修改的生产系统?
我现在更倾向于后者。
所以炼云并不是一个“输入一句话,然后生成一本书”的工具。它更像一个工作台,里面有立项、agent、prompt、活文档、伏笔、章节、批量任务、运行记录。听上去有点重,但这也是我想做它的原因。长篇小说不是一次 prompt 就能解决的问题,它本质上是一个持续维护状态的过程。
起因
之前我也试过很多很直接的 AI 写作方式,比如写一个很长的 prompt,把题材、主角、爽点、节奏、字数都塞进去,然后让模型生成大纲或者章节。
短内容这样其实还可以,写个小故事、写个广告文案、写一章试读,有时候效果还不错。但是一旦想写长篇,问题就开始变得很明显。
角色会成长,关系会变化,世界观规则不能前后打架,伏笔不能埋了就忘,大纲也不可能从第一章开始就一成不变。更麻烦的是,模型每次都像是重新开始工作,哪怕你给它塞了很多上下文,它也不一定真的理解当前这本书写到哪里了,哪些东西已经成为事实,哪些只是草稿,哪些应该被废弃。
这时候继续加长 prompt 只能缓解一部分问题,不能从根上解决问题。上下文越长,调用越贵,模型也越容易抓不住重点。更重要的是,人其实也看不清这个系统为什么这样写。
所以后来我的想法就变成了:不要把 AI 写作理解成“一次生成”,而是把它理解成一个流水线。每个 agent 负责一小段工作,中间产物全部落库,人可以随时打开看、手动改,系统也能知道后续应该基于哪个版本继续。
我不太相信一键成书
说实话,我现在不太相信“一键生成一本长篇小说”这个产品形态。
不是因为模型写不了字。恰恰相反,现在模型很会写字,很多时候它甚至太会写了,几千字很快就能出来。但长篇小说真正难的地方不只是写出一章,而是持续维持一整本书的方向、节奏和一致性。
如果产品只给一个输入框和一个生成按钮,最后拿到一大段正文,看起来很爽,但很快会遇到一堆问题。
这一章为什么这样推进?它参考了哪些设定?前面埋的坑还有没有记住?我刚刚手动改了一个角色设定,后面的章节会不会知道?如果某一章写崩了,我到底是 prompt 有问题、模型有问题,还是上游的大纲就不对?
这些问题不解决,AI 写作就会一直停留在“生成一些看起来不错的文本”这个阶段。它可以帮你起草,但很难真的参与一个长篇项目。
炼云想做的事情,就是把这些隐藏的问题暴露出来。
v0.1 现在有什么
当前版本已经包含了一条从想法到章节的基础闭环。
用户可以先在书架里输入一个 idea,然后进入立项 chat。这个 chat 不是闲聊,而是用来讨论选题方向,生成候选卡,确认之后再进入生产流程。
后面的流程大概是这样:
- 立项和故事设计。
- 生成分层大纲。
- 创建角色、世界观和活文档。
- 进入 gate,让人确认是否继续。
- 按章节循环执行写作、检查、维护和追踪。
UI 上现在能看到书架、立项 chat、书籍详情、文件树、伏笔看板、Prompt 仓库、Runs、Batches 和设置页。这里面我比较在意的其实是几个“看起来不那么像写作功能”的东西。
比如 Runs 页面。每一次 agent 调用、每一次 LLM 请求,都会有记录。以后章节写坏了,不需要靠猜,可以回头看当时输入了什么,模型返回了什么,schema 校验有没有失败,token 和延迟是多少。
再比如 Prompt 仓库。prompt 不再只是代码里的一个字符串,而是可以在 UI 里编辑、回滚、跟运行记录对应起来的产品资产。
还有伏笔看板。长篇小说里最难的不是“埋一个坑”,而是记得这个坑什么时候该收、有没有被暗示过、最后是不是已经废弃了。所以它不应该只是 markdown 里的一句话,而应该有状态。
这些东西做起来都不酷,但我觉得它们比“再调一个更强的 prompt”重要得多。
人类主编 + AI 工人
我对炼云的定位不是全自动写作系统,更不是自动发布系统。
我更想要的是一种“人类主编 + AI 工人”的模式。人类负责方向、品味、取舍,AI 负责生成候选、补全文档、写初稿、做检查,系统负责把这些工作串起来,并且把每一步留下痕迹。
这也是为什么里面有 gate 机制。
现在 gate-1 已经接进去了。立项和初始大纲完成之后,系统会暂停,让用户确认要不要继续。后面可以继续加 gate-2、gate-3,比如卷规划确认、关键章节确认、质量审核确认。
之前我做很多 AI 产品的时候,都会不自觉地想把流程做得更自动。但现在回头看,越是复杂的东西,越需要在关键节点停下来。全自动看起来很智能,但如果中间状态不可见,出了问题就很难修。
PG 是 source of truth
很多 AI 写作工具会把状态存在 prompt 里,或者存在一堆 markdown 文件里。
炼云现在选择 PostgreSQL 作为 source of truth。这个选择不花哨,但是很实际。长篇生产里有大量需要查询、筛选、聚合和追踪的状态,这些东西如果都塞进 markdown,后面一定会很痛苦。
比如伏笔不能只是一句 markdown:
主角小时候收到过一封神秘信。
它应该能回答更多问题:
- 什么时候引入?
- 权重是小伏笔、弧伏笔,还是整本书级别?
- 当前状态是 open、hinted、paying,还是 paid_off?
- 预期在哪个章节范围内回收?
- 关联哪些角色和规则?
只有结构化以后,系统才能在写下一章前查出“现在最该处理什么”,也才能在写完之后更新状态。
所以炼云里有两类数据。
一种是 markdown 长文档,比如人物档案、世界观描述、风格说明。这些东西适合人读,也适合 agent 作为背景材料。
另一种是结构化表,比如伏笔状态、大纲节点、运行记录、审批状态、章节索引。这些东西适合查询、过滤、统计和自动判断。
我现在越来越觉得,做 agent 产品不要把所有东西都塞进 prompt。prompt 是很重要,但它不是数据库,也不是任务队列,更不是观测系统。
prompt 也是产品资产
还有一个我比较想保留下来的设计,是 Prompt 仓库。
在很多项目里,prompt 都是写死在代码里的一个常量。这样早期很方便,但一旦 agent 多起来,prompt 就会变成产品行为的一部分。它应该有版本,应该能回滚,应该能和某一次模型调用对应起来。
炼云现在的做法是,部分 agent 的 system prompt 会 seed 到数据库里。UI 可以看,也可以改。agent 执行时会动态加载最新版本,如果数据库里没有,就回退到代码里的 fallback。
这不是什么复杂设计,但我觉得很重要。否则每次调 prompt 都像是在空气里改配置,今天改了哪里,明天为什么变差,最后谁也说不清。
架构设计
当前 v0.1 的架构可以粗略分成几层。
flowchart TD
UI[Web 工作台<br/>TanStack Start + React]
API[Server Functions]
Orchestrator[生产编排层<br/>book-producer / pg-boss]
Agents[Agent / Harness 层<br/>topic-scout / planner / writer / guard]
DB[(PostgreSQL<br/>books / chapters / docs / threads / runs)]
LLM[OpenAI-compatible LLM Endpoint]
UI --> API
API --> Orchestrator
Orchestrator --> Agents
Agents --> LLM
Agents --> DB
Orchestrator --> DB
API --> DB
Web 工作台
前端使用 TanStack Start 和 React。
这里我没有做成一个很炫的 landing page,也没有做成纯聊天产品,而是做成一个偏后台系统的工作台。书架、章节、文件树、伏笔、Runs、Batches、Prompt 仓库都直接暴露出来。
说实话现在 UI 还比较工程化,离真正好用的创作软件还差得远,但这个方向我觉得是对的。对这种工具来说,能不能看清状态比好不好看更重要。
数据层
数据层用 Drizzle ORM + PostgreSQL。
比较核心的表包括:
books:书籍主信息和生产状态。chapters/chapter_revisions:章节正文和不同阶段的修订。outline_nodes:卷、弧、章节拍的分层大纲。plot_threads/plot_thread_events:结构化伏笔和事件流。book_docs:角色、世界观、关系、时间线等活文档。prompts/prompt_revisions:提示词仓库。runs/llm_calls:运行追踪和模型调用记录。batches/batch_jobs:批量生产任务。
这些表的核心目的不是“把数据存起来”这么简单,而是让后续 agent 可以基于当前状态继续工作,让人也能随时接管。
Agent 层
当前项目里有多个不同职责的 agent 或 harness:
topic-scout:选题侦察。story-designer:故事设计。chapter-planner:章节规划。chapter-writer:章节写作。consistency-guard:一致性检查。quality-linter:质量检查。living-doc-updater:活文档维护。element-curator:元素词典维护。
我尽量避免让一个超级 agent 什么都做。因为一个 agent 什么都做,最后就会变成一个更长、更难调的 prompt。长篇生产更适合拆成多个职责明确的小 worker,每个 worker 只负责一个产物或者一个判断。
编排层
book-producer 是当前最核心的编排服务。
它负责把“写一本书”拆成多个阶段:
sequenceDiagram
participant User as 用户
participant UI as Web UI
participant Producer as book-producer
participant Agent as agents
participant DB as PostgreSQL
User->>UI: 输入 idea
UI->>Producer: 创建/确认立项
Producer->>Agent: story design / outline / docs
Agent->>DB: 写入大纲、角色、活文档
Producer->>DB: 创建 gate-1
User->>UI: approve
UI->>Producer: resumeAfterGate1
loop 每一章
Producer->>Agent: planner / writer / guard
Agent->>DB: 写入章节、状态、伏笔事件
Producer->>Agent: living doc update / summary
end
批量任务则通过 pg-boss 入队,适合一次性跑多个选题或多个实验方向。
观测层
runChildAgent 会把每次 agent 调用包装成一棵 run 树:
- 先写入
runs,状态为 running。 - 调用模型。
- 写入
llm_calls,记录 prompt、response、token、延迟和错误。 - 校验输出 schema。
- 更新 run 状态为 success 或 failure。
这让 /runs/$id 可以看到完整调用链。
对 agent 产品来说,观测不是锦上添花,而是基础设施。没有 trace,就很难判断到底是 prompt 问题、模型问题、输入问题,还是编排逻辑问题。
为什么开源
我觉得 AI 写作还远没有定型。
现在很多产品都在做更强的一键生成,这当然也有价值。但我更感兴趣的是另一条路:把创作过程拆开,让每个环节都可以被看见、被替换、被二次开发。
开源炼云主要是想做几个事情。
- 给想研究 AI 长篇创作的人一个可运行的参考实现。
- 让更多人看到 agent 产品不只是聊天框,也可以是生产系统。
- 把 prompt、数据结构、运行追踪和 UI 工作台放在一起讨论。
- 为后续更换 runtime kernel 做准备。
当前版本使用的是 Mastra 风格的 agent 和本地 harness services。下一步我想尝试把内核换成 Pi Agent。
不过我不太想直接推倒重写。更合理的方式应该是先抽出 runtime adapter:
Web 工作台 / 数据库 / Runs UI
│
▼
runtime adapter
│
├── 当前 Mastra/harness kernel
└── 未来 Pi Agent kernel
这样一来,炼云的 Web 工作台和数据库结构就不依赖某个具体 agent 框架。真正有价值的部分是“长篇生产系统”的抽象,而不是某个 SDK 的调用方式。
现在还不完美
v0.1 只是第一版开源,问题也很多。
比如 UI 还偏工程化,普通作者应该很难直接上手。agent kernel 也没有完全模块化,沙箱执行、权限控制、插件系统都还没有成型。prompt 和数据结构也需要更多真实长篇项目验证。
但我现在对这个项目的期待也不是马上变成一个完整产品。先把一个能跑、能看、能改的系统放出来,再慢慢围绕真实使用去迭代。
相比把它包装成一个“神奇 AI 写书神器”,我更愿意承认它现在就是一个早期的生产系统骨架。
最后
写这个项目的时候,我经常会想,这是不是又是一个做着很爽、但不知道有没有人用的东西?
可能是。
但它至少把我最近对 agent 产品的一些想法落实到了代码里:状态要显性化,prompt 要版本化,调用要可追踪,人类要能介入,runtime 要能替换。
如果 AI 真的要参与复杂创作,它不应该只是一个聊天框。它更应该是一个可以被观察、被调度、被审阅的生产系统。
炼云 v0.1 先把这个方向开源出来。后面我会继续往 runtime adapter、沙箱执行、插件化 prompt/agent packs,以及 Pi Agent kernel 的方向推进。