最近在做复杂度蛮高的 skill 设计工作。看到阿里云这篇文档,发现其中提到的问题和优化思路,与我在实践中遇到的颇为相似。
链接:https://mp.weixin.qq.com/s/FgGVPw0BOZEu5sH1FdrVoQ
Skill 学习笔记
一、Skill 的基本结构与各部分用处
一个 Skill 本质上是一个文件夹,最简情况只需一个 SKILL.md,复杂时可扩展出 scripts/、references/、assets/ 三个子目录。
1.1 整体目录结构
1 | my-awesome-skill/ |
1.2 SKILL.md = YAML 头 + Markdown 正文
| 部分 | 作用 | 关键点 |
|---|---|---|
| YAML frontmatter | Skill 的”封面” + 触发元数据 | 决定 是否被加载 |
| Markdown 正文 | 给 Agent 的”操作手册” | 决定 加载后怎么执行 |
| scripts/ | 不加载到上下文就能直接执行的脚本 | 决定 确定性能力 |
| references/ | 详细文档,按需读取 | 决定 上下文经济性 |
| assets/ | 模板、配置文件等静态资源 | 决定 可复用素材 |
1.3 YAML 头部字段速查
| 字段 | 是否必需 | 用处 |
|---|---|---|
name |
✅ 必需 | 唯一标识符,≤64 字符,仅小写字母/数字/连字符 |
description |
✅ 必需 | Agent 判断是否触发的核心依据,≤1024 字符 |
1.4 Markdown 正文的五段式结构
| 段 | 内容 | 用处 |
|---|---|---|
| 1. 快速开始 / 使用示例 | 1–2 个典型用户输入 | 让 Agent 秒懂使用场景 |
| 2. 参数列表 | 表格列出参数名、是否必需、默认值、说明 | 提供清晰的输入契约 |
| 3. 工作流 / 执行步骤 | 分步骤描述 Agent 怎么做(核心) | 提供确定性执行路径 |
| 4. 错误处理 | 常见错误场景及处理方式 | 提供异常兜底 |
| 5. 附加资源引用 | 何时、如何使用 scripts/ 和 references/ | 提供资源调度逻辑 |
1.5 Skill 的三级渐进式加载机制)
Skill 不是一次性全塞给 Agent 的,而是按需读取:
- L1(始终加载):所有已安装 Skill 的
name + description—— 用于触发判定 - L2(触发后加载):被命中 Skill 的 SKILL.md 正文 —— 用于执行
- L3(按需加载):references/ 中的详细文档、scripts/ 中的脚本 —— 仅在执行步骤明确指出时才读取
二、写法(写作原则与技巧)
2.1 创作前:四步思考的逆向顺序
1 | ① 触发时机 → ② 输入与输出 → ③ 大致流程(3–7 步骨架) → ④ 细节与规则 |
2.2 四条核心写作原则
| 原则 | 正例 ✅ | 反例 ❌ | 为什么有效 |
|---|---|---|---|
| 用祈使句 | 从用户输入中提取 webhook_url 参数 | Agent 应该从用户输入中提取参数 | 动词开头直接命中 LLM 的指令跟随回路;不给模型”可做可不做”的弹性,规则即命令 |
| 解释「为什么」 | 使用 –headed 模式,因为会议室平台会检测 headless | MUST use –headed mode | 把”判断依据”显式注入给 Agent,使其在边缘场景能自主推理而不是死守规则 |
| 控制篇幅 | 正文 ≤ 500 行,超出拆到 references/ | 把所有细节都堆进正文 | 正文属于 L2 触发后必加载层,越长越吃上下文;references/ 是 L3 按需加载,只在相关场景才读 |
| 保持通用性 | 用理论/原则指导 | 硬编码具体平台或特例 | 原则比特例覆盖面大得多,能让 Agent 在新场景下推广使用;避免 Skill 与某个平台/版本/工具强绑定,跨平台迁移时改动最小,生命周期更长 |
2.3 description 的写法(决定可用性)
description 是 Skill 触发的唯一入口,写法直接决定 Skill 能不能被用上。
| 写法 | 问题 |
|---|---|
❌ 帮助用户处理工单 |
太笼统,Agent 不知道何时触发 |
✅ 工单批量预处理技能。当用户提到"处理所有工单"、"排查所有工单"、"批量处理工单"、"我的工单有多少"、"帮我看看工单"时,立即触发此技能。 |
关键词丰富,触发场景明确 |
核心心法:Agent 倾向”少触发”而非”多触发”,所以 description 要写得积极一些,多列举触发关键词与场景。
2.4 脚本编写的四条建议
- 零依赖优先:脚本尽量用语言标准库
- 多语言 fallback:Python → Node.js → Shell 降级
- 结构化输出:脚本输出 JSON 到 stdout,方便解析
- 明确退出码:成功 0,失败非 0
三、什么时候拆分?拆到哪里?
这是把一个能用的 Skill 升级成可维护 Skill 的关键决策。
3.1 拆分的三个核心信号
| 信号 | 含义 | 行动 |
|---|---|---|
| 正文 > 500 行 | 上下文成本过高 | 拆到 references/ |
| 某段逻辑要求精确执行 | LLM 复述容易出错 | 拆到 scripts/ |
| 支持多个变体 | 不同框架/平台/语言并存 | 拆到 references/<variant>/ |
3.2 拆到 references/:篇幅与变体管理
触发场景:
- 正文超过 500 行
- 一段详细说明只有少数场景才用得到(比如某个错误码的深度排查)
- Skill 要支持多个变体(不同框架、平台、语言)
目录组织模式(按变体):
1 | cloud-deploy/ |
正文里只写”如果用户用 AWS,读 references/aws.md”——Agent 只读相关文件,避免无关信息占用上下文。
3.3 拆到 scripts/:确定性下沉
触发场景:
- 操作必须精确执行(签名、加密、格式转换)
- 操作跨平台一致性要求高(不能依赖 LLM 在不同平台复述)
- 操作有副作用(写文件、调 API、改数据库)
关键优势:scripts/ 下的脚本不需要加载到上下文就能直接执行——既省 token 又保证准确性。
3.4 拆到 assets/:静态资源
触发场景:
- 有可复用模板(邮件模板、PR 模板、配置文件)
- 有静态素材(图标、字体、demo 数据)
- 资源在多个步骤中被引用
3.5 拆分决策速查表
| 你想表达的东西 | 应该放在 |
|---|---|
| Skill 的核心工作流(3–7 步骨架) | SKILL.md 正文 |
| 触发关键词与场景 | description 字段 |
| 边界情况、深度排查、变体说明 | references/*.md |
| 必须精确执行的逻辑 | scripts/*.py |
| 模板、配置、demo 数据 | assets/ |
| 平台特定语法 | HTML 注释 <!-- platform: xxx --> |
3.6 拆分时的常见错误
- ❌ 正文塞太多:把所有错误码、所有变体说明都堆进 SKILL.md,导致正文 800+ 行,触发后上下文被吃光
- ❌ 该用脚本却用 prompt:让 LLM”用某算法计算签名”——跨平台、跨模型行为不一致
- ❌ 拆得太碎:把 50 行的简单内容拆到 references/,反而增加 Agent 调度开销。经验值:单文件 < 100 行的内容不必拆
- ❌ references/ 不命名清楚:导致 Agent 不知道何时该读哪个文件——文件名应明确表达变体或场景
四、一份可复用的写作 Checklist
每写完一个 Skill,按下面九条逐项检查:
- ✅ description 是否列出了 ≥ 5 个触发关键词/场景?
- ✅ 是否做完了”四步思考”,没有跳过 ①②?
- ✅ 工作流步骤是否每条都用祈使句开头?
- ✅ 关键约束是否每条都跟着”因为……”?
- ✅ 正文是否 ≤ 500 行?超出的部分是否拆到 references/?
- ✅ 必须确定执行的逻辑是否下沉到 scripts/?
- ✅ 是否避免了平台特定语法(@、/、!)和硬编码路径?
- ✅ 是否在 ≥ 2 个目标平台跑过冒烟测试,输出一致?
- ✅ description 中是否做了”中性化”,避免出现具体平台名(除非 Skill 本就只服务该平台)?
五、一图记住核心心智模型
1 | ┌─────────────────────────────────────────────────────┐ |