瓶颈搬家了
Playbook 的核心判断,也是我这两年最深刻的体感。
传统 SDLC 的每一道闸门、每一次评审、每一个交接,都是为了一个前提设计的:写代码最贵。当代理把构建阶段压到几小时,这个前提塌了。瓶颈不会消失,它只会搬家:搬到构建的左边(计划、设计)和右边(评审、部署)。
我看到的失败模式与此完全同构:代理写得飞快,然后卡在我还没想清楚需求、卡在我没空评审、卡在 CI 红了没人看。加速代理而不改造流程,只是把等待换了个地方。
没有⼈确切知道⾃⼰想要什么。
从流水线到环:工件链即审计轨迹
Playbook 里最重要的一个概念:每个阶段结束时提交一个工件,下一个阶段从读它开始。链条本身就是审计轨迹。
Playbook 的名字是 intent.md → spec.md → plan.md → diff + tests → PR review → incident record。我不使用完全相同的文件名,但我的链条是同构的,而且我在每一环上都挂了一个具体的技能:
工件是交接协议
代理会话的上下文会满、会断。工件是唯一可靠的跨会话记忆。handoff 技能专门负责把一次对话压缩成下一个代理能接着干的文档。
工件在 git 里
每个工件带作者和时间戳,评审记录、修订历史天然可追溯。我在 course-video-manager 里存了 近 60 份 ADR,每份记录一个曾经难以解释的决定。
人类在闸门处
人类不对每个阶段亲力亲为,而是在工件被接受的那一刻做决定:接受拷问的结果、接受规格、批准票图、合并 PR。判断留给人类,执行交给代理。
六阶段 × 我的技能:一张总图
Playbook 把实践分成六个非线性阶段。我的技能集不是按阶段组织的,它按「谁来调用」组织。把两张地图叠在一起,就得到我的完整工作方式。
关键设计:谁调用谁
我的技能沿一条轴切分:用户调用(user-invoked)的只做编排,比如 /grill-with-docs、/implement;模型调用(model-invoked)的装的是可复用的纪律,比如 tdd、code-review、grilling。编排技能可以唤起纪律技能,但两个编排技能永不相调。这个约束让每条流程都保持浅而清晰,技能之间可以自由组合而不互相纠缠。
计划与设计:拷问是最小对齐原语
Playbook 的 Plan 阶段是「用代理 brainstorm 出 intent.md」。我做的比它更狠一点:我让代理拷问我。
最常见的失败模式是对齐失败。你以为代理知道你要什么,直到它把东西做出来,你才发现它完全理解偏了。修复办法不是写更长的提示词,而是一次拷问(grilling):grilling 技能让代理对你进行 relentless 的访谈,直到设计树的每个分支都有答案。它背后没有魔法,就是把「分析师会问的问题」变成纪律:范围、用户、约束、成功长什么样。
grill-with-docs:拷问的同时把语言留下来
我的招牌技能 grill-with-docs 在拷问之上加了两样东西。第一是共享语言:访谈中敲定的术语当场写进 GLOSSARY.md,每条带「避免使用」的反义词表。第二是ADR:难以口头解释的决定当场落成架构决策记录。
course-video-manager GLOSSARY。Eric Evans 的 ubiquitous language,在 AI 时代多了一层含义:它是压缩代理上下文开销的编码。与 playbook 的对照
playbook 的 Plan 是「发起人和 Claude brainstorm,产出 intent.md」。我的 to-spec 对应它之后那步:不做访谈,直接把已讨论的对话综合成规格并发布到 issue tracker。
差别在默认方向:playbook 让代理问发起人,我用 grill-me / grill-with-docs 把访谈做成强制入口。先对齐,后成文。
为什么拷问值得每次都做
- 你想不清楚的分支,会在构建阶段以最贵的方式暴露
- 被代理追问逼出来的答案,比你自己写下来的更完整
- 访谈记录直接成为规格的第一稿,零转写损耗
设计即分解:示踪弹票与依赖图
规格被接受之后,我不让代理直接开工。先切成票,每张票声明自己被谁阻塞。
to-tickets 把规格拆成示踪弹(tracer bullet)式的垂直切片:每张票切一条窄但完整的路径,贯穿 schema、API、UI、测试每一层;完成即可独立验证;大小恰好装进一个新鲜上下文窗口。每张票显式声明它的阻塞边,票集天然构成一张有向无环图。
Playbook 的 plan mode,我的 to-tickets
playbook 让工程师在 plan mode 里和 Claude 迭代出 plan.md(列文件、顺序、风险、证明方式)。我得到的东西等价但更进一步:每张票自带依赖边,于是「计划」不仅是给人看的文档,还是给调度器看的图。wayfinder 把同样的思路放大到「一个会话装不下的大块工作」:先建一张决策票地图,逐张消解,直到通往目的地的路清晰可见。
构建:红绿循环与新鲜上下文
对齐和分解都完成之后,构建反而最简单。但前提是你给代理装好了两样东西:反馈环和纪律。
TDD:代理时代的反馈放大器
没有反馈,代理就是盲飞。tdd 技能把红-绿-重构循环变成可注入任何项目的纪律,而且它比人类 TDD 更严格地执行两条规则:先写失败的测试,一次只切一片。测试只写在预先确认的接缝(seam)上:公共接口,而非内部实现。
反模式 · 同义反复
断言用代码同样的方式重算期望值,测试凭构造通过,永远不可能与代码意见相左。期望值必须来自独立的真值:规格里的字面量、演算过的例子。
反模式 · 实现耦合
mock 内部协作者、测私有方法、绕过接口直查数据库。破绽:行为没变但重构时测试碎了。好测试读起来像规格,且能活过重构。
反模式 · 水平切片
先写完全部测试再写完全部实现。批量测试验证的是想象中的行为,对真实变化麻木。替代:垂直切片,一个测试配一个实现,循环往复。
implement 与 implement-spec:编排的艺术
- 单线工作:
implement读票,在约定接缝上唤起tdd,跑类型检查,收尾时唤起code-review,然后提交。 - 并行工作:
implement-spec把票图当成任务图,在就绪前沿(ready frontier)上同时跑多个实现者子代理,最后统一 code-review。 - 每个子代理都从冷上下文启动,这是特性不是妥协。子代理的意义就是逃离父会话的假设污染。我在 AGENTS.md 里明文要求派发子代理时必须开新鲜上下文,因为某些 harness 默认 fork 父对话,而 fork 恰恰继承了要逃离的东西。
- 并发的真正上限:不是能开多少会话,而是你能评审多少。playbook 说 two or three 是合理起点,我的答案一样:加会话的速度以评审跟得上为限。
永远小步前进。反馈的频率就是你的速度上限。永远不要接手太大的任务。
测试:让代理亲眼看见结果
Playbook 说「给 Claude 一个反馈环」。在 course-video-manager 里,我把这句话推到了它逻辑的终点。
规则很朴素:任何命令序列 + 领域知识才能完成的验证,都要包装成一条命令。pnpm typecheck、pnpm test、pnpm lint:boundaries,从根目录一键可达,健康输出写进 CLAUDE.md。UI 工作再进一步:必须有浏览器。
实践证据 · verify-cvm 与写账本(Write Ledger)
course-video-manager 的 CLAUDE.md 里有一条硬规矩:「任何在 UI 有可见效果的改动,开 PR 之前必须在浏览器里用 verify-cvm 验证。」测试全绿、check 全绿都不能替代它。
verify-cvm 是一个项目级技能:它把应用指向每轮运行单独克隆的数据(允许写,永不碰生产),代理由它驱动浏览器,最后留下一份写账本:我点了什么、看见了什么、改了哪些数据。PR 描述里附上截图或证据路径。无 UI 效果的改动也要写一行 No UI change 说明,不许省略。
保护反馈环本身
代理修代码时绝不能 weaken 检查它的东西。我的做法与 playbook 的 hook 建议同效但更朴素:修 bug 时不许改测试,测试在修复之前存在且代理无权重写,修复通过才是 bug 消失的证据。diagnosing-bugs 技能把整条调试路径分阶段设卡:先造一个对这只 bug 变红的反馈环,再最小化、假设、插桩、修复、回归测试,一步不跨阶段。
评审与门禁:建议与强制的分层
这里是我和 playbook 分歧最值得说的地方。
playbook 把控制分两层:技能是 advisory control(让代理在写代码时应用策略),hook 是 deterministic layer(每次动作都执行,可 allow/ask/block)。这个分层是对的。但我的落地更轻:我没有重度使用 hook,我的确定性层由三样东西构成:不可篡改的测试、verify-cvm 的浏览器证据、分支保护。这是诚实的取舍:hook 适合受监管行业,我的项目用更少的机械换来同等的关键约束。
code-review:双轴评审,两个互不相见的评审员
code-review 对固定基点以来的 diff 做两轴评审,并且用两个并行的子代理各管一轴,互相不污染:
轴一 · Standards
仓库的编码标准(course-video-manager 里有 CODING_STANDARDS.md、EFFECT_STANDARDS.md、TESTING_STANDARDS.md)加上 Fowler 坏味道基线。回答:代码是不是以这个仓库的方式写的。
轴二 · Spec
diff 是否忠实实现了来源工单或规格。回答:做的是不是被批准的那件事。这正是 playbook 里「review 对照 spec.md 和 plan.md」的合规轴。
评审结果进 pr 技能的固定形态:让改动清晰的最小可视化摘要 → 前后对照的证据 → 合并危险判断(单行道还是双行道,爆炸半径多大)。人类评审者拿到 PR 时,机械证据已经附在上面,注意力可以全部留给意图与风险。这就是 playbook 说的「human attention moves up a level」。
门禁处的人性化
playbook 建议把「需要人类批准」的 hook 放在部署阶段,因为构建期的批准弹窗会把人重新塞回所有并行会话的关键路径。我的 wizard 技能是同一件事的正面版本:当人真的必须在场时(配基础设施、设凭证、走第三方后台),代理生成一个交互式 bash 向导,把人该做的步骤变成一条可以跟着走的路。
维护:闭环与自主学习
Playbook 的最后一章是「闭环」:触发器在没有人的路径上唤起代理,诊断结果作为 intent.md 重新进入流水线。我有一套野路子的原型。
retro:每次会话结束后的环境自检
retro 是我在会话末尾跑的最后一个技能:让代理回顾刚才的工作,对它自己的工作环境提出改进建议,按严重度排序。导航不顺?检查命令缺了?steering file 里少了规矩?这些改进写回 CLAUDE.md、GLOSSARY、测试设施。错误犯第二次,纠正就进 steering file。这条规则与 playbook 的 CLAUDE.md 建议逐字同构。
ralph.sh:我的自治闭环实验
course-video-manager 的 plans/ralph.sh 是我在 playbook 发布前就写下的自治循环原型,结构和 Stage 6 惊人地一致:
docker sandbox run claude -p "@plans/task.md @progress.txt
1. Find the highest-priority feature and work only on that feature
2. Check pnpm typecheck and pnpm test
3. Update the PRD with the work done
4. Append progress to progress.txt (a note for the next person)
5. git commit. ONLY WORK ON A SINGLE FEATURE.
If the PRD is complete, output <promise>COMPLETE</promise>"
- 确定性触发层:一个 bash for 循环,与 playbook 的 detection script 同角色。检测保持确定性,不掺模型。
- 沙箱执行:整轮跑在 docker sandbox 里,与 playbook 的 sandbox + scoped credentials 要求一致。
- 跨迭代记忆:
progress.txt是给「下一个接手的人」的留言板,等价于工件链,只不过粒度是一轮迭代。 - 自检门槛:typecheck + test 每轮必过,等价于 confidence gate。
- 完成信号:
<promise>COMPLETE</promise>让循环自己停。完成时给我发一条通知。
这是「loop runs itself」的最小可行形态。playbook 用监控指标 breach 作为触发,我用一张 PRD 作为任务清单;playbook 的代理把诊断写成 intent.md 进评审闸门,ralph 的产出直接是带绿色 check 的提交。成熟度不同,骨架相同。
对抗熵增
代理加速编码,也加速软件熵。improve-codebase-architecture 定期扫描仓库里的「加深机会」(deep module:大行为量藏在小接口后),以视觉化 HTML 报告呈现,然后我挑一个,grill 透它。Kent Beck 说每天都要投资系统设计,这个技能是我给这句话做的闹钟。course-video-manager 的边界 lint(pnpm lint:boundaries 强制 core 包无文件系统、无子进程、无 git 耦合)是同一原则的结构化表达:复杂度想渗入,CI 先说不。
我的原则
八条。每条背后都有一次具体的失败。
01 · 技能要小,流程不归它管
GSD、BMAD、Spec-Kit 试图拥有整个流程,代价是你失去控制,流程本身的 bug 无解。我的技能小、可改、可组合,适配任何模型。这是我对 playbook「plays 是模块化的」最激进的诠释。
02 · 先对齐,后成文
拷问是每次改动前的强制入口。没有 grill 过的规格,不许进 to-tickets。
03 · 语言就是架构
GLOSSARY 不是文档,是代码的命名来源、测试的词汇表、评审的度量衡。它的回报是每次会话复利。
04 · 新鲜上下文是特性
子代理从冷启动开始,不是为了省 token,是为了逃离父会话的假设。fork 继承父上下文,恰恰杀死了子代理存在的意义。
05 · 测试在接缝上,期望来自独立真值
同义反复式测试比没有测试更糟,它给你虚假的绿色。
06 · 建议与强制分层
技能管「应该」,测试、证据、分支保护管「必须」。别把 advisory 当 deterministic,也别为每条规矩上 hook。
07 · 评审能力是并发上限
开第四个会话之前,先问自己的评审跟不跟得上。代理放大产出,也放大评审债务。
08 · 人类的判断留在循环之上
playbook 的收尾句,也是我的:循环不停地转,人类的判断悬于其上。闸门处做决定的人,永远是人。
30 天落地清单
不用一次全做。从任何一块「黏土」开始:不需要任何前置条件的那个。
| 周 | 动作 | 对应 playbook 阶段 | 领先指标 |
|---|---|---|---|
| 第 1 周 | 给仓库写 GLOSSARY.md(哪怕只有 10 个词);把 typecheck / test / lint 收敛成单命令并写进 CLAUDE.md 的「验证你的工作」块 | Build + Test | 首过 CI 率;代理重复犯错次数 |
| 第 2 周 | 引入拷问入口:每次改动前先 grill;访谈中敲定的术语当场进 GLOSSARY,难解释的决定落 ADR | Plan + Design | 首次对话到可执行规格的耗时;规格返工率 |
| 第 3 周 | 规格一律先过 to-tickets:示踪弹切片 + 显式阻塞边;实现走 implement(tdd 接缝 + 收尾 code-review) | Design + Build + Deploy | 计划到合并的时长;每改动返工轮数 |
| 第 4 周 | 会话末尾跑 retro,把环境改进写回 steering files;挑一个指标试一个自治循环(ralph 式),产出只走 PR 闸门 | Maintain | band breach 到 intent 的耗时;同类事故重复率 |
度量哲学直接继承 playbook:每个阶段配一个领先指标(下一次就能读到)和一个滞后指标(季度后才显现)。不要代理输出的虚荣指标,读 git 历史、PR 元数据和 CI 日志就够了。