SKILL.md完全指南:build-your-own-openclaw如何让AI Agent懒加载技能、动态扩展能力
SKILL.md完全指南:build-your-own-openclaw如何让AI Agent懒加载技能、动态扩展能力
build-your-own-openclaw 是一个从聊天循环到轻量版 OpenClaw 的 18 步实战教程,其中第 02 步就用一个名为 SKILL.md 的 Markdown 文件,让 AI Agent 实现了"懒加载技能"——平时只把技能的名称和简介放进上下文,真正需要时才加载完整内容。这正是大模型 Agent 节省 Token、动态扩展能力的核心技巧,也是当前 Agent Skills 开放标准的落地实践。本文带你彻底搞懂它的原理与写法。
📄 SKILL.md 是什么:一个"能力压缩包"
在 02-skills 步骤中,技能被定义为:运行时延迟加载的能力。每个技能就是一个文件夹,里面放一个 SKILL.md 文件,由两部分组成:
| 组成部分 | 格式 | 作用 |
|---|---|---|
| YAML 前言 | name + description |
技能"名片",常驻上下文,告诉 Agent 何时该用它 |
| Markdown 正文 | 自由指令文本 | 技能"说明书",仅在技能被触发后才加载 |
以项目自带的定时任务管理技能 cron-ops/SKILL.md 为例,它的开头是:
---
name: cron-ops
description: Create, list, and delete scheduled cron jobs
---
正文则教 Agent 如何创建、列出和删除定时任务:cron 表达式语法、一次性任务(one_off: true)、任务模板等。Agent 平时"只认识"这个技能的简介,直到你说"帮我建一个明早 9 点的提醒",它才会加载正文、照着做。
🚀 懒加载核心:三级渐进式披露
这套机制的设计精髓是渐进式披露(Progressive Disclosure),加载分为三级:
- 元数据(name + description)——始终在上下文中,仅约 100 词,成本极低
- SKILL.md 正文——技能被触发时才加载,建议控制在 5000 词以内
- 捆绑资源(scripts/references/assets)——按需加载,脚本甚至可以不读进上下文直接执行
这意味着你可以给 Agent 挂上百个技能,而上下文开销只是每个技能几行简介。上下文窗口是公共资源,技能越多越要克制——这是 skill-creator 技能 反复强调的第一原则。
🔍 实现走读:从扫描到按需加载
整个技能系统只用了三个关键文件,非常简洁:
1️⃣ 技能加载器 skill_loader.py
SkillLoader 扫描 skills/ 目录下的每个子文件夹,读取其中的 SKILL.md,解析出 SkillDef(含 id、name、description、content 四个字段)。解析逻辑复用了通用的 def_loader.py——扫描目录 → 提取 YAML 前言 → 回调解析函数,这套机制后来也被 Agent 定义、定时任务复用,是典型的"一处抽象、多处复用"。
2️⃣ 动态技能工具 skill_tool.py
这是懒加载的"魔术"所在。create_skill_tool 工厂函数会把所有技能的元数据拼成一段 XML,塞进工具自身的描述里:
skills_xml = "<skills>\n"
for meta in skill_metadata:
skills_xml += f' <skill name="{meta.name}">{meta.description}</skill>\n'
于是 Agent 看到的"skill"工具描述就自带了一份技能清单。当它判断用户意图匹配某个技能时,就调用这个工具传入技能名,工具才去磁盘读取并返回该技能的完整正文。技能名还用 enum 约束,防止 Agent 乱填不存在的技能。
3️⃣ 工具注册 agent.py
Agent 初始化时只需两行:SkillLoader.from_config(config) 创建加载器,registry.register(skill_tool) 注册工具。注意一个小细节:如果扫描不到任何技能,工具根本不会注册,保持工具表干净。
✍️ 如何写好一个 SKILL.md
项目内置的 skill-creator 技能 本身就是一份"教你造技能的技能",它给出的目录结构是标准最佳实践:
skill-name/
├── SKILL.md # 必需:YAML 前言 + Markdown 正文
└── 捆绑资源(可选)
├── scripts/ # 可执行脚本,可运行而不占上下文
├── references/ # 按需载入上下文的参考文档
└── assets/ # 用于输出的模板、字体等文件
几个实战要点:
- description 是触发机制。Agent 靠它决定"什么时候用这个技能",务必写清楚"做什么 + 什么场景触发",而不是只写功能名称
- "何时使用"信息必须放在前言里,正文在触发之后才加载,写在正文的"When to Use"对触发毫无帮助
- 正文保持精简,接近 500 行就该拆分成 references 文件,并在 SKILL.md 中说明"何时读哪个文件"
- 自由度过低的操作(如固定格式转换)用脚本兜底;灵活决策型任务用文字指导——skill-creator 称之为"匹配自由度与任务脆弱性"
想偷懒?skill-creator 自带脚手架脚本 init_skill.py,一条命令生成含 TODO 占位符的技能模板:
scripts/init_skill.py my-skill --path skills/public --resources scripts,references
🔄 动态扩展能力:新增技能无需改代码
这套架构最香的地方在于解耦:技能是纯数据(文件夹 + Markdown),不是代码。
- 新增技能:在
skills/下建个目录、写好SKILL.md,下次启动 Agent 时自动被发现,一行代码都不用改 - 让 Agent 自己造技能:教程演示中,直接对 Agent 说"创建一个天气查询技能",它会调用 skill-creator,生成新技能目录和文件——Agent 在运行时扩展了自己的能力
- 配合热重载:到 08-config-hot-reload 步骤,配置修改后即时生效,扩展链路进一步缩短
🧩 两种实现方式:工具注入 vs 系统提示注入
教程用了工具方式,但明确指出 OpenClaw 官方采用的是另一种做法:
| 工具方式(本教程) | 系统提示方式(OpenClaw) | |
|---|---|---|
| 元数据位置 | skill 工具的描述中 | 系统提示中 |
| 加载正文 | 调用 skill 工具 |
用 read 工具读 SKILL.md 文件 |
| 特点 | 逻辑集中、易理解 | 工具注册表更干净 |
两者殊途同归:元数据常驻、正文懒加载。想体验技能融入系统提示的形态,可继续看 13-multi-layer-prompts 步骤。
🏁 动手试一试
cd 02-skills
uv run my-bot chat
配置好 API 密钥后(参考 config.example.yaml),向 Agent 提问"你有哪些技能?",它会列出 cron-ops 和 skill-creator——注意此时它还没加载任何技能正文。接着让它"创建一个天气技能",亲眼见证懒加载与动态扩展的完整闭环。
📚 关键文件速查
| 文件 | 说明 |
|---|---|
| 02-skills/README.zh.md | 步骤 02 官方教程,含完整设计决策 |
| 02-skills/src/mybot/core/skill_loader.py | 技能扫描与加载 |
| 02-skills/src/mybot/tools/skill_tool.py | 动态 skill 工具工厂 |
| default_workspace/skills/cron-ops/SKILL.md | 实战技能示例 |
| default_workspace/skills/skill-creator/SKILL.md | 技能编写方法论 |
掌握 SKILL.md 这套"懒加载 + 渐进披露"模式,你就掌握了 AI Agent 规模化扩展能力的钥匙——技能可以无限叠加,而上下文永远轻盈。
