Matt Pocock 的 agent-skills:把软件工程基本功拆成可组合的 Skill

2 分钟阅读
·

之前写过 Superpowers 的使用思考,那是一套接管整个开发流程的技能框架。最近通读了另一个思路不同的仓库:Matt Pocock(Total TypeScript 作者)的 agent-skills,副标题叫「Skills For Real Engineers」。这篇笔记讲它的设计、取舍和适用场景。

它是什么

agent-skills 是一组给 Claude Code、Codex 等编程 agent 用的 skill 集合,目前包含 20 多个技能,分在 engineering/(日常代码工作)和 productivity/(非代码工作流)两个正式目录下,另有 misc/personal/in-progress/deprecated/ 四个不随插件发布的目录。

它和 GSD、BMAD、Spec-Kit 这类框架的定位不同。那些框架拥有自己的流程:你按它的阶段走,它替你决定下一步做什么。agent-skills 的每个 skill 都很小,只解决一个具体问题,互相之间靠少量明确的调用关系连接,流程的控制权留在使用者手里。README 里对此的解释是:流程框架接管流程的同时,也把流程里的 bug 变得难以排查;小而可组合的 skill 可以直接读、直接改、单独替换。

为什么做:四个失败模式

仓库 README 把动机归结为 AI 编程反复出现的四个失败模式,每个对应一组 skill:

  1. Agent 做的和你要的不一样。这是最常见的失败:你以为 agent 理解了需求,看到产出才发现理解偏差。对策是「grilling」:让 agent 反过来追问你,一次一个问题,每个问题附带它推荐的答案,把决策树的每个分支走完,确认达成共识后才动手。对应 /grill-me/grill-with-docs 两个技能。

  2. Agent 太啰嗦。项目有自己的领域术语,agent 每次被扔进项目都要重新猜,于是用二十个词表达一个词能表达的意思。对策是建立共享语言:一份 CONTEXT.md 记录项目的领域术语表(比如把「课程里某一课被物化到文件系统」收敛为「materialization cascade」),重要决策记录为 ADR。这个机制内置在 /grill-with-docsdomain-modeling 里。附带收益是命名一致、代码更容易被 agent 导航、思考消耗的 token 更少。

  3. 代码不能跑。对齐了需求之后 agent 仍然产出坏代码,问题通常出在反馈回路上:没有类型检查、没有浏览器访问、没有自动化测试,agent 等于盲写。对策是 /tdd(红绿循环,且测试只能写在事先和用户确认的 seam 上)和 /diagnosing-bugs(复现、最小化、假设、插桩、修复、回归测试的诊断循环)。

  4. 代码库变成大泥球。Agent 加速了写代码,也以同样的速度加速软件熵增。对策是把模块设计的检查内置到每个环节:/to-spec 在生成规格前先问你动到哪些模块,/improve-codebase-architecture 定期扫描整个代码库寻找「深模块」机会(小的公开接口背后承载大量行为),输出可视化报告,由你挑出其中一个方向再 grill 展开。

这几个失败模式下的引用也能看出作者的取材:《The Pragmatic Programmer》(问题 1 和 3)、《Domain-Driven Design》(问题 2)、《Extreme Programming Explained》和《A Philosophy of Software Design》(问题 4)。整套仓库的立场是:模型在变强,但软件工程的基本功(对齐、命名、反馈回路、模块设计)不会因此失效,值得把这些基本功固化成可重复执行的 prompt。

怎么做的

两层调用模型

仓库把所有 skill 沿一个轴分开:user-invokedmodel-invoked

  • user-invoked 技能带 disable-model-invocation: true,只能由人敲斜杠命令触发,负责编排,比如 /implement/to-spec。它们不占用 agent 每轮的上下文(description 不进窗口),代价是人得记住它们存在。
  • model-invoked 技能保留面向模型的 description,agent 判断任务匹配时可以自动调用,承载可复用的纪律,比如 tdddiagnosing-bugsresearch

规则是:user-invoked 技能可以调用 model-invoked 技能(/implement 内部驱动 /tdd),但 user-invoked 之间不允许互相调用。当 user-invoked 技能多到记不住时,用一个 router 技能解决:仓库里的 /ask-matt 就是这个角色,你描述处境,它告诉你该用哪个技能。

这个分层在 writing-great-skills 里有完整的论证,核心概念是可预测性:skill 的目标是让 agent 每次走相同的过程,而不是产出相同的结果。围绕这个目标它定义了一组词汇:description 的每个触发分支只写一次、步骤要有可检查的完成标准、参考资料按信息层级下沉到外部文件按需加载。这份文档本身可以作为写任何 skill 的参考,不限于这个仓库。

工程主线

一次典型改动的串联方式如下图所示:

agent-skills 一次改动的完整闭环

/setup-matt-pocock-skills 每个仓库跑一次,选定 issue tracker(GitHub、GitLab、Linear 或本地 markdown 文件)、triage 用的标签、文档存放位置,写入 docs/agents/ 下的配置文件。之后的流程是:/grill-with-docs 对齐需求并同步维护 CONTEXT.md 和 ADR,/to-spec 把已经讨论清楚的内容沉淀为规格发到 issue tracker,/to-tickets 把规格拆成一组 tracer-bullet 票据并声明互相的阻塞关系,/implement 按票据实现并在约定的 seam 上驱动 /tdd/code-review 沿 Standards 和 Spec 两个轴各起一个并行子代理审查 diff,最后提交。

主线之外有几个独立入口:/wayfinder 处理单个会话装不下的大工程,把找路过程表示成 issue tracker 上的一张 decision ticket 地图,每张票据解决一个决策而不是交付一段代码;/triage 用标签状态机推进 issue;/handoff 把当前会话压缩成交接文档给下一个 agent。

分发方式

两种安装方式对应两种思路。Claude Code 官方插件市场里的 mattpocock-skills 是订阅制:只读、随作者发布自动更新。npx skills add mattpocock/skills 是 fork 制:把 skill 文件拷贝进你的仓库,归你所有、可以随意改,想跟进上游再手动 npx skills update

仓库自己的 ADR(.agents/adr/0002)记录了一个有意思的分发细节:为什么有 Claude Code 原生插件却推迟 Codex 原生插件。原因是 Claude Code 的插件清单允许逐个列出 skill 目录,可以精确只发布正式目录;Codex 的清单只接受单个路径且递归发现,既没法同时指向 engineering/productivity/ 两个正式目录,也无法排除 deprecated/ 等目录,符号链接方案又在安装时被丢弃。这个 ADR 本身就是仓库「把难解释的决策写下来」主张的实例。

收益

  1. 失败模式有明确对策。对齐、啰嗦、反馈回路、设计腐化这四个问题各自有对应技能,使用时能说清楚在解决哪个问题,而不是泛泛地「加流程」。
  2. 可读可改。每个 skill 就是一个 SKILL.md 文件加少量附属文档,没有代码、没有运行时。grilling 的核心提示词只有四段。fork 制安装下可以直接改成自己的版本。
  3. 模型无关。全部是 prompt 层的资产,不绑定特定模型或特定 agent 产品,skills.sh 安装器支持多种 harness。
  4. 控制权在使用者手里。流程框架出问题时要 debug 框架本身;这里的每个环节是独立的 prompt,哪一步不合适可以跳过、替换或直接编辑。
  5. 上下文成本经过设计。user-invoked 技能零上下文占用,model-invoked 技能的 description 被要求精简到一个触发分支一句话,参考资料下沉到外部文件按需加载。这比把整个方法论塞进 CLAUDE.md 常驻上下文要省。

代价与限制

  1. 认知负担转移到人身上。user-invoked 技能只能靠人记住并手动触发。虽然有 /ask-matt 做路由,但「什么时候该 grill、什么时候该 wayfinder」仍然依赖使用者的判断。skill 不会在你忘记用时替你兜底。
  2. skill 只是 prompt,没有强制力。/tdd 写了红绿循环的规则,但 agent 是否每轮都遵守取决于模型和上下文状态。它没有 hook、没有 CI 门禁,纪律的执行强度低于工程化手段(比如 pre-commit 跑测试)。
  3. 文档资产需要持续维护。CONTEXT.md、ADR、triage 标签、issue tracker 配置都是长期负债。术语表过时后反而会误导 agent。仓库自己也承认这一点,专门设了 domain-modeling 技能来维护术语表,但维护动作还是要发生。
  4. 绑定 issue tracker 带来初始化成本。工程主线假设有一个 issue tracker 承接规格和票据。个人小项目需要先接受这套约定,或者用本地 markdown 兜底。
  5. 对小任务开销偏大。改一行配置也走 grill → spec → tickets → implement → review 的完整闭环显然不划算。这套流程的价值随任务规模增长,使用者要自己判断从哪个环节切入。README 的建议是每次改动都从 grilling 开始,但没有给出任务大小与流程深度的对应关系。
  6. 生态覆盖不均。Claude Code 有原生插件和自动更新,Codex 等其他 harness 只能走拷贝安装,跟进上游是手动动作。

适合什么场景

比较合适的情况是:长期维护的真实项目,有 issue tracker 或愿意建立本地票据约定;团队或个人愿意维护 CONTEXT.md 和 ADR 这类文档资产;对 agent 产出的质量有要求,愿意为对齐和反馈回路付出交互成本。这类场景里,流程的固定成本被长期使用摊薄,共享语言和 ADR 的价值随使用累积。

不合适的情况是:一次性脚本和探索性玩具,流程开销超过收益;追求高度自治、希望人完全退出的用法,这套技能的设计前提恰好是人在关键决策点在场(grilling 的本质就是把决策留给人);以及不愿意维护任何文档资产的团队,术语表和 ADR 腐化后这套体系的基础就没了。

我自己的用法介于两者之间:完整闭环留给跨模块的改动,小改动只保留 grilling 和 code-review 两个环节。如果你已经有一套自己的 skill 体系,这个仓库的 writing-great-skills 文档和两层调用模型即使不装它的技能也值得读一遍。


523 字 · 43 段落
xi ming

Written by xi mingFollow onGitHub