Ship with skills, not vibes 把 25 支 skill 串成一条开发流程
这不是工具箱清单,是一条主干流程加几条匝道。从一个模糊的想法走到 commit,中间每一步该打什么、该在哪里停下来、以及哪些地方会安静地坏掉。
01
先建立三个底层观念
本页描述的是 mattpocock/skills(MIT 授权)第 1.2.3 版,25 支已发布的 skill。这套 skill 不是 TauX 的作品;这篇教学是。下面所有的判准、坑与剧本都是我们读完官方文档与 issue 之后重新编写的中文教材,不是翻译,也不是转载。
不先懂这三件事,后面每一支 skill 都会用错。
一、谁能叫它
这是整个 pack 唯一的分类轴线。
| User-invoked | Model-invoked | |
|---|---|---|
| 谁能触发 | 只有人类打出名字。其他 skill 也不能叫它 | 你可以打,agent 也会自己判断后抓来用 |
| 设置 | disable-model-invocation: true |
两者都不设 |
| description 写给谁 | 人类(slash command 清单) | 模型(含大量触发语句) |
| 定位 | 编排者:决定流程怎么走 | 纪律库:可重复使用的方法论 |
三个实务后果
- 文档写「接着跑
/implement」,那是叫你去打。agent 不会自己接下去。 - harness 不把 user-invoked skill 注入模型的清单,所以 agent 常常「以为」这些 skill 没安装。它们在,照打就是。
- 想确认到底装了什么,看
.claude-plugin/plugin.json,那才是权威。
规则本身:user-invoked 可以调用 model-invoked,但永远不能调用另一个 user-invoked。
二、四种角色
主干
从想法到 ship 的固定路径:grill-with-docs → to-spec → to-tickets → implement → code-review。
匝道
产生工作、然后并入主干:triage(别人丢进来的)、wayfinder(一个 session 装不下)、improve-codebase-architecture(定期体检产生题目)。
独立
随时抓来、用完就走:prototype、research、diagnosing-bugs、resolving-merge-conflicts、wizard、handoff、teach、to-questionnaire、wait-what、grill-me。
词汇层
没有流程,只提供精确用词,被别人借用:codebase-design(模块形状)、domain-modeling(领域语言)、writing-for-agents(给 agent 读的文档)、grilling(访谈原语)。
词汇层最容易误用
它们没有流程。你对着 codebase-design 说「开始吧」,agent 会自己发明一套流程,然后烧掉 100k token 重构你没问的东西(已登记的 issue 449)。词汇层要用「driver skill 在上、词汇层在下」的方式跑。
三、Phase boundary
一个 session 里的一块工作叫 phase(访谈、实作、QA…)。「我的 context 该怎么办」这个问题只在两个 phase 之间才成立。phase 中间没得选,只有继续,或把剩下的丢给 subagent。
| 顺位 | 选项 | 什么时候选 |
|---|---|---|
| 1 | 继续 | 下一个 phase 需要这个 phase 的原话,或你的 smart zone 还有余裕。这是唯一保住一手数据的选项,所以先排除它再考虑别的 |
| 2 | clear | 后面的东西全部可丢。最便宜,但判断错了就是单向 |
| 3 | handoff | 有东西要搬家:换 harness、换目录、给同事、把中途发现的支线分出去 |
| 4 | subagent | 任务范围够紧,可以你人不在也跑得完 |
| 5 | compact | 以上都不是。它是保底而不是首选,但实务上落点最多 |
最常被搞错的两个:handoff 不是「跨窗口的通用桥梁」,它买的只有可携性;compact 是树的底部而不是第一反应。三者保住的东西不同——compact 保住你的意图,clear 什么都不保,handoff 保住工作的移动能力。而这三个都会把对话(一手数据)变成摘要(二手数据)。
02
安装:两条路,选一条
两种安装方式代表两种哲学。装两次会让你每个 skill 都有两份。
路线 A — 订阅
claude plugins install mattpocock-skills
或在 session 内打 /plugin install mattpocock-skills。已在官方 marketplace,不用先加来源,更新自动到。代价:唯读,你不能改。
路线 B — 可改版
npx skills@latest add mattpocock/skills
会问你要装哪些 skill、装到哪些 agent 上。一定要勾 setup-matt-pocock-skills。文档以「你拥有的普通文档」写进 repo,可随便改;要更新时自己跑 npx skills update。
路线 B 的陷阱
你手改的 SKILL.md 会被 npx skills update 覆盖。任何想长期生效的行为,写在你自己的 CLAUDE.md / AGENTS.md(见 第 09 节),或每次调用时讲出来——不要改 skill 档。
想玩 beta
npx skills@latest add mattpocock/skills --skill=<name>
plugin 不会给你这些。撰稿时的 in-progress bucket 有 loop-me、writing-beats、writing-fragments、writing-shape、claude-handoff、setup-ts-deep-modules——没有文档页、随时可能改掉或消失。另有一个不在 plugin 内的 misc bucket:git-guardrails-claude-code(用 hook 挡危险 git 指令)、setup-pre-commit、migrate-to-shoehorn、scaffold-exercises。
03
前置设置,每个 repo 跑一次
/setup-matt-pocock-skills 是所有 engineering skill 的前置条件,不是流程的一步。
| 决策 | 它会先提议 | 什么时候才真的问你 |
|---|---|---|
| Issue tracker | 依你的 git remote 猜 | 每次都问——这是唯一真正的选择 |
| Triage 标签 | 沿用五个标准名 | 只有装了 triage 才问 |
| Domain 文档配置 | 单一 context:root 一份 CONTEXT.md 加 docs/adr/ |
只有侦测到 monorepo 信号才问 |
Tracker 四个选项:GitHub(需 gh)、GitLab(需 glab)、Local markdown(.scratch/<feature>/,连 remote 都不用)、Other(你写一段描述工作流程的话)。
Local markdown 是一等公民不是备案:单人项目、没有 remote,完全支持。但不要在用 GitHub 的项目同时用 local markdown,它们是替代品不是叠加。
「Other」也不是占位符——Jira、Linear、Azure DevOps 能跑就是靠它:你描述工作流程,它把你的话写进 docs/agents/issue-tracker.md,下游 skill 照那段话做。这也是为什么这整套没有绑 GitHub,而且你永远不用改 skill 档来换 tracker。
三个一定要知道的坑
一、它不会帮你建 label
triage-labels.md 只是「对照表」。全新的 GitHub repo 上那些 label 根本不存在,贴标签就会失败。自己先建一次:
gh label create needs-triage
gh label create needs-info
gh label create ready-for-agent
gh label create ready-for-human
gh label create wontfix
gh label create bug
gh label create enhancement
要用 wayfinder 的话,另外五个也要先建(gh 遇到不存在的 label 是直接失败):wayfinder:map、wayfinder:grilling、wayfinder:prototype、wayfinder:research、wayfinder:task。
二、它看文档存不存在,不是看你用哪个 harness
你在 Codex 但 repo 有残留的 CLAUDE.md,那段 ## Agent skills 就会写到 Codex 永远读不到的地方。解法:手动搬到 AGENTS.md,或让 AGENTS.md 当本尊、CLAUDE.md 只放一行指向它。
三、更新 skills 之后可以再跑一次
种子模板会改版,旧的 issue-tracker.md 可能对不上新的 skill。下游行为变怪时,重跑是最便宜的修法。
判断它成功了
docs/agents/issue-tracker.md与domain.md存在(装了 triage 还有triage-labels.md)- 你的 harness 真的会读的那个指令档里出现
## Agent skills - 之后
/to-tickets不再问你 issue 放哪;/triage是「贴」标签而不是「发明」标签 - skill 档本身一个字都没动。如果 setup 改了某个
SKILL.md,那就是出事了
04
全套 25 支地图
「硬依赖」那一栏是实战重点——依赖没装,skill 会安静地退化成一场即兴表演。
| Skill | 调用权 | 角色 | 一句话 |
|---|---|---|---|
| setup-matt-pocock-skills | User | 前置 | 每 repo 跑一次,设置 tracker、label 与文档配置 |
| ask-matt | User | 路由器 | 描述你的处境,它告诉你该打哪一串 |
| grilling | Model | 原语 | 一轮一轮的访谈引擎,其他 grilling 全建在它上面 |
| grill-me | User | 独立 | 无状态访谈,不需 repo、主题不必是程序 |
| grill-with-docs | User | 主干头 | 同样的访谈,加上读 codebase、写 CONTEXT.md 与 ADR |
| wayfinder | User | 匝道 | 一个 session 装不下的大工程,画成 decision ticket 地图 |
| to-spec | User | 主干 | 把对话收敛成一份 spec 并发到 tracker,不再访谈 |
| to-tickets | User | 主干 | 把 spec 或对话切成 tracer-bullet ticket 并声明阻塞边 |
| implement | User | 主干 | 照 ticket 做,内部驱动 tdd,收尾跑 code-review,commit |
| tdd | Model | 引擎 | red-green,只在事先同意的 seam 上写测试 |
| code-review | Model | 主干尾 | 对某个固定点的 diff 做 Standards 与 Spec 双轴审查 |
| triage | User | 匝道 | 别人丢进来的 issue 走状态机 |
| improve-codebase-architecture | User | 匝道 | 扫 codebase 找「加深模块」的机会,出 HTML 报告 |
| prototype | Model | 独立 | 用丢弃式代码回答一个设计问题 |
| diagnosing-bugs | Model | 独立 | 难 bug 与性能回归的六阶段诊断,先有 red loop 才能猜 |
| research | Model | 独立 | 背景 agent 读一手来源,留下一份带引用的 markdown |
| resolving-merge-conflicts | Model | 独立 | 逐 hunk 依「意图」解冲突,跑检查,完成 merge,绝不放弃 |
| wizard | Model | 独立 | 产生一支交互 bash script,带人类走只有人能做的步骤 |
| codebase-design | Model | 词汇层 | 模块、界面、depth、seam 的精确用词与四条原则 |
| domain-modeling | Model | 词汇层 | 主动建立与磨利领域语言,实时写进 CONTEXT.md 与 ADR |
| handoff | User | 独立 | 把当前对话压成一份可携的交接文档 |
| teach | User | 独立 | 把当前目录变成跨 session 的教学工作区 |
| to-questionnaire | User | 独立 | 把「只有别人知道」的决策变成一份问卷 |
| wait-what | User | 独立 | 刚刚那段话没听懂时打它,agent 重讲一次 |
| writing-for-agents | Model | 词汇层 | 写给 agent 看的文档(skill、指令档、spec、prompt)的准则 |
两个分岔要记住
- prototype 岔路:访谈中遇到「讲不出来、要看到东西才知道」的问题,停下来做 prototype,看完回来一行回答。
- spec 与 tickets 只在跨 session 才划算。单一 context window 做得完的改动,直接
grill-with-docs接implement,跳过中间两步。
05
主干七步,逐步实作
贯穿案例
内部工具 repo(Next.js 加 Postgres),要加「合约到期提醒」——列出 30 天内到期的合约、寄信给负责人、后台显示红点。跨 schema、API、UI 与寄信,够广,值得走完整流程。
Step 1 — 把模糊的想法烤成决策
/grill-with-docs 我想加一个合约到期提醒功能
开一个干净的对话,关掉 plan mode。plan mode 会催 agent 赶快产出计划,那正好和「保持在提问状态」相反。
会发生什么
它会读你的 codebase,然后一轮一轮问你问题。每一轮是当前 frontier——所有前置条件都已解决的问题一次问完,所以你不会被问到还悬在半空的问题。格式固定:编号标题、内文、一行建议答案。13 题通常落在 3 轮;46 题分 4 轮是很正常的一场。
你该怎么回
1 是
2 选第二个
3 不要,理由是我们的合约没有部分终止
4 我不知道
最大的失败模式是被动。连答四十个「同意」,出来一份 agent 写的、你点头过的计划——感觉很有生产力,因为它很长。但什么都没被真正决定,而结果带着它没赚到的确定性。主动的意思是:问得比你需要的精度还浅时推回去;范围在漂时讲出来;真的不知道就答「我不知道」,这是真的答案。
grillable vs ungrillable
「一张长表单还是三页?」「这个交互应该是什么感觉?」——这种问题谈不出来,需要有东西可以反应。碰到就停下来去做 prototype,看完回来一行回答。在 ungrillable 的问题上硬谈,是 session 爆炸的主因:agent 一直换句话问,你一直猜,范围膨胀来填补不确定性。
| 解决了什么 | 落在哪 |
|---|---|
| 一个术语——这项目自己的用词 | CONTEXT.md,当场写入,不是最后批量产出 |
| 一个难以逆转、没有 context 会觉得意外、真的有取舍的决定 | docs/adr/ 下的一份 ADR |
| 其他所有你决定的事 | 只在对话里,别的地方没有 |
第三列的意思
你谈出来的绝大部分东西只存在于这个 context window。所以不要 clear、不要 compact,直接在同一个对话里接 /to-spec。
CONTEXT.md 是词汇表,而且只是词汇表——不放实作细节、不放 spec、不放草稿。ADR 三个条件要同时成立,所以大部分 session 产出 0 份 ADR,这是设计如此。
这一步用你最好的模型。grilling 吃的是模型自己对「系统会怎么坏」的直觉;实作阶段反而比较吃 context,可以用便宜一点的。
Step 2 — 把已决定的事变成一份可存活的文档
/to-spec,在同一个对话里,不要开新的。
它不访谈你。你走到这一步该决定的都决定完了,所以它是「综合」——从对话、codebase、CONTEXT.md 与 ADR 里整理。
spec 是决策纪录,不是决策现场
它存在的理由是 context window 会结束:你刚烤出来的一切,都在一个即将被清掉的对话里。spec 就是那场对话的幸存者。所以它不验证任何事、不决定任何事。spec 里任何一句你没说过的话,都是缺陷。
它会先跟你确认 seam
写任何一个字之前,它会先草拟这个功能要在哪些 seam(测试观察行为的公开边界)上被测,然后拿来问你。它偏好已存在的 seam 而不是新开一个,并取它能取到的最高的 seam——理想的数字是整个改动只有一个。这个「事先同意的 seam」会一路往下传:tdd 只在事先同意的 seam 上写测试,code-review 会检查有没有用了没同意过的 seam。所以这段对话要认真回,不要拖到实作阶段。
| 你在哪 | 跑什么 |
|---|---|
| 什么都还没决定 | 先 grill-with-docs |
| 决定了,而且一个 context window 做得完 | 直接 implement,跳过 spec |
| 决定了,工作要跨好几个 session | /to-spec,然后 /to-tickets |
| 刚清空一张 wayfinder 地图 | /to-spec #<map_issue> |
常见坑
ready-for-agent标签的误会:spec 会被粘贴它,意思是「不需要再 triage 了」,是输入资格而不是工单。但如果你有无人看管的 agent 在轮询这个标签,它分不出差别,会一口气想把整份 spec 做完。解法:在那个 agent 的 prompt 里明确排除 parent spec,或/to-tickets跑完就把标签拔掉。- 重构型工作不合模板:模板重压 user story,架构工作套上去会变成「没人要求过的故事」。改靠 implementation-decisions 与 testing-decisions 两节,耐久的架构决定让它以 ADR 形式从
grill-with-docs落地。 - 它不会查重:不会搜 tracker 看有没有人开过同样的 issue,也不会把它遵守的 ADR 连进来。热区自己先搜一下。
- spec 太大会被截断:巨大的 spec 超过 tracker issue 能干净返回的量,而且没有本地副本可退。
/to-spec和/to-tickets之间不要 clear 也不要 compact。
Step 3 — 切成 tracer bullet
/to-tickets,同一个窗口,或 /to-tickets #<spec_issue>。计划只在对话里、没写成 spec 也行,它直接读对话。
| 水平切片(错) | 垂直切片(对) | |
|---|---|---|
| 一张票交付 | 改动的一层(全部 schema 一张、全部 API 一张) | 穿过所有层的一条细路 |
| 落地后 | 每层都到位前什么都不能动 | 自己就能 demo |
| 验收条件 | 必须伸手到别张票拥有的工作 | 只评自己拥有的东西 |
这是最常被违反的规则,代价有实测:某团队用 26 张按层切的票(corpus、producer、aggregator、selector),平均每张票关闭要跑 20 次 agent,其中约四分之三是重工。他们自己的检讨把每一类失败都追回到水平切片,而不是实作质量。
你要做的检查
对每一张票问一句——「这张做完我能 demo 什么?」答不出行为的,就是水平切片。有人会在每张票加一行 demo path,据报能把模型推向垂直分解。
发布前
Prefactoring:它会先找「先让改动变容易,再做那个容易的改动」的工作,排在最前面。然后给你编号清单并质询你:粒度对不对、阻塞边是不是真的、有没有该合并或拆开的。在你核准之前不会有任何东西进 tracker——这个质询步骤就是你推回去的地方。
宽重构是唯一的例外
有一种形状打破 tracer-bullet 规则:单一机械式改动,但爆炸半径遍及全 codebase(改一个字段名、换一个共用类型)。一次编辑打烂上千个调用点,没有任何垂直切片能绿灯落地。走 expand–migrate–contract:Expand——新形式加在旧形式旁边,什么都不坏;Migrate——依爆炸半径分批搬调用点,一批一张票,都被 expand 阻塞,CI 保持绿灯因为旧形式还在;Contract——没有调用者了才删掉旧形式,被所有 migrate 批量阻塞。
常见坑
- 三行的改动切出 12 张票:过度分解是最常见的摩擦。在质询步骤叫它合并。更根本的答案是:整个改动塞得进一个 context window,你根本不需要这支 skill。
- GitHub 上没建成 sub-issue:已知未修(issue 554),Codex 更严重。
gh自 v2.94 原生支持gh issue create --parent与gh issue edit --add-sub-issue。 - 「Blocked by」只写在内文:同类问题(issue 513)。GitHub 有原生的
gh issue create --blocked-by。因为阻塞者先发布,号码在建立时一定拿得到。 - 验收条件什么都没评到:对每一条,指出「什么观察会证明它为假」,并确认它在起始 commit 上是红的。
- 票发完了,然后呢?没有自动派工。看板面、数没有未完成阻塞者的票有几张,就开几个 agent session。一票一个全新 context,中间 clear。
Step 4 — 一票一个 session
/implement https://github.com/you/repo/issues/12
为什么要写完整 reference
/implement #2 的 #2 是对「agent 看得到的任何编号清单」解析的——在新 session 里那可能是一个 todo 档或 checklist,而不是你设置的 tracker。而且它解析得很自信、不会 fail-closed,所以错了你不会马上发现。传完整 URL 或 owner/repo#2,并要它把标题念回来确认再开始。
一次 run 的五拍
- 读 ticket 或 spec,推出 seam
- 在事先同意的 seam 上驱动
tdd,一次一个 red-green 切片 - 频繁 typecheck,过程中跑单一测试文档
- 最后跑一次完整测试套件
- 跑
code-review,然后 commit 到当前 branch
它绝不做的事
它从不重开计划。没有访谈、没有澄清回合、不会提议另一种做法。上游决定的东西就是输入,它的工作就是把它变成一个 commit。这正是它和「对一个新 agent 打『做这个』」的差别——后者会边做边重新设计。
| 症状 | 说明 |
|---|---|
| 跑完了,但票还开着、验收条件还没打勾 | 正确且预期。implement 没有收尾步骤,它停在 commit。票要你自己关——这在依赖链上咬最凶:frontier 的定义是「阻塞者全关」,没人关就永远没有票变成可做 |
| 能不能一次做完所有票、平行跑? | 不行。同一 checkout 并行跑多个 implement 比「不支持」更糟:有实地回报一个下午内出现 amend 打到另一个 session 的 commit、stash 消失、commit 落到错的 branch。社区 workaround 是 worktree,但 stash 仍共用 |
| 能不能开 PR? | 没有内置。它 commit 到当前 branch,也不会帮你开 branch。有人在调用时覆写 |
| code-review 说看不到我的改动 | 它审 diff <fixed-point>...HEAD,排除 staged 与 working tree。implement 在 commit 前跑 review,所以除非已有中途 commit,那个 diff 里没东西。先 commit 再 review |
| 一张票烧掉 150k token | 通常是票太大而不是用错。一个 run 含探索 codebase、每个 seam 的 red-green、完整套件、review,超过 100k token 是正常的。杠杆在上游:把票调到一个新窗口装得下。单张票一直爆就拆它,不要调高 effort |
有些人刻意不要内置的那道 review——写程序的 agent 审自己写的程序会偏袒自己的解法。在干净的 session 里对固定点另跑 code-review 是合理的替代做法。
Step 5 — red-green 引擎
tdd 是参考数据,不是驱动器:它握着循环的规则,跑 session 的是别人(你,或 implement)。
Red-green
写失败的测试,然后只写刚好让它通过的程序。不预先写下一个测试。没有 refactor 阶段——2026 年 6 月移除,因为 agent 几乎从不执行它,而且 review 与 implementation 分开 session 效果更好。重构归 code-review。
Vertical slice
一个 seam、一个测试、一个最小实作,然后重复;第一个 cycle 是 tracer bullet,证明一条路端到端走得通。反面是先写所有测试再写所有程序——那是在验证想像的行为,检查东西的形状而不是用户做的事,并且在你理解实作之前就把你绑进一个测试结构。
Pre-agreed seam
规则是绝对的:没有确认过的 seam,不写测试。完整链路里 seam 在 to-spec 就谈好;单独调用时它直接问你。
| 反模式 | 征兆 |
|---|---|
| Implementation-coupled | 你改一个内部函数名字、行为没变,测试却坏了。mock 自己的内部协作者、断言调用次数、用数据库查询验证而不是用界面 |
| Tautological | 期望值是「照程序的算法」算出来的,所以测试必然通过。期望值必须来自别的地方:已知良好的字面值、手算的范例、spec |
| Horizontal slicing | 一批测试在任何实作之前就落地了 |
Mock 只用在系统边界:外部 API、时间、随机。有时是文档系统或数据库。不要 mock 你自己的模块。
常见坑
- 「它问我选哪个 test seam,我根本不知道选哪个」:最常见的摩擦(issue 607)。提示只列出候选 seam 的名字,没说各自抓到什么、漏掉什么。回问 agent 取舍:component 层的 seam 漏掉什么是 integration seam 抓得到的、慢多少。这也正是完整链路要在
to-spec就谈 seam 的理由。 - 它先写实作才写测试:会发生。skill 是「带着这件事一起活」的写法,没有任何指令能让 agent 100% 遵守。某个切片真的需要严格遵守,就盯着它跑。
- 它先写浏览器测试然后鬼打墙:有人回报 agent 先写 Playwright、然后在一个还不存在的功能上反复跑、最后结论是「测试坏了」。在 repo 的指令档声明:browser 测试在行为可运作之后才写。
- 它不知道你其他张票:对着一张票跑,它会很开心地提议属于兄弟票的工作(issue 129)。把 spec 和 ticket 一起给它有帮助;一开始就把票切对更有帮助。
Step 6 — 双轴审查
/code-review main
固定点你必须提供;不给它会问你,不会乱猜,而且会先验证 ref 解得出来、diff 非空,才生 sub-agent。
| Standards | Spec | |
|---|---|---|
| 问题 | 做得对不对? | 做的是对的东西吗? |
| 读什么 | repo 自己记载的规范,加内置 smell 基准 | 源头的 issue 或 spec |
| 报什么 | 明文违规(可以是硬性的)加 smell(永远是判断题) | 缺漏或部分实作的需求、范围蔓延、实作错的需求 |
| 每个发现必须引用 | 规范档加条目,或 smell 名称加 hunk | spec 的那一行 |
两个轴各跑在自己的 sub-agent 里,互相看不到对方的推理。报告结尾给「每个轴各自最糟的问题」,并拒绝跨轴选一个总冠军——因为一个改动可以一轴过一轴挂:遵守所有惯例但做错东西的程序 Standards 过、Spec 挂;完全照票做但破坏 repo 惯例的反之。混合的裁决会让过关的那轴掩护挂掉的那轴。
Smell 基准是 Standards 底下的地板:Fowler《Refactoring》第 3 章的 12 个 code smell。每个都是「可能是…」的启发式标签、永不是硬性违规,而且都以「它是什么,怎么修」陈述,所以发现送到你面前时自带一个动作。你的 linter 已经在管的东西,两个轴都跳过。
常见坑
- 和内置的同名指令撞名:最常被回报,未修。内置那个是「在 diff 里找 bug」,这个是规范与 spec 合规。装了就有一个会赢,谁赢取决于安装方式。
- sub-agent 又去调用自己,生出更多 agent:多人多 harness 重现过,有一次到 50 个以上。fork 上的修法是在两个 sub-agent brief 各加一行「不要调用 code-review 或生成额外 agent,直接执行这次审查」。无人看管跑这支时,盯着 agent 数量。
- 该在写程序的同一个 session 跑吗?偏好用新的。有人讲得很好:同一个 context 审自己,等于带着 slash command 的确认偏误。
- 发现可以信吗?不查证不能信。sub-agent 的输出是假设不是证据。它汇总两份报告但不逐条回文档验证,所以引用可能指错位置或夸大影响。看每个发现的引用再行动。
- 为什么每次跑都找到新问题?修改会创造新表面,而判断题那半不是决定性的。没有收敛保证。把一次 pass 当成线索清单,处理有明文规则背书的,然后停手——不要跑到它「干净」为止,它不会。
Step 7 — 收尾与循环
一票的循环:
- clear context
/implement <ticket>(tdd在里面跑)- commit
/code-review <fixed-point>,干净 session- 手动关票、对验收条件——implement 不会做这件事
- 回到 frontier 抓下一票,回到第 1 步
节奏
- 每天:主干。一票一 session,中间 clear。
- 每几天:
/improve-codebase-architecture,把结构债变成新的题目喂回主干。 - 有 inbound 工作时:
/triage。没有外部回报的项目,你会很少开它。 - 需要补技能时:
/teach,开一个专属目录。
别忘了
整条链唯一没有人帮你做的事,是关票与对验收条件。implement 停在 commit。依赖链要往前走,就得靠你把票关掉——不然 frontier 永远不会出现新的可做项目。
06
情境索引,什么时候抓哪一支
主干以外的 skill 都是「特定情况才岔出去」。这里按你的处境排列。
独立 — prototype
这个问题我谈不出来
它写的是回答一个问题的丢弃式代码。问题先来,而且决定后面所有东西的形状;回答错问题的 prototype 是纯浪费,不管它多好看。「丢弃式」是对怎么写的约束,不是「一定要销毁」的承诺:没有测试、除了跑得起来以外没有错误处理、没有抽象、没有持久化。
两条分支的产出物差很多。「这个逻辑或状态模型感觉对吗?」得到一个可分享的单一 HTML 档——自带 state panel、free-play 按钮、分页式导览,全部用领域语言标示,可以直接丢给设计师或领域专家自己感觉;背后逻辑是一个干净的纯模块,不碰 DOM,验证过就能抬进正式代码。「这个看起来该长怎样?」得到同一 route 上几个差异剧烈的 UI 变体,用浮动底列切换;变体必须在结构上不同意,不是颜色——三个微调过的 card grid 是壁纸不是 prototype。
发现自己在「加固」它的那一刻,你就不是在做 prototype 了——加测试、接真数据库、为了「以后可能要」而泛化。
产出物怎么处置:答案(裁决加它解决的问题)落在耐久的地方——commit message、ADR、实作 issue;prototype 本身不删,但也不进 main,commit 到 prototype/<name> branch、永不 merge,在实作 issue 上留一个指标。
坑:agent 会在你其实该实作的时候叫你 prototype——命名问题,它对不熟流程的 agent 读起来像「有票之后的显然下一步」。另外不要 prototype 整个 app:没有自然停止点,会靠惯性变成正式产品,而「没测试没错误处理」的程序就这样上线见用户。
独立 — research
有个外部事实卡住决策
它只从一手来源工作(官方文档、源代码、规格、第一方 API),每个主张都追回拥有答案的那个来源。它不在对话里回答你——输出是一份文档,每个主张带链接。决定性的动作是:读的部分跑在背景 agent。
research 是你委派的跑腿,不是你外包的思考。
坑:它会生出第二个自己(issue 530)——skill 叫调用者开背景 agent 但没限制 agent 类型,于是生出的是通用 agent、握着同样的工具和指令、再开一次。有人量到单一 research 任务跨三次重叠执行烧掉约 450k token,重复那个在半小时后、完全在视线外完成。调用后看一下背景任务列表,把重复的停掉。
另外三件:反向失败是你的全域指令禁止再委派时,背景 agent 会礼貌拒绝、skill 静静什么都没做;「高信任来源」由模型自己判断、没有 allowlist,你实际的缓解手段是随机追两三个引用,落在「那个东西的摘要」而不是那个东西本身就是失败;没有停止准则,范围是你的责任——一个 API、一个行为、一个版本主张,比「research X」回来得好太多。
research 文档不是 ADR:ADR 留、research 档用完归档或删掉。过期的 research 档比没有更糟,它会污染未来的 repo 读取。
独立 — diagnosing-bugs
有东西坏了、我不知道为什么
六阶段:建 repro、最小化、排序假设、埋探针、带回归测试修好、清干净。
它不让 agent 在有「紧」的反馈循环之前形成理论。一个具名指令、已经跑过一次、在这个 bug 上是红的、修好之后会变绿。coding agent 拿到 bug 报告的默认行为是读代码然后猜——这支 skill 挡掉它。没有能变红的指令,就没有 Phase 2。那道 gate 就是这支 skill 的全部价值。
「有一个」循环不是目标,「紧」才是:快(秒级)、决定性(每次同样裁决)、锐利(断言你确切的症状,不是「没 crash」)、agent 能无人看管地跑。30 秒又会 flaky 的循环,比没有好不了多少。对偶发性 bug,目标不是干净的 repro 而是提高重现率——循环触发、平行化、加压、注入 sleep。
建循环的阶梯,按偏好排序
- 在能碰到 bug 的 seam 上的失败测试
- 对着 dev server 的 curl 或 HTTP script
- 带 fixture 输入的 CLI 调用,加对已知良好快照 diff
- headless browser script,断言 DOM、console 或 network
- 重播捕获(存下来的 request、payload、event log)
- 丢弃式 harness(系统的最小子集、一次函数调用)
- property 或 fuzz 循环,处理「有时候输出错」
- 能交给
git bisect run的 bisect harness - differential loop(同输入,旧版对新版)
- human-in-the-loop 的 bash script,最后手段
| Gate | 必须为真 |
|---|---|
| 进 Phase 2 | 一个具名指令,已经跑过,输出也贴出来(已屏蔽敏感值),能在这个 bug 上变红 |
| 进 Phase 3 | repro 已重现且已最小化——剩下的每个元素都是承重的 |
| 进 Phase 4 | 3 到 5 个排序过、可否证的假设,各自陈述预测,在测试任何一个之前先给你看 |
| 进 Phase 5 | 探针对应到特定预测,一次一个变量,每条 debug log 带可 grep 的标签 |
| 完成 | 原始 repro 不再重现、仪器全部移除、猜对的那个假设写进 commit message |
坑:它会在你只想要一个直接答案的轻量问题上触发——最常被回报的问题(issue 578,四人回报同一形状)。讲清楚「直接回答,不要诊断」,或关掉它的 model invocation。不能拿它扫「性能问题在哪」,它诊断一个你已经能讲出名字的失败。它不会在写修正之前停下来问你,只有 Phase 3 有人类检查点。
独立 — resolving-merge-conflicts
我卡在 merge 或 rebase 冲突里
它拒绝把冲突当成文字问题。动一个 hunk 之前,先把两边追回一手来源——commit message、PR、原始 issue——所以它是在两个意图之间选,不是在两块文字之间选,并且在兼容的地方两边都保留。真的不兼容时,选符合这次 merge 已陈述目标的那边,并讲出取舍。它不会为了粉饰冲突而发明新行为,而且它不放弃:merge 一定被带到一个完成的 commit。
它还会找出 repo 自己的自动化检查并在 commit 前跑——因为 merge 是 git 里最容易产生「同时满足两个 branch、但两边测试都不过」的地方。
额外的实务知识:不要为了避免冲突而在平行任务之间「划分文档」,那成本比收益高。唯一值得保留的纪律是大重构先做。worktree 平行开发时,merge 回去最好由写那个改动的 session 做,因为只有它知道意图。把大家的冲突 batch 给最后一个 agent,正好丢掉这支 skill 要辛苦重建的东西。
匝道 — improve-codebase-architecture
codebase 在腐烂
它扫 codebase 找加深机会——浅模块(界面几乎和它藏的东西一样复杂)可以变成深模块的地方——写成一份 HTML 报告,然后对你选的候选做 grilling。
它从不改代码。整个 run 产出「一个 HTML 档加一场对话」。重构本身之后在另一个 session、走正常搭建流程。这就是它是巡检而不是重构工具的意思,也是为什么值得对「你还没准备要动」的 codebase 跑它。
两道过滤器:deletion test——想像删掉这个模块,复杂度会集中到一个更小的界面后面,还是散开到各个调用者身上?只有「集中」的案例拿到卡片。另外除非你指定区域,它先读最近的 commit 历史,把扫描偏向正在变动的路径——没人碰的代码里的加深,是你永远不会兑现的重构。
强度标章三阶:Strong(deletion test 清楚通过、摩擦真实,认真看)、Worth exploring(说得通,但报酬取决于代码接下来要去哪)、Speculative(为完整性列出,大部分可以安心忽略)。
| 情境 | 怎么用 |
|---|---|
| 例行保养 | 每几天、或有空档就跑,防止功能之间结构腐烂 |
| 大工程之前 | 把它指向 spec:「我们怎么让这个改动变容易?」这是最有效的 prompt |
| Brownfield 审计 | 对大型、无结构、vibe-coded 的 repo 跑,看清它实际是什么形状 |
| Legacy 测试工作 | 先用它找出缺少的 seam,再去对难测的程序写测试 |
坑:「它为了一个想法烤我一小时」是最大声的抱怨——调用时就讲「不要烤我,直接给报告」。报告开起来没样式没图,是因为它从 CDN 载外部资源、被挡时静默失败而 agent 看不到(它从不渲染那个页面),要它用 inline CSS 与手写 SVG。一个 session 一个候选。它几乎不会说「你的 codebase 没问题」——整份都是 Speculative 的报告,就是它用唯一会的方式告诉你它什么都没找到。
匝道 — triage
别人丢了一堆 issue 进来
只用于你没有建立的 issue。原始 bug 报告、外来 feature request、突然出现的外部 PR。to-tickets 产出的票依构造就已经 agent-ready,对它们跑 triage 最好的情况是白做工。它建议然后等待:告诉你分类与状态的判断加理由,在你指示之前不套用任何东西。
每个被 triage 的项目最后带恰好一个分类角色加一个状态角色。分类两个:bug、enhancement。状态五个:needs-triage(你需要评估它)、needs-info(等回报者,回复后回到 needs-triage)、ready-for-agent(完整规格化、附 agent brief)、ready-for-human(同样的 brief 加上「为什么不能委派」)、wontfix(关闭,理由已记录)。
wontfix 分三种,差别重要,因为只有一种会写进知识库:已实作的留个指向它已存在位置的留言、不写进 out-of-scope(那是已建功能不是被拒功能,写进去会污染去重检查);拒绝的 bug 礼貌解释后关闭;拒绝的 enhancement 在 out-of-scope 目录写一份文档、从关闭留言连过去。那个目录是一个被拒概念一份 markdown(不是一个 issue 一份),而 triage 在评估任何东西之前先读整个目录,按概念比对而非关键字。
先验证再写 brief:对 bug 照回报者的步骤重现,对 PR checkout 并跑相关测试,然后报告三种结果之一——已确认(附代码路径)、无法重现、细节不足以尝试(这本身就是最强的 needs-info 信号)。这一切都是为了让 agent brief 变好,而它被写成耐久而非精确:写类型、签章、行为契约,永不写文档路径与行号,因为 issue 可能躺好几周而底下代码在动。
坑:label 不会自动建立;五个状态不够用是最常被提的缺口(blocked、deferred、implemented 都有人要,都没 ship);不要一次对整个 backlog 放它跑——「显示需要注意的东西」那一 pass 是给挑选用的便宜列表,一次跑二十个 issue 时 agent 会悄悄把它当成证据基础,而它只回 issue 内文、不回留言。
匝道 — wayfinder
这个工程一个 session 装不下
它接手一个大到一个 agent session 装不下的工程——你能讲出目的地、但还看不见路线——把它画成 tracker 上一张共享的地图,由 decision ticket 组成,然后一次解一张直到路清楚。
它规划、不执行。每张票握着一个「解决后产出决定」的问题,而不是一块要执行的搭建切片。地图完成的定义是:在有人去建这个东西之前,没有东西还需要被决定。这条规则是 agent 最常打破的。
与 grill-with-docs 的分界是 session 数,不是项目大小:一个对话装得下就用 grilling(更便宜也更好);装不下才用 wayfinder。对一个范围良好的功能抓 wayfinder 是常见错误。
地图上的四样东西:Destination——走到尽头是什么样子,在任何票存在之前先命名;Decisions so far——每张关闭的票一行,各自连到细节真正住的地方;Not yet specified,也就是战争迷雾——你看得出要来、但还无法精确表述的决定,判准是你现在能不能精确说出那个问题,不是你能不能回答它;Out of scope——判定在目的地之外的工作,关掉、永不毕业。地图是索引不是保存,决定只活在它自己的票里。
Frontier 是「开着、没被阻塞、没被认领」的票。session 在做任何工作之前先把票 assign 给自己来认领,所以 assignee 就是认领。票全程用名字称呼,不用裸的编号——一墙的 issue 编号在叙述里没法读。
| 类型 | 模式 | 什么时候用 |
|---|---|---|
| grilling | HITL | 默认。问题可以靠谈清楚 |
| prototype | HITL | 「这该长怎样」——谈不出来的问题,产物从票上连出去当 asset |
| research | AFK | 工作目录之外的事实卡住决策。画地图时就发射、并行烧完 |
| task | 两者皆可 | 没有东西要决定,但手动工作卡住一个决定——开权限、注册服务、搬数据让形状看得见 |
task 是唯一「做」而不是「决定」的类型,它的存在理由是解除一个决定的阻塞,永不是交付目的地的一块。这是实务上最常出错的类型:agent 把它当实作步骤,开始在地图里写产品代码。research 是「一 session 一票」的唯一例外。
三个致命坑。一、agent 在 wayfinder session 中间开始写正式代码——最常回报的失败。「规划不执行」默认可以在地图的 Notes 里被覆写,但 Notes 是 agent 写的,所以约束和它的豁免住在同一个由「被约束方」拥有的文档里。有用户看着 agent 把「这张地图带执行」写进自己的 Notes,然后在后续 session 读回来当自己的许可,在正式服务器上动工。二、地图清空之后还是要 /to-spec 和 /to-tickets——decision ticket 在地图关闭时全都关了,剩下的是「一张塞满链接决定的地图」,那不是搭建计划。三、不要平行跑 grilling 票,两个 session 不共享 context,你会在一边被问到刚在另一边答过的问题。
还有一个实测:「我画了 27 张票,做到第 13 张时后面全部不合理了」。两个反制:把地图范围缩到一个有界的目的地(一个定义好的 epic 比笼统的「实作 V1」表现好太多),以及积极 prototype。作者的说法是 wayfinder 是「prototypemaxxing」而不是「planmaxxing」。
独立 — handoff
有东西要搬家
它把当前对话压成一份交接文档——一个 markdown 档,写到 OS 暂存目录(不是工作区),让一个全新 agent 读了就能接手。
它买的是可携性,不是压缩。这让它比听起来窄得多:只有工作要移动时你才需要文档。四个触发情境:换 harness、搬到不同目录或 repo、把工作送给同事、把 phase 中途发现的支线分叉出去。
最常被跳过的用法是分叉。你留在自己的 session,把累积的 context 复制一份交给第二个 agent 平行工作。prototype 岔路就是这样用的:你正在一场很深的设计对话里、撞到一个只有跑起来才能解的问题、又不想把辛苦建起来的 thread 花在查这件事上——handoff 到一个 prototype session、拿到答案、把答案交回来、在原 thread 引用它。两次跨越、一场活着的对话、什么都不用重讲。
什么会旅行:文档带着活的 thread(在飞什么、为什么、下一步),加上一段建议的 skill。秘密会在写入前被屏蔽。它刻意不带任何已经写下来的东西——spec、计划、ADR、issue、commit、diff 一律用路径或 URL 引用、绝不复制。
坑:文档在暂存目录,路径长、每个 OS 不同,问它路径并记下来再往下走;有些环境会在 session 之间清掉 temp,下一个 session 不会很快开始就自己复制到耐久的地方;交给下一个 agent 的方式是指向路径,不要把摘要贴进 shell 指令——含特殊字符的摘要会被搞烂,而典型失败是静默截断;「它抓到 what、没抓到 why」是公允的批评,把「下一个 session 要做什么」当参数传进去,并留意它把没验证过的信念写成事实。
独立 — to-questionnaire
答案在别人脑子里
它把一个你无法自己拍板的决策,变成一份问卷,交给那个握有你缺的东西的人。
它烤的是「这次寄送」,不是主题。针对主题访谈你在这里毫无意义——不懂主题正是你要写给别人的原因。所以它只问你永远答得出的两件事:要给谁(他们的角色、专业、跟你的关系,这固定了语气与文档要自带多少 context)与你需要拿回什么(你无法自己解决的具体决定或事实,这变成成品被衡量的检查表)。之后全是起草。
文档的形状:一行 purpose 加一小段给「从没在你脑子里待过的人」的 context;问题最重要的先来、依主题分组;一题一个想法、绝不复合;明确允许回答「我不知道」——被标记的不确定有用,读起来像事实的自信猜测没用;结尾一个 catch-all。
它刻意不分支、不多收件人。三个人握着三块答案,就跑三次。最常见的用法是一场 grilling 卡住了:在同一个对话里跑它——它没有 ingest 阶段,能在 grilling 之后 work 纯粹因为那场 session 已经在 context 里。
独立 — wait-what
这段话我没听懂
agent 会把刚讲的东西重新推销一次:补上你缺的 context、用白话写、并使用你项目 CONTEXT.md 里的词汇。
这支 skill 只有三行,那是设计不是未完成稿。打冗长的 skill 会靠变长而失败:一份四百行的「简洁 skill」还是会让模型冗长,因为模型读到的是体积而不是恳求。
名字就是机制。带头的词是 wait。「讲精简一点」是关于 agent 输出的指令,模型会用「剪字」来服从,于是你更迷路。wait 是关于你的状态:它说「理解在这里失败了」。听到「讲短一点」的 agent 写电报;听到「等等,你把我弄丢了」的 agent 会退回去重讲。每个流行的解法都在命名输出,模型于是过度修正成一种更短但没更清楚的语体;命名听者同时要到两半:更少的字,而且你缺的那个前提。
它也刻意说「重讲那个」而不是「上一则消息」——把你弄丢的通常比一段大,多远要退回去由 agent 决定。真正的解药是事先建立共享语言;wait-what 修的是已经发生的那一则。
独立 — teach
我想学一个东西,跨很多天
它把你执行它的那个目录变成常设教学工作区,用一系列自带样式的短 HTML 课程跨多个 session 教你一个主题。
它不从模型已知的东西教。parametric knowledge 被当成不可信:教之前它先去找高信任资源、记进资源档、并在每一课里引用。它是有状态的——mission、资源、课程、学习纪录全部以文档形式住在目录里:
| 路径 | 放什么 |
|---|---|
| MISSION.md | 你为什么学这个。其他一切挂在它上面;缺它,它第一件事就是访谈你到它存在 |
| RESOURCES.md | 经过挑选的来源,分 Knowledge 与 Wisdom(社区) |
| lessons/ | 编号课程——教学的主要单位 |
| reference/ | 压缩的小抄、算法、词汇表:你真的会回来翻的文档 |
| learning-records/ | ADR 风格的「你已明确学会什么」,用来决定接下来教什么 |
| assets/ | 可重用组件——第一个是共用 stylesheet——让课程看起来像同一门课 |
| NOTES.md | 你陈述的教学偏好 |
核心观念是 storage strength(长期保留)而不是 fluency(当下的回想感,读的时候像精通、一周后就没了)。它用期望难度建前者。知识先来(此时难度是敌人,会吃掉你理解所需的工作记忆),技能再靠紧的反馈循环操练(此时难度是工具)。课程很少被重读,参考文档会——所以一课的压缩精华属于参考目录,不是埋在引入它的那一课里。
坑:文档可能被写到错的地方(issue 377,有人的课程被写进全域 skill 目录),开始时明确讲出目录名;小考正确答案永远是第一个选项(多模型确认、未修,有贡献者测到 9 课 33 次全部落在 A);没有能力评估步骤,第一则消息就把你的既有知识与缺口讲出来;没有间隔重复调度,要复习就自己要。
不只给程序用——纪录里非程序的用途占更大部分。在程序里,最强的用途不是从零学一门语言,而是在陌生的 codebase 或新团队的技术栈里找方向。作者提过一个漂亮的组合:被烤到一个你不懂的东西时,不要停下 grilling 去学——handoff 到一个教学工作区、在那里学会、再回来接续。
独立 — wizard
有段人类才能做的手动流程
它产生一支交互 bash script,一步一步带人类走过手动程序——串第三方服务、跑一次性迁移、把项目从状态 A 搬到状态 B。
agent 写 script,但从不执行它。你在自己机器上跑。所以 wizard 不是一份你照着做的说明——它是一个驱动流程并持有状态的程序,你的部分是点、贴、按 Enter。Stage 是「一个画面上的一件聚焦任务」,script 在 stage 之间清空终端。
写 script 之前先 scoping:它读你的 repo 而不是冷问——环境档、compose 档、framework config、以及 CI 设置里每一个 secret 与变量引用;每一个都是 wizard 必须产出的值。然后把排序过的 stage 清单给你确认,之后才把每个 stage 对应到人类走的确切路径。不知道现在的 UI 长怎样时,它问你或查文档,而不是发明点击。
template 已经解决了 UX:进度、确认门、跨平台开 URL、secret 隐藏输入、环境档幂等写入、CI secret 写入、以及「它必须跳过什么」的收尾摘要。固定函数库那半每支 wizard 都一样、永不手改,一致性就是重点。写 wizard 的 agent 不会端到端跑它,改用静态验证,第一次跑是你,而那次就是测试。
坑:不能中途回上一步,第 3 站打错就中断重跑(重跑很便宜,已写进环境档的值会当默认反馈);提示里方向键有 bug(issue 741),backspace 有效;它不会去查第三方服务的状态;API key 不会进模型 context——但你在 scoping 时把 key 贴进聊天,那就跟任何粘贴的文字一样在 context 里了。
词汇层 — codebase-design
模块该长什么形状
它固定你设计模块时用的字,精确定义每一个、禁掉松散替代品,并陈述由它们推出的几条原则。
| 词 | 意思 |
|---|---|
| Module | 任何有界面与实作的东西。刻意与规模无关——一个函数、一个 class、一个 package、跨层的一个切片 |
| Interface | 调用者为了正确使用它必须知道的一切:类型签章,加上不变式、顺序约束、错误模式、必需设置、性能特性 |
| Depth | 界面上的杠杆。深:小界面后面大量行为。浅:界面几乎和实作一样复杂 |
| Seam | 一个你可以改变行为却不需在那里编辑的地方。它是界面的位置 |
| Adapter | 在某个 seam 上满足某界面的具体东西。命名的是角色不是材质 |
| Leverage | 调用者从 depth 拿到的:每学一单位界面得到更多能力 |
| Locality | 维护者从 depth 拿到的:改动、bug、验证集中在一处 |
Depth 刻意不定义成「实作行数除以界面行数」——那个指标会奖励把实作写得更臃肿。这里用的是 depth-as-leverage。
四条原则:depth 是界面的性质、不是实作的性质;deletion test——删掉这个模块,复杂度消失代表它是 pass-through,复杂度在 N 个调用者身上重新出现代表它有在赚钱;界面就是测试面,你想测到界面之外,就是模块形状错了;一个 adapter 代表假设性的 seam,两个 adapter 才代表真的 seam。
坑:不要拿它当驱动器(issue 449)。被叫去「继续并推进未决事项」时,agent 会抓它找得到最像动作的东西,重新探索前一个 session 已经画过的代码,跑很久才问你任何事。点名一个 driver skill,让这支坐在下面。
词汇层 — domain-modeling
词在打架
它在你设计的同时建立与磨利项目的 ubiquitous language——挑战和词汇表冲突的用词、在你用了模糊字时逼出精确的字、用具体情境压力测试一段关系直到边界精确。
它是主动纪律、不是被动的。读 CONTEXT.md 借用词汇是任何 skill 都能做的一行习惯;这支是给你在改变模型的时候用的。这就是它会打断你的原因:它在术语被解决的那一刻、对话中间就写进 CONTEXT.md——因为批量版是一场 session 的摘要,实时版是那场 session 的实际产出。
两个产物、两套标准。CONTEXT.md 装术语(一个东西是什么,一两句话),写入门槛是「一个模糊的词变成正式术语」,时机是实时,永不装实作细节、spec、草稿纸、一般程序概念。ADR 装一个决定(一到三句:context、选择、理由),写入门槛是三个全中——难以逆转、没有 context 会觉得意外、真实取舍的结果——而且是提议,不默认。
要真正记住的是 CONTEXT.md 那条规则,因为它是实战中会坏的那条:它是词汇表,而且只是词汇表。不管的话,模型会把「写进 CONTEXT.md」当成「把你给的每个答案都持久化」的许可,文档就变成一份跑动的 spec——这是本 skill 最常被回报的问题,跨多个模型。
让这支有感的动作:你陈述某件事怎么运作时,它去查代码并把矛盾摊出来——「你的代码取消整张 Order,但你刚说可以部分取消,哪个对?」语言和代码被迫出声对齐,在任何一边被改之前。限制:它只交叉参照代码与已 commit 的文档,不搜你的 issue tracker,所以几个月前在一张已关闭 issue 里吵完并刻意定案的命名冲突,会被当成新的摊出来。
坑:CONTEXT.md 长到 500 行以上——大小是症状不是病,直接下令它精简并移除实作细节;只有在文档真的精瘦、却仍涵盖两个读者不会想同时装进脑里的领域时,才考虑切分——切一个臃肿的文档只会得到好几个臃肿的文档。自动触发是它最弱的地方:一场 grilling 跑完 CONTEXT.md 一动也没动,就是这件事发生了,点名叫它。没有经人审阅、由 agent 撰写的词汇表比没有更糟:它会变成听起来很自信的传说,被后续 session 当成真理。
词汇层 — writing-for-agents
我要写给 agent 看的文档
skill、指令档、spec、runtime prompt、README——任何 agent 会读的文档。包装不同,写法一样。
它的默认动作是删除,不是解释。叫 agent 写给另一个 agent 的指令,它大部分字会花在解释模型已经知道的东西,每一行都是 no-op:付了 context 却没改变任何行为。这份参考就是找出它们的镜片,所以它在你已经有的文档上赚到的价值,至少和在空白文档上一样多。
两种负担。Context load 是永远加载的材料在 agent 窗口上的成本:指令档的一行、skill description、任何每个 turn 都在 context 里的东西,不管它有没有被触发。Cognitive load 是在你身上的成本:有哪些文档存在、什么时候该抓哪一个,你就是那个索引。这不是要最小化的成本,它是人类主导权的价格。想通这两种之后,大部分写作决定都变成同一个取舍在不同地方做。
五个杠杆:Context pointer(在 context 里、指名 context 外材料、并编码「何时去拿它」的引用;决定 agent 多可靠地伸手穿过它的是 pointer 的用字,不是它的目标)、Information hierarchy(从「档内步骤」到「档内参考」到「pointer 后的插件参考」的梯子)、Completion criteria(对抗过早完成的防线)、Leading words(模型预训练里已有的压缩概念,锚定两次:body 里锚定执行、pointer 里锚定触发)、Pruning(单一真实来源、相关性、逐句套用 no-op test)。
no-op test 是行为性的、不是美学性的:删掉那一行,问 agent 的行为有没有改变。一个句子不通过,删整句而不是修字。对它有歧见时,跑那份文档来解决,不要争论。判准:文档变好的同时变短,而且你会惊讶剩下这么少;没有任何东西被说两次(重复是「这份文档从未被测过」最可靠的征兆)。
独立 — grill-me
我有个想法,还没成形
它拿一个松散的想法访谈你,直到你能对它做出承诺。你不需要一份想好的计划才能开始——产出那份计划正是这场 session 的用途。它是无状态的:不写文档、不留工作区,留下的只有你脑子里那个更锐利的版本。主题不必是程序,也不需要 repo。
关掉 plan mode。它会催 agent 赶快产出计划,那正好和「保持在提问状态」相反。
它在正常工作的样子:你不同意某件事——一场你完全没推回去的 session,是一场你不需要的 session;问题以「少数几轮」而不是一长串点滴到达,而且后面的轮次明显建立在你前面说的话上;你走到一个没预期的地方,因为某个问题翻出了你一直在隐性做的决定;结束时,每个选择你都能对一个当时不在场的人辩护。
数轮不要数题。46 题分 4 轮是普通的一场。200 题代表范围太大,而且超长 session 会漂进 dumb zone——context window 满到问题质量下降。烤完之后如果确定要做,不要开新 session,那场对话的 context 就是价值所在。
路由器 — ask-matt
我不知道该用哪支
它建议然后停下。不会 grill、不会写 spec、不会开文档、不会帮你发射它刚点名的 skill——你拿到的是「下一步该打什么」,然后你去打。它给你的思考单位是 flow:一条穿过 skill 的路径,而不是单一个 skill。
必须知道的诚实限制。它是手写的地图、会落后 repo,而且只认得这个 pack 的 skill。它会告诉你「一半的 skill 没安装」——已知未修:大部分被它路由的 skill 是 user-invoked,harness 就不把它们放进注入 agent 的清单,agent 把那份清单当成完整的,于是报告它们不存在。它们有装。
它也可能描述错别的 skill 的行为:它从自己那份一行摘要回答,而不是从 skill 本身。有一份详细回报在单一 session 里追到三次,包括凭「把 thread 变成 spec」这个粗略印象建议跳过 to-spec——那份 SKILL.md 从未被打开,代价是少了一次真正的 seam 检查,切出来的票低估了工作量。当它对别的 skill 做出承重的断言时,要它先去打开那份 SKILL.md。
定位:ask-matt 是这整套之上的 secondary source。router 和 SKILL.md 打架时,SKILL.md 是对的。
07
四个完整剧本
主干案例在 第 05 节。这里是另外四个最常见的处境。
案例 A — 生产环境偶发 500
处境:客户回报「有时候按送出会喷 500」,你自己重现不出来。
- 这是别人回报的,先走匝道:
/triage。能不能照回报者步骤重现?重现不出来就needs-info,或决定现在就追。 - 决定现在追,开新 session:
/diagnosing-bugs,并明讲「先帮我建一个会变红的循环」。
Phase 1 是唯一难的一关,也是你唯一要盯的
它必须先给你一个已经跑过、输出贴出来、在这个 bug 上是红的指令。偶发性的 bug,目标不是干净重现,是提高重现率。没有红的指令,就不要让它进 Phase 2。它想开始猜就把它拉回来。
后面是机械性的:最小化(剩下的每个元素都要能说出为什么是承重的)、3 到 5 个排序过可否证的假设(唯一的人类检查点)、埋带标签的探针、先写回归测试再修、清干净、猜对的假设写进 commit message。
一个分岔要知道:没有正确的 seam 可以放那个回归测试时,它应该直说,而不是写一个给你假安全感的浅测试——「没有 seam」本身就是发现,交给 improve-codebase-architecture。
案例 B — 接手一个没人整理过的 legacy repo
处境:你刚加入一个八年的项目,或接手一个 vibe-coded 的 repo。没有 ADR、没有领域语言、没有设计原则。
- 第一天:
/setup-matt-pocock-skills设置 tracker 与文档配置。 - 第一天:
/grill-with-docs,请它帮你把这个既有 repo 用CONTEXT.md建立起来。预期一场很长的访问(有人回报 50 题以上才把文档弄成形),而且要主动导引——它会读代码、问你它找到什么,而「代码里现有的哪些词才是对的词」是你决定的。 - 第二天:
/improve-codebase-architecture,开口就说「不要烤我,先给我报告」。全部都是 Speculative 等于它其实什么都没找到;挑一个 Strong 的候选。 - 第二天:一次一个候选,让它对那个候选 grilling,产出是「决定」不是 diff。然后接
to-spec、to-tickets、implement。 - 之后:每几天再跑一次架构巡检当保养。
为什么顺序是这样
先建立共用词汇,架构巡检的输出会好非常多——候选会用「Order intake 模块」这种你们的名词,而不是「FooBarHandler」。
诚实的期望值:真正失控的项目,有人回报它「帮了一点但还是不够」;一个八年的 legacy codebase 上有人看到模型在原地绕圈,而同一支 skill 在整齐的 repo 上会产出干净的图。目前没有专门处理这种案例的 skill。
案例 C — 绿地大项目
处境:要从零做一个新产品模块,路线完全不清楚,明显不是一场对话能谈完的。
- 先确定五个
wayfinder:label 存在(不存在的 label 会让gh直接失败)。 /wayfinder。第一件事是命名 destination。它问的是「整张地图的目的地」,不是这场 session 的目的地;把范围缩到一个有界的 epic,不要「实作 V1」。- 它做一次广度优先的 grilling,画出 Destination、Decisions so far、迷雾与 Out of scope。迷雾与票的判准是你「现在」能不能精确说出那个问题。开场的 grill 找不到任何迷雾,它应该停下来说「这件事小到不用地图」。
- research 票在画地图时就被发射并行烧;其他票一次做一张,用 assign 给自己来认领。
- 每解一张:贴 resolution 留言、关票、在地图留一行,然后停下。清掉前方的迷雾,把现在可表述的毕业成新票。
- 地图清空后:
/to-spec #<map_issue>(传主地图,不是个别 decision ticket),然后/to-tickets、/implement。
三个致命坑已在 第 06 节 的 wayfinder 条目列出:agent 会开始写正式代码、不要跳过 to-spec、不要平行跑 grilling 票。
案例 D — 完全不是程序的决策
处境:你在想一个商业决定——要不要做一条新产品线、一份提案怎么定价、一篇文章的论证骨架。
- 开一个干净对话(不需要在任何 repo 里),关掉 plan mode,跑
/grill-me。 - 一轮一轮回答,用编号整批回。推回问得太浅的问题;范围在漂就讲;「我不知道」是真的答案。
- 遇到「看到东西才能答」的问题,它是 ungrillable。非程序情境下通常是:先做一页草稿、先算一张表、先问一个客户。
- 遇到「答案在别人脑子里」的问题,在同一个对话里跑
/to-questionnaire,寄给那个人,答案回来再开下一轮。 - 它是无状态的:不写文档、不留工作区。留下的只有你脑子里那个更锐利的版本。
08
已知坑总表
依「你会先看到的症状」排列。严重代表会浪费你钱或时间。
| 症状 | 严重 | 解法 |
|---|---|---|
| agent 说某些 skill 没安装 | — | user-invoked skill 不进模型的清单。它们有装,照打。权威是 .claude-plugin/plugin.json |
gh 说 label 不存在 | — | setup 不会建 label,自己 gh label create 一次 |
| 访谈一次丢出全部问题、没有建议答案 | — | grilling 或 domain-modeling 没加载。问 agent「你载了哪些 skill」 |
访谈很好但 CONTEXT.md 没变 | — | domain-modeling 没载。点名叫它 |
CONTEXT.md 膨胀成 500 行以上 | — | 它吸收了实作细节。直接下令精简并移除实作细节 |
| 读 spec 一直被截断 | 严重 | 两步之间不要 clear 或 compact,同一个窗口跑完 |
| 三行的改动切出 12 张票 | — | 质询步骤叫它合并。真的很小就直接 implement,别用这支 |
| 切出来一层一张票 | — | 逐票问「做完能 demo 什么」,答不出行为的就是水平切片 |
| 没建成 sub-issue、blocked-by 只写在内文 | — | 已知未修。事后自己用 gh issue create --parent、--add-sub-issue、--blocked-by |
| 验收条件在动工前就通过 | — | 对每条问「什么观察会证明它为假」,并确认它在起始 commit 是红的 |
/implement #2 做了完全无关的事 | 严重 | #2 是对「任何看得到的编号清单」解析。传完整 URL,并要它念回标题 |
| 跑完票还开着、验收条件没打勾 | — | 预期行为,它没有收尾步骤。手动关票,依赖链才会往前走 |
| code-review 说看不到我的改动 | — | 它 diff 到 HEAD,排除未 commit 的。先 commit 再 review |
| 平行跑好几个 implement 出现诡异 git 状况 | 严重 | 同一 checkout 不支持。用 worktree,但 stash 仍共用 |
| 和内置的 code-review 撞名 | — | 移除内置的那个,或 fork 成新名字 |
| review 的 sub-agent 又生出更多 agent | 严重 | 已知未修,有一次到 50 个以上。无人看管跑时盯 agent 数;fork 上加一行禁止再生成 |
| review 每次跑都找到新问题 | — | 没有收敛保证。当成线索清单,处理有明文规则背书的,然后停手 |
| research 烧掉 450k token | 严重 | nesting bug(issue 530),它会生出第二个自己。调用后检查背景任务列表 |
| 只想要一句答案,它跑去建重现情境 | — | 讲「直接回答,不要诊断」,或关掉它的 model invocation |
| 它先写实作才写测试 | — | 会发生,skill 带着这件事一起活。某个切片要严格就盯着跑 |
| 它先写浏览器测试然后鬼打墙 | — | 在 repo 的指令档声明:browser 测试在行为可运作之后才写 |
| 架构报告开起来没样式没图 | — | 外部 CDN 被挡。要它用 inline CSS 加手写 SVG |
| 它烤我一小时而不给我选项 | — | 调用时讲「不要烤我,直接给报告」 |
| 对词汇层说「开始」烧掉 100k token | 严重 | 它没有流程。点名一个 driver skill,让它坐在下面 |
| wayfinder 的 agent 开始写正式代码 | 严重 | Notes 可覆写「规划不执行」,而 Notes 是 agent 写的。先读 Notes |
| 27 张票做到第 13 张全部不合理 | — | 范围缩到一个有界 epic,并积极 prototype |
| grilling 每个问题三段落、很累 | — | 降 reasoning effort 加全域指令档一句白话指示。未解决 |
| handoff 文档不见了 | — | 暂存目录会被清。问它路径,需要就自己复制到耐久位置 |
| 课程被写到全域 skill 目录 | 严重 | issue 377。明确讲出目录名,第一课落在哪先确认 |
| 小考正确答案永远是 A | — | 已知未修(33 次全中)。把位置当无意义,或要一个 render 时洗牌的组件 |
| wizard 打错字想回上一步 | — | 没有回上一步。中断重跑(已存的值会当默认);方向键有 bug,用 backspace |
我改了 SKILL.md,更新后不见了 | 严重 | npx skills update 会覆盖、plugin 唯读。长期行为写进你自己的指令档 |
09
建议放进你自己的指令档
这是「用官方管道客制」的方式——改 skill 档会被覆盖,这里不会。整段可以直接复制进你的 CLAUDE.md 或 AGENTS.md。
## Agent behaviour
- When grilling, ask one question at a time.
- Do not start implementing without my explicit permission.
- Browser and end-to-end tests are written after the behaviour works,
never as the first red test.
- Keep questions and recommendations short. One paragraph maximum
per question.
- When a skill asserts something about another skill's behaviour,
open that skill's SKILL.md before acting on it.
- code-review sub-agents must not invoke /code-review or spawn
additional agents; perform the review directly.
每一行挡的是什么
- 一次一题:换回单题节奏。读得慢、用第二语言、或需要专注鹰架的人都推荐。
- 不要未经允许就开始实作:防 grilling 在 frontier 清空后自己开始做,弱模型或低 effort 时会发生。
- 浏览器测试最后写:防 tdd 先写 Playwright 然后鬼打墙。
- 问题与建议要短:缓解 wayfinder 与 grilling 的冗长。
- 先打开被断言的那份
SKILL.md:防 ask-matt 用自己的摘要误述别的 skill。 - review 的 sub-agent 不得再生成 agent:防失控 fan-out,这是 fork 用户实测有效的那一行。
10
核心词汇
这些词是整套 skill 的共用语言。看不懂它们,skill 的输出你就读不懂。
| 词 | 定义 |
|---|---|
| Seam | 你可以改变行为却不需要在那里编辑的地方。测试住在 seam 上。它是界面的位置 |
| Pre-agreed seam | 在写任何程序之前就谈好的 seam。这是测试耐久的原因——底下的实作可以重写而测试不动 |
| Tracer bullet | 穿过所有层的一条细但完整的路,落地当下就能单独 demo |
| Vertical / horizontal slice | 垂直是一条路穿所有层(对);水平是一次一层(错,最常见的失败) |
| Deep / shallow module | 深是小界面后面大量行为;浅是界面几乎和实作一样复杂 |
| Deletion test | 想像删掉这个模块:复杂度集中到更小的界面后(值得留)还是散开到调用者(那是 pass-through) |
| Locality / Leverage | Locality 是维护者得到的(改动集中在一处);Leverage 是调用者得到的(每学一单位界面得到更多能力) |
| Design tree / Frontier / Round | 设计树是决定挂着决定;frontier 是前置条件都已解决的决定集合;一 round 是把整个 frontier 一次问完 |
| Grillable / ungrillable | 谈得出来的问题,相对于需要有东西可反应的问题(后者去 prototype) |
| Fog of war | wayfinder 地图上「看得出要来、但还无法精确表述」的决定 |
| Decision ticket | wayfinder 的单位:握着一个问题(解决后产出决定),不是一块要执行的搭建切片 |
| Destination | 一整张 wayfinder 地图的终点样貌。画地图的第一个动作就是命名它 |
| Spec / Ticket | spec 是目的地与固定它的决策(保留);ticket 是抵达的执行步骤(用完即丢) |
| Primary / secondary source | 一手是对话本身、commit、官方文档、源代码;二手是任何摘要。冲突时一手为准 |
| Context pointer | 在 context 里、指名 context 外材料、并编码「何时去拿」的引用 |
| Progressive disclosure | 把只有某条分支需要的参考移到 pointer 后面,让主档保持可读 |
| Context load / Cognitive load | 前者是永远加载的材料在模型窗口上的成本;后者是「有哪些文档、何时该用」在你身上的成本 |
| No-op | 删掉之后 agent 行为不变的那一行文字。付了 context 却没改变任何行为 |
| Leading word | 模型预训练里已有的压缩概念(tight、red、tracer bullet),agent 拿它来思考 |
| Storage strength / fluency | 长期保留,相对于当下的回想感(后者读的时候像精通、一周后就没了) |
| Smart zone / dumb zone | context window 还有余裕,相对于已经满到质量下降 |
| HITL / AFK | 人类在循环里(必须靠活的交换解决),相对于你人不在也跑得完 |
| Phase boundary | 两块工作之间;唯一该问「我的 context 怎么办」的地方 |
| Expand–migrate–contract | 宽重构的三段式:新形式加在旧的旁边、分批搬调用点、没有调用者才删旧的 |
11
七种反模式
这套东西最常被用坏的方式。
- 被动 grilling。连答四十个「同意」,出来一份 agent 写的、你点头过的计划。一场你完全没推回去的 session,是一场你不需要的 session。
- 在 to-spec 和 to-tickets 之间 clear 或 compact。你烤出来的东西绝大部分只在那个 context window 里。这一刀下去,spec 会安静地漏掉你真正决定的东西。
- 对自己产生的票跑 triage。
to-tickets的票依构造已经 agent-ready。triage 是别人丢进来的工作的匝道。 - 范围良好的功能抓 wayfinder。判准是 session 数:一场对话装得下就用
grill-with-docs,它更便宜也更好。 - 把词汇层当驱动器。对
codebase-design或domain-modeling说「开始吧」,agent 会自己发明流程并烧掉大量 token。点名一个 driver。 - 把 review 跑在写程序的同一个 session。同一个 context 审自己不是 review,是带着 slash command 的确认偏误。
- 改
SKILL.md来客制。会被更新覆盖,plugin 安装根本唯读。长期行为写进你自己的指令档。
还有一个元反模式
把它当成「有了流程就不用想」。作者在 README 里的立场是相反的——那类接管流程的做法帮你的代价是拿走你的控制权、并让流程本身的 bug 难以解决。这套 skill 刻意做得小、好改、可组合。产出的质量追踪的是你答案的质量,而不是问题的数量。
12
14 天学习计划
每天约 30 到 60 分钟,用你自己真实的项目。
| 天 | 做什么 | 怎么算过关 |
|---|---|---|
| 01 | 读 三个底层观念;装 plugin 或 skills.sh(选一);在一个 repo 跑 setup;建好 label | docs/agents/ 三个文档存在,指令档有 ## Agent skills |
| 02 | /grill-me 烤一个非程序的决定。刻意练习「推回去」 | 至少推回三次;能对一个不在场的人辩护每个选择 |
| 03 | /grill-with-docs 对你现有 repo 做一次小功能的访谈 | CONTEXT.md 在过程中逐条长出来;ADR 0 到 1 份 |
| 04 | 同一对话接 /to-spec。认真看 seam 与 out-of-scope 两节 | spec 里每个决定你都记得自己做过 |
| 05 | 同一窗口接 /to-tickets。在质询步骤逐票问「能 demo 什么」 | 每票能 demo 行为;最上面那张没有阻塞者 |
| 06 | /implement 做第一张票(完整 URL),全程看 trace | trace 里看得到 tdd 调用;走到 commit |
| 07 | 新 session 跑 /code-review main。逐条追引用 | 两块分开的报告;你至少驳掉一个发现 |
| 08 | 读 codebase-design 的词汇表,把它当字典而不是流程 | 你的设计对话里不再出现 component、service、boundary |
| 09 | 遇到一个「谈不出来」的问题,跑 /prototype | 一个可分享的 HTML 档或几个结构上不同意的变体;答案一行 |
| 10 | 对一个真的 bug 跑 /diagnosing-bugs。盯紧 Phase 1 的 gate | 先看到红的指令输出,才看到第一个理论 |
| 11 | /improve-codebase-architecture(记得说「先给报告」),挑一个 Strong 候选 | HTML 报告;一个候选被烤成一个决定 |
| 12 | /handoff 练一次「分叉」:主对话留着,开一个平行 session | 原 session 还在原地;新 agent 直接开工不用你重讲 |
| 13 | 练 /wait-what 与 /to-questionnaire;把 第 09 节 写进指令档 | 重讲是「更短且更清楚」;问卷可以直接寄出去 |
| 14 | 挑一件真的太大的工作跑 /wayfinder,范围缩到一个有界 epic | destination 在任何票之前就写下来;每张开着的票读起来都是一个问题 |
之后的节奏:主干每天跑,架构巡检每几天跑一次,/teach 在需要补技能时开一个专属目录。
13
一页速查
每个 repo 一次
/setup-matt-pocock-skills— tracker、label 与文档配置
主干(想法到 ship)
/grill-with-docs— 有 repo、单一 session 谈得完/to-spec— 只在跨 session 才需要。同窗口,别 clear/to-tickets— 切 tracer bullet,声明阻塞边。同窗口/implement <完整 ticket URL>— 一票一 session,中间 clear/code-review <fixed-point>— 干净 session 跑,先 commit
匝道
/triage— 别人丢进来的 issue/wayfinder— 一个 session 装不下。清空后回/to-spec/improve-codebase-architecture— 每几天一次的结构体检
随时
/grill-me— 无 repo、无文档,主题不必是程序/prototype— 谈不出来的设计问题,一次一个问题/research— 外部事实。背景跑,检查有没有生两个/diagnosing-bugs— 难 bug。先有红的循环才准猜/resolving-merge-conflicts— 已经卡在冲突里/wizard— 只有人类能做的手动流程/handoff— 有东西要搬家,或分叉支线/to-questionnaire— 答案在别人脑子里/wait-what— 刚刚那段没听懂/teach— 跨很多天要学一个主题/ask-matt— 不知道用哪支。它建议然后停
词汇层,不要当驱动器用
codebase-design、domain-modeling、grilling、writing-for-agents
Phase boundary 五选一,依序判断
继续 → clear → handoff → subagent → compact
出处
这篇教学依据什么写成
依据 mattpocock/skills plugin 1.2.3 版(25 个已发布的 skill),读该 repo 的 README.md、CONTEXT.md、25 篇官方 skill 文档、.claude-plugin/plugin.json 与 CHANGELOG.md 之后整理与重写。该 repo 以 MIT 授权发布。
本页为 TauX 独立编写的中文教学,不是官方文档的翻译或转载。skill 本身、它的名称与它的行为属于原作者;本页的编排、判准、译名与所有评论由 TauX 撰写,不代表原作者立场。
文中所有 issue 编号皆为该 repo 的 issue,撰稿时多数仍开启。这代表两件事:这些坑是真的,而且它们可能已经被修好。跑起来遇到怪事,先去该 repo 搜一下症状——一份写死的坑表最好的下场,就是有一天全部过期。
版本标记在这里不是装饰。这套 skill 改得很快(to-prd 在 v1.1 改名成 to-spec、tdd 的 refactor 阶段在 2026 年 6 月被移除),没有版本号的教学读者无从判断哪一段还有效。
想把这条流程接进你自己的团队?
工具是公开的,难的是接到你既有的 tracker、规范与交付节奏上。那部分我们做过。