目标是在一个 15 个 Maven 模块、3412 个 Java 文件、约 73 万行、持续开发逾十年的内部信息系统上,先落「项目计划管理」模块——投标基础信息、中标结果信息、项目经济评审、项目技术评审、基础信息维护五个子模块。本手册把 Matt Pocock 的技能包当成一套可编程的工程纪律来拆解,并给出每一步在这个具体代码库上的翻译。
这份手册不是技能说明书的中文版。它的论点是:在一个十年高龄的单体上,Matt Pocock 技能包的价值不在于"让 AI 写得更快",而在于"让每一次 AI 的产出都能被更便宜地验证"。下面是支撑该论点的十二条论断,后续每一章都服务于其中一条。
GLOSSARY.md 里,再落到包结构上。code-review 技能的双轴设计(Standards / Spec 并行子智能体)与 Fowler 十二种代码气味基线,本质是把验证环节的成本后者,而不是把闸门设在生成端。tdd 技能要求"只在事先约定的接缝处测试"。这个系统在建立特征锁之前没有可靠接缝,因此第一个 ticket 永远是给即将触碰的旧代码加表征测试(Michael Feathers 的做法)。implement-spec 明确要求子智能体之间通过指针而非复制内容通信,探索结果落在仓库之外的 Markdown 笔记里。这一点在你的单体上比其他项目重要得多。to-spec、to-tickets、code-review、wayfinder 全都以"问题跟踪器已经被告知"为前提,未配置就直接报错。第一步是 /setup-matt-pocock-skills,而且内网环境应当选本地 Markdown 跟踪器。如果你只有十五分钟:读第 00 章的十二条论断、第 06 章的接缝设计、第 10 章的 90 天路线图。如果你要明天就动手:直接执行第 03 章末尾的「最小可用配置」与第 06 章的「第一张 ticket」。
在谈任何技能之前,必须先把这套十年单体的"难题类别"判定清楚。因为后续所有纪律的强度都由这个判定决定:新项目可以宽松,高默契 + 紧耦合 + 弱自动化验证的存量系统必须严格。
多模块单体。-pl 与 -am 的边界决定了反馈延迟。这是一切速度问题的物理上限。
约 214 行/文件。经验上偏高的单文件行数通常指向已经长成的"上帝类"与复制粘贴式扩展。
与 METR 实验所选"平均百万行级"的成熟仓库处于同一量级,因此那组最悲观的实测数据适用于此。
这套系统同时具备三个特性,而这三者的组合恰好是 AI 辅助开发收益最低的区域:
| 特性 | 在本系统上的表现 | 对智能体的直接后果 |
|---|---|---|
| 高 tacit knowledge (暗中约定多) | 十年演进、内部制度驱动、"某些字段必须在某个状态才能改"这类规则多半写在人脑或老员工的口头规范里,不在代码里。 | 智能体缺少 隐性约束。它生成的代码会编译通过、跑得起来,但破坏一条没人告诉它的业务铁律。这正是 METR 观察到的"仓库年限拖累 AI 有用性"的机制。 |
| 紧耦合 | 15 个模块共占一个 reactor,跨模块的 service 互相注入常见;"基础信息"类字典被全系统引用。 | 任何"局部正确"的改动都可能跨模块漏出。DORA 2025 明确指出:紧耦合 + 慢反馈的团队几乎拿不到 AI 收益。 |
| 弱自动化验证 | 十年老系统常见状态:测试覆盖极低或测试依赖数据库/容器,跑不动或跑得慢。 | 红-绿循环没有"红"。没有红灯的智能体等于闭眼开车,而这恰恰是 tdd 技能唯一无法代你去做的部分。 |
把用户列出的五个子模块按时序摆到业务时间轴上,会看到一个被很多遗留系统抹平的分界:中标前,处理的对象是"投标机会";中标后,处理的对象才是"项目"。这两件事的字段、状态机、权限、留痕要求都不同。旧系统最常见的熵源就是把它们塞进同一张主表和同一个"项目"名词里,于是所有差异只能靠 if (status == 6) 之类的分支去补。
本手册没有访问你的代码库,因此图 1 是按子模块语义推导的定位图,不是现状架构。落地第一步必须是第 3.3 节的探测清单——用五条命令把"到底是共用一张表,还是已经有拆分"问出来。不要用图 1 直接当作现状。
按 Sonar 公开的 2023 年基准——每百万行代码每年约产生 30.6 万美元技术债敞口、约 5,500 开发小时用于修复——线性折算到 73 万行,约 22 万美元 / 4,000 小时 / 年,折算约 2 个人年。
上面这串数字是按单一第三方基准线性外推的建模结果,用途是给"值不值得投入"一个数量级锚点,不能写进立项预算。真正可辩护的做法是用第 09 章的度量方法,在你自己的仓库上跑两周拿到实测基线。Sonar 基准本身也不区分语言与业务密度。
市面上"接管整个流程"的框架(GSD、BMAD、Spec-Kit)与这套技能的分野,不在于谁更全,而在于出了问题时你能不能定位到具体某一句话。这是选择它的第一性理由,对一个无法承受流程黑箱的存量系统尤其重要。
仓库 README 的开场自述是"My agent skills that I use every day to do real engineering - not vibe coding",并明确与 GSD / BMAD / Spec-Kit 划清界限:
"像 GSD、BMAD 和 Spec-Kit 这类方案试图接管整个流程来解决问题。但这样做同时夺走了你的控制权,并且让流程里的 bug 难以修复。"
"这些技能被设计成小而易改、可组合,与任何模型无关……随便 hack,改成你自己的。"
这段话直接决定了本手册第 10 章的立场:不要原样使用,要在第二个 Sprint 开始本地化改造。第 10.4 节给出三个针对本系统的自研技能草案。
技能包只有一个真正的分类轴——谁能调用它:
只能由人敲名字触发。在 Claude Code 里靠 frontmatter 的 disable-model-invocation: true 实现。职责是编排,例如 grill-with-docs、to-tickets、implement-spec、retro。
描述写给人看:去掉"当用户说..."这类触发器措辞,改成一句话摘要。
可以被智能体自主取用。描述写给模型看,保留丰富的触发措辞。职责是可复用纪律,例如 tdd、codebase-design、code-review、diagnosing-bugs。
判定法:模型能否有用地自主取出它?能,就保留在这层。
一条硬约束(.agents/invocation.md):用户可调技能可以调用模型可调技能,但永远不能调用另一个用户可调技能。这就是为什么 to-spec 里写着"如果用户没跑过 setup,就告诉用户去跑 /setup-matt-pocock-skills",而不是自己调用它——它不是调用不到,而是被设计性地禁止。这条约束保证了任何一次长流程都由人掌着方向盘。
| 失效模式 | 症状(会在你系统上这样出现) | 修复技能 | 机制 |
|---|---|---|---|
| #1 智能体没做我要它做的事 | 做完了才发现它把"评审通过"理解成了一个布尔而非带意见状态的结论;投标与项目混为一谈。 | grill-with-docsgrilling | 把歧义在设计树上一次问干净;前提是先把协商好的术语写进 GLOSSARY.md。 |
| #2 智能体太啰嗦 / 术语漂移 | 同一个"标段"在代码里出现 3 种叫法,检索与复用全部失效。 | domain-modeling | 术语一冲突立即指出并落盘;模糊词当场 sharpen。 |
| #3 代码跑不起来 | Maven 编译过了,一跑 MyBatis 或者事务就炸;或者改动悄悄覆盖了别人的字段。 | tdddiagnosing-bugs | 红-绿循环 + 阶段化诊断(含人工介入循环脚本模板)。 |
| #4 写成了泥球 | 五个子模块各自有独立的 XXService + XXDao + XXController 三件套,逻辑却几乎重复。 | codebase-designimprove-codebase-architecture | 用"深模块 / 接缝 / 局部性"词汇找加深候选,产出可视化 HTML 报告后逐个 grill。 |
README 对 improve-codebase-architecture 的说明值得单独抄出来:它是"一次勘察,不是一次救援"——"on a genuinely old codebase it will find real candidates, but it won't untangle the mud for you"。对一个十年的系统,这句话应当写进团队的操作规程:不要指望跑一次这个技能就把泥球解开,它只负责给你候选清单。
这一章给出可直接执行的安装、配置与路由规则。目标状态:明天早上团队里任何一个人都能正确启动一次完整的实现流程,不需要记住 27 个技能。
官方文档给了两种安装哲学,并且明确警告二者只能选一:同时安装会让每个技能在你机器上都出现两次。
托管只读包,作者更新你会自动收到。适合先把流程跑顺的前 4—6 周。
claude plugins install mattpocock-skills
或在会话内直接 /plugin install mattpocock-skills。
把技能以普通文件形式写进你的仓库,归你所有、随你改。适合第 5 周开始本地化。
npx skills@latest add mattpocock/skills
安装时务必勾上 setup-matt-pocock-skills;后续用 npx skills update 同步上游。
路线 B 依赖 npm 拉取;如果开发机不通外网,采用路线 A 的托管包同样会被墙。稳妥做法是:在一台能联网的机器上用 npx skills@latest add 拉下技能目录,把产出的 Markdown 文件直接提交到你的内网仓库里(作者许 MIT),从此就是普通文件,不依赖任何外网。这也是本手册第 10.4 节"本地化改造"的前提。注意:这样做之后,你的 CLAUDE.md 会跳过 npx 那一层,属于手动安装形态。
下图是这套技能在"实现一个新模块"场景下的标准编排。上层六个方块是人敲命令触发的编排层,下层十一个胶囊是被它们自动取用的能力层。箭头方向即推荐顺序。
to-spec、to-tickets、code-review、wayfinder 四个技能的前提都是"仓库已经告诉过我它的跟踪器在哪"。没跑过 setup 就直接调用,它们不会替你猜,只会报错让你回去跑 setup。因此这是真正的第 0 步。
| Setup 会问 | 本系统的推荐回答 | 为什么这么选 |
|---|---|---|
| 问题跟踪器 | 内网环境:本地 Markdown(.scratch/<feature>/issues/)。有 GitHub / GitLab:选对应项(分别走 gh / glab CLI)。 | 技能原生支持四种形态。选你实际跟踪工作的地方,而不是理想的地方——否则 ticket 会写到一个没人看的目录里。 |
| triage 标签词汇 | 接受默认的五个:needs-triage / needs-info / ready-for-agent / ready-for-human / wontfix。只有装了 triage 才会问这题。 | ready-for-agent 是关键:它是"这张票已经 grill 到可以被智能体安全接走"的唯一信号。不要自定义这套名字,除非你的跟踪器已有同义标签。 |
| 领域文档布局 | 两个上下文都用,就选 multi-context(根 GLOSSARY-MAP.md + 各上下文自己一份)。否则默认单上下文。 | 按第 01 章图 1 的判断,"投标"与"项目"是两个上下文,应当选多上下文布局——这正是 GLOSSARY-MAP.md 存在的理由:一个 map 指向两份术语表,并写清两者之间的关系。 |
写完之后,仓库根部的 CLAUDE.md(若不存在则 AGENTS.md)会增加一段「Agent skills」区块,它只包含三行导航指针,指向 docs/agents/issue-tracker.md 等文件。这个设计值得照抄到你的项目:CLAUDE.md 应当极为克制,只放指针,不放内容(见第 11 章反模式 #9)。
因为你要在别人的十年代码上动刀,图 1 只是假设。先把下面五条命令跑一遍,把答案写进 GLOSSARY.md 的备注与规格草稿:
# 1. 模块边界:本次改动实际会跨越哪几个 Maven 模块
mvn -q -o dependency:tree -Dincludes=com.yourorg | head -60
# 2. 有没有 Conway 式共用实体:搜 Project / 实体名在哪些 module 出现
rg -l "class Project|PO\b|ProjectEntity" --glob "*.java" | xargs -I{} dirname {} | sort | uniq -c
# 3. 状态机是否散落:数一下 status== 的分支密度
rg -c "status\s*==|getStatus\(\)\s*==" --glob "*.java" | sort -t: -k2 -rn | head -20
# 4. 反馈延迟基线:单模块跑一次测试的墙上时间
time mvn -q -pl <目标模块> -am -DskipITs test
# 5. 现有 seams:有没有能直接作为表征测试入口的 Service 接口
rg -l "@Service|@Repository" --glob "*.java" | wc -l
其余四条可以边做边补,但"单模块 mvn test 的墙上时间"必须现在就测,因为它决定了第 06 章所有设计的可行性。经验阈值:≤ 60 秒,TDD 循环成立;3—10 分钟,必须做测试切片与模块隔离优化;> 15 分钟,任何"AI 提效"都是先把这一项降下来再说。
这一章只收录能推出工程动作的理论。凡是只能当比喻用、推不出具体该改哪条命令或哪个文件的,一律不收。每条给出:理论 → 推导 → 在你这个 15 模块系统上的具体动作。
| 理论 | 表述(含来源) | 推导 | 本系统上的动作 |
|---|---|---|---|
| T1 反馈速率是速度上限 | "反馈的速率就是你的速度上限。永远不要承担过大的任务。" 《程序员修炼之道》 |
智能体的产出速率可以很高,但验证速率被构建与测试时间绑死。系统的实际速度是两者的较小值。提升智能体的产出而不同步提升验证,只是把工作量堆到下游。 | 把 mvn -pl <mod> -am test 的墙上时间作为一号度量,先降到 60 秒内。这是第 06 章全部设计的可行性前提。 |
| T2 深模块(接口小而实现深) | "最好的模块是深的:通过简单接口访问大量功能。" Ousterhout《软件设计的哲学》 注意 技能明确拒绝 Ousterhout 的"行数比值"定义(那会奖励注水),改用 depth-as-leverage。 |
模块的接口宽度决定调用方与测试需要理解多少。三个各 5 个方法的 Service,不如一个 5 方法、把三者都收进去的深模块。 | 对五个子模块逐个做 deletion test:设想删掉它——复杂度是消失了,还是重回到 N 个调用方?是后者才值得存在(详见第 07 章表格)。 |
| T3 一个适配器=假接缝;两个=真接缝 | 技能内部的接缝纪律。 | 只有一个实现的 port 是纯间接层,它不承载任何信息,只增加导航成本。引入 port 的合理理由是"至少有生产 + 测试两个适配器"。 | 禁止"未来可能换数据源"式的提前抽象。但如果 DAO 层已经有第二个实现(如内存版用于测试),那接缝才是真的,应在 GLOSSARY 里给它命名。 |
| T4 接口就是测试面 | 调用方与测试穿过同一个接缝。想测到接口之外,说明模块形状错了。 codebase-design 技能 |
如果为了测一个业务规则必须启动 Spring 容器 + 连库,说明接缝位置放错了,而不是"只能写集成测试"。 | 把评审规则、评审结论状态机抽成不依赖 Spring 的纯 Java,接缝压在这条活塞上;集成测试只留少数几条确认路径。 |
| T5 AI 是放大器,不是修正器 | "AI 放大的是组织的既有强弱,而非均匀地雨露均沾。" DORA 2025,n≈5,000 并明确指出:紧耦合 + 慢反馈的团队收益最小。 |
在验证能力弱的系统上加装 AI,等于放大泄漏率。因此顺序不可颠倒:先建控制系,再加动力。 | 第 10 章路线图的前 30 天不允许任何 AI 生成业务代码,只能复制狄做测试和 CI 集成的全部未XP 工作。 |
| T6 验证要比生产便宜 | 反格言版的"让验证更便宜,而不是让评审更慢"。 由 T1 + DORA 的稳定性结论推导 |
把精力投进"评审更严"收益是线性的;投进"跑一次更便宜"是乘性的,因为它提高了单位时间内可尝试的次数。 | 投资顺序:单测秒回 > 静态检查 > 人工评审。新增的每一条人工评审规则,都要先问"能不能写成 ArchUnit / Checkstyle 规则"。 |
| T7 改环境优于改指令 | retro 的归类:导航 / 自动检查 / 编码标准 / 工具经济。 |
给智能体的每条散文指令都有"是否被遵守"的不确定性;而一条 CI 检查要么过要么不过。机械性问题应当先机械化。 | retro 产出的每一项,先问能否变成 ArchUnit/Checkstyle 规则;只有真正的裁量判断(跨文件一致性、风格)才写进 CODING_STANDARDS.md。 |
技能里这句"the interface is the test surface",配上 Feathers 的接缝思想,可以推出一条具体的 ticket 切割规则:凡是含有业务规则的代码,不得与 Spring / MyBatis / HTTP 在同一个类里。理由不是美学,而是——只有这样才能在不启动容器的前提下用毫秒级代价画出红灯。这条规则可以直接写成 ArchUnit 检查,属于可靠刻度。
作者的论证很直接:智能体被丢进一个项目里被迫边做边猜术语,于是它用二十个词表达本来一个词就够了。统一语言的价值不止于省 token——它让变量、函数、文件的命名自动一致,从而让检索变得更准。
grilling 是整个技能包复用次数最多的原语。它的协议有四条硬规则:
➡️)。会话结束的条件是"前沿为空":设计树的每个分支都走过一遍,没有剩下的隐含假设。而且在你确认双方达到共识之前,不许动手。
❓ Q1 — 投标与项目是否共用同一个实体?
现有表里,"一个还没投标的对象"和一个"已经中标开始交付的对象",是同一行记录还是两行?这决定了后续所有状态机、权限、留痕的形状。
➡️ 推荐:拆成 BidOpportunity 与 Project 两个概念,由 AwardNotice 事件触发 Project 创建。
❓ Q2 — 评审结论是布尔还是枚举?
"通过/不通过"之外,实务里几乎必然存在"有条件通过""退回修改"。如果现在是 int status,后续每加一种结论都要改所有分支。
➡️ 推荐:定义 ReviewVerdict 枚举:待审 / 审核通过 / 附条件通过 / 退回修改 / 否决。禁止布尔与魔法数字。
❓ Q3 — 「基础信息」变更是否需要留痕与追溯?
被全系统引用的字典项一旦改了,历史单据算新值还是旧值?
➡️ 推荐:单据快照当时的字典值;字典项本身的变更走 expand–contract(详见 7.2),不直接改名。
这三题的答案会分别落成 ADR-0001 / ADR-0002 / ADR-0003,见 5.3。
下面是按卢文件格式写好的种子,条目内容需要根据你们实际的申请表字段校准——但结构与"Be opinionated / 给 Avoid 列"这个做法是照抄的。核心规则:定义一到两句、只定义"它是什么"而非"它做什么"、只收录本项目特有的概念(超时、通用错误码这类不收)。
# 投标上下文 bid-intake
我方从识别招标信息到递交投标文件这一段的信息对象。此上下文内的东西都还不是"项目"。
## Language
**Bid Opportunity(投标机会)**:
我方识别出的一条可参与的外部招标线索及其跟踪状态。
_Avoid_: 项目前期、招标、业务机会
**Invitation to Tender(招标)**:
甲方发出的招标行为与招标文件本身。方向是甲方→我方。
_Avoid_: 投标(混淆方向)、标讯
**Bid(投标)**:
我方对一次招标的响应行为与其提交的整套文件。方向是我方→甲方。
_Avoid_: 标书(既指文件又指行为)、报价
**Package(标段)**:
一份招标文件拆成的可独立投标、可独立中标的最小单元。
_Avoid_: 包、标段包、标包
**Bid Opening(开标)**:
甲方公开拆封投标人提交的文件的时点与过程。
_Avoid_: 开标(与"开始评标"混用)
**Award Notice(中标通知书)**:
甲方向我方正式发出的中标确认文件。是本上下文唯一能触发下一个上下文的事件。
_Avoid_: 中标结果(太宽,含落标)、成交通知
**Award Outcome(中标结果)**:
一次投标的最终结局,取值:中标 / 未中标 / 主动弃标。含结果日期与原因。
_Avoid_: 结果(任何含糊说法)
# 项目上下文 project-delivery
中标后进入内部交付与评审阶段的信息对象。仅由 Award Notice 触发创建。
## Language
**Project(项目)**:
中标通知书生效后,公司正式启动的一次内部交付活动。是本上下文的根实体。
_Avoid_: 工程、订单、标的
**Project Initiation(立项)**:
把已中标的投标机会登记为公司内部项目的动作。此前不得存在 Project。
_Avoid_: 建项、立项申请(与审批动作混用)
**Economic Review(经济评审)**:
对项目的成本、预算、付款与保证金等经济条款的独立评审。
_Avoid_: 财务评审、成本审核、商务评审
**Technical Review(技术评审)**:
对项目的技术方案、工期、资源与实施可行性的独立评审。
_Avoid_: 方案评审、技术审核
**Review Verdict(评审结论)**:
一次评审给出的正式结论。取值:待审 / 审核通过 / 附条件通过 / 退回修改 / 否决。
_Avoid_: 评审状态、审核标志、isPassed
**Review Comment(评审意见)**:
评审人针对某一具体条款提出的可追溯书面意见,含提出人与处理状态。
_Avoid_: 备注、说明
Dictionary Entry(字典项)/ Qualification(资质)/ Counterparty(合作方)属于被两个上下文共享的基础信息。它们必须放在各自的 GLOSSARY 之外单独成章,并在 GLOSSARY-MAP.md 的 Relationships 段写清依赖方向:两个上下文都依赖它,它不依赖任何上下文。这条写完之后,第 07 章的"宽重构"判定才能有依据。
技能对 ADR 的把门极严——必须同时满足三条:难以逆转 / 缺了上下文会让人困惑 / 是真实权衡的结果。缺任一条就不写 ADR。按此筛:
| 候选 ADR | 难逆转? | 缺上下文会困惑? | 真实权衡? | 结论 |
|---|---|---|---|---|
| ADR-0001 BidOpportunity 与 Project 分离 | 是。一旦拆开,历史数据与所有引用都要迁移。 | 是。后人会问"为什么中标是两张表"。 | 是。代价是 JOIN 与数据迁移;收益是状态机不再分叉。 | 写 ADR |
| ADR-0002 评审结论用枚举不用布尔 | 是。扩散到全系统后要改无数分支。 | 是。后人会想加第 6 种是否被允许。 | 是。枚举不够灵活,换来的是穷尽性。 | 写 ADR |
| ADR-0003 字典项只能 expand–contract 变更 | 是。定了之后不能给字典项改名。 | 是。后人会问"为什么不能直接改名"。 | 是。牺牲便利换取可回滚。 | 写 ADR |
| 反例 用 MyBatis 而不是 JPA | 是。但…… | —— | 否。多半是路径依赖而非权衡。 | 不写 |
对照:还会触发 ADR 的情形之一是"用户在 grill 中以一个站得住的理由否决了某个候选"——此时应主动提议:"要不要把你这个理由记成 ADR,免得以后的架构复查又推荐一遍?"
tdd 技能有一条极硬的规则:"只在事先约定好的接缝处写测试。没有确认过的接缝,一个测试都不许写。"对一个没有测试的十年系统,这条规则会立刻暴露真正的问题——你现在根本没有可用的接缝。
这里要引入技能包之外的一个必要补充:Michael Feathers 的表征测试(characterization test)。技能作者自己强调他关心的是"care about the design of the code",但没写如何处理零测试遗产,而 Feathers 的做法正好补上缺口:
tdd 真正的循环:先写失败的测试,再写最少的代码让它通过,一个垂直切片一个循环。表征测试在 Java 里通常有两种载体,选哪种取决于"输出是否是结构化清单":
把 73 万行按"测试它需要付出多少"重新分层,会得到下面这张图。深浅不是艺术效果,而是单位时间能得到多少次反馈。
技能给出一张判断表,用来决定"这个接缝值不值得抽象出一个接口"。核心纪律是 T3:只有一个适配器的接缝是假的,别加。
| 依赖类别 | 在你系统里的实例 | 接缝条件 | 处理方式 |
|---|---|---|---|
| 1. 进程内 纯计算、无 I/O | 报价计算、税率、评审结论流转 | 永远可以加深 | 直接合并进深模块,通过接口测。不需要 port。 |
| 2. 可本地替换 有本地替身 | 数据库(H2 / Testcontainers)、文件系统 | 替身存在即可加深 | 接缝在模块内部,不出现在外部接口上。 |
| 3. 远程但自有 自己的其他服务 | 公司内部的其他 Maven 模块、内部网关 | 需定义 port | 在接缝处定义 port,生产用 HTTP 适配器、测试用内存适配器。 |
| 4. 真正的外部 三方服务 | 外部招标信息源、短信/开票网关 | 注入 + mock | 把外部依赖作为注入的 port,测试提供 mock 适配器。 |
来源:skills/engineering/codebase-design/DEEPENING.md。原词为 In-process / Local-substitutable / Remote but owned / True external。
| 反模式 | 在这个系统上会长什么样 | 识别 / 修正 |
|---|---|---|
| 同义反复式断言 | assertEquals(add(a,b), a+b);或者直接把被测代码的返回值手抄成期望值。 | 期望值必须来自独立的事实来源:已知的标答、手算的算例、规格里的条款。这种测试结构上不可能失败。 |
| 横切式测试 | 先把五个子模块的所有测试写完,再统一写实现。 | 批量测试验证的是想象中的行为,而且会在理解实现之前就锁定测试结构。改用垂直切片:一个测试 → 一个实现 → 再下一个。 |
| 为测而抽却丢掉局部性 | 把一段又长的 Service 里的某个方法抽成 static 纯函数去测,但真正的 bug 都在怎么调用它的地方。 | improve-codebase-architecture 特意点了这一条:抽出来的纯函数好测了,但复杂性只是搬了家。修正方向是加深模块,而不是抽出纯函数。 |
tdd 明确写着:"重构不属于循环的一部分"。红 → 绿这段时间里只做一件事:写最少的代码让测试通过。重构属于评审阶段(交给 code-review)。这条规则对"看到老代码就想顺手改"的工程师尤其难遵守,但它是 implement-spec 里"每个子智能体一个 worktree、互不污染"能成立的前提。
to-tickets 把工作拆成追踪弹式的垂直切片,每张票声明它阻塞谁。它同时有一条极其重要的例外规则,而这条例外恰好命中你的"基础信息维护"。
每条票在发布前必须亲自问过人三个问题:颗粒度合适吗?阻塞边对吗(每张票只依赖真正门控它的票)?有没有该合并或该再拆的?迭代到人认可为止。
宽重构 = 一个机械性改动(改一个列名、改一个共享符号的类型),其爆炸半径横跨整个代码库,单次改动会同时打断上千个调用点,因此没有任何垂直切片能保持绿色。
处理方式不是硬塞进追踪弹,而是排成 expand–contract 三段:
技能还给出最后一道保险:如果连批次都无法各自保持绿色,就让它们共用一个集成分支,全部阻塞在一个"集成并验证"票上,此时"绿"只在这一处承诺。
在你的五个子模块里,属于宽重构的典型情形是:
| 情形 | 判定 | 为什么跳过垂直切片 |
|---|---|---|
给"评审结论"从 int 换成枚举 | 宽重构 | 所有读 status 的地方一起断。必须先加枚举列并双写(expand),再分批迁移读取点。 |
| 改一个被全系统引用的字典项字段名 | 宽重构 | 引用点可能上百。且需按第 5.3 节 ADR-0003 走。 |
| 调整"基础信息维护"的审批流 | 垂直切片 | 若只影响维护入口本身,可以纵向切。 |
| 新增"投标基础信息"子模块 | 垂直切片 | 全新代码,天然纵向。 |
| 把 BidOpportunity 从 Project 表里拆出来 | 宽重构 | 这是最典型的:一张表两个概念。必须同时保持两形态共存。 |
下图给出一组推荐的任务图。"前沿(frontier)"是所有前置都已完成、可以立刻开工的票的集合——这个概念在 to-tickets、grilling、implement-spec、wayfinder 四个技能里反复出现,是这套方法论的核心概念之一。
implement-spec 的主要收益。这一章把支持与反对的证据放在同一张表里。任何只引一边的结论都不可信——尤其当一个 25 万+ 星的技能包正处在舆论的顺风上时。每条都标注来源、年份与证据强度:RCT > 受控实验 > 大样本观察 > 自报调查 > 单一案例 > 建模。
| 支持/反证据 | 来源 · 年份 | 强度 | 内容 | 对本系统的适用度 |
|---|---|---|---|---|
| 支持 AI 在成熟大仓库上让资深开发者变慢 | METR RCT · 2025-07 | RCT(最高) | 16 名资深开发者、246 个真实任务,仓库平均超过 100 万行、平均 10 年历史。随机分组后,允许用 AI 的一组完成时间增加 19%。更关键的是:参与者事前预测会快 24%,事后仍认为快了 20%。接受率低于 44%,约 9% 的任务时间花在审阅 AI 输出上。 | 高——画像几乎完全吻合:规模同量级、年限吻合、开发者熟悉度高。这是本报告最重要的一条证据。 |
| 支持 AI 是放大器,紧耦合系统收益最小 | Google Cloud DORA · 2025 | 大样本调查 n≈5,000 |
"AI 放大既有强弱而非均匀普适"。AI 采纳与交付吞吐量首次转为正相关,但与交付不稳定性仍正相关。明确指出:紧耦合架构 + 缓慢反馈循环的团队几乎看不到收益。个体效能的正向效应在全部指标中最大。 | 高——15 个模块共享 reactor 正是"紧耦合"的定义场景。 |
| 支持 默认工作模式会挤掉"整理" | GitClear 纵向研究 · 2025 | 大样本观察 2.11 亿行变更 |
2020—2024 年间:被移动/重构成行占比 24.8% → 9.5%;复制粘贴行 8.4% → 12.3%;含 5 行以上重复块的提交增长约 8 倍;变更流失率 3.3% → 5.7%。2024 年是数据集中第一次出现"复制 > 重构"。 | 高——这直接预测了你们仓库若不做防护会变成什么样。 |
| 反证据 Copilot 组任务完成数 +26% | MIT / Princeton / UPenn · 2024 | 受控 + 观察 4,800 名开发者 |
覆盖 Microsoft、Accenture 与一家财富 100 强。使用 Copilot 的开发者平均多完成 26% 的任务。 | 中——场景差异巨大:多为隔离、规模较小的任务,不是十年单体上的功能改造。 |
| 反证据 受控实验中快 55.8% | GitHub 官方实验 | 受控实验 | 另一个经常被引用的数字:持 Copilot 的开发者完成同一任务快 55.8%;并报告可读性 +3.62%、可维护性 +2.47% 等小幅正向。 | 低——任务是孤立的、无历史的,与"在三百万行上下文里加一个受限于业务铁律的功能"不可比。 |
| 反证据 质量并非必然下降 | Qodo 数据 (厂商来源) |
厂商数据 强度最低 |
AI 工具结合 AI 代码评审时,团队报告质量改善者达 81%,而只用 AI 工具不做自动评审的为 55%。 | 中——强度低,但它指向的结论与本报告一致:差别在于评审这一个变量。 |
| 背景 维护成本是常态而非意外 | Stripe Developer Coefficient · 2018 | 自报调查 n=1,000+ 开发者 / 1,000+ 高管 |
开发者每周 17.3 小时用于技术债与坏代码(13.5 + 3.8),占 41.1 小时工作周的 42%;并外推出约 3,000 亿美元的全球产出损失。 | 中低——自报且数据已过多年,只能当背景锚点,不能当预算依据。 |
| 背景 信任赤字真实存在 | Stack Overflow 开发者调查 · 2025 | 调查 (经 DORA 综述引用) |
对 AI 输出不信任度 46%、信任 33%;另有 66% 表示修复"差一点就对"的 AI 代码比自己写更花时间。 | 中——二手转述自综述报道,原始问卷未直接核验;但与 METR 的"审阅开销"互相印证。 |
DORA 团队把 AI 采纳早期的稳定性下滑明确称为"expected J-Curve (or tuition cost)"——并给出了压平曲线的处方:投资平台工程 + 强版本控制实践 + 小批量size。这条处方与本手册第 06、07 章的建议是同一件事的两种说法。
① METR 作者自己列了一张"我们不提供证据的主张"清单,明确没有主张"大多数开发者的多数场景"或"未来不会变快",甚至明说"显然存在能取得正收益的使用方式"。引这条数据时不能过度外推。
② GitClear 反映的是相关性而非因果:它的 diff 分类无法区分"团队有意识地少重构"与"AI 导致的复制"。但它与 METR 的"接受率不足 44% + 大改后再提交"描述了同一个现象。
③ 正反证据没有被隐藏:隔离任务上的确显著更快。真实结论因此是条件的——收益取决于任务是否与庞大的隐含上下文耦合,而这恰好是你这类系统的定义特征。
METR 那 19% 与开发者自认为快 20% 之间的缺口,直接推出一条度量原则:主观感受不能参与度量,只能作为线索。下面是三层指标与四条防作弊原则。
| 层 | 指标 | 怎么测 | 为什么是它 |
|---|---|---|---|
| L1 输入 (采纳广度) | 被标记为 ready-for-agent 的票占比 | 跟踪器里的标签计数。 | 它衡量的不是"用了多少 AI",而是有多少工作被 grill 到了能安全交给智能体的程度。 |
| L2 过程 (效率) | 单模块构建-测试墙钟时间(P50 / P90) | 定时跑 mvn -pl <mod> -am test 并上报。 | 一号指标。它是反馈速率的直接代理,也是 T1 那条理论的可观测量。 |
| 单票周期 P50 / P90 | 票创建到关闭的时间戳差。 | 比"工时估计"客观,而且能暴露被卡在哪一层。 | |
| L3 结果 (质量) | 变更失败率 / 回滚率 | 发布后 7 天内需要热修或回滚的变更占比(DORA 四指标的变形)。 | 这是唯一能证伪" AI 让我更快"这件事的指标——速度可以自欺,回滚不能。 |
| 重复块增量 / 重构行数占比 | 本地跑一次 GitClear 式的 diff 分类(或用 SonarQube 的重复行指标)。 | 直接监测第 6 章的 prediction:若 重构占比在下降而重复在上升,说明 AI 正在给这座仓库加债。 |
不要一上来做看板。抓起三个数字就足够启动:① 单模块测试墙钟时间(每天自动跑一次);② 回滚/热修率(每周一次);③ ready-for-agent 票占比(每周一次)。等到这三条曲线稳定两周、有了真实基线,再考虑加指标。度量体系本身也应该遵循"小批量"。
这份路线图有一个反常识的安排:前三十天禁止让智能体生成任何业务代码。理由是第 08 章的证据——在紧耦合、慢反馈、高默契约定的系统里,先把前置的安全网与快速反馈建好,是唯一能把 J 曲线压平的做法。
| 投入方向 | 建议配比 | 理由 |
|---|---|---|
| 反馈通道(测试速度、CI 切片、静态检查) | 40% | 这是唯一对后续所有工作产生乘数效应的投入。对应 T1、T6 与第 9.1 节的二号指标。 |
| 术语与规格(grill、GLOSSARY、ADR、票) | 25% | 决定返工率。在一个误解成本极高的系统里,这部分最容易被砍,也最不该被砍。 |
| 业务功能实现 | 25% | 看起来偏低,但在前置就绪后,这一块的实际速度会被抬起来。 |
| 度量与复盘 | 10% | 三条曲线 + 双周 retro。没有它,你无法证伪,也就无法知道该停还是该加。 |
作者的原话是"Hack around with them. Make them your own."。下面是针对本系统最值得自己写的三个技能,都遵循同一套格式约定:YAML frontmatter + 极短的正文 + 按需引用的附属文件。
legacy-fast-feedback,模型可调)---
name: legacy-fast-feedback
description: Use when running or changing tests in this Maven reactor, or when a
test command is needed. Knows which modules are cheap to test alone and which
fan out through -am.
---
先跑 docs/agents/feedback-baseline.md 里记录的最快命令。
对目标模块优先尝试:mvn -o -q -pl <mod> -am -DskipITs test
不得使用全量 reactor 构建来验证单个模块。
若某模块 -am 会拖入超过 4 个模块,先查阅上述文档里的替代切片。
禁止为了"能跑起来"而跳过测试(-DskipTests / -Dmaven.test.skip=true)。
maven-boundary-guard,模型可调)---
name: maven-boundary-guard
description: Use when adding imports across Maven modules, adding a dependency to
pom.xml, or placing a new class. Classifies each dependency into the four
DEEPENING categories.
---
跨 import 或新增 pom 依赖前,先回答三个问题:
1. 这次依赖属于 in-process / local-substitutable / remote-owned / true-external 哪一类?
2. 若为 remote-owned,接缝处是否需要 port?是否已有两个及以上适配器?
只有一个适配器的接缝是假接缝,不要引入。
3. 新增的类不得同时承担业务规则与 I/O。业务规则必须独立于 Spring 容器可实例化。
违反第 3 条时,先在 target seam 处剥离规则,而不是写集成测试绕开。
legacy-safety-net,用户可调)---
name: legacy-safety-net
description: Weave characterization tests around a piece of old code before any
change is allowed to touch it.
disable-model-invocation: true
---
改动任何十年以上、无测试的旧代码之前:
1. 找出即将被触碰的最小行为集合(一个服务方法的输入/输出,或一张表的写入结果)。
2. 用 JUnit 或 Approval 风格把"它现在实际做什么"冻结下来。允许对现有 bug
做记录性断言,并在测试名里标注 @Characterization 与日期。
3. 基线第一次必须由一个人逐字段过一遍并签字(写在票的评论里)。
4. 测试必须能在 60 秒内单独跑完,否则先处理第 3.3 节的第 4 条测量。
红线:不得在没做完第 2 步的情况下让任何智能体改动该段代码。
① 用户可调技能的 description 写给人看,去掉"当用户说..."式触发措辞;模型可调技能反过来,要保留丰富的触发措辞。
② 技能之间互相调用时写 Call the Skill tool with "技能名",不要用相对路径跨目录引用;一次调用只能带一个技能名。
③ 不能让一个技能去调用另一个用户可调技能——需要人做的,就写成"告诉用户去跑 /xxx"。
每条给症状与修正。症状一律写成"在这类系统上的具体样子"——因为泛泛而谈的反模式,在人们恰好犯了它的时候也认不出来。
| 反模式 | 在你这个系统上的症状 | 修正 |
|---|---|---|
| 把 AI 当成求援信号 | 工期紧了就"让智能体先写一版",跳过术语与测试;理由是"先出东西再说"。 | 承认这是借高利贷。唯一合规的提速是 Ticket 颗粒度变小,不是跳过前置阶段。 |
| 用"感觉快了"做立项论据 | 汇报里写"效率提升明显",但没有任何一条第 09 章的曲线。 | METR 那 39 个百分点的感知缺口是这个问题的直接证据。没基线不算证据。 |
指望一次 improve-codebase-architecture 解开十年泥球 | 跑完拿到一堆候选,团队很兴奋,然后发现没有一条能直接落地。 | 它只产出候选,然后针对你选中的那一个继续 grill。价值在"持续缩小脂肪",不在"一次换血"。 |
| 同时安装两套安装形态 | 插件版与 skills.sh 版共存,每个技能出现两次,改了不生效。 | 文档明确要求二选一。最终形态应为本地化后的 skills.sh 版本。 |
| 反模式 | 症状 | 修正 |
|---|---|---|
| 横向切片 | "先把五个子模块的 Entity 和 Mapper 全部生成出来",看起来进展神速。 | 批量产出验证的是想象中的行为。改垂直切片:一条能演示的窄路径走完全部层次。 |
| 宽重构伪装成切片 | 一张"评审结论改为枚举"的票改了一百多个文件,最后必须集成分支才能编译。 | 改走 expand → 分批 migrate → contract,每批一张票,每批 CI 绿。 |
| 把 Port 当勋章 | 为"将来可能换数据库"给每个 DAO 加了接口,只有一个实现。 | 一个适配器 = 假接缝。等出现第二个真正的适配器时再抽。 |
| 为可测性抽出纯函数 | 抽出 static 方法测过了,但真正的 bug 藏在调用它的那几个分支里。 | 这是 locality 缺失。修正方向是加深模块,不是抽函数。 |
| 在红绿循环里顺手重构 | 改一个投标字段时顺手"优化"了旁边的命名与结构,diff 涨了三倍。 | 技能写得很清楚:重构属于评审阶段,不属于循环。它是并行实现能成立的前提。 |
| 让 AI 写像素复制的代码而不做整合 | 五个子模块各有各的 XxxHelper,逻辑重复但未察觉。 | code-review 的 Duplicated Code 基线会抓到它;更好的是事前用自动化重复块检查拦住。 |
| 反模式 | 症状 | 修正 |
|---|---|---|
把 CLAUDE.md 写成百科全书 | 根目录的转向文件越长越好几千行,每条都会被推进上下文,而且谁也没验证过是否被遵守。 | 它只放导航指针。具体内容应当由 CODING_STANDARDS.md 与自动检查承担。 |
| 用散文规则约束机械性问题 | "新增类不要跨模块依赖"写进规范,但没人记得住。 | 机械性问题默认做成 ArchUnit / Checkstyle 规则;只有真正的裁量判断才写规范。 |
| ADR 通货膨胀 | 每个技术选型都写一篇,三个月后没人读,真需要时找不到。 | 严格执行三道门槛:难逆转 / 缺上下文会困惑 / 是真实权衡。缺一即不写。 |
| GLOSSARY 里塞实现细节 | 术语表出现了表名、字段名、REST 路径。 | 它只收本上下文特有的概念,且定义"是什么"而非"做什么"。通用编程概念不入册。 |
| 跳过 retro | 项目做完了没任何沉淀,下一个模块重复踩同一个坑。 | 每次办双周 retro,产出按严重度排序的环境改动,且优先落到自动化检查。 |
① 在与你画像吻合的系统上(成熟、大、高默契),现有 AI 编码工具大概率先降低交付速度(METR RCT)。② AI 采纳会提高交付不稳定性,而紧耦合 + 慢反馈的组织收益最小(DORA 2025)。③ 默认工作模式下,代码库的整合类活动占比在下降(GitClear 2.11 亿行)。④ 因此,先建验证能力,再加生成能力这一顺序,是目前证据唯一支持的稳妥解。
① 「投标」与「项目」的概念分离,是这五个子模块里回报最高的一件事,高于任何单个功能的交付。这不是证据直接给出的结论,而是依据"降低隐式耦合"的一般原理推导出的判断——需要在 grill 阶段被你们自己的业务专家证伪。
② 前 30 天禁止生成业务代码的安排是可辩护的,但对工期紧的团队可能政治上门槛太高。若必须压缩,至少保留 T1 表征测试这一张票。
③ mattpocock/skills 的真正价值是它把"什么时候该停下来问清楚"写成了可执行的协议,而不是它提供的任何一个写代码的技巧。后者会随模型换代过期,前者不会。
不需要任何审批、不需要装插件:在仓库里新建一个 GLOSSARY.md,只写第 5.2 节里那十几个术语,然后找一个业务同事核对一轮。这件事的成本是半天,收益是——从此你们讨论"项目"这个词时,指的是同一个东西,而且这份共识可以直接被任何智能体读取。
三条最重要的提醒:本手册未访问你的代码库,因此图 1 的架构判断与 5.2 节的术语内容均为待校验的假设;图 5 的 J 曲线是建模值而非实测值;第 1.3 节的成本折算是线性外推的建模结果,不可用于预算。
按证据类型分组。核心部分全部回溯到一手来源——技能的原始 Markdown、研究报告原文、官方博客。
https://github.com/mattpocock/skills(MIT)skills/productivity/grilling/SKILL.md — 设计树、前沿、轮次协议,"找事实是你的活"skills/engineering/grill-with-docs/SKILL.md — 两行:调用 grilling + domain-modelingskills/engineering/to-spec/SKILL.md — 规格模板、接缝数量、"不超过一个"原则skills/engineering/to-tickets/SKILL.md — 垂直切片三条规则、宽重构的 expand–contract 定义skills/engineering/implement/SKILL.md 与 implement-spec/SKILL.md — 上下文指针、前沿并发、worktreeskills/engineering/tdd/SKILL.md — 只测约定接缝、三条反模式、重构不属于循环skills/engineering/codebase-design/SKILL.md 与 DEEPENING.md — 深模块词汇表、依赖四象限、replace-don't-layerskills/engineering/code-review/SKILL.md — 双轴并行、Fowler 十二种气味基线skills/engineering/domain-modeling/SKILL.md 与 GLOSSARY-FORMAT.md — ADR 三门槛、术语表格式skills/engineering/setup-matt-pocock-skills/SKILL.md — 三 Section、五种 triage 标签、CLAUDE.md 区块skills/engineering/improve-codebase-architecture/SKILL.md — 五个摩擦探测点、"勘察不是救援"skills/engineering/retro/SKILL.md — 六个改进类别、机械性问题优先机械化.agents/invocation.md — 两类调用权的定义与"不得跨调用"的硬约束code-review 的默认基线。