159
0
0

如何写好一个SKILL?

2026-08-15
2026-08-15
文章摘要
|

前言

SKILL 是把「指令、脚本、模板」一体化打包成可复用能力包的机制,关键在于三件事:Agent 能自动发现它、按需加载它、在需要时调用里面的脚本和资源。它不只是存 prompt,而是一份 Agent 能自己翻阅的操作手册。每个 SKILL 是一个文件夹,里面有一份 SKILL.md,还可以带上脚本、模板、参考文档这些资源。

它和普通 prompt 最大的区别是:Skill 能被 Agent 自动发现和按需加载,不用你每次手动输入;和 MCP 工具的区别是:MCP 给 Agent 提供外部工具和数据的访问能力,而 Skill 教 Agent 拿到这些工具和数据之后该怎么用。

那么 SKILL 这么好用,设计的也很优秀,那么我们应该怎样才能写好一个 SKILL 并运用到我们的日常开发中呢?

整体框架

我们先来看看一个 SKILL 的完整框架:

skill-name/
├── SKILL.md                  # [必需] 入口文件:frontmatter + body
├── agents/
│   └── openai.yaml           # [推荐] 技能的"名片"
├── scripts/                  # [可选] 可执行脚本
├── references/               # [可选] 参考文档
└── assets/                   # [可选] 产出物模板

逐个说明:

  • SKILL.md — 唯一必需的文件,包含元数据以及具体的 body 正文。

  • scripts/ — 写好的程序,AI 不需要读懂它,直接调用 shell 执行就行。比如 scripts/rotate_pdf.py,AI 只要跑 python rotate_pdf.py input.pdf 90 就能旋转 PDF,不用每次重新写旋转逻辑。适合那些结果必须精确、不能让 AI 自由发挥的操作

  • references/ — AI 在工作过程中需要查阅的参考资料。比如一个 "BigQuery 查询" 技能,AI 要知道公司有哪些表、每个表有什么字段,这些信息放在 references/schema.md 里,AI 需要时再读取。和 scripts 的区别是:references 是给 AI 的,scripts 是给 AI 执行

  • assets/ — 不是给 AI 看的,而是直接用在最终产出里的文件。比如一个 "前端项目生成器" 技能,assets/frontend-template/ 里放着一套 HTML/React 样板代码,AI 直接把这套模板拷贝出来,在上面修改。再比如 assets/logo.png 是公司 logo,AI 生成网页时直接引用它。AI 不需要 "读懂" 一张 logo 图片,只需要知道它在哪、什么时候放进去

  • agents/openai.yaml — 技能的 "名片"。很多 AI 产品会在界面上展示一个技能列表,让用户选择或搜索。这个文件里存的就是列表中显示的名称、简介、图标等信息。它不影响 AI 的行为,纯粹是给产品界面用的

这里补充下 SKILL.md:

---
name: my-skill                    # ← 上半部分:元数据
description: >-                   #    AI 靠这里决定要不要激活这个技能
  当用户需要做某件事时,使用这个技能。
---

下半部分:操作指令                   # ← AI 激活技能后才会读到这里
按照以下步骤执行...

上半部分叫 frontmatter--- 之间的 YAML),包含 namedescription 两个字段。AI 在每次对话开始时都会扫描所有已安装技能的 frontmatter,靠 description 来判断 "这个技能和当前请求相关吗"——这是技能被触发的唯一依据

下半部分叫 body(Markdown 正文),是技能被激活之后才加载的操作指令。如果技能没被触发,AI 永远不会读到这里。

SKILL是给AI写指令

知道了 skill 是什么,下一步就是要写一个。大多数人第一次写出来的 skill 都有一个问题,比如现在我有一个“代码审查”技能:

---
name: code-review
description: 代码审查技能
---

# Code Review Skill

## 背景
本技能基于团队多年的代码审查经验总结而成,旨在提升代码质量和团队协作效率。

## 审查原则
- 保持专业、建设性的语气
- 关注代码质量而非个人风格
- 平衡严格性和灵活性

## 使用方式
当用户提交代码时,对代码进行全面审查,给出改进建议。注意保持友好和鼓励的态度。

## 版本记录
- v1.0: 初始版本
- v1.1: 增加了对 Python 的支持

简单来说,如果这是一份给人看的团队文档,写得不错——有背景、原则、使用方式,甚至有版本记录。

但是这份 skill 实际上是拿给 AI 读的。重新来看:

  • "基于团队多年经验总结" — AI 不关心这个技能是怎么来的,它只需要知道现在该怎么做

  • "保持专业、建设性的语气" — 人类读了能 get 到一个大致的感觉,但 AI 会把 "专业" 和 "建设性" 展开成无数种组合,每次输出都不一样

  • "平衡严格性和灵活性" — 人类经验丰富的审查者知道什么时候严格什么时候灵活,但 AI 没有这个直觉,这句话等于没说

  • "全面审查,给出改进建议" — 这是对人类审查者的期望,但 AI 需要的是:先检查什么?再检查什么?什么问题必须指出?什么问题可以忽略?

  • "版本记录" — AI 每次被唤醒都是全新的,v1.0 还是 v1.1 对它没有意义

  • description 只写了 "代码审查技能" — AI 靠 description 判断是否触发,"代码审查技能" 五个字太模糊:用户说 "帮我看看这段代码" 要触发吗?"这个函数性能怎么样" 要触发吗?

所以这个问题通常出在写错了对象。我们现在通过 codex 的 skill-creator 来看看如何给 AI 写指令。

skill-creator框架

skill-creator 要解决的问题只有一个:怎么在有限的上下文窗口里,给 AI 最有效的指令?

第一层:简洁

AI 的上下文窗口是有限、共享的。你的 skill 越多,留给其他用途的就越少。所以 skill-creator 的第一原则就是:每一句话都要值得它占用的 token

第二层:两个设计维度

一、信息放在哪里

skill-creator 设计了一个三级分层架构,让不同的信息在不同的时机进入上下文:

  • L1(元数据):始终在上下文中,约 100 词——AI 靠它判断要不要激活这个技能

  • L2(SKILL.md body):触发后才加载,控制在 5k 词以内——操作指令

  • L3(scripts/references/assets):按需使用,无上限(其中 scripts 只执行)

维度二:给 AI 多大自由度?

比如,让 AI 写一篇技术博客,这种就只需要给出方向,具体怎么写让 AI 自己决定,这就是高自由度。

但让 AI 生成一个 YAML 配置文件就不一样了。比如 skill-creator 要生成的 openai.yaml,里面有个 short_description 字段,要求 25-64 个字符、首字母大写、不能有引号。AI 写成 65 个字符?不行,产品界面会截断。写成 24 个字符?不行,校验不通过。漏了首字母大写?界面显示不一致。这种任务差一个字符就出问题,你不能让 AI 自由发挥,必须用脚本来锁死格式——这就是低自由度。这类任务叫 "脆弱操作":不是说它复杂,而是说它做对只有一种方式,做错有一百种方式

第三层:落地流程

skill-creator 给出了一个六步创建流程,把设计思想变成可执行的操作步骤:

根本约束:简洁

核心约束

AI 的上下文窗口是有限的,而 skill 一旦被激活,内容也要摊上去。占得越多,留给其他东西空间就越少。

所以 skill-creator 第一条原则就是:

The context window is a public good. Skills share the context window with everything else Codex needs: system prompt, conversation history, other Skills' metadata, and the actual user request.

skill-creator 给了一个前提假设:AI 本身已经很聪明了,你只需要补充它不知道的东西。

Default assumption: Codex is already very smart. Only add context Codex doesn't already have.

基于这个假设,每写一段内容之前问自己两个问题:

  • "AI 是不是已经知道这个了?" — 比如 "Python 的 for 循环怎么写",AI 当然知道,不用教

  • "这段内容值不值得占用工作台上的空间?" — 一段 200 字的解释,能不能用一个 10 行的代码示例替代?

什么不该放进SKILL?

Skill-creator 明确列出了禁止清单

A skill should only contain essential files that directly support its functionality. Do NOT create extraneous documentation or auxiliary files.

不该有的文件:

  • README.md

  • INSTALLATION_GUIDE.md

  • QUICK_REFERENCE.md

  • CHANGELOG.md

原因很简单,就是因为 SKILL 的读者是 AI 而不是人类开发者。

约束时,不做什么比做什么更精确

意思是要写对,比如当skill-creator 创建laotou-thought-style(一种写作风格技能)时,它没有写:

请用温暖、克制、有洞察力的语气写作。

这种正面描述看起来清晰,但对 AI 来说,"温暖" 的程度、"克制" 和 "有洞察力" 之间的平衡——全是模糊空间。

它做的是写了一份反模式清单references/anti-patterns.md):

不要这样做

症状

怎么改

角色堆砌

连续出现多个名字和对白

保留一个冲突场景,补抽象提炼

只有鸡汤没有动作

全文 "要坚持、要努力"

改为今天可做的一小步

直接大道理

开头就讲规律

先铺生活场景

收尾太猛

结尾 "必须改变!"

换成 "慢慢来""就好"

过度绝对化

"永远""一定"

加限定词 "多数时候""往往"

每一条都是具体的、可检测的、有明确修正方案的。因为“不做什么”能把 AI 的行为空间收窄到你想要的范围。

skill-creator 自身也遵循了这个原则——它的 SKILL.md 用了很大篇幅说 "什么不该写"(What to Not Include in a Skill),而不是泛泛地说 "写好内容"。

当你写完 SKILL.md,做一次 "反转测试":每一条正面指导,能不能改写成 "不要做 X" 的形式?如果可以,改写后通常更精确。

还有就是使用祈使语气 / 不定式。

设计维度一:信息放在哪儿?

这里细说一下架构的细节。

三级渐进式加载

skill-creator 原文对三个层级的定义:

  1. Metadata (name + description) - Always in context (~100 words)

  2. SKILL.md body - When skill triggers (<5k words)

  3. Bundled resources - As needed by Codex (Unlimited because scripts can be executed without reading into context window)

层级

内容

何时在上下文中

token 成本

L1

frontmatter(name + description)

始终

~100 词

L2

SKILL.md body

触发后加载

<5k 词

L3

scripts/ references/ assets/

按需加载

无上限

这本质上是一个信息熵管理系统

  • L1 是过滤器 — 从几十个已安装技能中筛选出当前需要的那一个。description 不精确 → 误触发或漏触发

  • L2 是操作手册 — 触发后告诉 AI 该怎么做。太长 → 注意力被稀释。body 控制在 500 行以内

  • L3 是工具箱 — 只在需要时打开。其中 scripts/ 最高效——执行而不读入,零 token 成本

Frontmatter:触发机制的全部来源

Frontmatter 只有两个必需字段:namedescription。但 description 的写法至关重要:

This is the primary triggering mechanism for your skill, and helps Codex understand when to use the skill.

关键规则:

  • 把所有“when to use”信息放在 description 里,不要放在 body 里。body 是触发后才加载的,那时候 Codex 已经决定用了,“什么时候用”的信息已经迟了

  • 不要在 frontmatter 中放 namedescription 以外的字段(licenseallowed-toolsmetadata 除外)

比如 docx 技能的 description:

"Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. Use when Codex needs to work with professional documents (.docx files) for: (1) Creating new documents, (2) Modifying or editing content, (3) Working with tracked changes, (4) Adding comments, or any other document tasks"

翻译过来就是:

全面的文档创建、编辑与分析能力,支持修订追踪、批注、格式保留以及文本提取。当 Codex 需要处理专业文档(.docx 文件)时使用,适用于以下场景:(1)创建新文档,(2)修改或编辑内容,(3)处理修订追踪,(4)添加批注,或任何其他文档相关任务。

我们可以发现,他把能力的描述以及什么时候用都说的很清楚了。

四种捆绑资源的本质区别

Scripts

可执行代码(Python/Bash 等),用于需要确定性可靠性或反复重写的任务。

  • 什么时候需要:同样的代码每次都要重新写,或者需要确定性的可靠输出

  • 举例scripts/rotate_pdf.py 用于 PDF 旋转任务

  • 核心优势:token 高效、确定性、可以执行而不读入上下文窗口

  • 注意:脚本有时仍需要被 Codex 读取,用于修补或环境适配

References

文档和参考资料,在需要时加入到上下文中,辅助 Codex 思考。

  • 什么时候需要:Codex 在工作时需要参考的详细文档

  • 举例references/finance.md(财务 schema)、references/api_docs.md(API 规范)、references/policies.md(公司政策)

  • 用途:数据库 schema、API 文档、领域知识、公司政策、详细工作流指南

  • 核心优势:保持 SKILL.md 精炼,只在 Codex 判断需要时才加载

  • 最佳实践:如果文件很大(>10k 词),在 SKILL.md 中包含 grep 搜索模式

  • 避免重复:信息应该只存在于 SKILL.md references 文件中,不能两边都有。详细信息优先放 references,SKILL.md 只保留核心流程指令和工作流指导

Assets

不是用来加载到上下文中的文件,而是直接用在 Codex 产出物中的资源。

  • 什么时候需要:技能需要在最终输出中使用的文件

  • 举例assets/logo.png(品牌素材)、assets/slides.pptx(PPT 模板)、assets/frontend-template/(HTML/React 样板)、assets/font.ttf(字体)

  • 用途:模板、图片、图标、样板代码、字体、示例文档——这些会被复制或修改

  • 核心优势:将输出资源与文档分离,Codex 可以使用它们而无需读入上下文

Agents元数据(agents/openai.yaml)(推荐)

面向 UI 的元数据,不给 AI 读,给产品前端读:

  • 包含 display_nameshort_descriptiondefault_prompt 等字段

  • 通过脚本 generate_openai_yaml.py 确定性生成,而不是手写

  • 更新 SKILL.md 后要检查 agents/openai.yaml 是否还匹配,过期了就重新生成

  • 详细字段定义见 references/openai_yaml.md

设计维度二:给AI多大自由度?

知道了信息该放在哪里、该怎么约束,下一个问题是:AI 做什么,脚本做什么?

AI 非常擅长理解语义、生成文本、做创造性工作。但它不擅长精确格式控制、长度约束、命名规范——这些 "脆弱操作"。

三个自由档位

高自由度(文字指令):多种方法都可行时,决策依赖上下文,用启发式引导。

中自由度(伪代码 / 带参数的脚本):有最佳实践但允许变通,配置影响行为。

低自由度(具体脚本,少量参数):操作脆弱容易出错,一致性至关重要,必须遵循特定序列。这种一般直接用脚本生成。

核心逻辑:

任务越脆弱(容易出错) → 自由度越低 → 用脚本锁死

任务越灵活(多种方案都对) → 自由度越高 → 用文字引导

低自由度的实现:skill-creator的三个脚本

init_skill.py(输入保障,398 行)

初始化新技能目录的脚手架工具,类似 create-react-app 之于 React 项目:

scripts/init_skill.py <skill-name> --path <output-directory> \
  [--resources scripts,references,assets] [--examples] \
  [--interface key=value]

核心功能:

  • 创建技能目录

  • 生成带 TODO 占位符的 SKILL.md 模板(TODO 是给 Codex 看的 "填空题")

  • 调用 generate_openai_yaml.py 生成 agents/openai.yaml(通过 --interface key=value 传入 AI 生成的 display_name、short_description、default_prompt)

  • 可选创建 scripts/references/assets/ 子目录

  • 可选添加示例文件(--examples

  • 内置 normalize_skill_name() 自动把任意用户输入标准化为 hyphen-case

使用示例:

scripts/init_skill.py my-skill --path skills/public
scripts/init_skill.py my-skill --path skills/public --resources scripts,references
scripts/init_skill.py my-skill --path skills/public --resources scripts --examples

generate_openai_yaml.py(格式保障,226 行)

专门负责生成和更新 agents/openai.yaml

  • 从 SKILL.md 的 frontmatter 读取技能名

  • 自动将 hyphen-case 转为 Title Case(my-cool-skillMy Cool Skill

  • 内置缩写词典(GH、MCP、API 等保持大写)和品牌词典(openai → OpenAI)

  • 自动生成 25-64 字符的 short_description

  • 支持 --interface key=value 覆盖任意字段

scripts/generate_openai_yaml.py <path/to/skill-folder> --interface key=value

quick_validate.py(输出保障,102 行)

技能创建后的 "质检员":

scripts/quick_validate.py <path/to/skill-folder>

校验内容:

  • SKILL.md 是否存在

  • YAML frontmatter 格式是否合法

  • name:是否为 hyphen-case,≤ 64 字符,无连续 / 首尾连字符

  • description:是否存在,无尖括号,≤ 1024 字符

  • 只允许 namedescriptionlicenseallowed-toolsmetadata 这 5 个 frontmatter 键

质量保证链

三个脚本形成了一条确定性保障链,夹住中间的创造性步骤:

init_skill.py(输入保障)
  命名标准化 + 目录结构创建 + 模板生成
  → 确保起点正确
       ↓
  AI 创造性编写(高自由度)
  → SKILL.md 内容、references、自定义 scripts
       ↓
quick_validate.py(输出保障)
  frontmatter 格式 + 命名规范 + 长度约束校验
  → 确保终点合规

关键就是脚本是执行而不读入的——零 token 成本

总结

回到最初的问题:怎么写出好的 skill?

回顾整个框架:

根本约束:简洁
 ├── 信息放在哪里? → 三级分层,按需加载
 ├── 给 AI 多大自由度? → 脆弱操作脚本锁死,创造性工作文字引导
 └── 怎么落地? → 六步流程:理解→规划→初始化→编辑→校验→迭代

Skill 是给 AI 写指令,而不是给人。用最少的 token,在正确的层级,给 AI 最精准的约束,让它在边界内自由发挥。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或者给予支持!

如何写好一个SKILL?
/archives/how-to-write-skill
作者
generals
发布于
2026-08-15
许可协议
CC BY-NC-SA 4.0