重复同样事情的问题

你有没有遇到过必须向某人解释同一件事二十遍的情况?现在想象一下,这个人是个机器人,而且每隔几个小时就会失去记忆。

“不,Claude,commit 必须先通过测试。” “Claude,我已经告诉过你要用 type: description 格式。” “别加表情符号,该死的!”

这就是我每天的工作,直到我发现了 Skills。简单来说:这些是你写一次,Claude 就会永远遵循的指令。就像训练狗一样,但不需要狗粮。

什么是 Skills

从 2.1.3 版本开始,Claude Code 将旧的 slash commands 与更强大的东西合并:Skills。这些是包含指令的 Markdown 文件,Claude 可以通过两种方式执行:

  1. 手动:当你输入 /my-skill
  2. 自动:当 Claude 检测到应该使用它时

第二点就是魔法所在。你不再需要记住调用命令。如果你有一个技能说"在用户完成任务且有未提交的更改时使用",Claude 会自动执行。

就像有一个管家知道何时收拾桌子而不需要你要求。

它们在哪里

~/.claude/skills/          # 个人(所有项目)
.claude/skills/            # 项目(与团队共享)
~/.claude/commands/        # 旧版,仍然有效
.claude/commands/          # 旧版,仍然有效

如果你只想自己使用技能,就把它放在你的主目录。如果你想让整个团队都有,就提交到仓库。就这么简单。

Skill 的结构

一个 skill 是一个带有 frontmatter YAML 和内容的 Markdown 文件:

1
2
3
4
5
6
7
8
---
name: my-skill
description: 它做什么的简要描述
---

# 指令

Claude 在调用此技能时应该做什么。

这是最基本的。但 frontmatter 有更多值得了解的选项。

必填字段

name

技能的标识符。只能使用小写字母、数字和连字符(最多 64 个字符)。必须与文件或目录名称匹配。

1
2
name: check-types      # ✓ 有效
name: Check_Types      # ✗ 无效(大写字母和下划线)

description

这是最重要的字段。 Claude 用它做两件事:

  1. 决定何时自动调用技能
  2. 理解应该做什么

最多 1024 个字符。包含用户会自然说出的关键词。

1
2
3
4
5
6
7
# 不好 - 太模糊
description: 做一些关于 commits 的事情

# 好 - 具体且有触发器
description: >
  创建 git commits,验证 type-check、lint 和 tests。
  当用户说"commit"、"提交"或完成有待处理更改的任务时使用。

可选字段

model

为此技能强制使用特定模型。对需要更多能力的任务很有用。

1
2
3
model: opus    # 用于安全审计、复杂重构
model: sonnet  # 在能力和成本之间平衡
model: haiku   # 用于简单快速的任务

如果不指定,使用当前对话的模型。

allowed-tools

限制 Claude 可以使用的工具。对于只读或安全技能至关重要。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 只能读取,不能修改
allowed-tools:
  - Read
  - Grep
  - Glob

# 只能执行特定命令
allowed-tools:
  - Bash(git:*)      # 只能用 git 命令
  - Bash(uv:*)       # 只能用 uv 命令
  - Read

实际例子:一个不应该碰任何东西的分析技能:

1
2
3
4
5
6
7
8
---
name: analyze-deps
description: 分析项目依赖关系而不修改任何内容
allowed-tools:
  - Read
  - Grep
  - Bash(uv pip list:*)
---

context: fork

在隔离的子代理中执行技能,有自己的上下文。主对话历史不会被污染。

1
context: fork

对于不想用噪音填满聊天的复杂多步操作很有用。

agent

仅在 context: fork 下工作。定义执行技能的代理类型。

1
2
3
context: fork
agent: Explore    # 快速探索代理
agent: Plan       # 规划代理

user-invocable

控制是否在 /(slash commands)菜单中显示。默认为 true

1
user-invocable: false  # 从菜单中隐藏,但 Claude 可以使用

对于只应该自动激活的内部技能很有用。

disable-model-invocation

阻止 Claude 自己调用技能。只有你可以用 /name 激活。

1
disable-model-invocation: true

对于需要明确人工决策的破坏性或昂贵操作很有用。

hooks

定义在技能生命周期中执行的钩子。支持 PreToolUsePostToolUseStop

1
2
3
4
5
6
7
hooks:
  PreToolUse:
    - matcher: "Bash"
      hooks:
        - type: command
          command: "./scripts/validate-input.sh $TOOL_INPUT"
          once: true

替换变量

在技能内容中你可以使用:

变量包含内容
$ARGUMENTS调用 /skill arg1 arg2 时传递的参数
${CLAUDE_SESSION_ID}当前会话 ID(对日志有用)

总结表

字段必填用途
name技能标识符
description何时以及为什么使用
model强制特定模型
allowed-tools限制工具
contextfork 用于隔离子代理
agent代理类型(与 context: fork 一起)
user-invocable/ 菜单中显示/隐藏
disable-model-invocation阻止自动调用
hooks生命周期钩子

完整示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
---
name: security-audit
description: >
  OWASP 安全审计。当用户要求检查安全性、查找漏洞或部署到生产环境之前时使用。
model: opus
allowed-tools:
  - Read
  - Grep
  - Glob
user-invocable: true
disable-model-invocation: true  # 只能手动,成本很高
---

# 安全审计

[指令...]

有关完整参考,请查阅 Agent Skills 官方文档

自由文本还是确定性代码?

这是个关键问题:如果技能是 Markdown,是否意味着 Claude 总是"解释"你写的内容?我能做真正可预测的事情吗?

简短回答:技能的确定性取决于你如何编写它们

想象一个谱系:

模糊/灵活 ──────────────────────────► 确定性
"检查代码"              "按顺序执行这 3 个命令"

灵活技能(Claude 决定)

1
2
3
4
5
6
---
name: review
description: 检查代码中的问题
---

分析代码并建议改进。

这里 Claude 有完全的自由。可以查看任何想要的内容,建议任何看起来合适的东西。对探索有用,对关键流程危险。

确定性技能(伪装的脚本)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
---
name: check
description: 强制质量检查
allowed-tools:
  - Bash
---

**严格**按顺序执行这些命令:

1. `uv run basedpyright src/`
2. `uv run ruff check src/`
3. `uv run pytest -x`

## 规则

- **不要**创造性地解释错误
- **不要**在任何一个失败时继续
- **不要**建议自动修复
- 只报告:✓ 通过 / ✗ 失败并输出结果

这基本上是一个 3 行脚本。Claude 没有创造性的余地。执行、报告、结束。

带条件逻辑的技能

1
2
3
4
5
6
7
8
9
---
name: release
description: 准备项目发布
---

## 步骤 1:验证分支

```bash
git branch --show-current
  • 如果不是 main中止并显示"只能从 main 分支"

步骤 2:清洁状态

1
git status --porcelain
  • 如果有输出 → 中止并显示"有未提交的更改"

步骤 3:版本号递增 + 推送

1
2
uv run bump2version patch
git push && git push --tags

这里有分支逻辑,但仍然是确定性的:条件是明确的。

### 调用真实脚本的技能

如果你需要真正复杂的逻辑(循环、解析、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 就会自动完成一切。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
---
name: commit
description: 创建带有强制质量验证的 git commits。
  在提交前执行类型检查、lint 和测试。
---

# Commit

## 何时使用(自动)

在以下情况下应用:
- 用户说"commit"、"提交"、"保存更改"
- 用户完成任务且有未提交的更改

## 禁止事项

- 不执行验证就提交
- 请求确认(直接做就行)
- 添加 Co-Authored-By
- 在提交消息中使用表情符号

## 流程

### 阶段 1:检测更改

```bash
git diff --name-only HEAD

阶段 2:强制验证

1
2
3
uv run basedpyright src/
uv run ruff check src/
uv run pytest

如果任何一个失败,不要继续。

阶段 3:创建提交

  1. git add -A
  2. 分析更改
  3. 生成消息:type: description
  4. 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. 具体的描述

1
2
3
4
5
6
# 不好
description: 做一些关于 commits 的事情

# 好
description: 创建 git commits,验证类型检查、lint 和测试。
  如果有错误则阻止。

2. 定义何时应用

1
2
3
4
5
6
## 何时使用此技能(自动)

在以下情况下自动应用:
- 用户说"commit"或"保存更改"
- 有 staged 的更改准备好
- 用户完成一个任务

3. 明确禁止事项

Claude 倾向于想要礼貌地请求确认。如果你不想要那样,明确地说出来:

1
2
3
4
5
## 禁止事项

- 请求确认(永远不要)
- 添加 Co-Authored-By
- 使用表情符号

4. 对重要事项使用 model: opus

如果技能做的事情很关键(安全审计、复杂重构),强制使用最有能力的模型:

1
2
3
4
5
---
name: owasp
description: OWASP 安全审计
model: opus
---

5. 必要时限制工具

有时你想要一个只读而不修改任何内容的技能:

1
2
3
4
5
6
7
8
---
name: readonly-analysis
description: 分析代码而不修改
allowed-tools:
  - Glob
  - Grep
  - Read
---

简单 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 的区别

方面SkillsCommands
自动调用
结构目录或文件仅文件
建议用于所有新功能旧版

Commands 仍然有效,但 skills 严格来说更好。如果你有旧的 commands,不需要迁移它们,但对于新东西使用 skills。

结论

Skills 基本上就是编程,但用自然语言。你定义你想要发生什么、何时发生以及有什么限制。Claude 处理其余的事情。

最好的是它们与你的代码一起版本化。如果你在团队中工作,每个人都有相同的技能。如果你改变了什么,它会在 git 历史中。

投入精力编写它们值得吗?如果你重复同样的事情超过三次,绝对值得。你编写的每个技能都是一次你再也不需要进行的对话。

现在如果你不介意的话,我必须去教 Claude “重构"不意味着"从头重写一切”。


TL;DR:Skills 是 Claude Code 手动或自动执行的 Markdown 指令。它们可以根据需要灵活或确定:从"分析这个"到伪装成散文的脚本。如果你需要复杂逻辑,调用外部脚本。它们存在于 .claude/skills/ 中并与你的代码一起版本化。