第 5 章 编写你的第一个 Skill(技能)
🛠️ 本章特色:在第 4 章学会了安装和使用社区技能之后,本章轮到你动手创造了。我们将从零开始编写一个最简单的 Skill,逐步掌握目录结构、元数据规范、工具调用和脚本集成,最终完成一个可以发布到社区的完整技能模块。
本章目录:
| 节 | 内容 | 你将学到 |
|---|---|---|
| 1 | 为什么需要 Skill | Skill 的本质、它解决的三个核心问题 |
| 2 | 创建 Skill 目录 | 标准目录结构、文件组织规范 |
| 3 | 编写 SKILL.md | YAML Frontmatter 规范、字段说明、命名规则 |
| 4 | 理解 Skill 如何工作 | 工具调用机制、脚本集成、依赖声明 |
| 5 | 加载与测试 | 让 OpenClaw 识别新 Skill、验证触发条件 |
| 6 | 进阶:带脚本的 Skill | 一个完整的时间查询技能实例 |
| 7 | 总结与进阶 | 最佳实践、加载优先级、课后练习 |
1. 为什么需要 Skill
1.1 从"能聊天"到"能做事"
在第 4 章中,我们学习了如何安装社区提供的技能。但你可能会想:如果社区里没有我需要的技能怎么办?答案是:自己写一个。
Skill(技能,结构化的指令文件集合) 是 OpenClaw 中赋予智能体特定能力的基本构建单元。你可以把它理解为一份操作指南,告诉智能体:"当你面对某种情境时,应该怎么做。"无论是调用系统命令、访问网页,还是执行自定义脚本,Skill 都是连接用户意图与具体行为的桥梁。
设想这样一个场景:你希望智能体不仅能回答问题,还能主动完成任务。比如:
- 你说"帮我发一封邮件",智能体知道调用邮件工具
- 你问"今天北京天气怎么样",智能体知道去查天气 API
- 你要求"列出当前目录下的文件",智能体知道执行系统命令
但问题是,智能体本身并不知道这些工具的存在,也不知道什么时候该用什么。Skill 就是用来教它这些能力的。
1.2 Skill 描述的三件事
每个 Skill 都明确描述了三件事:
- 什么时候触发:什么样的用户请求会激活这个 Skill
- 用什么工具执行:调用内置工具还是外部脚本
- 怎么安全地做:有哪些注意事项和限制
通过 Skill,我们把人类的自然语言意图转化为可执行、可复用、可共享的行为模块。
简单来说:Skill 就是用自然语言写成的"操作手册",教智能体在特定场景下如何行动。它不需要你精通编程语言,但需要你清晰地表达"做什么"和"怎么做"。
理解了 Skill 的本质,接下来动手创建你的第一个技能。
2. 创建 Skill 目录
2.1 Skill 的存放位置
OpenClaw 的 Skill 默认存放在工作区的 skills/ 目录下。首先,为你的新 Skill 创建一个文件夹:
mkdir -p skills/hello-world
这条命令会在当前工作区下创建 skills/hello-world/ 目录。对于初学者来说,放在工作区是最直观的选择,修改后重新对话就能立即生效,不需要重启服务。
2.2 标准目录结构
根据规范,一个完整的 Skill 目录结构如下:
hello-world/
├── SKILL.md # 必需:元数据 + 使用说明
├── scripts/ # 可选:可执行脚本(Python、Bash、JS 等)
├── references/ # 可选:补充参考文档
├── assets/ # 可选:模板、图标、配置文件等资源
└── ... # 其他辅助文件
┌──────────────────────────────────────────────────────┐
│ Skill 目录结构说明 │
│ │
│ SKILL.md(必需) │
│ ├── YAML Frontmatter → 元数据(名称、描述、依赖) │
│ └── Markdown 正文 → 触发条件、执行方式、注意事项 │
│ │
│ scripts/(可选) │
│ └── 可执行脚本,被 SKILL.md 正文引用 │
│ │
│ references/(可选) │
│ └── 补充文档,如 API 说明、使用示例 │
│ │
│ assets/(可选) │
│ └── 模板文件、配置模板、图标等资源 │
└──────────────────────────────────────────────────────┘
对于入门示例,我们只需要 SKILL.md 这一个文件就够了。随着技能变复杂,再逐步添加 scripts/ 和其他目录。
目录创建好后,接下来编写核心文件 SKILL.md。
3. 编写 SKILL.md
每个 Skill 的核心是 SKILL.md,它由两部分组成:
- YAML Frontmatter(文件头元数据):定义名称、描述、依赖等机器可读的信息
- Markdown 正文:用自然语言告诉智能体应该怎么做
3.1 第一个 SKILL.md 示例
下面是我们为"打招呼"功能编写的示例:
---
name: hello-world
description: 当用户请求问候或打招呼时,返回友好的问候语。
---
## 触发条件
当用户发出问候类请求时使用此技能,例如:"你好"、"早上好"、"say hello"、"打个招呼"等。
## 执行方式
无需调用外部工具,直接回复以下内容:
> 你好!我是大白,随时为你服务!🤖
如果用户要求用特定语言问候(如英语、日语),可以用对应语言回复,保持友好热情的语气。
注意两点:
- YAML 元数据必须被两行
---包围,这是标准的 Markdown Frontmatter 语法 description字段要简明扼要(不超过 160 字符),它会出现在系统提示词中,直接影响大模型是否选择这个 Skill
3.2 关键字段规范
OpenClaw 对 SKILL.md 的 Frontmatter 有明确的格式要求:
| 字段 | 是否必需 | 说明 |
|---|---|---|
name |
是 | 1 到 64 字符;仅允许小写字母、数字和连字符(-);不能以 - 开头或结尾;不能有连续连字符(--);应与父目录名完全一致 |
description |
是 | 1 到 160 字符;清晰说明功能与触发场景,建议包含关键词 |
license |
否 | 许可证标识,如 MIT、Apache-2.0 |
metadata.openclaw.requires |
否 | 声明运行时依赖(环境变量、二进制工具、配置项),不满足时自动跳过加载 |
3.3 命名规范
name 字段的命名有严格限制,以下用具体示例说明:
| 示例 | 是否合法 | 原因 |
|---|---|---|
zhz-photo2video |
✅ 合法 | 全小写,连字符分隔 |
hello-world |
✅ 合法 | 符合所有规则 |
PDF-Processing |
❌ 不合法 | 含大写字母 |
-pdf |
❌ 不合法 | 以连字符开头 |
pdf- |
❌ 不合法 | 以连字符结尾 |
my--tool |
❌ 不合法 | 连续连字符 |
My Tool |
❌ 不合法 | 含空格和大写字母 |
我们的 hello-world 完全符合规范:全小写、无非法字符、与目录名一致。
写好 SKILL.md 之后,接下来理解它在系统中是如何被执行的。
4. 理解 Skill 如何工作
4.1 Skill 与工具的关系
Skill 本身不直接执行代码,而是指导智能体调用合适的工具。OpenClaw 内置了多种工具:
| 工具名称 | 功能 | 典型场景 |
|---|---|---|
exec |
执行系统命令 | 运行脚本、安装软件包 |
read |
读取文件内容 | 查看配置文件、读取日志 |
write |
写入文件 | 生成报告、保存数据 |
web_fetch |
抓取网页内容 | 提取文章正文、下载文件 |
web_search |
搜索互联网信息 | 查找技术文档、搜索新闻 |
message |
发送消息到渠道 | 推送通知、回复用户 |
在"Hello World"示例中,我们没有使用任何工具,只是让智能体直接输出固定文本。这种"无工具"模式适用于纯对话响应。
4.2 声明运行时依赖
如果你的 Skill 需要执行更复杂的操作,可以调用脚本,并在 Frontmatter 中声明依赖。例如,一个天气查询 Skill 可能会这样声明:
---
name: weather-check
description: 查询指定城市的实时天气。
metadata:
openclaw:
requires:
bins: ["curl"]
env: ["WEATHER_API_KEY"]
---
这里声明了两个依赖:
- bins:系统需要有
curl命令 - env:需要配置
WEATHER_API_KEY环境变量
如果其中任何一个不满足,OpenClaw 就不会加载这个 Skill,而是自动跳过。这种机制保证了 Skill 不会因为缺少依赖而在运行时出错。
4.3 脚本文件引用
脚本文件放在 scripts/ 目录下,在 SKILL.md 正文中用相对路径引用即可:
## 执行方式
运行脚本 `scripts/weather.sh <城市名>`,将返回的 JSON 结果解析为用户可读的天气报告。
脚本语言选择建议:如果需要跨平台运行,推荐使用 Python 脚本(.py),因为 Python 在 Windows、macOS 和 Linux 上都能运行。Bash 脚本(.sh)在 Windows 上需要额外的兼容层(如 Git Bash 或 WSL),适用性受限。
理解了工作原理,接下来看看如何让 OpenClaw 识别并测试你的新 Skill。
5. 加载与测试
5.1 让 OpenClaw 识别新 Skill
编写完成后,如何让 OpenClaw 识别这个新 Skill?
最简单的方式:开启新的对话会话。 OpenClaw 在每个会话开始时会重新扫描可用的 Skills,所以只需要新建一个对话即可生效。不需要重启 Gateway 服务。
如果你在 Web 界面,可以直接发送斜杠命令 /new 开始新对话。
如果你在命令行,可以使用:
openclaw
5.2 验证 Skill 是否加载
要确认 Skill 是否被正确加载,有两种方法:
方法一:直接询问智能体。 在对话中问:"你有哪些可用的技能?"智能体会列出当前可用的 Skills 清单,确认 hello-world 是否在其中。
方法二:查看加载列表。 命令行执行 openclaw skills list 直接查看已加载列表”
5.3 测试触发条件
现在,向智能体发送一条可能触发该 Skill 的消息。
命令行方式(需要指定 agent 名称,默认为 main):
openclaw agent --agent main --message "give me a greeting"
预期输出为:
你好!我是大白,随时为你服务!🤖
聊天界面方式:在 Dashboard 或聊天界面中,输入以下任意内容测试触发:
| 测试输入 | 预期结果 | 目的 |
|---|---|---|
| "你好" | 返回问候语 | 验证中文触发 |
| "打个招呼" | 返回问候语 | 验证间接表达触发 |
| "say hello" | 返回问候语 | 验证英文触发 |
| "今天天气怎么样" | 不触发此 Skill | 验证不误触发 |
多测试几种说法,确认 Skill 能被正确触发。同时也测试不该触发的场景,确保不会误触发。如果 Skill 没有被触发,检查 description 字段是否足够清晰地描述了触发场景。
测试通过后,接下来看一个更实用的带脚本的 Skill 示例。
6. 进阶:带脚本的 Skill
6.1 一个完整的时间查询技能
纯文本回复的 Skill 比较简单,下面我们来看一个实际调用脚本的例子。假设你想做一个"获取当前时间"的 Skill。
目录结构:
skills/current-time/
├── SKILL.md
└── scripts/
└── get_time.py
脚本文件 scripts/get_time.py:
# 获取当前时间并格式化输出
from datetime import datetime
now = datetime.now()
print(f"当前时间:{now.strftime('%Y年%m月%d日 %H:%M:%S')}")
print(f"星期:{['一', '二', '三', '四', '五', '六', '日'][now.weekday()]}")
SKILL.md 文件:
---
name: current-time
description: 当用户询问当前时间、几点、日期时使用。
---
## 触发条件
用户询问当前时间、日期、几点钟、星期几时使用。
## 执行方式
执行脚本 `scripts/get_time.py`,将输出内容返回给用户。
使用以下命令运行:
python scripts/get_time.py
## 注意事项
- 脚本使用 Python 标准库,无需安装额外依赖
- 时间基于系统时钟,与设备所在时区一致
6.2 Skill 的典型工作模式
这个例子展示了 Skill 的典型工作模式:
┌──────────────────────────────────────────────────────┐
│ 带脚本 Skill 的工作流程 │
│ │
│ 用户:"现在几点了?" │
│ │ │
│ ▼ │
│ ① 大模型匹配 SKILL.md 的 description │
│ 确认触发 current-time 技能 │
│ │ │
│ ▼ │
│ ② 大模型阅读 SKILL.md 的执行方式 │
│ 确定需要运行 scripts/get_time.py │
│ │ │
│ ▼ │
│ ③ 智能体调用 exec 工具 │
│ 执行 python scripts/get_time.py │
│ │ │
│ ▼ │
│ ④ 获取脚本输出 │
│ "当前时间:2026年10月04日 11:16:00" │
│ "星期六" │
│ │ │
│ ▼ │
│ ⑤ 大模型整合输出,回复用户 │
│ "现在是 2026 年 10 月 4 日,星期六,上午 11:16。" │
└──────────────────────────────────────────────────────┘
简单来说:SKILL.md 负责告诉智能体"什么时候做、怎么做",scripts/ 目录存放具体的执行逻辑。两者配合,让智能体既能理解用户意图,又能执行实际操作。
掌握了带脚本的 Skill 编写,接下来了解一些工程实践方面的要点。
7. 总结与进阶
7.1 加载优先级机制
OpenClaw 支持多层级的 Skill 存放路径。当存在同名 Skill 时,高优先级路径中的版本会覆盖低优先级的版本:
| 存放路径 | 优先级 | 作用域 | 适用场景 |
|---|---|---|---|
<workspace>/skills/ |
最高 | 当前工作区所有会话 | 开发调试、个人定制 |
| 用户级 Skills 目录 | 中 | 本机所有工作区共享 | 跨项目通用技能 |
| 内置 Skills | 低 | OpenClaw 自带功能 | 系统基础能力 |
开发调试阶段使用工作区 skills/ 目录,修改后只需重开对话即可生效,非常方便。待技能稳定后,再考虑发布到社区或移到用户级目录。
7.2 最佳实践
编写高质量 Skill 的几条核心原则:
- 指令要具体,不要模糊:明确告诉模型"做什么",而不是"怎么做"。"直接回复'你好'"比"请友好地回应"更可靠
- description 是关键:这个字段出现在系统提示词中,直接决定大模型是否会选择你的 Skill。写得越精准、触发场景越清晰,匹配效果越好
- 保持 SKILL.md 简洁:正文建议控制在 5000 tokens 以内。复杂逻辑放到
scripts/,详细参考文档放到references/ - 安全优先:如果 Skill 涉及文件操作或命令执行,在正文中明确标注风险,并提醒智能体在执行前确认。不要将用户输入直接拼接到命令中
- 充分利用社区:写完高质量的 Skill 后,可以发布到 ClawHub(https://clawhub.ai/),让社区复用和贡献改进
7.3 发布 Skill 到 ClawHub
编写并测试通过后,你可以将 Skill 发布到 ClawHub,供社区安装和使用。发布前请确认:
- 已安装 ClawHub CLI(
npm i -g clawhub或对应平台的安装方式) - GitHub 账户满足 ClawHub 的发布门槛(账户创建需满一定时间)
SKILL.md中的name与计划使用的--slug一致,description清晰包含触发关键词
第一步:登录 ClawHub
clawhub login
执行后会打开浏览器完成 GitHub 授权。若在无图形界面的服务器或 CI 环境中,可先在 ClawHub 网页端创建 API Token,然后使用:
clawhub login --token clh_你的token
登录状态可用 clawhub whoami 验证。
C:\Users\zhang>clawhub whoami
√ bjbook
第二步:进入技能所在目录并发布
cd C:\Users\zhang\.openclaw\workspace
clawhub publish skills\hello-world
正式发布前,先用 --dry-run 查看 ClawHub 将如何处理你的 Skill,而不实际上传:
clawhub publish skills\hello-world --dry-run
√ Would publish hello-world@1.0.0
确认元数据、slug、版本均无误后,再去掉 --dry-run 执行正式发布。
发布后注意事项:
- ClawHub 会对新发布或更新的 Skill 进行自动化安全检查和元数据校验。校验失败则不会公开发布。
- 新版本在审核完成前可能不会出现在常规的安装/下载界面中。
- 发布完成后,可在 ClawHub 网页端确认 Skill 已可见,或在命令行用
clawhub search "你的技能名"验证。
如果只是在本地使用、不打算公开,可以跳过本节,无需执行发布。
7.4 本章核心知识回顾
编写 Skill 的本质,是将人类意图翻译为智能体可理解、可执行的行为规范。它不要求你精通编程语言,而是强调清晰的表达、合理的工具绑定和严谨的安全设计。
本章带你从零完成了一个 Skill 的完整开发流程:
创建标准目录结构。编写 SKILL.md,掌握 YAML Frontmatter 的字段规范和命名规则。理解 Skill 与内置工具的关系,学会声明运行时依赖。加载并测试 Skill,验证触发条件和边界情况。编写带脚本的进阶 Skill,掌握 SKILL.md 与 scripts/ 的配合模式。
7.5 课后练习
-
基础题:按照本章示例,创建
hello-world技能并在对话中验证它能被正确触发。尝试修改问候语内容,重开对话后确认修改生效。 -
进阶题:编写一个"系统信息"技能(
system-info),调用 Python 脚本获取当前操作系统名称、CPU 核心数和内存总量,并将结果格式化后返回给用户。提示:可以使用 Python 的platform和psutil库。 -
思考题:假设你写了一个 Skill,
description字段写成了"处理用户的各种请求"。你觉得这个 Skill 会被正确触发吗?为什么?你会怎么改进这个 description?
本章完
本文为《OpenClaw 实战指南》系列第 5 篇。下一章,我们将深入 OpenClaw 的记忆系统,看看智能体是如何记住你、理解你的偏好的。