重复同样事情的问题
你有没有遇到过必须向某人解释同一件事二十遍的情况?现在想象一下,这个人是个机器人,而且每隔几个小时就会失去记忆。
“不,Claude,commit 必须先通过测试。”
“Claude,我已经告诉过你要用 type: description 格式。”
“别加表情符号,该死的!”
这就是我每天的工作,直到我发现了 Skills。简单来说:这些是你写一次,Claude 就会永远遵循的指令。就像训练狗一样,但不需要狗粮。
什么是 Skills
从 2.1.3 版本开始,Claude Code 将旧的 slash commands 与更强大的东西合并:Skills。这些是包含指令的 Markdown 文件,Claude 可以通过两种方式执行:
- 手动:当你输入
/my-skill时 - 自动:当 Claude 检测到应该使用它时
第二点就是魔法所在。你不再需要记住调用命令。如果你有一个技能说"在用户完成任务且有未提交的更改时使用",Claude 会自动执行。
就像有一个管家知道何时收拾桌子而不需要你要求。
它们在哪里
~/.claude/skills/ # 个人(所有项目)
.claude/skills/ # 项目(与团队共享)
~/.claude/commands/ # 旧版,仍然有效
.claude/commands/ # 旧版,仍然有效
如果你只想自己使用技能,就把它放在你的主目录。如果你想让整个团队都有,就提交到仓库。就这么简单。
Skill 的结构
一个 skill 是一个带有 frontmatter YAML 和内容的 Markdown 文件:
| |
这是最基本的。但 frontmatter 有更多值得了解的选项。
必填字段
name
技能的标识符。只能使用小写字母、数字和连字符(最多 64 个字符)。必须与文件或目录名称匹配。
| |
description
这是最重要的字段。 Claude 用它做两件事:
- 决定何时自动调用技能
- 理解应该做什么
最多 1024 个字符。包含用户会自然说出的关键词。
| |
可选字段
model
为此技能强制使用特定模型。对需要更多能力的任务很有用。
| |
如果不指定,使用当前对话的模型。
allowed-tools
限制 Claude 可以使用的工具。对于只读或安全技能至关重要。
| |
实际例子:一个不应该碰任何东西的分析技能:
| |
context: fork
在隔离的子代理中执行技能,有自己的上下文。主对话历史不会被污染。
| |
对于不想用噪音填满聊天的复杂多步操作很有用。
agent
仅在 context: fork 下工作。定义执行技能的代理类型。
| |
user-invocable
控制是否在 /(slash commands)菜单中显示。默认为 true。
| |
对于只应该自动激活的内部技能很有用。
disable-model-invocation
阻止 Claude 自己调用技能。只有你可以用 /name 激活。
| |
对于需要明确人工决策的破坏性或昂贵操作很有用。
hooks
定义在技能生命周期中执行的钩子。支持 PreToolUse、PostToolUse 和 Stop。
| |
替换变量
在技能内容中你可以使用:
| 变量 | 包含内容 |
|---|---|
$ARGUMENTS | 调用 /skill arg1 arg2 时传递的参数 |
${CLAUDE_SESSION_ID} | 当前会话 ID(对日志有用) |
总结表
| 字段 | 必填 | 用途 |
|---|---|---|
name | ✓ | 技能标识符 |
description | ✓ | 何时以及为什么使用 |
model | 强制特定模型 | |
allowed-tools | 限制工具 | |
context | fork 用于隔离子代理 | |
agent | 代理类型(与 context: fork 一起) | |
user-invocable | 在 / 菜单中显示/隐藏 | |
disable-model-invocation | 阻止自动调用 | |
hooks | 生命周期钩子 |
完整示例
| |
有关完整参考,请查阅 Agent Skills 官方文档。
自由文本还是确定性代码?
这是个关键问题:如果技能是 Markdown,是否意味着 Claude 总是"解释"你写的内容?我能做真正可预测的事情吗?
简短回答:技能的确定性取决于你如何编写它们。
想象一个谱系:
模糊/灵活 ──────────────────────────► 确定性
"检查代码" "按顺序执行这 3 个命令"
灵活技能(Claude 决定)
| |
这里 Claude 有完全的自由。可以查看任何想要的内容,建议任何看起来合适的东西。对探索有用,对关键流程危险。
确定性技能(伪装的脚本)
| |
这基本上是一个 3 行脚本。Claude 没有创造性的余地。执行、报告、结束。
带条件逻辑的技能
| |
- 如果不是
main→ 中止并显示"只能从 main 分支"
步骤 2:清洁状态
| |
- 如果有输出 → 中止并显示"有未提交的更改"
步骤 3:版本号递增 + 推送
| |
这里有分支逻辑,但仍然是确定性的:条件是明确的。
### 调用真实脚本的技能
如果你需要真正复杂的逻辑(循环、解析、API),将代码放在脚本中,让技能只执行它:
.claude/skills/deploy/ ├── SKILL.md └── deploy.sh
**SKILL.md:**
```markdown
---
name: deploy
description: 部署到生产环境
---
执行:
```bash
bash .claude/skills/deploy/deploy.sh
报告结果。不要修改脚本。
**deploy.sh:**
```bash
#!/bin/bash
set -e
uv run pytest || exit 1
hugo --minify
rsync -avz public/ user@server:/var/www/
两全其美:复杂逻辑存在于 Bash/Python 中它应该在的地方,而技能只是触发器。
何时使用每种方法
| 需求 | 方法 |
|---|---|
| 固定命令,总是相同的 | 确定性技能 |
| 有很多分支的复杂逻辑 | 外部脚本 |
| 需要判断的分析 | 有护栏的灵活技能 |
| 危险操作 | 限制性 allowed-tools |
实际例子:commit 技能
这是我用得最多的。以前我必须记住:“好的,执行测试,然后是 linter,然后是类型检查,然后才提交”。现在我只需说"提交",Claude 就会自动完成一切。
| |
阶段 2:强制验证
| |
如果任何一个失败,不要继续。
阶段 3:创建提交
git add -A- 分析更改
- 生成消息:
type: description git commit
看到"何时使用"部分了吗?这就是允许自动调用的部分。Claude 读到这个会想:"啊,用户刚说'完成了',有待处理的更改,我应该使用这个技能"。
## 另一个例子:任务归档
如果你使用 `TASKS.md` 文件来跟踪你做的事情(我在使用 Beads 之前这样做),这个技能会自动清理完成的任务:
```markdown
---
name: archive-tasks
description: 将 TASKS.md 中已完成的任务归档到 TASKS-DONE.md。
当 TASKS.md 有很多完成的任务或超过 20K tokens 时自动使用。
---
# Archive Tasks
## 何时使用(自动)
- TASKS.md 有超过 50 个完成的任务 `[x]`
- TASKS.md 超过 20,000 tokens
- 用户提到 TASKS.md 太大
## 流程
1. 读取 `docs/llm/TASKS.md`
2. 识别完成的任务(`[x]`)
3. 移动到 `docs/llm/TASKS-DONE.md` 并添加日期
4. 从 TASKS.md 中删除
5. 报告有多少个被归档
## 规则
- **不要删除**待办任务 `[ ]`
- **保留**上下文(父级部分)
- **添加**归档日期
美妙的是你不需要记住。Claude 看到 TASKS.md 太大就会行动。
编写好技能的技巧
1. 具体的描述
| |
2. 定义何时应用
| |
3. 明确禁止事项
Claude 倾向于想要礼貌地请求确认。如果你不想要那样,明确地说出来:
| |
4. 对重要事项使用 model: opus
如果技能做的事情很关键(安全审计、复杂重构),强制使用最有能力的模型:
| |
5. 必要时限制工具
有时你想要一个只读而不修改任何内容的技能:
| |
简单 vs 复杂技能
简单技能是单个文件:
.claude/skills/review.md
复杂技能是带有资源的目录:
.claude/skills/deploy/
├── SKILL.md # 指令
├── templates/
│ └── k8s-deployment.yaml
└── scripts/
└── healthcheck.sh
Claude 可以读取目录中的文件作为附加上下文。
我使用的技能
| 技能 | 用途 | 自动调用 |
|---|---|---|
commit | 带验证的提交 | 当我说"commit"或完成某事时 |
check-diagnostics | 验证类型和 lint | 提交之前 |
owasp | 安全审计 | 手动(成本高) |
archive-tasks | 清理 TASKS.md | 当太大时 |
与旧版 commands 的区别
| 方面 | Skills | Commands |
|---|---|---|
| 自动调用 | 是 | 否 |
| 结构 | 目录或文件 | 仅文件 |
| 建议 | 用于所有新功能 | 旧版 |
Commands 仍然有效,但 skills 严格来说更好。如果你有旧的 commands,不需要迁移它们,但对于新东西使用 skills。
结论
Skills 基本上就是编程,但用自然语言。你定义你想要发生什么、何时发生以及有什么限制。Claude 处理其余的事情。
最好的是它们与你的代码一起版本化。如果你在团队中工作,每个人都有相同的技能。如果你改变了什么,它会在 git 历史中。
投入精力编写它们值得吗?如果你重复同样的事情超过三次,绝对值得。你编写的每个技能都是一次你再也不需要进行的对话。
现在如果你不介意的话,我必须去教 Claude “重构"不意味着"从头重写一切”。
TL;DR:Skills 是 Claude Code 手动或自动执行的 Markdown 指令。它们可以根据需要灵活或确定:从"分析这个"到伪装成散文的脚本。如果你需要复杂逻辑,调用外部脚本。它们存在于 .claude/skills/ 中并与你的代码一起版本化。