构建AI写作系统(02)-工作流状态机

03 工作流状态机:阶段划分与阻断设计

这是「构建自己的AI写作系统」系列的第2篇。

构建自己AI写作系统(1)-总览中,我把一个完整的AI写作系统分成了五层架构。

本文深入第一层——工作流状态机

它回答的问题是:AI写作不是"打开对话框就开始",而是一套有阶段、有阻断、有回环的流程。没有状态机,你在创作中最大的成本不是"写不出来",是"写了白写"。

上一篇文章构建自己AI写作系统(1)-总览描绘了五层架构的全貌,本篇从最底层开始搭建。


你打开 ChatGPT,输入"帮我写一篇短篇小说,重生题材,一万字"。

它吐出了五千字。你读了一遍。

好像还行。又好像哪里不对。

你加了一句:"再改改,让冲突更激烈一些。"

它又吐出一版。你读了一遍。更不对了。

现在你卡住了。你不知道该改哪里,也不知道该不该继续让它写。你甚至开始怀疑——是不是第一版其实更好?你往前翻对话记录,翻了十几屏,找不到了。

这不是 AI 的问题。

是你的问题。

你没有一个判断"该不该继续"的标准。


什么是状态机

状态机这个概念,听起来像计算机课的考点。

但它的核心意思极其朴素:把一件事拆成离散的阶段,每个阶段之间有一条明确的线——过了才能继续,没过就回去修。

三个要素:离散阶段 + 明确转换条件 + 回环。

"回环"是这里最关键的词。写作不是一个线性流水线。你从大纲走到开篇,但如果开篇写出来发现大纲有问题,你得能退回去。审核不通过,你得能回到修改。

状态机干的就是这个:它替你记住你现在在哪儿、下一步该去哪儿、什么情况下可以往前走、什么情况下必须退回去。

为什么需要它?

因为人在创作中最大的成本不是"写不出来",是写了白写

大纲没想清楚就写正文,写了三千字发现结构是歪的。

开篇没确认就往下推,写到结尾发现伏笔没收——要么改结尾,要么在开篇补种植,要么放弃那个伏笔。无论哪种,都是对已完成段落的拆楼式返工。

状态机不保证你不犯错。

它保证你在代价最小的时候犯错


8 个节点:从灵感到定稿

我的短篇小说写作系统定义了 8 个状态节点。

开书 → 大纲 → 开篇 → 章节循环 → 收尾 → 审核 → 润色 → 定稿

不是 3 个(写→审→发)。不是 5 个。是 8 个。

为什么?

因为"大纲"和"开篇"需要两种完全不同的大脑模式。大纲是建筑师画图纸。开篇是室内设计师铺第一块砖。一个人可以同时是建筑师和室内设计师,但他不能在画了一半图纸的时候跳到铺砖,然后再跳回来。不是不能——是每次跳回来都要重新加载上下文。

上下文切换的成本,写作的人都知道。

"审核"和"润色"必须分开,是因为发现问题不等于修好问题。你把一致性检查、风格校准、去 AI 味校稿、安全审查混在一起做,最后你分不清哪处修改是因为逻辑断裂,哪处是因为风格漂移。审核是诊断。润色是治疗。诊断和治疗之间应该有一道门。

具体到每个节点干什么:

1. 开书。

确认六要素——核心期待、目标读者、写作风格、情感类型、核心禁区、目标字数。

你说"我要写一个重生文",这叫冲动。你说"我要写一个让读者感到'追悔莫及'的重生文,面向 25-35 岁女性,知乎渠道,世情风,8000 字"——这叫可执行的起点。

开书的输出是一个 idea_seed.md。不是什么高深的文档——就是一张确认卡。但它意味着你的"想写"变成了"要写"。

2. 大纲。

结构骨架 + 角色速写 + 导语。输出 story_outline.md + character_brief.md

大纲不是剧情摘要。大纲是逐段展开的结构蓝图——每一段的核心任务是什么、情绪温度多少、伏笔在哪里种植、在哪里回收。

角色速写不是人物小传。是欲望-恐惧对立 + 语言特征 + 贯穿物件。比如《妻局》里的沈城,他的贯穿物件是一本记事本——前世记账,今生写线索。苏慧的贯穿物件是一枚铜钱——她爸留给她的遗物。

3. 开篇。

前 500-1000 字。单独成段。

为什么开篇是一个独立的节点?因为开篇决定读者是否关页面。前 200 字没有建立核心冲突或悬念——读者就走了。另外,开篇必须锚定主角身份——禁止用裸代词"他/她"开头而不给出姓名或明确称呼。读者不能读了三段还不知道"她是谁"。

4. 章节循环。

按大纲逐段推进。每一章写完后更新伏笔状态——哪些伏笔已种植、哪些已回收、哪些悬置。

这不是机械执行大纲。章节循环意味着每写完一章回头看一眼:这一章和上一章之间的关系是什么?冲突升级了吗?节奏有没有断?

5. 收尾。

最后一章 + 余韵段落。

结尾必须有力量——与开头形成呼应或反差。不能是升华式总结("人生就是这样……")。必须是具象的、个人的收束动作。一个物件。一个沉默。一个没说的话。

6. 审核。

完整质量闭环:一致性检查 → 风格校准 → 去 AI 味校稿 → 安全审查 → 门禁检查。任一环节未通过,不能定稿。

审核不是"找茬"。审核是用一套固定的维度,把你可能因为疲劳而忽略的问题全部翻出来。人在写了八千字之后,大脑会进入一种"自动补全"状态——你看自己的文字,脑子里补上了它缺少的东西。审核脚本不看你的脑子,只看你的字。

7. 润色。

针对审核发现的问题逐条修改。

这里有一个容易被忽视的纪律:只修发现的问题,不重写。 润色阶段最危险的操作,是你在修一个 P1 标点问题时忽然觉得"这段写得太差了,我重写一下"——然后你引入了一个新的 P0 逻辑断裂。润色的边界是审核报告划定的。

8. 定稿。

全部检查通过,格式化输出终稿。

定稿这个节点本身看起来没什么内容。但它的存在意味着一个明确的心理信号:结束了。 写作者最大的痛苦之一,是不知道什么时候该收手。定稿节点就是你对自己说"够了"的地方。


阻断:为什么"不能跳过"比"能做什么"更重要

状态机定义了阶段顺序。

但光有顺序没用。你必须强制它——上一阶段没通过,不能进入下一阶段。

这叫阻断。

阻断不是限制你的自由。阻断是保护你不在错误的方向上走太远

飞机起飞前有一张检查单。不是因为飞行员记不住,是因为人类在重复性任务中会犯错。你不会想让机长靠"我差不多检查过了"来起飞。你的作品也不应该靠"我差不多改好了"来定稿。

三个真实的阻断

阻断一:大纲不审核,不能写正文。

触发条件:outline_review.md 不存在 → 开篇节点被硬阻断。

《妻局》的大纲审核提供了一个教科书级别的案例。

大纲 v4 生成后,主编(我的 AI 审核角色)从十一个维度核查。其中第十个维度"物件系统与伏笔回收"暴露了一个要命的问题:铜钱——苏慧的核心贯穿物件——在大纲中完全消失了。

角色速写里写得明明白白:铜钱是她爸留给她的遗物,"前世放在沈城手心,今生留在桌上"。但在大纲的逐段展开中,茶馆摊牌没有铜钱,苏慧约沈城没有铜钱,收束段落也没有铜钱。这个物件像一条在图纸上画了出处的线,然后在施工图上断掉了。

如果没有主编审核这个阻断节点,会发生什么?

我会直接开写正文。写到茶馆段落,写完沈城和苏慧的高潮对峙,忽然发现"铜钱该放在哪里"——但此刻情感节奏已经锁死。硬插进去,节奏崩。不插,苏慧少了一条贯穿的动作线。

审核报告给了一个具体的方案:在苏慧约沈城那一段,"她把铜钱也放在桌上——'这个你前世没拿走。这辈子也不用拿。我就是想让你看看——你当年没拿走的东西,还在。'"沈城不拿。铜钱和紫砂壶一起留在茶馆桌上——她爸的两样东西,她都放下了。

这个问题如果留到润色阶段才发现,改的成本是拆掉高潮段的情感结构重新焊接

阻断把它卡在了大纲阶段。改动只需要改大纲的三行字。

阻断二:门禁不通过,不能定稿。

触发条件:gate_result.json 显示 passed: false → 定稿节点被硬阻断。唯一合法操作:进入修复流程。

这是短篇小说写作专家 Iron Law 第三条——"禁止在门禁失败后强行定稿"。门禁检查是一个 Python 脚本,它读你的手稿,逐项检查元信息污染、字数偏差、风格偏差、结尾质量。它没有人情世故。它不会因为"你已经改了四遍了看着差不多了"就通融。

《妻局》经历了一轮"门禁失败→修复→重检"的循环。

用户在修改草稿时做了一件很有想法的事——把"世纪酒店的婚礼"画面加入沈城的回忆中。这一笔情感杀伤力极强,阶级差异被一个画面钉死了。但它同时导致了一处伏笔断裂:原版中"窗外那辆黑车"的种植句被删掉,而等待段落中"那辆黑车我再没在街对面见过"的回收句还在。回收变成了无源之水。

一致性报告输出了 15 条伏笔的追踪状态,3 条标记为断裂——其中黑车线索的种植和回收之间的链接是最典型的结构损伤。修复方案不是"把删掉的那句话加回来"那么简单——因为加了黑车句,新加入的温暖结尾就必须和它共存。最后采用了"先留线索(黑车),再说愿望(希望你幸福),然后走"的双句结构。

如果没有门禁阻断,这篇稿子就会以一个"读者读到等待段会愣一下——他在说什么黑车?"的状态发出去。

人会累。人在累的时候会说服自己"差不多了"。

脚本没有累的概念。

阻断三:公众号预览→发布,没有"确认发布"信号不推草稿。

这是从短篇系统迁移到公众号写作场景后新加的阻断。

公众号文章的发布是不可撤回的——一旦群发,错误就会留在所有订阅者的手机里。修改只能改正文 20 个字,标题一个字都不能改。

所以在我自己的公众号生产管线中,"生成预览链接"和"发布"之间硬插了一个阻断:没有收到用户的"确认发布"四个字,草稿永远停留在预览状态。 哪怕文章早就写完了、配图排好了、预览链接已经在手机上看过三遍了——只要那四个字没来,不推。

这个阻断保护的甚至不是内容质量。

它保护的是你不会在凌晨两点头脑不清的时候把群发键按下去。


阻断分级:不是所有问题都致命

不是所有阻断都一样重。

我把阻断分成三级。

P0 硬阻断。

不修不能继续。包括:角色命名锚定缺失(开篇 200 字内未建立主角可辨识称呼)、代词无先行词("她"首次出现前未建立女性角色身份)、伏笔悬而未收(A 类伏笔种植后全文未回收 )、时间线断裂(前文说"三天前"后文事件顺序矛盾)、设定被推翻(前文独生子后文出亲兄弟)、元信息污染(正文中出现 [说明]TODO、写作分析段落)、安全红线(色情/暴力血腥/违法犯罪教程/政治敏感)。

一致性检查脚本会对 P0 问题做自动扫描。开篇代词锚定、角色正式姓名是否出现在正文中、伏笔回收状态——这三项是脚本里最"铁"的检查。

举个例子,假设一篇世情文全文用"大哥""弟弟""老妈"指代三个核心角色,从头到尾没有一个角色的正式姓名出现过——这是 P0 缺陷。读者读了六千字,脑子里只有亲属称谓没有具体的人。角色速写里写了"大哥(陈建国)"但正文中"陈建国"三个字一次没出现——脚本会直接标记 missing_character_name

P1 软阻断。

标记警告,但用户可以决定是否修复。包括:角色关系未在正文中交代、标点符号混合使用(引号一会儿 "一会儿「」)、亲属称谓指代过多(>10 次)但无姓名锚点、代词连续使用超过 3 次且中间无姓名锚点("他……他……他……"效应,可能导致指代不清)。

P1 不阻塞门禁,但会出现在一致性报告中。用户需要手动确认"我看到了,我可以接受"。

P2 提醒。

纯优化建议。包括:数字/金额逻辑可疑("他亏了 1200 块,但流水有 2800,铺租只有 800——这账不对")、关键信息无意重复(同一短语在叙事中出现超过 4 次,可能是 motif 也可能是冗余)。

P2 不阻塞任何东西。它只是低声说一句:你看一眼这里,不看也行。

三级分层的核心逻辑是:不要让完美主义阻塞交付。 如果所有问题都是 P0,你永远定不了稿——因为一篇一万字的短篇,永远找得出可以优化的地方。P0 只守底线——故事能成立、信息不矛盾、安全不踩线。P1 和 P2 是锦上添花,不是必要条件。


状态持久化:系统需要知道你走到哪儿了

状态机有 8 个节点。你今天写到大纲,明天继续写开篇。

系统怎么知道你上次停在了哪里?

三种方案。

方案 A:文件系统(当前方案)。

项目目录本身就是状态载体。检查某个文件是否存在,就知道当前处于哪个阶段。

妻局/
├── 00_meta/
│   ├── idea_seed.md          # 开书完成 ✓
│   ├── story_outline.md      # 大纲完成 ✓
│   ├── character_brief.md    # 角色速写完成 ✓
│   └── outline_review.md     # 大纲审核完成 ✓
├── 01_manuscript/
│   ├── draft_v1.md           # 草稿完成 ✓
│   └── draft_final.md        # 终稿——还没生成 ✗
├── 02_review/
│   ├── consistency_report.md # 一致性检查完成 ✓
│   └── gate_result.json      # 门禁通过 ✓
└── 03_output/                # 还没填充 ✗

不需要额外的状态文件。每个节点的输出物就是状态的唯一证据。

优点:零额外维护成本,不会出现"状态文件说完成了但实际文件不存在"的幽灵状态。缺点:粒度粗,你不知道"章节循环"进行到第几章了——只能知道草稿文件存在。扩展性差——如果要加入更细的状态(比如"开篇第一段写完,等待用户确认"),文件系统就吃力了。

适合:单人单项目、节点状态天然对应文件产出的场景。

方案 B:JSON 状态文件。

在项目根目录维护一个 state.json

{
  "project": "妻局",
  "current_phase": "章节循环",
  "chapter_index": 7,
  "foreshadowing_tracker": {
    "F1_九指": "resolved",
    "F7_黑车": "planted",
    "F13_铜钱": "resolved"
  },
  "last_action": "写完§7茶馆摊牌",
  "updated_at": "2026-05-05T14:30:00"
}

优点:细粒度追踪——伏笔状态、当前章节索引、最后操作时间。机器可读,适合做自动化流程触发(读到 current_phase: "审核" 自动触发门禁脚本)。缺点:需要维护一致性——如果文件实际存在但 state.json 里标记为"未完成",系统会混乱。额外一层代码。

适合:多人协作、需要自动化流程编排、状态维度超过文件存在性。

方案 C:Git 分支。

每个阶段一个分支。feature/开书 → merge 到 mainfeature/大纲 → merge → ……

优点:完整的版本历史——每一步都可以回退,每一次修改都有 diff 可查。缺点:太重。短篇一天能写一篇,一天之内切 8 次分支合并 8 次,你的 Git 日志会比你的正文还长。

适合:多人协作的长篇项目、需要并行开发(不同的人在各自的章节分支上工作)。

我目前的选择。

方案 A。因为短篇写作的节点划分天然对应文件目录结构。outline_review.md 存在 → 大纲已审核 → 可以开写。gate_result.jsonpassed 字段为 true → 可以定稿。文件系统的存在性检查是不需要额外代码的状态机引擎。

但如果你正在做一个多 Agent 写作系统——一个 Agent 写大纲、一个 Agent 写章节、一个 Agent 审核——方案 B 是必须的。JSON 状态文件是多个 Agent 之间的共享工作记忆。


短篇 vs 公众号:两种状态机

短篇小说和公众号文章是两种完全不同的创作模式。它们的状态机也应该不同。

维度 短篇小说 公众号文章
节点数 8 5(确认清单 → 骨架 → 草稿 → 冷却审核 → 定稿发布)
回环频率 高(审核→修改→重审,3-5 次) 低(1-2 次,通常一次审核够用)
核心阻断 大纲审核 预览确认
状态载体 项目目录 + 文件存在性 JSON 配置 + 发布状态标记
阻断特点 质量导向(伏笔、一致性、安全) 流程导向(未确认不发布)
单次周期 3-7 天 2-6 小时

最本质的差异:短篇是建设性的——你在搭建一个之前不存在的世界,断了要回去补地基。公众号是表达性的——你把已有的思考组织成人能看懂的东西,断了通常改一改措辞就行。

所以短篇状态机的回环次数远多于公众号。一篇《妻局》从大纲到定稿,大纲被审核了 4 个版本(v1 → v2 → v3 → v4),草稿被审核了一次但输出了 15 条伏笔追踪和 5 条 P0 修复指令。回环不是失败。回环是正常流程。

公众号状态机可以更轻。核心关卡只有一个:写完之后放一会儿再看。 冷却 6 小时再审核,你能看见自己刚写完时看不见的东西。这句听着玄,试一次就知道了。


你的最小状态机

如果你现在就想搭建自己的写作状态机,不需要 8 个节点。

7 步够用。

1\. 确认清单   → 输出:三句话(写什么/写给谁/什么算好)
2\. 骨架       → 输出:结构 + 3 个关键转折点
3\. 草稿       → 输出:全文。不停笔。不回头改。
4\. 冷却       → 条件:放至少 6 小时。必须。
5\. 审核       → 输出:对照清单逐项标记问题。只标记,不改。
6\. 修改       → 输出:逐条修。不重写。修完一条勾一条。
7\. 定稿       → 条件:清单全部勾完 → 格式化输出。

每个节点的进入条件只有一条:上一个节点的输出文件存在且非空。

确认清单.md 不为空 → 可以写骨架。
骨架.md 不为空 → 可以写草稿。
以此类推。

阻断不需要复杂的脚本。第一步你只需要一个习惯:在你准备跳到下一步的时候,看一眼上一步的输出文件,问自己一句——这个东西,真的够格让我继续吗?

如果你犹豫了,那就是阻断生效了。


最后

状态机最大的价值不是"流程化"。

让你在每一个"差不多可以了"的瞬间,有一个东西替你记住——你上一步定的标准是什么。

人会自我说服。文件不会。

下一篇是 04——开篇六要素与信息差策略。我会展开这六个要素为什么缺一不可,以及全篇最重要的叙事决策:信息前置还是信息隐藏。这个决策决定了读者是在俯视你的角色,还是在和角色一起摸索。选错一个,整个故事的张力类型就错了。


©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容