作者:Bibek Poudel

译者:Carl Cui

1*K2fBI6vF9eAbcvjXq6ve6Q

如果你写的 skill 没有触发,问题基本上都出在元数据的 description 部分,而不在 skill 内容本身。

不少人都有类似的经历:写了一个 SKILL.md,将其放在正确的文件夹中,要求 agent 使用它,但是啥反应也没有。修改了 skill 内容,仍然没有效果。问题从来不是 skill 本身的内容,而是 agent 用来决定是否激活它开头的那两行。

在本指南中,我先讲解 Agent Skills 工作原理,指出为什么大多数人会写错,然后从简单到复杂构建四个 skill:一个 README 编写器、一个 git 提交消息生成器、一个代码审查器和一个完整的 MCP 驱动的冲刺规划器。

什么是 Agent Skill?

Skill 不是插件,也不是访问 API 的脚本。我们可以把它当作为团队新成员编写的入职指南。与其在每次跟 agent 对话时重新解释你的工作流程和偏好,不如将它们打包起来丢给 agent,让它根据你的请求自动加载。

本质上,skill 以一个文件夹的形式存在:

your-skill-name/
├── SKILL.md          # 必需:指令 + 元数据
├── scripts/          # 可选:agent 运行的可执行代码
├── references/       # 可选:仅在需要时加载的文档
└── assets/           # 可选:模板、图片、字体

唯一必需的文件是 SKILL.md。其他所有内容都是可选的,但随着 skill 复杂度的增加而变得重要。

SKILL.md 格式是一个开放标准,由 Anthropic 于 2025 年 12 月在 agentskills.io 发布。它适用于 Claude Code、OpenAI Codex 和 OpenClaw。虽然格式是标准化的,但每个平台在发现和工具调用方面的实现略有不同。可以理解为同一编程语言,经过不同编译器编译后,结果不是完全相同的。在 Claude Code 上有效的 skill 很可能在 Codex 上也有效,但运行时行为(如 session snapshotting、工具权限和调用模式)在不同平台之间有所不同。

Skill 存放位置

在写 skill 之前,你需要知道把它放在哪里。每个平台会从指定的位置加载 skill,不同位置的 skill 具有不同的作用域。

Claude Code:

位置作用域
~/.claude/skills/个人,在所有项目中可用
项目 .claude/skills/项目级别,通过 git 与团队共享

OpenAI Codex:

位置作用域
~/.codex/skills/个人,在所有项目中可用
项目 .codex/skills/项目级别,提交到 git 与团队共享

OpenClaw:

位置作用域
~/.openclaw/skills/对所有配置的 agent 可用
${workspace}/skills每个 agent 的工作空间,仅限特定 agent

当两个 skill 名字相同时,优先级高的 skill 起作用:项目级别的 skill 会覆盖具有相同名称的个人 skill 。

三级加载系统

这部分解释了几乎所有 skill 不触发或消耗太多上下文的问题。

Skill 使用渐进式披露:一个三级加载系统,内容仅在需要时被拉入上下文。

1*RsFkgCV2SNql7n5cxPGxFg

  • Level 1:元数据(始终加载,每个 skill 约 100 个 token)

    启动时,agent 仅从每个已安装 skill 的 YAML frontmatter 中读取 namedescription(其他什么都不读)。这个紧凑的列表进入 system prompt,以便 agent 知道存在哪些 skill 以及何时使用它们。所以可以安装许多 skill 而不会消耗过多上下文。

  • Level 2:Skill 内容(触发时加载,低于 5k 个 token)

    当 agent 确定某个 skill 相关时,它会通过 bash 命令将 SKILL.md 的主体读入上下文。到这个时候,skill 内容才会被加载。

  • Level 3:引用的文件和脚本(按需加载,实际上无限制)

    如果 skill 主体引用了其他文件,agent 仅在需要时读取它们。脚本可以在不被读入上下文的情况下执行。这就是 skill 可扩展的原因:无论你捆绑了多少内容,空闲时的 token 成本都是零。

以下是真实请求的序列示例:

1. 会话开始
   --> agent 加载:每个 skill  name + description(每个约 100  token
2. 用户询问:“你能为这个项目写一个 README 吗?”
   --> agent 读取:readme-writer/SKILL.md 完整主体(Level 2
3. SKILL.md 引用了一个风格指南文件
   --> agent 读取:readme-writer/references/style.mdLevel 3
4. SKILL.md 包含一个验证脚本
   --> agent 执行:scripts/validate.sh 
   (运行而不被读入上下文)

Skill vs. 斜杠命令

Claude Code 和 Codex 都支持两种 skill 调用模式。Agent 可以在你的请求匹配 description 时自动激活 skill(隐式调用),或者你可以直接调用它(显式调用)。

在 Claude Code 中,skill 默认出现在斜杠命令菜单中。你可以直接用 /skill-name 调用一个,或者只需描述你想要什么,Claude 会自动激活相关 skill:

# Claude Code 中的直接调用
/readme-writer
# 或者只需描述任务,Claude 会自动激活它
你能为这个项目写一个 README 吗?

在 Codex CLI 中,你使用 $ 前缀或使用 /skills 选择器来触发 skill:

# Codex CLI 中的显式调用
$readme-writer document this project
# 或者使用 skill 选择器
/skills

尽管两个平台都支持显式调用,但编写良好的描述仍然非常重要。它决定了 skill 何时自动激活,让 skill 感觉像是你现有工作方式的自然延伸,而不是你必须记住的命令。

常见的错误

YAML frontmatter 中的 description 字段不是给人看的。它是 agent 在决定是否激活你的 skill 时使用的触发条件。

以下是规范的结构:

[skill 做什么] + [何时使用它,带有特定的触发短语]

不好的结构:

description: 帮助处理文档。

下面这个也不好,因为它描述了 What 但没有描述 When:

description: 使用高级格式创建复杂的多页文档。

下面这个是比较好的:

description: 为软件项目创建和编写专业的 README.md 文件。当用户要求"写一个 README""创建一个 readme""记录这个项目""生成项目文档""帮我写一个 README.md"时使用。

agentskills.io 规范定义了这些约束:

  1. name:仅限小写字母、数字和连字符,最多 64 个字符,不能以连字符开头或结尾,不能有连续的连字符
  2. description:最多 1024 个字符,必须描述 skill 做什么以及何时使用
  3. 文件必须完全命名为 SKILL.md,区分大小写
  4. 避免在 frontmatter 中使用 XML 尖括号(< or >) ,因为它们可能会将意外的指令注入 system prompt

一些平台在这些基础上添加了约束,如果有疑问,请查看平台特定文档以及 agentskills.io/specification 上的基础规范。

Skill 1:README 编写器

这是第一个实用的 skill。几乎每个开发人员都曾在某个时候写过 README。这个 skill 教会 agent 你偏好的结构,并自动生成文件。

## 创建 skill 目录
mkdir -p ~/.claude/skills/readme-writer
  • SKILL.md
---
name: readme-writer
description: 为软件项目创建和编写专业的 README.md 文件。当用户要求"写一个 README"、"创建一个 readme"、"记录这个项目"、"生成项目文档"或"帮我写一个 README.md"时使用。适用于项目描述、现有代码或两者。
---

# README 编写器

## 概述

生成一个完整、专业的 README.md 文件并将其写入磁盘。输出应该足够清晰,让第一次贡献者能够理解项目、在本地设置并开始贡献。

## 步骤 1:收集项目上下文

在询问用户之前,先在代码库中寻找上下文:

\```bash
ls -la
cat package.json 2>/dev/null || cat pyproject.toml 2>/dev/null || \
  cat go.mod 2>/dev/null || echo "未找到清单文件"
ls .env.example .env.sample 2>/dev/null || echo "未找到环境变量示例"
\```

收集:
- 这个项目做什么?(1-2 句话总结)
- 它使用什么语言和主要框架?
- 如何安装和运行它?
- 需要环境变量吗?
- 有 LICENSE 文件吗?

## 步骤 2:编写 README

使用此结构。仅包含相关的部分。不要添加空的部分。

\```
# 项目名称

一句话清晰描述这个项目做什么以及为谁服务。

## 功能
- 功能一(具体说明)
- 功能二

## 先决条件
列出需要安装的内容。如果重要,包括版本要求。

## 安装
逐步设置。每个命令必须可复制粘贴。

\```bash
git clone https://github.com/username/project
cd project
npm install
\```

## 配置
如果项目需要环境变量,显示一个示例:

\```bash
cp .env.example .env
\```

然后解释用户需要手动设置的每个变量。

## 使用
首先显示最常见的用例。

\```bash
npm run dev
\```

## 许可证
[MIT](LICENSE)
\```

## 步骤 3:将文件写入磁盘

内容准备好后,写入:

\```bash
cat > README.md << 'EOF'
[完整的 readme 内容]
EOF
\```

确认已写入:

\```bash
echo "README.md 已写入:$(wc -l < README.md) 行"
\```

## 步骤 4:质量检查

完成前,验证:
- [ ] 没有像"[你的描述在这里]"这样的占位符文本
- [ ] 安装部分中的每个命令都适用于这个项目
- [ ] 先决条件匹配项目实际需要的内容
- [ ] 许可证部分匹配 LICENSE 文件(如果存在)

可以这样测试它,转到任何项目目录并询问:

你能为这个项目写一个 README 吗?

Agent 将检查代码库,编写 README,将其保存为 README.md,不需要复制粘贴。

Skill 2:Git 提交消息生成器

这个 skill 展示了如何编写触发短语,以涵盖开发者可能用不同方式请求同一件事的情况。

mkdir -p ~/.claude/skills/git-commit-writer
  • SKILL.md
---
name: git-commit-writer
description: 遵循 conventional commits 规范生成标准化的 git 提交消息。当用户要求"写一个提交消息"、"帮我提交"、"总结我的更改"、"我的提交应该说什么"或"起草一个提交"时使用。分析暂存的差异和更改描述,以生成 type(scope): description 格式的消息。
---

# Git 提交消息编写器

## 格式

\```
type(scope): 简短描述

[可选正文]

[可选页脚]
\```

允许的类型:feat、fix、docs、style、refactor、test、chore、perf、ci、build

## 指令

### 步骤 1:获取差异

\```bash
git diff --staged
\```

如果没有暂存任何内容:

\```bash
git diff HEAD
\```

### 步骤 2:分析更改

查找:
- 哪些文件更改了,它们属于什么类别
- 这是否添加了新功能(feat)、修复了错误(fix)还是更新了文档/配置/测试
- 作用域:哪个模块、组件或区域受到影响

### 步骤 3:编写消息

- 保持主题行在 72 个字符以下
- 使用祈使语气:"添加功能"而不是"添加了功能"
- 不要以句号结束主题行
- 如果更改需要比主题行允许的更多上下文,则添加正文

### 质量检查

- [ ] 类型是允许的类型之一
- [ ] 主题行在 72 个字符以下
- [ ] 使用了祈使语气
- [ ] 作用域足够具体,有用

## 示例

\```
feat(auth): 添加 Google OAuth2 登录

使用现有的会话管理系统实现 Google OAuth2 流程。用户现在可以使用他们的 Google 账户登录。

关闭 #142
\```

\```
fix(api): 处理支付提供商的空响应
\```

\```
docs(readme): 为 Node 22 更新本地设置说明
\```

Skill 3:代码审核器(多文件)

这个 skill 展示了何时将内容拆分到多个文件中:流程保留在 SKILL.md 中,详细标准存在于仅在实际审查期间加载的参考文件中。这是构建复杂 skill 的正确方式。

mkdir -p ~/.claude/skills/code-reviewer/references
  • SKILL.md
---
name: code-reviewer
description: 进行结构化的代码审查,提供分类反馈。当用户要求"审查这段代码"、"检查我的 PR"、"查看这个函数"或"给我这个实现的反馈"时使用。产生结构化输出,将阻塞性问题与建议分开。
---

# 代码审查器

## 审查流程

### 步骤 1:理解上下文

审查前,确定:
- 这段代码应该做什么?
- 它使用什么语言和框架?
- 这是一个新功能、错误修复还是重构?

### 步骤 2:运行审查

有关按类别的详细审查标准,请参见 [references/criteria.md](references/criteria.md)。

按顺序处理每个类别。即使某些类别似乎不太可能有问题,也不要跳过。

### 步骤 3:结构化输出

\```
## 总结
[2-3 句话概述和整体评估]

## 阻塞性问题
[必须修复的问题:安全漏洞、逻辑错误、数据丢失风险。
如果没有,写"未找到。"]

## 建议
[非阻塞性改进,编号。包括位置、原因以及如何修复每个问题。]

## 积极方面
[代码做得好的地方。始终至少包含一个。]
\```
  • references/criteria.md
# 审查标准

## 安全(首先检查)
- SQL 注入:用户输入是否参数化?
- XSS:输出在渲染前是否被正确转义?
- 身份验证检查:受保护的路由是否真正受到保护?
- 密钥:API 密钥或凭据是否硬编码在任何地方?
- 输入验证:是否在服务器端进行验证?

## 正确性
- 逻辑是否符合所述意图?
- 是否处理了边缘情况:空数组、空值、零、负数?
- 错误状态是否正确呈现?
- 异步操作是否正确等待?

## 可读性
- 新团队成员能在 5 分钟内理解吗?
- 变量和函数名是否具有描述性?
- 函数是做一件事还是多件事?

## 性能
- 是否有明显的 N+1 查询模式?
- 昂贵的操作是否在循环内部,而本可以在外部?

## 测试
- 是否有针对新行为的测试?
- 是否测试了边缘情况,而不仅仅是快乐路径?

SKILL.md 主体保持在 40 行以下。详细标准存在于 references/criteria.md 中,仅在审查时加载。这样 Level 2 就能保持简洁,同时 agent 仍然能访问它在 Level 3 所需的所有信息。

Skill 4:使用 MCP 的 Linear 冲刺规划器

这是一个 MCP 增强的 skill。MCP 服务让 agent 可以访问 Linear 的 API。Skill 赋予它如何可靠且一致地使用该访问权限的知识。没有这个 skill,用户连接了 MCP 但仍然需要弄清楚每一步;有了这个 skill,整个工作流程只需一句话就能运行。

mkdir -p ~/.claude/skills/linear-sprint-planner/references
  • SKILL.md
---
name: linear-sprint-planner
description: 自动化 Linear 冲刺规划,包括周期创建、待办事项分类和任务分配。当用户说"规划冲刺"、"设置下一个周期"、"帮我优先处理待办事项"或"在 Linear 中创建冲刺任务"时使用。需要连接 Linear MCP 服务器。
metadata:
  mcp-server: linear
  version: 1.0.0
---
# Linear 冲刺规划器

## 先决条件

验证 Linear MCP 服务器是否已连接。如果不可用,告诉用户先在 MCP 设置中连接它。

## 流程

### 步骤 1:收集当前状态

按顺序从 Linear 获取:
1. 当前活动周期和完成百分比
2. 所有待办事项(状态:Backlog 或 Todo,未分配给任何周期)
3. 团队成员和当前工作量
4. 任何标记为高优先级的事项

有关分页和速率限制处理,请参见 [references/linear-api.md](references/linear-api.md)。

### 步骤 2:分析容量

- 计算参与冲刺的团队成员数量
- 估算点数(默认:除非有历史速度,否则每人每周 10 点)
- 减去计划的休假时间

继续前呈现摘要:
团队容量:- [N] 名工程师 × [X] 点 = [总计] 可用 - 结转:[X] 点 - 新增容量:[X] 点
### 步骤 3:优先处理待办事项

按此顺序排序:
1. P0/P1 错误和阻塞项(始终包含)
2. 用户明确标记的事项
3. 解除其他团队阻塞的事项
4. 按产品优先级排序的功能
5. 技术债务

除非用户要求,否则不要超过容量的 10%。

### 步骤 4:呈现以供批准

在 Linear 中创建任何内容之前,显示建议的计划:
建议的冲刺 [N]:[日期范围] 容量:[X] 点 事项:- [ISSUE-123] 修复支付超时(P0)- 3 点 - [ISSUE-456] 添加 CSV 导出(P2)- 5 点 - [ISSUE-789] 重构身份验证中间件 - 2 点 总计:[X] / [X] 点 我应该创建这个周期并分配这些事项吗?
在进行更改之前,始终等待确认。

### 步骤 5:创建并确认

一旦批准:
1. 使用商定的日期范围创建周期
2. 将每个事项添加到周期中
3. 如果用户指定了所有者,则更新分配
4. 返回带有 Linear 周期链接的摘要

如果任何 API 调用失败,请参见 [references/error-handling.md](references/error-handling.md)。
  • references/linear-api.md
# Linear API 模式
## 获取待办事项
以 50 个为一批进行分页。检查 pageInfo.hasNextPage 并使用 after 游标。
过滤:status [Backlog, Todo], cycle: null。
## 创建周期
必需:name、startsAt、endsAt、teamId
## 添加事项
使用 issueUpdate mutation 设置 cycleId。尽可能批量处理。
## 速率限制
遇到 429 时:等待 1 秒,重试一次。如果再次失败,向用户报告并继续。
  • references/error-handling.md
# 错误处理
## MCP 连接错误
告诉用户:"Linear MCP 似乎已断开连接。请在运行冲刺规划之前重新连接。"不要继续。
## 缺少数据
使用可用数据继续。在最终摘要中注明缺少的内容。
## 周期创建失败
不要尝试添加事项。报告错误并建议检查权限。
  • 测试它
帮我在 Linear 中规划下一个冲刺

Agent 获取实时数据,提出计划,等待批准,然后执行。一句话触发整个工作流程。

在往下说之前,得弄明白一个重要的事:Skill 不保证执行,模型还是会自己拿主意。可以把它们看作是显著提高一致性的结构化指导,但不是确定性的。如果模型跑偏了,最好的办法通常是改进一下你的 skill 或者 description。

四个 skill 之间的关系

以下是四个 skill 及其在复杂度谱系中位置的视觉表示:

1*k47dVXRsihIO2NJEXovi0A

git-commit-writer 开始;当你需要文件输出时,使用 readme-writer 这种模式;当你的 skill 变得太长时,像 code-reviewer 那样拆分它;当你需要外部工具协调时,使用 linear-sprint-planner 这样的模式。

allowed-tools 字段

大多数人从未使用的一个 frontmatter 字段是 allowed-tools。它限制了 skill 激活时 agent 可以调用的工具。

这对于只读 skill 很有用,你不希望 agent 意外写入或执行任何内容:

---
name: log-analyzer
description: 分析应用程序日志文件以识别错误和模式。当用户说"检查日志"、"我的日志中有什么错误"或"分析这个日志文件"时使用。
allowed-tools: Read, Grep, Glob
---
# 日志分析器
1. 使用 Glob 查找日志文件:*.log、logs/*.log、/var/log/*.log
2. 使用 Grep 搜索错误模式:ERROR、FATAL、Exception、Traceback
3. 按类型和频率分组错误
4. 首先总结最常见的错误

激活此 skill 后,agent 无法执行 shell 命令、写入文件或进行任何外部调用。这是为观察性 skill 添加安全保证的简单方法。

注意:allowed-tools 在 Agent Skills 规范中被标记为实验性,并且支持情况因 agent 实现而异,目前在 Claude Code 中得到了很好的支持。

与团队共享 skill

最简洁的方法是将项目 skill 提交到你的仓库:

mkdir -p .claude/skills/readme-writer
# 添加 SKILL.md,然后:
git add .claude/skills/
git commit -m "为团队添加 readme-writer skill"
git push

当团队成员拉取仓库时, skill 立即可用,无需单独的安装步骤。在 Codex 中,等效路径是 .codex/skills/

常见的调试方式

  1. 检查你的描述

最常见的问题。添加更具体的触发短语,匹配用户实际表达请求的方式。

  1. 检查文件路径
# Claude Code 个人 skill 
ls ~/.claude/skills/your-skill/SKILL.md
# Claude Code 项目 skill 
ls .claude/skills/your-skill/SKILL.md
# Codex
ls ~/.codex/skills/your-skill/SKILL.md
  1. 检查 YAML 语法

无效的 YAML 会静默阻止加载。Frontmatter 必须从第 1 行以 --- 开始,并以另一个 --- 结束。

  1. 重启会话

Skill 在会话开始时被快照。在运行会话期间进行的编辑需要重启才能生效。

  1. 在调试模式下运行
claude --debug
  1. 使用显式调用测试
使用 readme-writer skill 记录这个项目

如果显式调用时有效但自动调用时无效,description 需要更具体的触发短语。

安全相关

Skill 可以捆绑可执行代码和控制 agent 行为,同样的能力也使恶意 skill 变得危险。

仅从受信任的来源安装 skill。在安装任何社区 skill 之前,阅读文件夹中的每个文件,尤其是 scripts/ 中的任何内容。注意告诉 agent 进行出站网络调用或将数据发送到外部服务的指令。

Cisco 的研究人员已经警告说,有些 skill 被用于通过 prompt injection 静默窃取数据。安全审计扫描了数千个社区 skill,发现其中相当一部分存在严重漏洞,包括凭证盗窃和恶意软件。Snyk 已经发布了关于这个问题的具体发现。ClawHub 有一个 VirusTotal 集成,你可以在安装前用来检查 skill,但对于任何具有广泛权限的东西,人工审查仍然值得。

实用规则:

  1. 永远不要安装要求你将密钥粘贴到聊天中的 skill
  2. 在安装前始终阅读 scripts/
  3. 对在设置指令中进行出站网络访问的 skill 持怀疑态度
  4. 优先选择来自官方来源的 skill:Anthropic 或 OpenAI 的 skill 仓库,或你自己团队的

总结

三级加载系统是核心概念,其他一切都由此而来。Level 1 是你的触发器,Level 2 是你的操作手册,Level 3 是你的参考资料库。把这些弄对,你就可以构建任何东西,从单个 Markdown 文件到协调外部 API 和执行代码的多步骤工作流程。

SKILL.md 格式也不再仅仅是 Claude 的功能。OpenAI 为 Codex 采用了它。OpenClaw 将其用作核心插件格式。你今天编写的 skill 可以跨所有三个平台移植,这种可移植性值得投资。

请随意修改和扩展本指南中构建的 skill,以适应你的特定工作流程。官方 skill 仓库是研究 Anthropic 和 OpenAI 编写良好示例的好地方:

参考资料

原文链接

The SKILL.md Pattern: How to Write AI Agent Skills That Actually Work