news 2026/10/24 3:09:40

连续运行3天不丢字:ainovel-cli 多Agent小说生成的 Step 级 Checkpoint 与 Saga 原子提交全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
连续运行3天不丢字:ainovel-cli 多Agent小说生成的 Step 级 Checkpoint 与 Saga 原子提交全解析

连续运行3天不丢字:ainovel-cli 多Agent小说生成的 Step 级 Checkpoint 与 Saga 原子提交全解析

【免费下载链接】ainovel-cli✨多agent实现全自动AI小说生成项目地址: https://gitcode.com/gh_mirrors/ai/ainovel-cli

ainovel-cli是一个用多 Agent 协作实现全自动AI 小说生成的开源工具:架构师规划、写手产出、编辑审校,一条命令可以连续跑数天、产出数百章正文。长时运行最怕的就是"跑到一半崩了,前面全白写"。它的解法只有两句话——Step 级 checkpoint记录每一步落盘事实,Saga 原子提交保证章节提交中断后可从断点重放。这篇文章带你彻底看懂这套"不丢字"机制,不需要读一行源码也能收获。

上面是它真实的运行界面:左侧是运行状态与 token 预算,中间是实时事件流(每一章都经历 plan → draft → check → commit 的完整链路),右侧是因果链回溯。跑 3 天、写 170 多章,随时可以中断、重启、续跑。

为什么"多 Agent 长跑"最怕丢字

传统脚本挂了重跑一遍就行,但 AI 小说生成不一样:

  • 每一步都烧钱:一章正文要调用多次大模型,重试成本是真金白银
  • 上下文不可再生:模型不会"记得"上一轮写了什么,断点信息必须来自磁盘
  • 多 Agent 交错执行:写手刚提交、架构师还没规划下一章,崩溃可能发生在任何缝隙里

所以 ainovel-cli 的设计铁律是:完成的唯一证据是 checkpoint 写入,而不是"模型说自己完成了"。

一、Step 级 Checkpoint:只追加的"进度账本"

1. 每个关键步骤都打一个 checkpoint

从定义 internal/domain/checkpoint.go 可以看到,一条 checkpoint 只记录五个事实:

字段含义例子
Seq全局单调递增序号1024
Scope作用域:章节/弧/卷/全局chapter:172
Step完成了哪一步plan/draft/commit
Artifact产物文件chapters/172.md
Digest产物内容指纹用于判重

所有 checkpoint 以只追加(append-only)方式写入meta/checkpoints.jsonl(见 internal/store/checkpoints.go)。只追加意味着:永远不需要修改历史,日志坏了也不会互相污染,重启时从上往下读一遍就能完整重建进度。

每章写作会依次留下多个 step:plan(章节计划)→draft(草稿)→commit(终稿提交),弧末还有review、arc_summary。崩溃恢复时,Engine 读到的不是"我上次干到哪一步"的模糊记忆,而是磁盘上的确定事实(恢复入口见 internal/host/resume.go)。

2. 幂等设计:重复执行零副作用

这是"不丢字"的第一道防线。每个写类工具执行前都会先查 checkpoint:如果当前 scope 最新的Step + Digest与本次完全相同,直接返回已有产物,不再重做。

效果是什么?

  • 网络抖动导致的重试 → 安全
  • 崩溃后恢复的重复派发 → 安全
  • 同一个 step 被派发三次 → 磁盘上只有一条记录(相同Scope+Step+Digest视为幂等,不产生新行)

换句话说,你可以放心地反复重启进程,引擎不会把同一章写两次、不会把大纲推进两次。

3. CheckpointDeltaGuard:防止 Agent"嘴上说完成"

大模型偶尔会"幻觉式收工"——活没干完却结束了本轮。为此每个 Worker(架构师/写手/编辑)都挂了一个事实护栏 internal/agents/guard/subagent_guards.go:本轮开始时的 checkpoint 是基线,结束前必须看到对应 step 的新 checkpoint,否则拒绝收工;连续拦 3 次直接升级终止。

弱模型死循环到这里也会被兜住——这是它敢让流程"无人值守"跑 3 天的底气之一。

二、Saga 原子提交:一章正文的"跨文件事务"

1. 为什么需要 Saga

一章提交要同时写多个文件:终稿chapters/chXX.md、章节摘要、时间线、伏笔账本、角色关系、进度progress.json……文件系统没有跨文件事务,写到一半断电怎么办?

答案是把这次提交做成一条Saga(持久化意图):先把"完整提交意图 + 正文快照"冻结到meta/pending_commit.json,之后每一步都基于这份冻结载荷推进,任何时刻崩溃都能精确续上。核心实现就在 internal/tools/commit_chapter.go。

2. 四个阶段,每走一步都留痕

PendingCommit的状态机定义在 internal/domain/commit.go,推进顺序是:

① started 冻结完整载荷 + 正文快照落盘 ② state_applied 终稿/摘要/时间线/伏笔等状态写入完成 ③ progress_marked 进度标记完成 + 提交结果固化 ④ signal_saved commit checkpoint 追加完成 最后:清除 pending_commit,提交闭环

两个关键细节值得新手理解:

  • 正文快照只认第一次。恢复时一律重放首次落盘的冻结载荷,禁止采用重启后模型"重新生成"的参数或已被覆盖的草稿——否则会出现"旧状态 + 新正文"的错配,这正是丢字的典型来源。
  • checkpoint 必须先于清除意图。只有commitcheckpoint 落盘后才会删除pending_commit.json(见 commit_chapter.go 注释)。反过来,重启后只要还能看到 pending_commit,就知道"上一轮提交没走完",继续按阶段补齐即可。

3. 崩溃在任何一个缝隙,都只"续"不"重"

假设崩溃发生在 ② 和 ③ 之间:终稿文件已经写了,但进度还没标记。重启后引擎读到pending_commit处于state_applied,于是跳过已完成的写入,直接从"更新进度"继续。因为每一步都是幂等的(写入前查 checkpoint / 查 completed 列表),重放不会产生重复章节。

这就是标题里"3 天不丢字"的工程含义:不是"永不崩溃",而是任何崩溃窗口内的每一步都已持久化意图,恢复 = 按断点重放。

三、单文件原子写:最底层的最后一道保险

上面所有"落盘"都有一个共同前提:单个文件要么写成功、要么像没写过。ainovel-cli 用的是经典的temp 文件 + fsync + rename 原子替换方案(设计见 docs/architecture.md):

  1. 内容先写到同目录临时文件
  2. fsync强制刷到磁盘
  3. rename原子覆盖目标路径

操作系统保证 rename 是原子的——断电时你只会看到"旧文件完整"或"新文件完整",永远不会有一个写到一半的残文件。

四、三层防线总结

层级机制防的是什么
文件层tmp + fsync + rename 原子替换写一半断电产生残文件
Step 层checkpoints.jsonl 只追加 + Digest 幂等重复执行、崩溃后重放
提交层PendingCommit Saga 四阶段推进跨文件提交中断后的状态错配

再配上 internal/agents/guard/subagent_guards.go 的收工护栏,"模型说完成了"永远要换算成"磁盘上有什么"。

五、延伸阅读

想深入这套体系的更多设计决策(Engine 循环、Arbiter 裁定、恢复流程),推荐按顺序读这几份仓库内文档:

  • 总体架构与铁律:docs/architecture.md
  • 章节推进 Gate 与许可对账:docs/chapter-advance-gate.md
  • 引擎与 Arbiter 协作:docs/engine-arbiter.md
  • 关键源码:checkpoint 存储 internal/store/checkpoints.go、Saga 定义 internal/domain/commit.go、提交工具 internal/tools/commit_chapter.go

小结:ainovel-cli 的"不丢字"不靠运气,靠的是把"完成"从模型的话转换成磁盘上的事实——checkpoint 记每一步、Saga 管每一次提交、原子写保每一个文件。理解了这个模式,对你自己写任何长时运行的 AI Agent 系统都有直接参考价值。

【免费下载链接】ainovel-cli✨多agent实现全自动AI小说生成项目地址: https://gitcode.com/gh_mirrors/ai/ainovel-cli

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 5:41:33

Blazor 后台为什么可以不写 Controller + Service + DTO?

本文对应版本:EasyAdminBlazor 2.3.0。 源码位置: EasyAdminBlazor.Core/FreeSql/Repository.cs(BasicRepository / DddRepository / RepositoryOptions)EasyAdminBlazor/AdminExtensions.cs(仓储注册与审计&#xf…

作者头像 李华
网站建设 2026/10/23 21:43:29

text-to-cad 实战:从自然语言到 STEP/STL 三维模型生成全链路解析

1. 从一句话到三维模型:text-to-cad 到底在解决什么问题第一次听到 text-to-cad 这个词,我脑子里蹦出来的画面是:对着电脑敲一句“给我画一个 806010mm、四角带 M4 沉头孔的安装板”,然后软件自己把模型建好、导出 STEP 文件丢给我…

作者头像 李华
网站建设 2026/10/19 10:00:32

职臣AI文献综述怎么选?一图看懂适用场景

写文献综述时,真正让人卡住的往往不是“不会写”,而是不知道从哪里开始:研究范围太大,资料零散,国内外观点难以归类,最后还要反复调整结构和格式。职臣AI的文献综述功能,可以看作一个围绕“研究…

作者头像 李华
网站建设 2026/10/22 15:58:33

职臣AI文献综述:从研究问题到可核验的文献脉络

文献综述难写,常常不是因为“字数不够”,而是文献、问题和论证之间还没有连起来。职臣AI的文献综述页面,适合从这个连接过程入手观察:它没有让用户一上来就索要一篇成稿,而是把操作拆成信息设置、参考文献确定、浏览与…

作者头像 李华