Skill-应知应会
已经写过一两个 Skill?这篇文章帮你从"能写"升级到"会写"。
一、Skill 的本质:Context Engineering
Anthropic 团队反复强调一个观点——Skill 本质上是在做 Context Engineering。它不是一个 markdown 文件,而是一个文件夹。用文件夹这个形式,来表达渐进式信息披露的理念。
skill/
├── SKILL.md # 导航页 + 核心流程 + 关键经验
├── references/ # 详细说明、API 参考、边界条件 → 按需加载
├── scripts/ # 可执行脚本 → 直接执行,零 token
├── examples/ # 示例 → 需要时参照
└── assets/ # 模板、图片、固定素材 → 用于输出SKILL.md 是一个导航页,不是操作手册。 它的职责是告诉模型:核心流程是什么 → 遇到 A 情况去 references 找详细说明 → 需要执行 B 操作时运行 scripts 里的脚本 → 最后输出时用 assets 里的模板。
整个过程是渐进的、按需的、上下文友好的。
关键洞察:Skill 解决的从来都不是提示词的问题,而是上下文、经验沉淀以及能力复用的问题。
二、Instructions 与 Scripts:经验和能力的互补
Instructions 和 Scripts 解决的是两个不同层面的问题:
| Instructions | Scripts | |
|---|---|---|
| 提供什么 | 经验和判断 | 能力和执行 |
| 回答什么问题 | "为什么" + "什么时候" | "怎么做" |
| 适合什么 | 决策、经验、陷阱 | 确定性、重复性任务 |
| 举例 | "Stripe 返回 200 不代表支付成功,需检查 payment_events 表" | check_payment_events() 脚本 |
如果只有 Scripts,模型知道怎么查,但未必知道为什么查。如果只有 Instructions,模型知道应该查,但每次都得重新实现查的逻辑。
两者缺一不可。
很多 Skill 的常见问题是把该写成 Scripts 的内容写成了 Instructions——导致模型每次执行同样的任务都要重新发明轮子,消耗大量 token 且结果不稳定。
凡是每次都要重写的代码,就写成一个脚本放到 scripts/ 里,SKILL.md 里只放调用指令。
三、渐进式披露实战:什么放哪
这是 Skill 设计中最需要判断力的部分。
SKILL.md 放什么(始终 + 触发时加载)
- 核心工作流(最精简的步骤 1→2→3→4)
- Gotchas(易错点、反直觉的业务规则)——这是最有价值的内容
- 决策树/路由表(A 场景去读 X 文件,B 场景去读 Y 文件)
- 全局约束(危险操作确认、批量上限、输出格式)
- 要点式的核心指令,不要废话
永远不要往 SKILL.md 里塞这些: AI 已经知道的常识、大段的背景介绍、详细 API 文档、完整的历史案例。
references/ 放什么(按需加载)
- 详细 API 文档、Schema 定义(可以 3000-5000 词)
- 各子领域的完整操作指南
- 错误码对照表
- 历史案例、边界场景
scripts/ 放什么(直接执行,零 token)
- 确定性计算(校验、转换、格式化)
- 批量操作(一次处理 N 条记录)
- 重复性准备工作(环境检查、依赖安装)
assets/ 放什么(用于输出)
- 模板文件(PPT、HTML 脚手架、配置模板)
- 图片、字体、图标
经典反模式
# ❌ 8000 词全塞一个文件
skill/
└── SKILL.md (8000 词)
# ✅ 渐进式披露
skill/
├── SKILL.md (1500 词:核心流程 + Gotchas + 路由)
└── references/
├── patterns.md (2500 词:详细模式)
├── advanced.md (3700 词:高级技巧)
└── api-ref.md (5000 词:API 参考)四、Description 深入:路由规则的艺术
模型如何判断?把 Description 当路由规则写
Claude Code 启动时,扫描所有 Skill 的 name + description(Level 1 常驻)。然后对用户当前的问题做语义匹配,判断应该加载哪个 Skill。
Description 承担着整个 Skill 的路由工作。 它不是产品功能介绍,而是触发条件说明。真实世界里,很少有人会说"帮我调用一个 PR 管理工具"。大家更可能说:"帮我盯一下这个 PR"、"CI 又挂了"、"这个分支能合了吗"。
好的 Description 怎么写
# ❌ 纯功能介绍 —— 模型不知道怎么匹配
description: PR 管理 Skill,帮助用户监控 PR 状态,处理 CI 问题,自动 Merge。
# ✅ 描述用户意图 —— 模型看到就能路由
description: 当用户说"盯 PR"、"CI 挂了"、"合并"、"review MR"、"这个分支能合了吗"时触发。用于管理 GitHub PR 的状态查询、CI 排障和自动合并。触发评估法:量化你的 Description 质量
- 准备 20 条混合用例:10 条该触发 + 10 条不该触发(注意:不该触发的用例要选"近邻迷惑"的——共享关键词但实际需要不同 Skill)
- 逐条测试,记录触发准确率和召回率
- 根据漏触发和误触发调整 Description
- 达标线:触发准确率 ≥85%,触发召回率 ≥85%
Skill 数量多了之后的路由冲突
当 Skill 从几个变成几十个,不同 Skill 的 Description 可能出现语义重叠。解决策略:
| 策略 | 做法 | 适用场景 |
|---|---|---|
| 差异化 description | 每个 Description 有明确区分关键词 | 功能部分重叠 |
| 合并 | 两个总是一起触发的合并为一个 | 高度相关 |
| 写排除声明 | 显式说明"本 Skill 不处理 X" | 容易被误触发 |
| 手动指定 | 对话中精确指定 Skill | 需要精确控制 |
## 适用范围
本 Skill 专注于代码安全漏洞扫描(SQL 注入、XSS、硬编码凭据)。
以下场景不在本 Skill 范围内:
- 代码风格和命名规范 → 使用 go-code-review
- 性能优化建议 → 使用 go-perf-review五、Skill vs Command vs Agent vs MCP vs Rule
你项目里可能同时用这五样东西,它们职责完全不同:
| Skill | Command | Agent | MCP | Rule | |
|---|---|---|---|---|---|
| 触发者 | AI 自动(也可手动) | 用户 /命令 | AI/Skill 派生子任务 | AI 工具调用 | 始终生效 |
| 本质 | 上下文指令包 + 脚本 | 预设对话流程 | 独立 AI 子进程 | 外部能力接入 | 全局约束 |
| 加载 | 匹配意图时加载 | 手动调用时展开 | 独立上下文 | 按工具调用 | 全对话加载 |
| 何时用 | "做某类任务时按这个规范" | "帮我做一件具体的事" | "并行调查/独立完成子任务" | "连接外部数据/服务" | "所有对话都遵守的底线" |
| 长度 | 可长(触发才占上下文) | 中 | 中 | - | 宜短(始终占上下文) |
一句话区分: Rule 是底线,Skill 是章法,Command 是快捷指令,Agent 是独立办事的人,MCP 是接进来的外设。
六、不要写废话:Skill 里最有价值的是 Gotchas
这是 Anthropic 内部反复强调的原则。不要重复 AI 已经知道的常识。 Skill 真正要沉淀的是"隐性知识"——那些存在于老员工经验里、模型绝对不知道的东西。
什么算 Gotchas
## ⚠️ 关键注意事项
- staging 环境返回 200 不代表发布成功,需检查 deployment_status 表
- 这个表不能按 created_at 排序,必须用 event_time
- request_id 和 trace_id 在日志里是同一个字段,不要重复关联
- 用户表的 deleted_at 是软删除标记,查询时必须加 WHERE deleted_at IS NULL
- 支付回调可能重复到达,幂等性校验必须基于 order_id + event_type这些信息没有一条是 AI 的常识。它们只存在于团队的经验里。把它们写进 Skill,就是"把老师傅经验写下来"。
七、模块化:Skill 太长了怎么拆
当 SKILL.md 超过 500 行,或者包含多个独立工作流时,就该拆了。
拆分结构
project-migration/ # 主 Skill:流程总览与编排
├── SKILL.md # 导航,按顺序引用子步骤
└── steps/
├── 00-environment-setup.md
├── 01-dependency-update.md
└── 02-api-migration.md
project-migration-sub-env-setup/ # 子 Skill:可独立调用
├── SKILL.md
└── scripts/
└── check-env.sh主 Skill 如何编排
## 执行流程
按顺序执行,每个步骤完成后运行验证命令确认无误再继续:
### Step 1: 环境初始化
读取并执行 [环境初始化](steps/00-environment-setup.md)。
**检查点**:`bash scripts/check-env.sh`
### Step 2: 依赖更新
读取并执行 [依赖更新](steps/01-dependency-update.md)。
**检查点**:`go mod tidy && go build ./...`
## 注意事项
- 如果某个检查点未通过,停止后续步骤,先修复当前问题
- 每个子步骤可以独立使用,无需跑完整个流程拆分原则
- 单一职责:一个子 Skill 只管一件事
- 写清楚依赖:前置条件写明白,别让 AI 猜
- 每个子 Skill 能独立使用:不依赖主流程也能跑
八、上下文变量:让 Skill 感知环境
| 变量 | 含义 | 典型用法 |
|---|---|---|
${ARGUMENTS} | 用户传入的参数 | 解析 /命令 arg1 arg2 |
${CLAUDE_SKILL_DIR} | Skill 自身目录绝对路径 | 引用同目录脚本和资源 |
${CLAUDE_EFFORT} | 当前 effort 级别 | 根据 effort 调整策略 |
${CLAUDE_SESSION_ID} | 当前会话 ID | 日志、追踪 |
九、安全意识
Skill 里的脚本是会被真实执行的,不是普通文档。必须守住几条底线:
- 绝不硬编码密钥:API Key、密码、Token 一律通过环境变量或配置文件(加入 .gitignore)管理
- 危险操作加确认:删除、覆盖、DDL 等操作必须先展示摘要,用户确认后再执行
- 数据库操作先备份:变更前 mysqldump,验证失败用备份回滚
- 防范 Prompt 注入:外部读入的数据标记为"数据"而非"指令",不拼接到命令中
- 文件路径防穿越:检查不包含
..,校验扩展名白名单
十、执行模式
| 特性 | 用法 | 场景 |
|---|---|---|
context: fork | 在隔离子 agent 中执行 | 自包含任务,不污染主上下文 |
model | 覆盖模型 | 简单任务用 haiku 省钱 |
effort | 覆盖 effort 级别 | 关键任务强制高 effort |
allowed-tools | 预授权工具 | 减少弹窗确认,提升体验 |
disallowed-tools | 强制禁用 | Bash(rm *) 之类危险操作 |
十一、权限控制三层模型
全局 settings.json allow/deny
↓
Skill allowed-tools / disallowed-tools(只减不增)
↓
运行时用户确认弹窗- 无额外权限或 hooks 的 Skill,自动允许无需批准
skillOverrides可精细控制:off(隐藏)、user-invocable-only(仅手动)、name-only(折叠描述)- 全局
disableSkillShellExecution禁用所有 Skill 的内联 Shell 执行
十二、写好 Skill 的核心检查清单
内容质量
- [ ] 目标是"做什么 + 什么时候做 + 什么时候不做"
- [ ] Description 精准路由(意图导向,非功能罗列)
- [ ] 用祈使句直接下指令,不商量
- [ ] 解释"为什么",而非堆砌 MUST
- [ ] Gotchas(易错点)充分标注 —— 这是最有价值的内容
- [ ] 有 3-5 个 Before/After 或 Few-Shot 示例
- [ ] 有可执行的验证命令
- [ ] 没有写 AI 已经知道的常识
工程结构
- [ ] SKILL.md 正文 ≤500 行
- [ ] 超出的内容拆分到 references/ 或子 Skill
- [ ] 重复性操作写成 scripts/,不堆在 Instructions 里
- [ ] 依赖关系写清楚(前置条件、相关 Skill)
- [ ] 善用表格、决策树组织信息
安全
- [ ] 无硬编码密钥 / Token / 密码
- [ ] 危险操作(删除、覆盖、DDL)有确认或备份机制
- [ ] 脚本输入有校验,文件路径防穿越
- [ ] 网络请求用 HTTPS,有超时设置
可维护
- [ ] 版本号合理(修复 1.0→1.1,新增 1.1→1.2,重构 1.x→2.0)
- [ ] 子 Skill 脱离主流程也能独立使用
- [ ] 定期根据实际使用反馈优化
十三、常见反模式速查
| 反模式 | 症状 | 解法 |
|---|---|---|
| 大杂烩 | 一个 Skill 干三四件事 | 拆成主 Skill + 子 Skill |
| Description 黑话 | 全是内部术语(TCC、QCMS 之类) | 用通用语言 + 技术关键词 |
| 没有示例 | 纯文字,无代码 | 加 Before/After + Few-Shot |
| 没有检查点 | 做完 5 步才验证 | 关键步骤间插入验证命令 |
| 写死数值 | 超时=30s,缓冲区=4096 | 给判断规则和参考范围 |
| 当 Wiki 写 | 背景 300 行,正文 50 行 | 背景放 references/,正文直奔主题 |
| Scripts 写成 Instructions | 每次都让模型重新实现同段逻辑 | 写成脚本,SKILL.md 里只调用 |
| 堆砌常识 | 大量 AI 本来就知道的内容 | 只写 Gotchas 和项目特定的经验 |
十四、一句话总结
Skill 的本质是 Context Engineering——用文件夹实现渐进式披露,Instructions 提供经验和判断,Scripts 提供能力和执行,Description 做路由规则,Gotchas 沉淀隐性知识。把 Skill 当成"给聪明新同事的操作手册"来写:不要写废话,解释为什么,把最值钱的经验放在最显眼的位置。