Loop Engineering 多循环失败模式:从碰撞事故到 branch lock 与优先级栈的实战复盘
2026/9/23 21:40:02 网站建设 项目流程

Loop Engineering 多循环失败模式:从碰撞事故到 branch lock 与优先级栈的实战复盘

【免费下载链接】loop-engineeringPractical patterns, starters & CLI tools for loop engineering with AI coding agents. Design systems that prompt and orchestrate agents (inspired by Addy Osmani and Boris Cherny). Includes loop-audit, loop-init, loop-cost.项目地址: https://gitcode.com/gh_mirrors/lo/loop-engineering

导读:当同一个仓库里同时跑着多个 AI 编码 Agent 循环(loop)时,循环之间会在分支、状态文件、token 预算和人工注意力四个维度上互相"打架"。本文以 loop-engineering 仓库中multi-loop-failure-story的撰写规范为主线,复盘两起真实的多循环碰撞事故(CI Sweeper vs PR Babysitter、Dependency Sweeper vs CI Sweeper),并结合docs/multi-loop.md的协调原则与loop-worktree的 advisory lock 实现,给出从"事故复盘"到"机制修复"的完整方法。读完你既能写出一篇合格的多循环失败复盘,也能为手头的多循环系统落地碰撞检测与优先级调度。

一、先认识任务本身:什么是 multi-loop failure story

在 loop-engineering 仓库中,scripts/issue-bodies/multi-loop-failure-story.md是一份面向贡献者的失败故事撰写任务书。它的背景很直白:stories/multi-loop-coordination.md已经覆盖了多循环协调的"成功案例",但工程实践同样需要诚实的碰撞与优先级失败记录——因为失败故事才是碰撞检测机制的真实需求来源

这份任务书定义了投稿者需要新建一个位于stories/目录下的故事文件,并给出了四条硬性验收标准(acceptance criteria):

  1. 说明哪些循环并发运行、它们是如何被调度的;
  2. 说明冲突发生在哪里——分支(branch)、状态文件(state file)、token 预算、还是人工注意力(human attention);
  3. 说明你是如何检测到冲突的,以及你做了哪些改变(优先级顺序、kill switch、执行节奏 cadence);
  4. 如果你调整了默认优先级栈,需要链接到 docs/multi-loop.md。

这份模板之所以重要,是因为它把"失败"拆解成了可观测、可度量、可复现的工程问题,而不是一句"多循环出了问题"的抱怨。仓库里已有的两篇真实故事,正是按这个骨架写出来的范本。

二、失败故事的通用骨架:Setup / What Broke / Metrics / Lesson

stories/multi-loop-collision.mdstories/dependency-vs-ci-sweeper-collision.md两篇真实复盘看,一篇合格的多循环失败故事遵循四段式结构:

段落要回答的问题对应验收标准
Setup哪些循环在跑?调度 cadence 是什么?共享了哪些资源?标准 1
What Broke具体冲突是什么?在哪个维度上撞车?标准 2
Metrics冲突造成了多少可量化的代价(重复修复、浪费 token、人工耗时)?标准 3(检测)
Lesson根因是什么?改了哪些机制?对应哪个文档更新?标准 3、4

值得注意的是,这两篇故事都刻意记录了正面事实("What Worked")——例如 CI Sweeper 正确识别了失败测试、Dependency Sweeper 正确发现了过期的补丁依赖——这种诚实记录避免把事故归结为"某个循环很蠢",而是把矛头指向缺少协调机制本身。这正是失败故事与报障单的本质区别。

三、真实案例一:CI Sweeper 与 PR Babysitter 的同 PR 撞车

stories/multi-loop-collision.md记录了 PR #318 上的一次典型撞车:

  • Setup:CI Sweeper 以/loop 15m的节奏运行、最多 3 次尝试;PR Babysitter 以/loop 10m运行在同一个仓库;两者共享分支fix/auth-token-refresh
  • What Broke:CI Sweeper 在 14:02 为修复失败测试创建了一个 worktree;PR Babysitter 在 14:07 又对同一个 PR 提交了另一个不同的 minimal fix。两个提交、两种思路,reviewer 被搞糊涂了;该 PR 的 token 消耗达到约 400k,而正常情况只有约 80k。
  • Metrics:重复修复尝试 2 次;人工整理耗时 45 分钟;根因是没有acting_on碰撞检查
  • Lesson:动作型循环(action loop)必须在状态文件里维护branch lock。修复动作是:在 docs/multi-loop.md 中加入碰撞检测规则——任何循环在创建 worktree 之前先读取所有 pattern 的状态文件;CI Sweeper 拥有红色 CI 的修复权,PR Babysitter 看到ci-sweeper-state.md中该 PR 已有acting_on记录就主动跳过。

这条故事的工程价值在于:它把"两个 Agent 抢同一个 PR"这种模糊的协调问题,精确归因到状态文件的acting_on字段缺失,从而让修复方向变得非常具体——不是"加强沟通",而是"加一把锁"。

四、真实案例二:Dependency Sweeper 无视红色 CI 引发的预算雪崩

stories/dependency-vs-ci-sweeper-collision.md记录了一次更严重的连锁事故,冲突维度覆盖了分支、token 预算和状态文件:

  • Setup:CI Sweeper 以/loop 15m(活跃时段)盯着红色 main;Dependency Sweeper 以/loop 6h运行;两者共享main分支和活跃 CI。
  • What Broke(三个层次):
    1. 分支与 CI 冲突:CI Sweeper 正在 main 上修复由 API 契约变更引起的测试回归时,Dependency Sweeper 按计划触发,未经检查就把一个"安全的"小版本依赖更新直接合并进已经变红的 main;
    2. 预算耗尽:这个依赖更新引入了传递性回归,破坏了更多测试;CI Sweeper 对此毫不知情,继续在已被新破坏的环境中修复旧 bug,不到一小时烧光了当天约 150 万 token 的预算;
    3. 状态文件冲突:两个循环同时尝试写入loop-run-log.md,导致 git push 失败和锁重试,拖延了人工介入。
  • Metrics:浪费约 150 万 token;冲突提交 4 个;人工调试 3 小时;根因是 Dependency Sweeper 无视了红色 CI 状态
  • Lesson当高优先级修复正在进行时,低优先级变更循环绝不能执行。修复动作是:在 docs/multi-loop.md 定义严格的优先级栈;Dependency Sweeper 增加 pre-flight 检查——先读ci-sweeper-state.md确认 main 的 CI 是否绿色,非绿则跳过执行并推迟 2 小时重试;同时用错峰的 cron 调度避免状态文件写冲突。

五、冲突的四个维度:分支、状态文件、预算与人工注意力

把两起事故放在一起,可以归纳出多循环冲突的四个标准维度——这正是失败故事任务书验收标准第 2 条要求作者明确指认的:

  1. 分支(branch):两个循环对同一分支/同一 PR 产生不同修复,导致冲突提交。案例一属于此维度。
  2. 状态文件(state file):多个循环同时写同一个文件(如loop-run-log.md),引发 push 失败与锁重试。案例二的第三层属于此维度。
  3. token 预算(token budget):低优先级循环破坏环境后,高优先级循环继续在坏环境下"做无用功",加速烧光共享预算。案例二的第二层属于此维度。
  4. 人工注意力(human attention):重复通知、矛盾提交迫使人类花 45 分钟~3 小时去"解开"冲突。两起案例的最终代价都落在这一维度。

这四类冲突并非独立发生——案例二就是一次"分支 + 预算 + 状态文件"的三重连锁。写失败故事时,明确指认冲突维度,等于为后续修复机制提供了定位坐标。

六、检测与预防机制:state file 的 acting_on 约定

针对案例一暴露的根因,docs/multi-loop.md 将"碰撞检测"固化为一条可执行的约定:

每个动作型循环都应在自己的状态文件中写入acting_on: branch-or-pr-id。在创建修复 worktree 之前:

  1. 读取所有其他 pattern 的状态文件;
  2. 如果另一个循环的acting_on与之匹配,则跳过本次运行,并把跳过记录写入loop-run-log.md

这套约定的背后是仓库统一的状态文件布局(见 docs/multi-loop.md):

STATE.md # Daily Triage(优先级、人工收件箱) pr-babysitter-state.md # PR 观察者 ci-sweeper-state.md # 活跃 CI 失败 + 尝试次数 dependency-sweeper-state.md # 进行中的依赖更新 post-merge-state.md # 清理积压 loop-run-log.md # 只追加的可观测性日志

原则可以概括为:一个分支同一小时内至多一个循环可以变更它;triage 只出报告,动作型循环才执行;所有循环共享同一份路径 denylist;token 预算按聚合口径管理(预算模板见 templates/loop-budget.md.template)。

七、冲突裁决:默认优先级栈

当循环冲突时,docs/multi-loop.md 给出了明确的优先级裁决表:

优先级循环理由
1CI Sweeper红色 main 阻塞一切
2PR Babysitter活跃 PR 对时间敏感
3Dependency SweeperCI 变红时暂停
4Post-Merge Cleanup非高峰、紧急度最低
5Daily TriageL1 只出报告,负责调度其他循环

在根目录 LOOP.md 中,应把调度表显式写成文档:

## Multi-loop schedule - CI Sweeper: /loop 15m (active hours) - PR Babysitter: /loop 10m (active hours, skip if CI Sweeper acting on same PR) - Daily Triage: /loop 1d 08:00 - Dependency Sweeper: /loop 6h (skip if main CI red) - Post-Merge: /loop 1d 22:00

案例二正是这条栈的活教材:Dependency Sweeper(优先级 3)在 CI Sweeper(优先级 1)活跃时动了 main,违反了"CI 变红时暂停"的规则,代价是 150 万 token。此外,docs/multi-loop.md 还建议在STATE.md中设一个共享的Human Inbox区块,把跨循环的模糊事项显式提交给人类裁决,例如:

## Human Inbox (ambiguous / cross-loop) - [ ] PR #42: CI Sweeper and PR Babysitter both flagged — human pick owner

同时,多循环系统应该渐进式上线:先跑 Daily Triage(L1),再上 PR Babysitter(L2),Post-Merge Cleanup 可 L1→L2;只有当 PR Babysitter 的尝试上限与 verifier 机制被验证运行两周稳定后,才考虑加入 CI Sweeper(见 docs/multi-loop.md 的"safe three-loop setup"示例)。

八、机制落地:loop-worktree 的 advisory lock 把约定变成代码

acting_on约定本质上是"人肉检查"——靠控制脚本自觉执行。loop-engineering 把这条约定进一步工具化,落到了 tools/loop-worktree 中。从 lock.ts 与 cli.ts 的源码可以确认:

  • 锁存放在.loop-worktrees/locks/<owner>.json,一个 owner(通常就是 pattern 名)一个文件;
  • --owner被限制为字母、数字、._-(不允许路径分隔符),因为它直接作为锁文件名使用;
  • --ttl可选(如30m6h1d),不传则锁永不自动过期,只能显式 unlock;过期锁不会静默忽略,而是由locks --sweep报告、--force删除;
  • 并发lock调用通过一个短生命周期 mutex 文件串行化,防止两个进程在"检查-写入"之间竞态双双通过重叠检查——这正是该机制存在的目的(见 lock.ts 中withLocksMutex的实现注释)。

标准用法是在控制脚本里配对lock/unlock(见 loop-worktree README):

loop-worktree lock --paths package.json,package-lock.json --owner dependency-sweeper --ttl 6h \ || exit 2 # 其他 owner 持有重叠路径 -- 跳过本次运行 loop-worktree create --run-id "$RUN_ID" --pattern dependency-sweeper # ... 执行修复 ... loop-worktree unlock --owner dependency-sweeper

关键设计点在于锁是按路径 glob 而不是按 run id 键控的——这样它能捕获不同 pattern 之间的跨循环碰撞(比如 CI Sweeper 和 Dependency Sweeper 都要动package.json),而不只是同一个 pattern 内部的冲突。路径重叠的比较是分段进行的:通配符段(***)与任意段兼容,因此src/**src/foo.ts重叠,而docs/apidocs/apidocs.md不重叠。文档明确这是有意为之的简单实现——一把 advisory lock,而非完整的 glob 引擎。

同时需要强调的是它的边界:loop-worktree create本身不检查锁lock/unlockcreate靠控制脚本中的配对约定保持一致——这与loop-context --checkloop-worktree mark --status escalated的配对方式同构。从源码注释看,这正是仓库"prose plus tooling"哲学的体现:跳过lock的循环并不会被物理阻断。另外,loop-sandbox 通过自己的--lock-paths选项遵循同一套约定(一次性沙箱 Agent 运行同样可能碰撞定时循环的文件,但它默认不启用锁保护)。

九、如何撰写一篇合格的失败复盘(按验收标准逐条对照)

把任务书、两篇真实故事与 docs/multi-loop.md 的机制放在一起,可以整理出一份可直接执行的写作清单:

  1. 并发与调度(标准 1):如实列出循环清单、每个循环的 cadence(如/loop 15m/loop 6h)与运行层级(L1/L2)。参考 docs/operating-loops.md 中"报告型 triage 很便宜,只有在状态文件显示有可执行项时才派生子 Agent"的成本原则——调度设计本身就是故事背景的一部分。
  2. 冲突维度(标准 2):从分支、状态文件、token 预算、人工注意力四个维度中明确指认本次冲突落在哪里,最好给出量化的 token 消耗与正常基线(如"约 400k,正常约 80k")。
  3. 检测与变更(标准 3):说明检测手段(审计状态文件、查看 run log)与采取的机制变更——新增acting_on检查、调整优先级栈、加 kill switch(暂停调度器、人工通知)、错峰 cadence 都属于此类。成本与暂停时机可参考 docs/operating-loops.md:预算超 80%、误报率超 30%、同一事项 48 小时内两次升级时应当降速,生产事故中应暂停自动修复循环。
  4. 机制链接(标准 4):如果调整了优先级栈,链接到 docs/multi-loop.md;如果引入了工具化锁,可进一步引用 tools/loop-worktree/README.md 的 "Preventing multi-loop collisions" 一节。

最后记住失败故事应有的姿态:它是一份工程记录,不是事故检讨书。诚实地记录"What Worked"(哪些循环判断是正确的),精确地度量代价(token、提交数、人工小时),并把根因收敛到缺失的具体机制("没有acting_on检查""无视了红色 CI 状态")——这样的故事才是多循环协调机制持续进化的真实需求输入,也是仓库把成功故事(stories/multi-loop-coordination.md)与失败故事并置收录的根本原因。

十、结语:让失败成为机制设计的输入

多循环系统的稳定性不来自"更聪明的 Agent",而来自边界acting_on状态约定定义了循环间的所有权,优先级栈定义了冲突时的裁决顺序,loop-worktree lock把约定固化成跨进程的 advisory lock,错峰 cadence 与独立状态文件则从调度层面消解竞争。两起真实事故的共同结论是:每当一个低优先级循环在高优先级循环活跃时无视共享状态执行变更,代价就会成倍放大——从一次冲突提交,演变为百万级 token 浪费和数小时人工调试。写好一篇 multi-loop failure story,本质上是把你踩过的坑,翻译成下一个循环系统可以引用的机制需求。

【免费下载链接】loop-engineeringPractical patterns, starters & CLI tools for loop engineering with AI coding agents. Design systems that prompt and orchestrate agents (inspired by Addy Osmani and Boris Cherny). Includes loop-audit, loop-init, loop-cost.项目地址: https://gitcode.com/gh_mirrors/lo/loop-engineering

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询