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 的 namedescription(以及各实现允许的其他短字段)启动或索引阶段就能扫一遍:模型/客户端能回答「有哪些技能、各自在什么场景该被考虑」
第 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 条规则:

  1. description 要写触发场景,不要写宣传词
    建议按「做什么 + 什么时候用 + 用户常问的话术」来写。宁可写窄写精确,千万别乱写一堆大而全,不然多个 Skill 会互相抢着用。
  2. 正文只放决策和约束,长文放 references/
    Main 文件尽量短平快,有大段 API、模板、定义词表这类就分出去,正文写一句「何时要看哪份」即可。
  3. 先给最小能一把跑通的例子,再给进阶用法
    顶部就让人能一步走通,后面有时间/有精力再加进阶玩法和细节,不要一上来就把所有角落都填满。
  4. 脚本只做确定性操作,判断和取舍写明文
    比如格式化、批量处理之类的用脚本,和业务强相关的判断、流程调度这些都明确写在 Markdown 指引里。
  5. 限制条件写清楚,别指望模型靠猜
    说清楚支持范围、前置条件、遇到缺信息怎么办,不然模型可能会瞎补。
  6. 每个模板结尾都要加 checklist
    总 checklist 写在主文件,针对场景的 checklist 放在具体模板里面,Checklist 不求多,关键能直接判定是不是合格。

如果只想马上提高准确率,优先做第 1 条:收紧/细化 description 的范围,这样 Skill 更容易在该触发的时候被选中,在不该用的时候不会误用。


➡️ 下一步:Skill 的发版和分发

写好 Skill 只是第一步。团队常常会问:Skill 文件放哪?谁发布?别人怎么引入?怎么避免一堆重复的Skill?这些内容在 工具引入篇 里用 skill-baseskb 介绍得很细。另外,Skill 多了之后如何细分 description、怎么确保知识唯一,也在 什么值得做成 Skill碎片化篇 里有详细说明。

skill-base: 官网 · GitHub
一个专门用来给团队分发 Agent Skill 的私有托管平台。


🧭 系列导航(姊妹篇)

文章在讲什么
1痛点与动机为什么需要 Skill
3工具引入篇skill-base / skb 分发与安装
4什么值得做成 Skill选题与落地标准
5管理后台查询页案例项目级 Skill 的落地改造样例
6运维手册触发、冲突与版本治理
延伸碎片化困局多 Skill 触发与治理

📚 相关阅读