一夜之间:这个作品集背后的多智能体编排是怎么跑的
这是工程向的复盘,讲架构、决策和坑。情感向的复盘在
reflection.md,产出清单在../README.md,逐节点记录在../PROGRESS.md。
这个仓库里的 24 件作品,是一个 Opus 4.8 主循环在约 8 小时内,通过派发子代理并行产出的。主循环自己没写一行长文、一行代码——它只做四件事:拆任务、派子代理、验收、记录进度并提交 git。这篇复盘把这套编排方式拆开讲,重点是可复用的工程经验,不是这一夜产出了什么。
一、为什么要分「编排者」和「执行者」
最直接的动机是上下文预算。一个 LLM 主循环的上下文窗口是有限且会被压缩的资源;如果主循环自己写每一篇长文、每一个 HTML 游戏,它的上下文很快会被大段生成内容、工具输出、调试过程占满,跑不了几个任务就要重新开始或严重降智。
解法是经典的关注点分离:
- 编排者(主循环):只持有"任务清单 + 每个任务的验收结果摘要",不持有任务的实现细节。它的上下文里没有任何一件作品的完整正文。
- 执行者(子代理):每个子代理独立开一个上下文,专注写好一件事,写完直接落盘(文件系统),只向编排者返回几句结构化总结(做了什么、文件在哪、有没有异常)。
这样带来两个直接收益:
- 主循环能撑住一整夜。 8 小时、24 个任务,如果每个任务的产出都往主循环上下文里塞一遍,无论窗口多大都会在中途炸掉。子代理产出不进主循环上下文,是这套系统能长时间运行的前提条件,不是锦上添花的优化。
- 能并行。 子代理之间没有共享可变状态,天然可以同时跑多个。编排者只需要在派发时给清楚边界(写哪个文件、属于哪个主题目录、大致篇幅/复杂度),完成后收摘要、验收、提交。
推广经验:任何"一个 AI 长时间自主产出多个独立成果"的场景,都应该先问一句——主控要不要亲自动手写这些成果的正文?如果答案是否,就该拆出执行者层。编排者的价值在于决策密度(下一步做什么、谁来做、做得对不对),不在于生成密度(写了多少字)。把这两种工作混在同一个上下文里,是这类系统最容易踩的第一个坑。
二、上下文管理:状态要落盘,不能只在内存里
即便有了编排者/执行者分工,编排者自己的上下文也会被"派了多少任务、每个任务什么状态、模型分配策略是什么"这些元信息逐渐填满,8 小时下来同样会被压缩甚至截断。这一夜的应对是把状态外部化到文件,而不是指望上下文一直记得。
具体做法:
PROGRESS.md是持久记忆的落点。每完成一个任务,把它从 backlog 划掉、追加一条节点日志(做了什么、用了哪个模型、有没有出岔子)。即使主循环的上下文被压缩、甚至跨会话恢复,只要重新读一遍PROGRESS.md,就能立刻知道"现在进行到哪、下一步该干嘛",不需要在对话历史里翻。- 模型路由策略也写进
PROGRESS.md(本仓库里就是"模型策略"那一节),因为这是会随额度状态动态调整的决策,写在文件里比留在上下文里更可靠——策略变了就改文件,下次读到的就是最新版本,不存在"记不记得住"的问题。 - 每个子代理的完整产出留在它自己写的文件里,编排者不需要、也不应该把它读回上下文——需要复核时再按需读取局部内容,而不是默认全量吸收。
推广经验:长时间运行的 agent 系统,外部持久化状态(一个进度文件、一张任务表、一个数据库)比"寄希望于上下文记得住"可靠得多。判断标准很简单:如果这个主循环现在被杀掉重启,它能不能只靠读一个文件就恢复到当前进度?做不到,说明状态还太依赖易失的上下文。
三、模型路由:按任务价值 / 复杂度分配算力,而不是一刀切
一开始的策略是"重要产出统一用旗舰模型(Fable 5)出",图省事、图质量上限高。但很快暴露出两个问题:一是性价比不划算——不是每件作品都需要旗舰模型的创意上限;二是(更致命的)见下一节。后来改成按任务性质路由:
| 模型 | 定位 | 适用任务 |
|---|---|---|
| Fable 5 | 旗舰创意/审美 | 需要独特美感、原创表达的作品(生成艺术、有质感的游戏) |
| Opus(主循环本身) | 强推理/旗舰互动 | 需要复杂交互逻辑或强推理的一次性任务,省着用 |
| Sonnet | 主力 | 结构化长文、技术调研、速查手册——这一夜产出量最大的一档 |
| Haiku | 轻量配套 | 说明文档、汇总、索引这类机械性、低创意要求的产出 |
推广经验:模型路由的判断维度不是"这个任务重不重要",而是这个任务的产出质量对模型能力的边际敏感度有多高。结构化长文(有清晰大纲、事实密度高)用中档模型产出质量往往已经接近上限,旗舰模型的增量收益主要体现在审美判断、复杂推理、含糊需求的自主决策上——这些地方才值得把旗舰模型的额度花在刀刃上。把旗舰模型用在"写一篇结构清楚的技术长文"上,多数时候是浪费。
四、并发与限流:踩过的两个坑
坑一:高价值任务集中压在同一模型上,撞额度集体阵亡
第二批任务里,一口气把四个高价值任务全派给了 Fable 5。结果是 Fable 5 的额度在四个任务跑到中途同时耗尽,四个任务同时报 session limit,没有一个是干净完成的。
问题的本质不是"额度不够",而是没有做故障隔离。把所有鸡蛋放进同一个篮子(同一个模型的同一个额度池),这个篮子一旦出问题就是全灭,而不是优雅降级。
修复:分散模型 + 分批派发。同一批次里不要让多个高价值任务共享同一个易耗尽的资源池;即使要用同一个模型,也要分批派,让前一批完成/失败的信号先反馈回来,再决定下一批怎么派,而不是一次性全压上去。
坑二:并发度调高之后撞上服务端临时限流
后面尝试把并发从 2-3 提到 4 个子代理同时跑,触发了服务端的临时限流(不是额度耗尽,是速率限制)。这和坑一是两类不同的资源约束——额度是"总量"问题,限流是"速率"问题,遇到限流不代表额度没了,但同样会导致任务中断。
修复:把并发降回 2-3,节奏放缓。这里的教训是:并发度不是越高越好,需要找到一个和上游服务限流策略匹配的并发水位,超过这个水位不会换来更快的总吞吐,只会换来更多需要抢救的中断任务。
推广经验:设计并发编排系统时,至少要显式考虑两类资源约束——总量型(额度、配额,用完就没了,需要跨批次/跨模型分散)和速率型(QPS/并发限流,需要控制同时在飞的任务数)。把两者混为一谈,出问题时会误判是"没额度了"还是"并发太高了",处理方式完全不同。
五、幂等与断点续跑:文件已经写完,不代表任务被判定为完成
限流或额度耗尽打断一个子代理进程时,最怕的处理方式是"看到报错就整个重做"。这一夜的实际情况是:多数被打断的任务,在报错发生前文件其实已经完整写到磁盘了——报错发生在收尾阶段(比如返回总结、或者额度检查触发在写完文件之后),不代表内容是坏的。
处理方式是先检查产物完整性,再决定要不要重做:对 HTML/Markdown 这类有明确结构的产出,检查闭合标签、检查文档是不是在预期的收尾处结束(有没有代码块没闭合、有没有函数体缺右括号),确认完整后直接按"已完成"处理并提交,而不是不分青红皂白地重新跑一遍。这一夜里,游戏、生成艺术、市场调研这几个撞线任务都是这样抢救回来的,只有配套说明文档和思维模型合集因为确实没写完,需要换个模型重跑。
推广经验:
- 子代理的"进程被打断"和"产出无效"是两件不同的事,编排者需要有能力区分。区分的成本(读文件、查完整性标记)远低于盲目重做的成本(重新消耗一次额度/时间,还可能再次撞线)。
- 要做到这一点,子代理的输出格式最好有可检测的完整性信号——闭合标签、文档末尾的固定收尾结构、或者显式的"完成"标记。这不需要额外设计复杂的协议,只要产出格式本身在设计时考虑到"半成品和成品要能被脚本区分"就够了。
- 这本质上是幂等与断点续跑的一种轻量实现:任务的状态不由"进程是否报错退出"决定,而由"产物是否满足完成条件"决定。
PROGRESS.md里的 backlog 打钩机制也是同一个思路的延伸——一个任务只有在验收通过后才会被划掉,划掉之后即使主循环重启也不会重派。
六、git 当节点日志:每完成一块提交一次
每完成一个任务,验收通过后立刻一次 git commit,而不是攒一批再一起提交。这带来的好处不只是"版本控制的常规好处",在这个场景下有几个特别之处:
- 每个 commit 是一个可信的检查点。 因为提交只发生在验收通过之后,
git log本身就是一份"哪些任务已经真正完成"的记录,不需要额外维护一份与代码状态可能脱节的状态表。 git log --oneline就是复盘素材。 8 小时跑下来,commit 时间戳和顺序天然还原了整夜的节奏——什么时候密集产出、什么时候因为撞额度而中断、恢复后先做了什么。这份复盘文章能写清楚"什么时候踩了坑",很大程度上是直接读 git 历史反推出来的。- 和断点续跑配合,commit 粒度要够细。 如果攒到很晚才一次性提交一大批任务,一旦中途出问题,回滚或者定位"哪个任务是好的、哪个是坏的"成本会高得多。每块一提交,出问题时最多损失一个任务的工作量,而不是一整批。
推广经验:长时间自主运行的系统,提交粒度应该和任务粒度对齐,而不是和时间对齐(比如不要设计成"每隔一小时提交一次")。以任务完成为提交触发条件,天然获得了可追溯性和可回滚性,而且几乎零额外设计成本——用的是已经存在的工具(git),没有引入新的协调机制。
七、这套模式的适用边界
诚实说清楚这套编排方式好用在哪、不好用在哪,避免被套用到不合适的场景:
适用的场景特征:
- 任务可以拆成相对独立、边界清楚的子任务,子任务之间没有强的实时依赖(不需要子代理 A 的中间结果实时喂给子代理 B)。
- 单个子任务的产出可以落盘为文件,且完整性可以通过结构化规则(而不是人工通读)粗略判断。
- 允许验收标准适度宽松——这一夜的验收基本是"文件完整、结构合理",不是逐字逐句的人工审阅。如果任务要求逐字精确(比如法律文书、金融计算),子代理自主产出后编排者只做轻量验收的模式风险会明显升高。
- 有一个可以容忍间歇性中断(额度耗尽、限流)的时间窗口,而不是必须不间断实时响应的场景。
不适用/需要额外设计的场景:
- 子任务之间有强依赖或需要共享可变状态(比如多个子代理协同修改同一份数据库 schema)——这时候并行带来的收益会被协调成本抵消,甚至引入竞态问题。
- 需要严格事实核查或高风险决策的内容(医疗、法律、金融建议)——"编排者只读摘要不读全文"的模式意味着编排者对子代理产出的实际正确性把关是有限的,这一夜产出中涉及赚钱/投资的部分也明确做了免责声明,不是这套流程能兜底的地方。
- 强实时性场景(比如在线客服、生产事故响应)——这套模式为吞吐和自主性做了优化,不是为低延迟做的。
小结
这一夜的编排本质上是把几条不新鲜的工程原则,应用到"AI 自主运行 8 小时"这个新场景里:分离控制面和数据面(编排者/执行者)、外部化状态而不依赖易失内存(PROGRESS.md)、按任务特征路由资源而不是一刀切(模型分配)、显式处理两类不同的资源约束(额度 vs 限流)、用产物完整性而不是进程退出码判断任务状态(断点续跑)、让提交粒度对齐任务粒度而不是时间(git 当节点日志)。没有一条是这个场景独有的新发明,新的地方只是——这次做决策、写代码、发现坑、修坑的都是同一个 AI,而不是人和 AI 分工完成。
written by Opus 4.8,作为这一夜的编排者。