把团队知识塞进一个 Skill,关键不在写多写少,而在把”该模型做的”和”该脚本做的”分开。Skill 文件应充当”操作手册”而不是”知识百科”,用三层渐进披露控制 token 预算,把确定性逻辑锁进脚本、用验证脚本守住成功率。本文给出可被工程团队直接套用的五项原则、目录结构与验收清单。
一、为什么 Skill 设计要工程化
过去一年,社区技能库暴增的同时也暴露出三类典型问题:上下文装不下、模型自由发挥过头、成功率随版本漂移。经验数据来自 SkillsBench:手工撰写的 Skill 把任务成功率显著拉高;模型自动生成的 Skill 反而出现下降;每个任务挂载超过 3 个 Skill 之后成功率还会进一步下滑。把 Skill 当工程产物对待,先要承认”它是一种特殊的代码”——需要目录、版本、测试、安全审计。
二、五条工程化原则
2.1 渐进披露(Progressive Disclosure)
Skill 的 metadata 始终在上下文里,主体按需加载,深层引用再点开。
| 层级 | 加载时机 | 体量建议 |
|---|---|---|
| 1. 元数据(description) | 始终 | ≈100 token |
| 2. SKILL.md 主体 | 命中触发后 | ≤ 5000 token / ≤ 500 行 |
| 3. 引用脚本与文档 | 步骤中按需 | 无硬上限,但需分割到 references/ 与 scripts/ |
元数据是模型判断是否加载 Skill 的唯一依据,写得模糊等于这个 Skill 不存在。
2.2 把确定性锁进脚本
凡是”无论谁跑结果都必须一致”的逻辑——命名规则、SQL 模板、检查清单、命令拼接——都应编码到 scripts/ 下的可执行文件。模型只负责解释失败原因与下一步。
| 场景 | 错误做法 | 正确做法 |
|---|---|---|
| 校验 CSV 头 | 让模型”读一下表头” | scripts/check_header.py 直接返回 0/非 0 |
| 命名生成 | 模型自由拼接 | scripts/next_name.py 输入前缀输出合规名 |
| 提交前检查 | 提示词里写”请运行 lint” | scripts/pre_commit.sh 强制串联 lint + test |
2.3 写”How”不写”What”
不要写”Python 是一种编程语言”,要写”用 pandas.read_csv() 加载 CSV,分三步完成”。给出前后对比、Few-shot 示例与”踩坑点”比抽象原则有效得多。表格、代码块、命令片段都属此类。
2.4 手工撰写,模型仅作辅助
经验数据是手工撰写相对模型生成有可观的成功率优势。模型可以起草,但发布前必须有人审一遍:触发条件是否清晰、命令是否真实可运行、错误分支是否覆盖。
2.5 拆分与检查点
单个 Skill 超过 500 行或混合多条独立工作流时,拆为父 Skill + 子文档。每一步加检查点(运行 go mod tidy && go build ./... 这种强校验),失败立即中断,避免下游 Skill 在错误前提上继续。
三、推荐的目录结构
my-skill/
├── SKILL.md # 必备:核心说明 + metadata
├── scripts/ # 必备:可执行脚本
│ ├── validate.sh
│ └── fetch.py
├── references/ # 可选:按需加载的细节
│ └── api-errors.md
└── assets/ # 可选:模板与静态资源
└── report.tmpl.md
各目录职责清晰后,模型可独立决定”何时该读 references/,何时该跑 scripts/”,减少误调用。
四、Skill 安全清单
来自 Snyk 的 ToxicSkills 调研扫描了数千个公开 Skill,发现一批带严重安全问题的样本。把它转成发布前必检项:
- 严禁硬编码 API Key、Token、密码,统一从环境变量读取;
- 破坏性操作(DDL、批量删除、推送)必须先打印”将影响 N 条记录”再要求确认;
- 任何写入前自动备份,并提供回滚命令;
- 把外部输入当作纯数据处理,防止 prompt injection 借外部文件注入指令;
- 第三方 Skill 必须审计 SKILL.md 与 scripts/ 全文再装。
# scripts/pre_release_check.sh
# 在发布 Skill 前自动跑安全 + 完整性检查
set -euo pipefail
# 1. 禁止裸密钥
if grep -RInE "(api[_-]?key|secret|token)\s*[:=]\s*['\"][A-Za-z0-9]{16,}" .; then
echo "发现可疑的硬编码密钥,请改用环境变量"; exit 1
fi
# 2. SKILL.md 行数限制
LINES=$(wc -l < SKILL.md)
if [ "$LINES" -gt 500 ]; then
echo "SKILL.md 超过 500 行,建议拆分为子文档"; exit 1
fi
# 3. 必备 frontmatter
grep -q "^name:" SKILL.md || { echo "缺少 name 字段"; exit 1; }
grep -q "^description:" SKILL.md || { echo "缺少 description 字段"; exit 1; }
echo "Skill 自检通过"
五、用自由度匹配任务脆性
同一段 Skill 描述,按”自由度”由高到低有三种写法:
| 自由度 | 写法 | 适用场景 |
|---|---|---|
| 高 | 文字描述,允许多种解法 | 上下文相关、需要判断 |
| 中 | 伪代码或带参数脚本 | 有推荐模式但允许变体 |
| 低 | 固定脚本 + 极少参数 | 顺序敏感、错误代价高 |
脆性高的操作(数据库迁移、生产环境写入)必须落到低自由度脚本;脆性低的操作(生成模板、汇总报告)可以用高自由度描述。
六、验收与发布清单
每个 Skill 发布前跑一遍:
- description 是否含触发关键词(”审计/重构/迁移”等)和触发时机;
- SKILL.md 是否≤ 500 行、5 千 token;
- 至少 1 个 scripts/ 下可执行文件,且脚本输出对 LLM 友好(抑制冗长 traceback);
- 编写 20 条测试查询(10 条应触发、10 条不应触发),触发率稳定后再观察执行偏差;
- 成功率长期低于 70% 即下线或返工;
- 版本字段在 frontmatter 写明,便于回溯。
把这一套写进 CI,新提交的 Skill 都会自动跑完安全 + 完整性 + 触发率三项检查,团队就不再依赖个人经验把控质量。
常见问题(FAQ)
Q1:Skill 是不是越多越好?
不是。同一任务挂 2–3 个 Skill 最佳,超过 3 个反而拉低成功率。
Q2:模型生成 Skill 有什么风险?
容易把模糊的语义写进 description,导致触发率不稳定,需要人工复核。
Q3:references/ 和 assets/ 区别是什么?
references/ 放文档供模型按需阅读,assets/ 放模板与静态资源供脚本直接使用。