Skill 是当前 AI Agent 生态中最重要也最被低估的能力之一。这篇文章讲清楚三件事:Skill 用来解决什么问题、SKILL.md 的标准写法与必备元素、一个可以直接抄走的完整示例。
什么是 Skill?
Skill(技能包)是一份结构化的指令包:一个 SKILL.md 文件打头,配上可选的脚本、模板、参考资料,放在约定好的目录里,让 AI 助手(Claude Code、CodeBuddy、Cursor 等)按需加载并执行某个领域任务。
它长这样:
skills/
└── weekly-report/ # 一个 Skill
├── SKILL.md # 使用说明书(唯一必需的"心脏")
├── scripts/ # 可选:辅助脚本
├── templates/ # 可选:模板文件
└── assets/ # 可选:静态资源先看一个最小可用的 SKILL.md:
---
name: weekly-report
description: 当用户要求生成周报时使用。从 git log 提取本周提交,按模板生成 Markdown 周报。
---
# 周报生成
1. 运行 `node scripts/generate.mjs` 获取本周提交
2. 按 `templates/report.md` 的模板整理输出就这么简单。但简单不等于容易写对——一份 Skill 写得好不好,差距全在细节里,下面展开讲。
Skill 解决什么问题?
把 Skill 和另外两种常见做法对比,就清楚它的价值了:
| 方式 | 做法 | 优点 | 痛点 |
|---|---|---|---|
| 系统提示词 | 把指令写进全局 system prompt | 零成本、立即生效 | 永远占着上下文窗口;改一处影响所有场景;跨项目无法复用 |
| 规则文件(.cursorrules 等) | 项目内放一份指令文件 | 项目级共享 | 还是"一次性全量注入",指令多了互相打架;无结构、无版本 |
| Skill | 独立指令包,按需加载 | 用的时候才加载,平时零开销;可版本化;可带脚本模板;跨项目复制即用 | 需要一点学习成本 |
核心差异就一句话:
提示词是"赛前把全部战术背下来",Skill 是"用到哪个战术才翻开哪一页"。
AI 助手根据任务内容,匹配 Skill 的 description,命中才加载对应指令——这既省了上下文窗口,又避免了无关指令的干扰,还能把"经验"沉淀成可复用的资产。
Skill 的目录结构与元素
标准 Skill 由以下元素组成(只有第一个是必需的):
| 元素 | 路径/位置 | 是否必需 | 作用 |
|---|---|---|---|
| SKILL.md | <skill>/SKILL.md | ✅ 必需 | 核心说明书,Agent 加载后只读它 |
| 脚本 | <skill>/scripts/ | 可选 | 把机械操作交给程序,如解析日志、调 API |
| 模板 | <skill>/templates/ | 可选 | 输出的骨架,如周报模板、PR 描述模板 |
| 参考资料 | <skill>/reference/ | 可选 | 领域知识、规范文档,Agent 需要时再查 |
| 静态资源 | <skill>/assets/ | 可选 | 图片、图标等 |
| 校验/测试 | <skill>/tests/ | 可选 | 验证 Skill 本身可用 |
安装位置有两级:~/.claude/skills/(个人全局,所有项目可用)和项目内 .claude/skills/(团队共享,随仓库分发)。
设计原则:SKILL.md 只讲"怎么做"和"按什么顺序",需要大量逻辑处理的部分丢给脚本,不要让 Agent 在提示词里复述复杂算法。
SKILL.md 的标准写法
Frontmatter(头部元数据)
---
name: skill-name
description: 什么时候用、能做什么
metadata:
version: 1.0.0
license: MIT
---| 字段 | 必填 | 规则 |
|---|---|---|
name | ✅ | 简短唯一,小写字母 + 连字符,如 weekly-report |
description | ✅ | 全文最重要的字段,见下一节 |
metadata.version | 可选 | 语义化版本号,改版可追踪 |
metadata.license | 可选 | 开源协议 |
metadata.allowed-tools | 可选 | 白名单,限制 Skill 可调用的工具,安全兜底 |
正文(Body)必备元素
不管 Skill 多简单,正文建议覆盖以下部分:
- 一句概述:这个 Skill 是什么、产出什么
- 使用场景(When to Use):明确什么情况下激活、什么情况下不要用
- 核心步骤(How to Use):编号的操作流程,每一步要具体到"做什么、用什么工具、产出什么"
- 输入与输出:接收什么输入、交付什么格式的结果
- 示例:一个完整的工作示例,让 Agent 照着做
- 注意事项 / 边界:易错点、权限限制、失败处理
正文内容有三个质量标准:
- 面向 Agent 写,不面向人写——它没有"常识",把隐含步骤显式化
- 可执行性优先——每一步都是命令级描述,而不是形容词
- 宁可多写约束,不要少写边界——"不要做 X"和"必须做 Y"同样重要
description:决定 Skill 生死的字段
Agent 不会逐字读你所有的 Skill,它靠 description 判断"当前任务要不要加载这个 Skill"。所以:
description 写不好 = Skill 永远没机会被加载。
好的 description 要回答三个问题:
- When——用户在什么场景下会触发?
- What——这个 Skill 具体能做什么、产出什么?
- How to trigger——什么样的任务措辞会命中它?
对比一下:
# ❌ 差:太笼统,Agent 不知道何时用
description: 生成周报的 Skill
# ❌ 差:描述能力而非触发场景
description: 可以提取 git 提交记录,整理成周报
# ✅ 好:场景 + 能力 + 触发词,一眼可判
description: 当用户要求"生成周报"、"总结本周工作"、"整理这周提交"时使用。
从 git log 提取本周所有提交,按模板生成结构化 Markdown 周报,包含完成事项、问题与下周计划。规则总结:以"当……时使用"开头,写触发场景;用具体动词(提取、生成、汇总、检查);明确产出物;单条不超过一两百字。
完整实战示例:weekly-report 周报生成 Skill
下面是一个完整、可直接复制的 Skill,覆盖了上文的全部元素。
目录结构
.claude/skills/weekly-report/
├── SKILL.md
├── scripts/
│ └── generate.mjs # 提取 git log 的脚本
└── templates/
└── report.md # 周报模板SKILL.md
---
name: weekly-report
description: 当用户要求"生成周报"、"总结本周工作"、"整理这周提交/进展"时使用。
从 git log 提取当前分支本周的提交记录,结合模板生成结构化 Markdown 周报,
包含:本周完成事项、遇到的问题与解决、下周计划。输出后先向用户确认再保存。
metadata:
version: 1.0.0
---
# 周报生成
## 概述
将 git 提交历史转化为一份结构化的周报,减少手工整理成本。
## 使用场景
- ✅ 用户说"生成周报 / 总结本周 / 这周干了啥"
- ✅ 需要按周汇总多个仓库的提交
- ❌ 用户只要看某一次提交的详情(直接看 git show 即可,不需要 Skill)
## 步骤
1. 运行 `node scripts/generate.mjs`,脚本会输出本周提交的 JSON 数据
2. 如果脚本报"没有本周提交",直接告知用户本周无提交,不要生成空周报
3. 按 `templates/report.md` 的模板,把提交数据填入对应板块
4. 提交信息中带 `fix:` 前缀的归入"问题修复",`feat:` 归入"功能开发",其余归入"其他"
5. 为每个板块写 1 句话总结(不要罗列提交原文)
6. 输出 Markdown 周报给用户确认,用户确认后再写入 `weekly-report-2026-W35.md` 这类文件
## 输入与输出
- 输入:当前 git 仓库(无需额外参数)
- 输出:Markdown 周报,包含【本周完成】【问题与解决】【下周计划】三个板块
## 注意事项
- 只统计本周一至今的提交
- 不包含 merge 提交和 revert 提交
- 敏感信息(密钥、内网地址)自动打码
- 脚本执行失败时,回退方案:用 `git log --since="7 days ago" --oneline` 手动提取scripts/generate.mjs
import { execSync } from 'node:child_process'
// 取本周一
const now = new Date()
const day = (now.getDay() + 6) % 7 // 周一=0
const monday = new Date(now)
monday.setDate(now.getDate() - day)
monday.setHours(0, 0, 0, 0)
const since = monday.toISOString()
const log = execSync(
`git log --since="${since}" --no-merges --pretty=format:"%s|%an" --reverse`
).toString().trim()
const rows = log
.split('\n')
.filter(Boolean)
.map((line) => {
const [subject, author] = line.split('|')
return { subject, author }
})
const categorize = (s) => {
if (s.startsWith('fix:')) return '问题修复'
if (s.startsWith('feat:')) return '功能开发'
if (s.startsWith('docs:')) return '文档'
return '其他'
}
const groups = rows.reduce((acc, r) => {
const cat = categorize(r.subject)
;(acc[cat] ||= []).push(r)
return acc
}, {})
console.log(JSON.stringify({ since: since.slice(0, 10), groups }, null, 2))templates/report.md
# 周报({{since}} ~ {{today}})
## 本周完成
{{#each groups.功能开发}}
- {{subject}}({{author}})
{{/each}}
(若无则写"无")
## 问题与解决
{{#each groups.问题修复}}
- {{subject}}
{{/each}}
(若无则写"无")
## 下周计划
- (结合项目当前进展,向用户询问后填写)使用效果
用户在任意仓库里说一句:
"帮我生成这周的周报"
Agent 匹配到 weekly-report 的 description → 加载 SKILL.md → 按步骤运行脚本 → 得到提交数据 → 套模板 → 产出:
# 周报(2026-08-25 ~ 2026-08-31)
## 本周完成
- feat: 新增 Mermaid 渲染插件,文章流程图可直接用代码块书写(xy)
- feat: 支持 Skill 按需加载,优化上下文占用(xy)
- docs: 补全 AI 板块三篇文章(xy)
## 问题与解决
- fix: Mermaid 代码块换行被 markdown 合并导致语法错误,改用 fence 插件直通 HTML 解决
## 下周计划
- 待确认整个流程:一句话 → Skill 自动接管 → 标准化产出。这就是 Skill 的价值——把"每次都要重复交代的做事方法"沉淀成一次性的资产。
最佳实践清单
写 Skill 时对照检查:
另外几条长期经验:
- 从真实痛点出发:Skill 解决"你反复让 AI 做、每次都重新交代"的事,而不是为了写而写
- 保持单一职责:一个 Skill 只干一件事,拆开比合并好——触发匹配更准
- 写完后实测:真的触发一次,看 Agent 是否按预期执行、产出是否达标
- 版本与演进:Skill 也是代码,用 git 管起来,配合你的工作流迭代
结尾
Skill 把 AI 从"每次从零开始"变成"召之即来的专家"。它不神秘:一个 SKILL.md、一套清晰的步骤、一批可选的脚本模板,就能把你自己验证过的做事方法论固化下来,跨项目、跨团队复用。
现在就可以动手:从你每周最重复的那件事开始,写第一个 Skill。
相关阅读:LangChain Agent 实战 | Agent 流程编排深度指南