如果你已经在用 AI 编程助手写代码,多半经历过这样的落差:让模型「写个测试」,它给你一份测试,但没跑过一次;让它「修个 bug」,它改了三行、顺手重构了半个文件。模型很聪明,但它不知道你的工程纪律。Skills 就是补上这一块的机制 —— 给 Agent 一本可以按需翻开的操作手册。本文分两部分:先讲清 Skills 机制的原理(为什么它有效、Agent 是怎么「自主选择」的),再拆解目前社区里最成体系的一套 —— Matt Pocock 的「Skills For Real Engineers」(25 个,公开仓库 mattpocock/skills)。
一、Skill 到底是什么
一个 skill 就是一个文件夹,核心是一份 SKILL.md:一段 description + 一套操作指令,,可选地带上可执行脚本和参考文档。它不是插件、不是扩展 API,本质就是结构化的 prompt——但被文件系统组织起来、按需加载。
它要解决的问题很具体:模型的上下文窗口有限,不可能把所有工程纪律常驻在每次对话里。Skills 的做法是:
- 平时只注入元数据:会话开始时,每个 skill 的名称和一行 description 进入系统提示(几十行就装下几十个 skill);
- 用时才加载正文:命中时才把完整指令读进上下文,用完即弃。
这本质上是给 Agent 装了一个「按需检索的程序性知识库」——声明式知识(是什么)模型自己有,程序性知识(你们团队怎么做)靠 skill 补。
二、Agent 怎么「自主选择」一个 skill
机制分四步,理解了它,你就知道该把精力花在哪个环节:
- 清单注入:会话开始,所有 skill 的名称 + description 作为元数据注入系统提示。完整正文并不加载。
- 语义匹配:处理请求时,Agent 把任务描述和这些 description 做语义匹配。匹配命中,就调用工具加载对应的
SKILL.md,再按里面的流程干活。 - 两种触发方式:
- 显式触发:用户输入
/skill-name,无条件加载——适合「编排型」流程(比如”开始评审”); - 自主触发:Agent 根据 description 自己判断——适合「纪律型」技能(比如 TDD 循环、调试流程)。
- 显式触发:用户输入
- 优先级:同名时用户级目录覆盖插件级目录——这既是定制入口,也是坑(后面讲)。
由此得出一个关键推论:自主触发的质量,完全取决于 description 的写法。写得越具体、越包含真实场景下的触发短语(”diagnose this crash”、”red-green-refactor”),命中率越高。description 不是简介,是这个 skill 的全部入口。反过来,这也解释了为什么 skill 要「小而聚焦」——一个试图覆盖所有场景的 description,在语义匹配时反而哪个场景都命中不好。
三、写好一个 skill 的几条经验
无论自己写还是改别人的,这几条反复被验证:
- description 写触发场景,不写功能清单。「用于调试难以复现的 bug,当用户报告 flaky test 或间歇性崩溃时使用」远好于「一个强大的调试工具」。
- 正文写给未来的 Agent,不是写给人看。指令要用祈使句、按执行顺序组织、把「检查点」写明白(”先跑测试确认变红,再动手修”),因为读者是一个没有你当前对话记忆的新会话。
- 一件事一个 skill。小 skill 可以组合成大流程(后面 matt 的工作流就是这样串的),大而全的 skill 无法复用也无法调试。
- 可执行的部分就写成脚本。与其用自然语言描述”检查 XX 格式”,不如附带一个校验脚本——Agent 执行脚本比理解散文可靠得多。
- 小心重复安装。同一个 skill 从插件和从文件管理器各装一份,会产生两个同名副本——裸名称会解析到你本地那份可编辑副本,插件更新就悄悄失效了。装一套就好。
四、Matt Pocock 的「Skills For Real Engineers」
Matt Pocock 是 TypeScript 社区的知名教育者(Total TypeScript 作者),他开源的这套 skill 集合是目前社区里体系感最强的一套。README 里开宗明义的设计哲学值得全文引用:
开发真实的应用很难。GSD、BMAD、Spec-Kit 这类方法试图通过接管整个流程来帮你——但代价是夺走你的控制权,让流程中的 bug 难以排查。这些 skills 设计得小、易改、可组合。基于几十年的工程经验。拿去魔改,变成你自己的。
4.1 四个失败模式,四组解药
这套技能的骨架,是 Matt 总结的四个 agent 高频失败模式。每个模式对应一组 skill:
| 失败模式 | 对应 skills | 思路 |
|---|---|---|
| #1 Agent 做的不是我想要的(需求错位) | grill-me / grill-with-docs |
拷问式访谈:让 Agent 反过来连环追问你,把模糊需求磨清楚——这是他最受欢迎的 skill |
| #2 Agent 太啰嗦 / 说不到点上(缺乏共享语言) | domain-modeling、writing-for-agents |
给项目建立术语表和决策记录,人和 Agent 说同一种话 |
| #3 代码跑不起来(反馈回路缺失) | tdd、diagnosing-bugs |
红-绿-重构的垂直切片;调试的分阶段纪律循环 |
| #4 造出一坨泥球(架构熵增) | codebase-design、improve-codebase-architecture |
Ousterhout「深模块」设计词汇;定期扫描架构债 |
4.2 编排型与纪律型:两层结构
这套技能内部分了两层,正好对应前文说的两种触发方式:
编排型(显式 / 触发)——你主动发起的流程入口:
ask-matt:路由器。不知道该用哪个 skill 时问它;grill-with-docs:拷问式访谈 + 顺手沉淀CONTEXT.md(项目词汇表)和 ADR(架构决策记录)——一次对话同时解决 #1 和 #2;to-spec:把当前对话直接合成一份 spec 发布到 issue tracker;to-tickets:把计划拆成一串「曳光弹」ticket,并声明相互的阻塞关系;implement:按 spec/ticket 实现,过程中驱动tdd,收尾自动跑code-review;wayfinder:超过一个会话能装下的大工程——拆成「决策 ticket 地图」,逐个解决;triage:按分诊状态机处理 issue 和外部 PR,产出 Agent 可直接执行的 brief;setup-...:每个仓库跑一次的初始化(配置 issue tracker、标签、文档位置)。
纪律型(Agent 自主触发)——内嵌的工程纪律,在编排流程里被调用,也可以单独生效:
tdd:一次一个垂直切片的红-绿-重构;diagnosing-bugs:复现变红 → 最小化 → 假设 → 插桩 → 修复 → 回归测试的完整循环;code-review:双轴评审——既查是否符合仓库编码规范,也查是否忠实实现了 spec;codebase-design:给 Agent 装上「深模块 / 浅模块」的架构词汇;- 还有原型验证、调研(带引用)、合并冲突解决(按双方意图逐块处理,永不粗暴 abort)、生成交互式向导带人配密钥等。
4.3 把工作流串起来
单个 skill 是零件,串起来才是生产力。Matt 给出的典型闭环:
1 | setup(每仓库一次) |
小改动不用走全流程——implement 单独就能干;大工程把 wayfinder 顶在前面;平时调试和架构维护随时独立触发。框架接管流程,skills 只在你需要纪律的地方提供纪律——这是它和 BMAD 类重框架的分野。
五、几点实践建议
结合自己一段时间的使用,给想上手的几条:
- 从两个 skill 开始:
tdd(纪律型,立刻有体感)和grill-me(编排型,治「需求错位」的立竿见影)。不要一上来装 25 个。 - description 优先:用一段时间后,把没被自主触发过的 skill 翻出来看 description——八成是触发词写得太文艺。
- 让 skill 沉淀你的规范:把团队的 code review checklist、发布流程写成 skill,比塞在聊天记录里强一个数量级——它是可版本管理、可迭代、可分享的。
- 警惕双份安装(前文第三节的坑):插件版管更新,本地版管魔改,二选一。
- 中文场景完全可用:指令是英文还是中文不影响效果——语义匹配跨语言工作良好;写自己的 skill 时直接用中文 description 也行。
六、结语
Skills 机制的本质,是把「怎么干活」从对话的偶然输入,变成可版本管理、可复用、可组合的工程资产。Matt Pocock 这套技能包的价值不在于 25 个具体 skill,而在于它示范了一种组织方式:用小组件对治大框架,用显式编排承载流程,用自主纪律保证质量,用文档沉淀对抗遗忘。
AI 编程工具的竞争正在从「谁的模型更强」转向「谁的工程语境更完整」。Skills 是这条路上目前最轻、也最开放的一块拼图——而它只是一份 Markdown。



