编写原则
保持精简
Skill 和系统提示、对话历史、其他 Skill 的元数据共用同一个上下文窗口。默认 Agent 已经很能干,只写它不知道的东西:你们团队的约定、容易出错的步骤、特定格式的细节。对每段内容问一句:“没有这段,Agent 会做错吗?”
多用简短的示例,少用长篇解释。正文用祈使句,直接写“做什么”。
按任务的脆弱程度决定写多细
| 任务特点 | 写法 |
|---|---|
| 多种做法都可以,取决于上下文 | 文字指引,给原则和判断依据 |
| 有推荐做法,允许一些变化 | 伪代码或带参数的脚本 |
| 操作脆弱、必须严格按顺序 | 写成脚本放进 scripts/,参数尽量少 |
拆分内容
SKILL.md只放核心流程和选择指引,建议控制在 500 行以内;- 细节、多种变体(不同平台、不同框架)分别放进参考文档,正文里写清楚“什么情况读哪个文件”;
- 参考文档只从
SKILL.md引用一层,不要让参考文档再层层引用; - 超过 100 行的参考文档,在开头放一个目录;
- 同一条信息只放一处,要么在
SKILL.md,要么在参考文档; - 正文多主题、每次只用其中一部分时,改用 Progressive 结构。
编写流程
- 收集几个真实的使用场景:用户会怎么说、期望得到什么;
- 针对每个场景,找出可复用的部分:反复要写的代码放
scripts/,反复要查的资料放参考文档,反复要用的模板放assets/; - 写
SKILL.md:先写好name和description,再写正文; - 实际运行脚本,确认没有错误;
- 用安装器安装一遍,确认能通过预览;
- 在真实任务里使用,根据卡住或走弯路的地方迭代。
也可以直接让 StablEdge 帮忙:内置的 skill-creator Skill 提供了创建 Skill 的流程指引。
示例一:最小 Skill
只有一个 SKILL.md,适合一套简短的固定流程。
release-notes/
└── SKILL.md
release-notes/SKILL.md:
---
name: release-notes
description: "整理版本更新说明时使用:把提交记录归类为新增、优化、修复三段并写成面向用户的说明。触发词:更新说明、发版说明、更新日志、changelog。不用于撰写营销文案。"
version: "1.0"
metadata:
category: "写作"
tags: "发版,文档"
---
# 版本更新说明
1. 读取用户提供的提交列表或变更说明;没有提供时先询问版本号和范围。
2. 去掉纯内部改动(重构、测试、构建脚本),除非它影响用户。
3. 按三段输出,每段内按影响从大到小排序:
- **新增**:用户能用上的新能力;
- **优化**:已有功能变得更快、更稳或更好用;
- **修复**:用户能感知到的问题被修好。
4. 每条一句话,以用户视角描述结果,不写内部模块名。
5. 某一段没有内容时省略该段。
示例二:Progressive Skill
一个带参考文档、模板和脚本的 Progressive Skill,用来按团队规范生成周报。
weekly-report/
├── SKILL.md
├── references/
│ └── style-guide.md
├── assets/
│ └── report-template.md
└── scripts/
└── collect_stats.py
weekly-report/SKILL.md:
---
name: weekly-report
description: "按团队规范撰写周报时使用:汇总本周完成事项、数据和下周计划,输出统一格式的 Markdown 周报。触发词:周报、工作周报、本周总结、weekly report。不用于月报、季度总结。"
version: "1.0"
progressive:
always:
- rules
resources:
- path: references/style-guide.md
role: reference
- path: assets/report-template.md
role: template
- path: scripts/collect_stats.py
role: executable
---
# 周报
## 必须遵守 {#rules}
- 周报只写事实和数据,不写形容词堆砌的总结。
- 每个事项都要有负责人和状态(已完成 / 进行中 / 阻塞)。
- 输出前对照模板检查章节是否齐全。
## 生成流程 {#workflow}
1. 用 `skill(action='copy_file', skill_name='weekly-report', path='assets/report-template.md', dest='weekly-report.md')` 把模板复制到工作区。
2. 需要统计数据时,读取 `scripts-usage` 章节运行统计脚本。
3. 按模板逐节填写,措辞要求见 `style` 章节。
### 统计脚本 {#scripts-usage}
用 `skill(action='run_script', skill_name='weekly-report', path='scripts/collect_stats.py', argv=['tasks.csv'])` 运行,
参数是工作区内的任务导出文件。脚本把统计结果以 JSON 输出到标准输出。
## 措辞规范 {#style}
完整规范在 `references/style-guide.md`,用 `skill(action='read_file', skill_name='weekly-report', path='references/style-guide.md')` 读取。
要点:
- 用主动语态;
- 数字保留到整数,百分比保留一位小数。
weekly-report/scripts/collect_stats.py:
import csv
import json
import sys
def main() -> int:
if len(sys.argv) != 2:
print("用法:collect_stats.py <tasks.csv>", file=sys.stderr)
return 2
counts: dict[str, int] = {}
with open(sys.argv[1], encoding="utf-8", newline="") as handle:
for row in csv.DictReader(handle):
status = (row.get("status") or "unknown").strip()
counts[status] = counts.get(status, 0) + 1
print(json.dumps({"total": sum(counts.values()), "by_status": counts}, ensure_ascii=False))
return 0
if __name__ == "__main__":
sys.exit(main())
references/style-guide.md 和 assets/report-template.md 按团队实际规范编写即可。加载这个 Skill 时,Agent 先看到的封面是:读取章节的提示、附带文件清单(带角色)、rules 章节全文,以及下面这份自动生成的章节索引:
## 可按需读取的章节
- `rules` — 必须遵守
- `workflow` — 生成流程
- `scripts-usage` — 统计脚本
- `style` — 措辞规范
脚本以相对工作区的路径读取 tasks.csv,因为宿主运行脚本时的工作目录就是当前工作区。
常见错误
| 现象 | 原因 | 解决 |
|---|---|---|
| Skill 没有出现在列表里,诊断为缺少 frontmatter | 文件带 BOM,或第一行不是 --- | 用无 BOM 的 UTF-8 保存,第一个字符必须是 --- |
| 诊断为 frontmatter 不是合法 YAML | description 没加引号,里面又有特殊字符 | 给 description 加双引号 |
| 诊断为字段不合法 | name 含不允许的字符;metadata 的值不是字符串(如 tags 写成了列表) | 按命名规则修改;tags 用逗号分隔的字符串 |
| 自己的 Skill 被忽略 | 与内置 Skill 或另一个已安装 Skill 同名 | 换一个名字 |
| Skill 总是不被选中 | description 只写了做什么,没写触发词 | 补充用户真实会说的触发词,见 description 的写法 |
| Progressive Skill 加载后返回了整份正文 | 有标题缺少 {#id}、ID 重复,或 always / resources 引用了不存在的内容 | 按校验规则逐项修正 |
写了 resources 但没生效 | frontmatter 里没有 progressive | 加上 progressive: {} 或改用 Progressive 结构 |
| Agent 找不到正文里提到的文件 | 正文让 Agent 用普通文件工具去读,或写了绝对路径 | 写相对于 Skill 目录的路径,并提示用 skill 工具读取 |
run_script 报路径错误 | 脚本不在 scripts/ 目录下 | 把脚本移到 scripts/ |
run_script 报参数或超时超限 | 参数超过 64 项或单项超过 8 KB,超时超过 300 秒 | 改为让脚本读取工作区里的输入文件 |
| 安装预览报 Skill 有歧义 | 一个 Skill 目录下又嵌套了另一个 SKILL.md | 每个 Skill 单独一个目录,互不嵌套 |