如何写出高质量的AI Skill:从Anthropic官方仓库学到的7个原则
如果你想让AI Agent真正能干好活,光靠聊天是不够的。你得给它写"说明书"——也就是Skill。
Anthropic官方开源了一个叫skill-creator的仓库,里面装的不是一个普通技能,而是一个"教AI怎么创建技能"的技能。通过分析这个元技能,我们可以学到一手的最佳实践。
这篇文章就把我从这个仓库里学到的东西整理出来。不管你在用OpenCode、Claude Code还是Cursor,这些原则都通用。
01 skill-creator仓库里有什么
先看看这个仓库长什么样:
skill-creator/
├── SKILL.md # 核心指南,只有357行
├── references/ # 参考文档
│ ├── output-patterns.md # 输出模式
│ └── workflows.md # 工作流模式
└── scripts/ # 辅助脚本
├── init_skill.py # 技能初始化
├── package_skill.py # 打包验证
└── quick_validate.py # 快速验证注意一个数字:核心的SKILL.md只有357行。这说明写Skill的第一原则就是简洁。
再复杂的技能,说明书也得短。
02 SKILL.md长什么样
一个标准的SKILL.md文件分成两部分。
第一部分是YAML头信息:
---
name: skill-creator
description: |
指导如何创建有效的技能。当用户想要创建新技能或更新已有技能时使用,
这些技能可以通过专业知识、工作流程或工具集成来扩展Agent的能力。
license: MIT
---这里只有name和description是必需的。description要同时说明两件事:这个技能是干什么的,什么时候该用它。
第二部分是正文。正文要用祈使句——就是直接说"做什么",不要说"你应该做什么"或"我们可以做什么"。
好的写法:"用简洁例子代替冗长解释"
不好的写法:"我建议你用简洁例子代替冗长解释"
03 七个核心原则
原则1:上下文窗口是公共资源
原文说:"上下文窗口是一种公共资源。技能要和系统提示、对话历史、其他技能的元数据、用户请求共享这个窗口。"
什么意思?AI每次能处理的信息是有限的。你的技能说明占得越多,留给真正任务的空间就越少。
所以每个词都要有价值。不断问自己:AI真的需要这个解释吗?它已经知道的东西就不用写。
实践建议:
能用一句话说完的别用三段话
SKILL.md正文控制在500行以内
接近这个数就把详细内容拆到references/文件夹里
原则2:根据任务性质给自由度
不是所有任务都需要同样的约束。根据任务的"脆弱性"和"可变性"来决定给多少自由:
| 自由度 | 适合场景 | 怎么写 |
|---|---|---|
| 高自由度 | 有多种方法都行,需要AI自己判断 | 文字指令就行 |
| 中自由度 | 有推荐做法,但允许变化 | 伪代码或带参数的脚本 |
| 低自由度 | 操作容易出错,必须按固定流程 | 写死的脚本,参数越少越好 |
比如"写一封邮件"可以给高自由度,但"用特定格式导出财务报表"就得给低自由度。
原则3:渐进式披露
Skill采用三级加载系统:
级别1:元数据(name + description)
始终加载,大概100个token
级别2:SKILL.md正文
技能被触发时才加载,建议5000 token以内
级别3:脚本和参考资料
按需加载,需要时才读关键是保持SKILL.md短小。如果拆分了文件,一定要在SKILL.md里明确说清楚什么时候该读那些文件。
原则4:别放无关文件
原文明确说了:"技能只应包含直接支持其功能的核心文件。不要创建额外的文档,比如README.md、INSTALLATION_GUIDE.md、CHANGELOG.md等。"
这些文件对你作为开发者可能有用,但对AI干活没用。加了只会增加混乱。
技能里只放三类东西:
SKILL.md(必需)
scripts/(可执行脚本)
references/(参考文档)
assets/(静态资源)
其他的一概不放。
原则5:description要写清楚
原文说:"只有name和description会被AI用来判断什么时候触发这个技能,所以要清楚说明技能是什么以及什么时候该用它。"
好的description例子(来自docx技能):
description: |
全面的文档创建、编辑和分析能力,支持修订跟踪、评论、格式保留和文本提取。
当Agent需要处理专业文档(.docx文件)时使用,包括:
(1) 创建新文档
(2) 修改或编辑内容
(3) 处理修订跟踪
(4) 添加评论
或其他任何文档相关任务差的description例子:
description: "帮助处理PDF文件"注意:所有"什么时候用"的信息都要放在description里,因为正文只在技能触发后才加载,AI看不到。
原则6:用祈使句
原文写作指南里专门说了:"始终使用祈使句/动词原形形式。"
对的写法:
"运行脚本检查依赖"
"用pandoc提取文本"
"合并PDF前验证页数"
错的写法:
"你应该运行脚本检查依赖"
"我们可以用pandoc提取文本"
"我建议验证页数"
原则7:避免重复
原文说:"信息要么放在SKILL.md,要么放在references文件里,不能两边都有。除非是技能核心内容,否则优先放references——这样既保持SKILL.md简洁,又让信息能被找到而不占用上下文。"
这跟"不要重复自己"是一个道理。信息只存一处,需要引用时说明去哪找。
04 创建技能的6个步骤
skill-creator的SKILL.md里明确给出了6个步骤:
步骤1:理解具体用例
问自己几个问题:这个技能要支持什么功能?用户会怎么用?能给几个使用例子吗?
比如要建一个图片编辑技能,用例可能是:
"移除这张图片的红眼"
"把图片旋转90度"
"调整图片亮度"
步骤2:规划可复用的内容
针对每个用例,想想要从零开始做需要什么,哪些可以写成脚本、整理成参考资料。
比如PDF处理技能:
用例"帮我旋转这个PDF" → 脚本rotate_pdf.py
用例"今天多少用户登录" → 参考资料schema.md
步骤3:初始化
用官方脚本创建技能骨架:
python scripts/init_skill.py <技能名> --path <输出目录>这个脚本会创建目录、生成带模板的SKILL.md、建好scripts/、references/、assets/文件夹。
步骤4:编辑
记住:这个技能是给另一个AI实例用的。只放对那个AI有用的信息,放它不知道的东西。
新增的脚本要实际跑过测试,确保没bug、输出符合预期。
步骤5:打包
开发完成后打包成可分发的.skill文件:
python scripts/package_skill.py <技能文件夹路径>打包脚本会验证YAML格式、命名规范、目录结构、描述完整性,最后生成.skill文件。
步骤6:迭代优化
真实用一段时间,留意哪里不好用、哪里效率低,然后回来改。
05 Agent Skills开放标准
这些技能不是Claude Code独家的。Anthropic最初开发了这套标准,现在已经被多个工具采用:OpenCode、Claude Code、Cursor、GitHub Copilot、Ampcode、trae等。标准很简单:
目录结构:
技能名/
└── SKILL.md # 必需可选目录:
scripts/ - 可执行代码
references/ - 参考文档
assets/ - 静态资源
SKILL.md格式:
---
name: 技能名 # 必需,1-64字符
description: 技能做什么 # 必需,1-1024字符
license: MIT # 可选
compatibility: 兼容性要求 # 可选
metadata: # 可选
author: 作者名
version: "1.0"
---
# 正文存放位置有两种:
项目级:.opencode/skills/技能名/SKILL.md
全局:~/.config/opencode/skills/技能名/SKILL.md
06 完整示例:一个文档处理技能
基于上面的原则,下面是一个处理Word文档的技能例子。
目录结构
docx-processor/
├── SKILL.md
├── scripts/
│ ├── extract_text.py
│ ├── add_toc.py
│ └── convert_format.py
├── references/
│ ├── ooxml-reference.md
│ └── formatting-guide.md
└── assets/
└── letterhead-template.docxSKILL.md
---
name: docx-processor
description: |
全面的Word文档(.docx)处理能力,包括文本提取、目录生成、格式转换。
当用户需要处理Word文档、创建报告、转换格式或提取内容时使用。
触发场景:
- 提到"Word文档"、".docx"
- 请求创建报告、备忘录
- 需要目录、页码、页眉页脚
- 提取或重组文档内容
license: MIT
metadata:
author: your-name
version: "1.0"
---DOCX处理器
快速参考
| 任务 | 方法 |
|---|---|
| 提取文本 | python scripts/extract_text.py 文档.docx |
| 添加目录 | python scripts/add_toc.py 文档.docx |
| 转PDF | python scripts/convert_format.py 输入.docx 输出.pdf |
详细指南
提取文档内容
python scripts/extract_text.py 文档.docx输出保存为文档.txt。
添加目录
python scripts/add_toc.py 文档.docx脚本步骤:
扫描文档中的标题
生成目录结构
插入文档开头
输出文件:文档-with-toc.docx
格式转换
python scripts/convert_format.py 输入.docx 输出.pdf支持格式:docx → pdf、txt、html
使用信纸模板
from docx import Document
doc = Document('assets/letterhead-template.docx')
doc.add_paragraph('正文内容...')
doc.save('output.docx')高级功能
修订跟踪:见references/formatting-guide.md
OOXML细节:见references/ooxml-reference.md
scripts/extract_text.py
#!/usr/bin/env python3
"""
提取Word文档中的文本
用法:python extract_text.py <文档.docx>
"""
import sys
from docx import Document
def extract_text(docx_path):
doc = Document(docx_path)
paragraphs = [para.text for para in doc.paragraphs if para.text.strip()]
return '\n\n'.join(paragraphs)
def main():
if len(sys.argv) != 2:
print('用法:python extract_text.py <文档.docx>')
sys.exit(1)
docx_path = sys.argv[1]
try:
text = extract_text(docx_path)
output_path = docx_path.replace('.docx', '.txt')
with open(output_path, 'w', encoding='utf-8') as f:
f.write(text)
print(f'文本已提取:{output_path}')
except Exception as e:
print(f'错误:{e}')
sys.exit(1)
if __name__ == '__main__':
main()scripts/add_toc.py
#!/usr/bin/env python3
"""
为Word文档添加目录
用法:python add_toc.py <文档.docx>
"""
import sys
from docx import Document
def add_table_of_contents(docx_path):
doc = Document(docx_path)
# 在开头插入目录标题
first_para = doc.paragraphs[0]
toc_title = first_para.insert_paragraph_before('目录')
toc_title.style = 'Heading 1'
# 收集标题并生成目录项
prev_para = toc_title
for para in doc.paragraphs:
if para.style.name.startswith('Heading'):
level = int(para.style.name.replace('Heading ', ''))
indent = ' ' * (level - 1)
text = para.text.strip()
if text:
toc_item = prev_para.insert_paragraph_before(f'{indent}{text}')
prev_para = toc_item
# 保存
output_path = docx_path.replace('.docx', '-with-toc.docx')
doc.save(output_path)
return output_path
def main():
if len(sys.argv) != 2:
print('用法:python add_toc.py <文档.docx>')
sys.exit(1)
docx_path = sys.argv[1]
try:
output_path = add_table_of_contents(docx_path)
print(f'目录已添加:{output_path}')
except Exception as e:
print(f'错误:{e}')
sys.exit(1)
if __name__ == '__main__':
main()写在最后
写Skill其实不复杂,记住几条原则就行:
短:能用一句话说完的别用三段
准:description要说清楚什么时候用
分:详细内容放references,核心指令留SKILL.md
试:脚本要实际跑过,确定能用
13,000多个技能,你不需要全装。但如果你想自己写一个,这套方法论能帮你写出让AI真正好用的技能。
本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!