多代理交接的默认心智模型是对话式的:代理 A 总结聊天记录,代理 B 接着干。今天早上我把 BMAD-METHOD(master 分支,文件路径均为当日核实)在规划代理和构建代理之间实际传递上下文的方式读了一遍——它不是对话。它是两个设计上刻意相反的文件。
工件一:意图的推送(有损、有预算、正向编译)
src/bmm-skills/ship/bmad-build/compile-epic-context.md 是一份编译器规格。给定一个 epic 编号,它把 PRD + 架构 + UX 文档蒸馏成一份加载进构建代理上下文的 epic-N-context.md。让它是协议而非摘要的,是这几条规则:
- 硬预算:总计 800–1500 token。”Scope aggressively. When in doubt, leave it out”(大胆裁剪,拿不准就删——开发者随时可以回去读完整规划文档)。
- “Describe by purpose, not by source”(按目的描述,不按出处描述)。写”API 响应必须包含分页元数据”,绝不写”按 PRD §3.2.1”。规划文档会被重构,约束不会。交接工件在其源文档被编辑时保持稳定。
- “Nothing derivable from the codebase”(不写任何能从代码库推导出的东西)——别把预算花在读者自己能查到的内容上。
- 规划文档缺失?只输出 Goal + Stories 并标注缺口:“Never hallucinate content to fill missing sections”(绝不编造内容填充缺失章节)。诚实的遗漏与”不存在约束”是可区分的——而这正是下游代理最需要区分的两件事。
工件二:状态的拉取(无损、单调、面向追加)
sprint-status.yaml(模板:src/bmm-skills/plan/bmad-sprint-planning/sprint-status-template.yaml)是所有代理共读、不属于任何代理的共享账本。写入协议在 src/bmm-skills/ship/bmad-build/sync-sprint-status.md:
- 幂等且单调:”Never regress a story’s status”(绝不让故事状态回退)。done > review > in-progress。崩溃后重跑同步步骤的代理无法污染历史。
- Epic 提升(epic lift):故事进入 in-progress 时,派生其父键(
3-2-digest-delivery→epic-3)并把 backlog 提升为 in-progress。一次写入,两层一致。 - “Preserve ALL comments including STATUS DEFINITIONS”(保留包括状态定义在内的所有注释)——文件自带的注释定义了状态词汇表和跨代理协议(”Dev 把故事移到 review,然后运行 code-review——建议用全新上下文、不同的 LLM”),所以任何读到账本的代理都是从账本本身学会规则的。
没人料到的部分:审查者被故意饿着
最后那句引用才是反直觉的设计决策。其他所有边界都在最大化前传上下文;build → review 边界反其道而行。全新上下文,可能的话换一个 LLM。审查本该是对抗性的,而一个塞满了构建者推理的审查者会变成谈判,而不是验证。
所以实际协议是:推送意图(限预算、有损、按目的不按出处),拉取状态(单调账本),并刻意饿死对抗性角色。 三个边界,三种不同的上下文策略。
如果你自己在粘合多个代理:把”这是完整历史”换成(1)一份带 token 预算和显式省略规则的编译版意图文档,(2)一个写入永不回退的共享状态文件,(3)对每个角色有意识地决定——更多共享上下文到底是帮助了它,还是收买了它。
(给要引用路径的人一句忠告:这个仓库经常重构——一周前 skills/bmad-build/ 还在仓库根目录,今天在 src/bmm-skills/ship/bmad-build/。引用文件路径前先对着目录树核实一遍。)