Agent Skills 系列(2):`SKILL.md`、渐进式披露与最小范例
📌 系列说明
如果你已经认同「AI 缺的是你们家的默认接法」(见第 1 篇),接下来要解决的是:这些约定以什么形态交给模型、什么时候才真正进上下文。本篇只谈写法与结构:SKILL.md 里写什么、大段材料放哪、为什么不会一上来就把所有 Skill 全文塞进对话。安装、搜索、发布和团队同步Skill参考 工具引入篇;什么值得做成Skill以及触发条件收窄可以看 什么值得做成 Skill 与 碎片化困局。
💡 什么是 Agent Skill?
Agent Skill 是一份可被 Agent 运行时「先发现、再按需展开」的结构化说明。 标准结构是一个技能目录:根目录必有 SKILL.md(YAML 头 + Markdown 正文),同级目录下还可以放 references/、scripts/ 等大段材料——维护时像写文档,运行时不必每次对话手工粘贴整本规范。
🪜 渐进式披露:为什么不会「装 20 个 Skill 就撑爆上下文」
这是 Agent Skills 里很核心的一条设计:能力可以很多,但默认只付很轻的发现成本;细节只有在真的需要时才加载。
| 层级 | 通常加载什么 | 作用 |
|---|---|---|
| 第 1 层:元数据 | SKILL.md 里 YAML 的 name、description(以及各实现允许的其他短字段) | 启动或索引阶段就能扫一遍:模型/客户端能回答「有哪些技能、各自在什么场景该被考虑」 |
| 第 2 层:指令正文 | SKILL.md 去掉头之后的 Markdown:流程、约束、禁区、输出格式 | 当用户需求与 description 指向的场景对上号再加载——把「团队怎么做事」放进这一层 |
| 第 3 层:附件 | references/ 下长文、scripts/ 可执行脚本、大段模板等 | 用到再读、再跑,避免每个会话都把几万字规范摊在上下文里 |
这里需要注意:
description不是摘要作文,而是触发说明:要写清「什么用户措辞 / 什么任务类型下该启用本 Skill」,否则要么永远不被选中,要么描述太宽、和别的 Skill 抢触发(碎片化篇会展开)。- 大段样例、接口表、复制粘贴块优先进
references/,如果内容太多建议在references里拆成多个 md 文件,在SKILL.md里用一两句规定「何时去读哪一份」。
📁 Skill 目录长什么样(结构)
最小形态就是一个文件夹 + 单文件:
vue3-form-generator/
└── SKILL.md
需要渐进展开时,常见扩展是:
vue3-form-generator/
├── SKILL.md # 必需:元数据 + 主指令
├── references/
│ ├── form-templates.md # 可选:大段示例、字段字典
│ ├── login-form.md # 多文件示例
│ └── api-reference.md # 更多可以放的文档
└── scripts/
└── validate.mjs # 可选:工具链允许时的脚本(是否执行看客户端)
SKILL.md 顶部 YAML frontmatter 至少会用到:
name:技能标识,人类可读、稳定。description:何时启用 + 一句能力边界(给第 1 层 discovery 用)。
正文建议这样写:让任何一个新人第一次打开就能直接按着来操作,不要写成一篇宣传稿。简单来说,可以按这样的结构来:目的 → 重要约定/禁止事项 → 场景和做法的对照表 → 验收标准 → (可选)指向 references 里的具体大示例。
🔍 真实范例:vue-best-practices 里「主流程 + references/ 多文件」
vuejs-ai/skills 仓库中的 vue-best-practices 把「主指令短、细则外挂」做得很标准:根目录 SKILL.md 写清工作流顺序与必做项,长篇约定拆到 references/ 下多份 Markdown;与上文示意图里的 references/ 命名一致。
目录形态大致如下(references/ 内 二十余份 主题文件,此处只列几份示意):
vue-best-practices/
├── SKILL.md
└── references/
├── reactivity.md
├── sfc.md
├── component-data-flow.md
├── composables.md
├── component-slots.md
├── state-management.md
└── …(其余片段略)
SKILL.md 负责编排「先读哪几份、再按需打开哪几份」;下面是 YAML 头 + 必读的 core references + 一节按需引用 的摘录(英文原文来自仓库,便于你对照路径):
---
name: vue-best-practices
description: MUST be used for Vue.js tasks. Strongly recommends Composition API with `<script setup>` and TypeScript as the standard approach. Covers Vue 3, SSR, Volar, vue-tsc. Load for any Vue, .vue files, Vue Router, Pinia, or Vite with Vue work. ALWAYS use Composition API unless the project explicitly requires Options API.
license: MIT
metadata:
author: github.com/vuejs-ai
version: "18.0.0"
---
# Vue Best Practices Workflow
Use this skill as an instruction set. Follow the workflow in order unless the user explicitly asks for a different order.
## 1) Confirm architecture before coding (required)
…
### 1.1 Must-read core references (required)
- Before implementing any Vue task, make sure to read and apply these core references:
- `references/reactivity.md`
- `references/sfc.md`
- `references/component-data-flow.md`
- `references/composables.md`
- Keep these references in active working context for the entire task, not only when a specific issue appears.
## 3) Consider optional features only when requirements call for them
…
- Slots: parent needs to control child content/layout -> [component-slots](references/component-slots.md)
- Fallthrough attributes: wrapper/base components must forward attrs/events safely -> [component-fallthrough-attrs](references/component-fallthrough-attrs.md)
# …(性能、异步组件等同样链到独立 references 文件)
这类结构说明:references/ 可以堆很多片段,但 SKILL.md 用「工作流 + 必读清单 + 按需链接」把加载顺序说清楚——默认不必把每个 .md 全文塞进上下文,按任务阶段展开即可。
✅ 最简单的单文件示例(能用先跑通)
下面这个例子和之前第一篇介绍的套路类似,比如「HTTP 必须走团队封装、组件要用自家基座」,说白了就是把约定写清楚,别让模型自己猜流程。下面用单文件演示,方便快速复制粘贴;如果内容越来越多,参考上文,把长的内容放到 references/ 目录下。
---
name: vue3-project-standards
description: Vue3 管理后台项目开发规范。仅在开发 Vue3 管理后台、仪表盘或内部系统时调用。
---
# Vue3 管理后台项目开发规范
## 背景
本规范适用于基于 Vue3 + Element Plus 技术栈的管理后台(Admin)项目。对于前台 ToC 项目,原则上不建议直接使用 Element Plus。
## UI 组件
- 表格统一使用 `<ProTable>`
- 弹窗统一使用 `<DialogV2>`
- 表单统一使用 `<FormRenderer>`
## HTTP
- 必须用团队封装的 `request.js`
- 禁止直接用 axios/fetch
- 错误处理统一放到响应拦截器,业务代码不要重复写 try/catch
## 示例
(例如登录表单完整实现可参考 references/login-form.md,这里仅作说明。)
有了这份 Skill,遇到「写一个登录表单」这类需求时,AI 就会优先用你们约定的封装方案,而不是随手写份模型训练集里的代码。
⚖️ 对比一下:有 Skill 和没 Skill 的差别
| 场景 | 没 Skill | 有 Skill |
|---|---|---|
| 让 AI 写登录表单 | 原生 <form> + 随便请求 | 用 <FormRenderer> + request.js |
| 让 AI 发请求 | axios / fetch 随意写 | 统一用封装,加上错误处理规范 |
| 参数风格/接口前缀 | 跟着网上常见写法到处飘 | 默认参照项目里的规矩执行 |
🛠️ 实操例子:用“表单生成器”走一遍标准写法
下面是一份整理过的 SKILL.md 主体内容:字段名、约定、禁用项都在。类似 Vue 单文件组件这种整块代码,建议扔到 references/standard-login.vue.md 里,正文只给一句“填表时先看参考”。为避免 Markdown 渲染出锅,下面把模板拆成三段演示——实际用时,整合成一个主文件或参考文件指向都行。
第一段:frontmatter 到标准表单结构
---
name: vue3-form-generator
description: Vue3 表单生成器规范。当用户要求生成登录表单、注册表单或任何带输入字段的表单时使用。
---
# Vue3 表单生成器规范
## 目的
所有表单代码必须遵从本规范。
## 技术栈
- Vue3 Composition API
- UI:Element Plus(强制)
- 网络请求:`request.js`(禁止用 axios/fetch)
- 表单容器:`<FormRenderer>`
## 组件对照
| 场景 | 组件 |
|------|------|
| 短文本 | `<el-input>` |
| 密码 | `<el-input type="password">` |
| 下拉 | `<el-select>` |
| 日期 | `<el-date-picker>` |
| 开关 | `<el-switch>` |
## 校验
1. 所有必填字段都要加 `rules`
2. 手机号要用 `/^1[3-9]\d{9}$/`
3. 密码要求至少 8 位,且必须有数字和字母
## 代码模板
### 标准表单结构
(大量 `<template>` / `<script setup>` 代码可直接去 references 看,或者下边接着给一段。)
第二段:Vue 示例(强烈建议最终放 references)
<template>
<FormRenderer
:schema="formSchema"
v-model="formData"
@submit="handleSubmit"
/>
</template>
<script setup>
import { reactive } from 'vue';
import { FormRenderer } from '@/components';
import { request } from '@/utils/request';
const formData = reactive({
username: '',
password: '',
phone: ''
});
const formSchema = [
{
prop: 'username',
label: '用户名',
component: 'input',
rules: [{ required: true, message: '请输入用户名' }]
},
{
prop: 'password',
label: '密码',
component: 'password',
rules: [
{ required: true, message: '请输入密码' },
{ min: 8, message: '密码至少8位' }
]
},
{
prop: 'phone',
label: '手机号',
component: 'input',
rules: [
{ required: true, message: '请输入手机号' },
{ pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确' }
]
}
];
const handleSubmit = async () => {
await request.post('/api/form/submit', formData);
};
</script>
第三段:禁止项(紧跟着示例写)
## 禁止事项
- 禁止直接用原生 `<form>` + `<input>` 拼业务表单
- 禁止直接用 `axios` 或 `fetch`
- 禁止硬编码 API 前缀(要用统一配置/封装)
📋 一份好 Skill 都少不了这三块
| 块 | 用来干嘛 | 举例 |
|---|---|---|
| 硬约束 | 明确什么不能做、什么必须做 | 不能用 axios,必须用 request.js |
| 对照表 | 把需求用表格钉到具体实现 | 表格需求 → 用 ProTable |
| 可复制的模板 | 给一段现成可用的代码或注明参考路径 | 标准的 FormRenderer schema |
☑️ Checklist 需不需要写?
简短说:要写,真的有用。
原因很简单:前面三块是教“怎么做”;Checklist 是提醒“是不是做完了”。它把你脑子里的默认要求写出来,能帮大家提前避免两类坑:
- 格式写对了,但偷偷用了被禁止的库(比如不小心又写了
fetch)。 - 看起来齐了,其实缺了重要信息(如时间段、目标受众等)。
建议 Checklist 分两层:
- 在
SKILL.md结尾加一份通用 checklist,每次用到该 Skill 都要对照一遍。 - references 里的每个场景模板末尾也加 checklist,针对这个场景的特殊点补充(比如日报需要包含「昨日进展」「今日计划」「遇到问题」三个清晰分段)。
示例:
## 验收清单(Checklist)
- [ ] 任务类型已识别并匹配到唯一模板(或说明为何用通用模板)
- [ ] 该补充的上下文信息都补了(受众、时间范围、目标)
- [ ] 硬约束和禁止项都遵守了(比如技术栈、格式、语气)
- [ ] 输出结构对齐模板(比如字段数量、字段格式都对了)
- [ ] 遇到拿不准的内容已单独说明(不乱猜不瞎补)
Checklist 没必要搞成十几条,写 5 条以内,保证每一条都能“一眼判对错”就足够了。
✏️ 推荐 6 条写 Skill 的规则
参考 Agent Skills 最佳实践(Claude 中文) 和前面讲过的内容,总结为:写 SKILL.md,参考这 6 条规则:
description要写触发场景,不要写宣传词
建议按「做什么 + 什么时候用 + 用户常问的话术」来写。宁可写窄写精确,千万别乱写一堆大而全,不然多个 Skill 会互相抢着用。- 正文只放决策和约束,长文放 references/
Main 文件尽量短平快,有大段 API、模板、定义词表这类就分出去,正文写一句「何时要看哪份」即可。 - 先给最小能一把跑通的例子,再给进阶用法
顶部就让人能一步走通,后面有时间/有精力再加进阶玩法和细节,不要一上来就把所有角落都填满。 - 脚本只做确定性操作,判断和取舍写明文
比如格式化、批量处理之类的用脚本,和业务强相关的判断、流程调度这些都明确写在 Markdown 指引里。 - 限制条件写清楚,别指望模型靠猜
说清楚支持范围、前置条件、遇到缺信息怎么办,不然模型可能会瞎补。 - 每个模板结尾都要加 checklist
总 checklist 写在主文件,针对场景的 checklist 放在具体模板里面,Checklist 不求多,关键能直接判定是不是合格。
如果只想马上提高准确率,优先做第 1 条:收紧/细化 description 的范围,这样 Skill 更容易在该触发的时候被选中,在不该用的时候不会误用。
➡️ 下一步:Skill 的发版和分发
写好 Skill 只是第一步。团队常常会问:Skill 文件放哪?谁发布?别人怎么引入?怎么避免一堆重复的Skill?这些内容在 工具引入篇 里用 skill-base 和 skb 介绍得很细。另外,Skill 多了之后如何细分 description、怎么确保知识唯一,也在 什么值得做成 Skill 和 碎片化篇 里有详细说明。
skill-base: 官网 · GitHub
一个专门用来给团队分发 Agent Skill 的私有托管平台。
🧭 系列导航(姊妹篇)
| 篇 | 文章 | 在讲什么 |
|---|---|---|
| 1 | 痛点与动机 | 为什么需要 Skill |
| 3 | 工具引入篇 | skill-base / skb 分发与安装 |
| 4 | 什么值得做成 Skill | 选题与落地标准 |
| 5 | 管理后台查询页案例 | 项目级 Skill 的落地改造样例 |
| 6 | 运维手册 | 触发、冲突与版本治理 |
| 延伸 | 碎片化困局 | 多 Skill 触发与治理 |
📚 相关阅读
- 概念梳理(Claude 中文):Agent Skills:讲了渐进式披露和目录结构。
- Anthropic:Agent Skills 概览:官方字段和行为为准。
- 系列(1)痛点与动机
- 系列(3)工具引入篇