OpenClaw Skill开发:自定义技能实战指南
🔑 摘要:OpenClaw Skill是赋予AI代理专业能力的核心机制——通过编写SKILL.md文件,你可以让Agent学会使用特定工具、遵循特定流程、在特定场景下自动触发。本文从Skill系统架构出发,深入解析SKILL.md的YAML前置元数据、描述触发机制、条件门控和资源引用规范;结合天气查询、待办管理两个完整实战案例,手把手带你从零构建自定义Skill;最后讲解如何通过ClawHub市场发布你的Skill,让更多开发者受益。无论你是OpenClaw新手还是想进阶定制化的高级用户,这篇指南都能帮你系统掌握Skill开发全流程。
目录
一、Skill系统架构总览
1.1 什么是Skill?
在OpenClaw的世界里,Skill(技能)是Agent能力的核心载体。简单来说,Skill就是一份Markdown格式的指令文件,它告诉AI代理三件事:
- 何时触发——在什么场景下应该激活这个技能
- 做什么——具体执行什么操作、遵循什么流程
- 怎么做——调用哪些工具、使用什么参数、遵循什么规范
Skill本质上是一种声明式的能力注入机制。你不需要修改OpenClaw的源代码,只需要在指定目录放置一个SKILL.md文件,Agent就自动获得了新能力。这种设计让OpenClaw的扩展性极强——任何人都可以为Agent添加新技能,就像给手机安装App一样简单。
从技术角度看,Skill系统采用渐进式加载(Progressive Disclosure)策略,将信息分为三个层次:
这种分层设计的好处显而易见:Agent不需要每次都把所有Skill的完整内容塞进上下文,而是先看元数据决定是否触发,再按需读取正文和资源文件,大幅节省了Token消耗。
1.2 Skill在OpenClaw架构中的位置
OpenClaw的整体架构可以简化为以下流程:用户通过各类渠道(Discord、Telegram、飞书、WhatsApp等)发送消息,Gateway接收并路由到Agent,Agent根据Skill指令调用工具执行任务,最终将结果返回用户。
在这个架构中,Skill扮演着**“翻译官”**的角色——它将用户的自然语言意图,翻译为具体的工具调用序列和执行规范。没有Skill,Agent只会使用基础的对话能力;有了Skill,Agent就能执行搜索、下载、文档操作、浏览器自动化等复杂任务。
1.3 Skill系统的设计哲学
OpenClaw的Skill系统遵循几个核心设计原则:
- 约定优于配置:一个SKILL.md文件即可完成最简技能定义,无需额外配置
- 渐进增强:从最简的元数据到完整的脚本+资源目录,复杂度随需求增长
- 热插拔:Skill可以随时添加、修改、删除,Gateway会自动检测变化
- 优先级覆盖:同一技能名在不同位置存在时,高优先级版本覆盖低优先级版本
- 安全隔离:通过门控机制(Gating)确保Skill仅在满足条件时加载
[AI生成概念图-待生成:OpenClaw Skill系统架构全景图,展示从用户消息到Skill触发的完整数据流]
二、Skill目录结构与加载机制
2.1 标准目录结构
一个完整的Skill目录通常包含以下结构:
my-skill/
├── SKILL.md # 必需:技能定义文件
├── scripts/ # 可选:可执行脚本
│ ├── run.sh # Shell脚本
│ └── process.py # Python脚本
├── references/ # 可选:参考文档
│ └── api-spec.md # API规范文档
├── assets/ # 可选:静态资源
│ ├── template.html # HTML模板
│ └── config.json # 配置文件
└── examples/ # 可选:示例文件
└── sample-output.txt # 示例输出
其中,SKILL.md是唯一必需的文件,其他目录和文件都是可选的。对于简单的Skill,一个SKILL.md就足够了;对于复杂的Skill,可以通过scripts目录放置可执行脚本,通过references目录放置参考文档,通过assets目录放置模板和配置。
2.2 加载优先级
OpenClaw从多个位置加载Skill,按以下优先级从高到低排列。当同一技能名出现在多个位置时,最高优先级的版本生效:
| 优先级 | 来源 | 路径 | 适用范围 |
|---|---|---|---|
| 1(最高) | 工作区技能 | <workspace>/skills |
仅当前Agent |
| 2 | 项目Agent技能 | <workspace>/.agents/skills |
仅当前工作区的Agent |
| 3 | 个人Agent技能 | ~/.agents/skills |
本机所有Agent |
| 4 | 托管/本地技能 | ~/.openclaw/skills |
本机所有Agent |
| 5 | 内置技能 | 随安装包发布 | 全局 |
| 6(最低) | 额外目录 | skills.load.extraDirs + 插件技能 |
全局 |
这种多层加载机制的设计意图非常明确:
- 工作区级覆盖:你可以在某个项目的workspace中放置定制版本的Skill,覆盖全局版本
- 渐进定制:从使用内置Skill开始,逐步在本地添加自定义版本
- 多Agent隔离:每个Agent可以有自己的Skill集合,互不干扰
2.3 分组布局
Skill根目录支持分组布局。OpenClaw会在配置的根目录下递归搜索SKILL.md文件,所以你可以用子文件夹来组织Skill,而不会影响Skill的名称:
<workspace>/skills/research/SKILL.md → 技能名 "research"
<workspace>/skills/personal/research/SKILL.md → 也是技能名 "research"
文件夹路径仅用于组织目的。Skill的名称、斜杠命令和允许列表键都来自SKILL.md中的name字段(或目录名,当name缺失时)。
三、SKILL.md配置详解
SKILL.md是Skill的核心配置文件,采用YAML前置元数据(Frontmatter)+ Markdown正文的格式。下面我们逐字段详细解析。
3.1 YAML前置元数据
YAML前置元数据位于SKILL.md的顶部,用---包围。它定义了Skill的基本属性和行为控制参数。
必填字段
| 字段 | 类型 | 说明 |
|---|---|---|
name |
string | Skill唯一标识符,仅使用小写字母、数字和连字符 |
description |
string | 一行描述,展示给Agent和斜杠命令发现,建议不超过160字符 |
可选字段
| 字段 | 默认值 | 说明 |
|---|---|---|
user-invocable |
true |
是否作为用户斜杠命令暴露 |
disable-model-invocation |
false |
是否从Agent系统提示中排除(仍可通过/skill运行) |
command-dispatch |
— | 设为tool时,斜杠命令直接路由到工具,绕过模型 |
command-tool |
— | 当command-dispatch: tool时,要调用的工具名 |
command-arg-mode |
raw |
工具调度时,参数的传递模式 |
homepage |
— | 显示在macOS Skills UI中的网站URL |
条件门控字段
门控(Gating)机制确保Skill仅在满足特定条件时才加载,避免在缺少依赖的环境中报错:
| 门控键 | 说明 |
|---|---|
requires.bins |
所有指定的二进制必须在PATH中存在 |
requires.anyBins |
至少一个指定的二进制必须在PATH中存在 |
requires.env |
每个指定的环境变量必须存在 |
requires.config |
每个指定的openclaw.json路径必须为真值 |
os |
平台过滤器:["darwin"]、["linux"]、["win32"] |
always |
设为true跳过所有门控检查 |
3.2 一个完整的SKILL.md示例
下面是一个具备完整元数据的Skill定义:
---
name: gemini-search
description: Search using Gemini CLI. Use when user needs AI-powered web search with Gemini.
metadata:
openclaw:
requires:
bins: ["gemini"]
primaryEnv: GEMINI_API_KEY
clawdbot:
requires:
bins: ["gemini"]
install:
- id: node
kind: node
package: gemini-cli
bins: ["gemini"]
label: Install Gemini CLI (npm)
---
# Gemini Search
When the user asks to search the web using Gemini, run:
gemini --search "user's query here"
## Guidelines
- Always quote the search query
- Summarize results in a clear, concise format
- Cite sources from the output
上面的示例中,metadata.openclaw.requires.bins指定了Skill依赖的gemini命令行工具,primaryEnv指定了需要的环境变量。如果系统中没有安装gemini命令,这个Skill就不会被加载,避免了运行时错误。
3.3 正文编写规范
SKILL.md的正文部分是给Agent看的指令,编写时需要注意以下几点:
- 清晰的触发条件:在正文开头明确说明何时使用该Skill
- 具体的执行步骤:用编号或步骤列出操作流程
- 参数说明:说明每个参数的含义和取值范围
- 示例输出:展示典型的输出格式
- 错误处理:说明可能出现的错误和应对方式
- 使用
{baseDir}引用资源:用{baseDir}代替硬编码路径引用Skill目录内的文件
关于{baseDir}的使用,这是一个非常重要的机制。当Agent需要执行Skill目录内的脚本时,不能使用硬编码的绝对路径,因为Skill可能被安装在不同位置。{baseDir}会在运行时被替换为Skill的实际目录路径:
Run the helper script at {baseDir}/scripts/run.sh.
---
## 四、技能注册与触发机制
### 4.1 自动发现与注册
OpenClaw的Skill注册是完全自动化的,你不需要手动注册任何Skill。当Gateway启动时,它会扫描所有配置的Skill根目录,递归查找SKILL.md文件,解析元数据,检查门控条件,最终构建出当前可用的Skill列表。
```mermaid
sequenceDiagram
participant GW as Gateway
participant FS as 文件系统
participant SK as Skill列表
GW->>FS: 扫描skills/目录
FS-->>GW: 返回SKILL.md文件列表
GW->>GW: 解析YAML前置元数据
GW->>GW: 检查门控条件(bins/env/os)
GW->>SK: 注册通过的Skill
GW->>GW: 构建Agent系统提示
注册过程中,门控检查是关键步骤。如果一个Skill声明了requires.bins: ["python3"],但系统中没有安装Python 3,那么这个Skill就会被跳过,不会出现在Agent的可用技能列表中。这种机制确保了Agent不会尝试使用它无法执行的Skill。
4.2 触发机制
Skill的触发有三种方式:
方式一:自动触发(Agent自主决策)
这是最常用的触发方式。Agent在收到用户消息后,会扫描所有已注册Skill的description字段,判断哪个Skill与当前对话最相关,然后自动激活该Skill。
这就是为什么description字段的编写至关重要——它直接决定了Skill能否被正确触发。一个好的description应该:
- 明确说明Skill的功能
- 列出触发关键词和场景
- 适当"推销"自己(因为Agent倾向于低触发率,描述稍微积极一些有助于提高触发率)
# ❌ 不好的描述——太简短,容易遗漏触发
description: Weather lookup skill
# ✅ 好的描述——包含功能、触发词和使用场景
description: Get current weather, rain, temperature, and forecasts for locations or travel planning. Use when user mentions weather, temperature, rain, forecast, or asks about travel conditions.
方式二:斜杠命令(用户显式调用)
用户可以在对话中使用/skill-name格式显式调用Skill。例如:
/weather 北京
/todo 创建 明天下午3点开会
当user-invocable: true(默认值)时,Skill会自动注册为斜杠命令。如果设置user-invocable: false,则只能通过Agent自动触发或/skill命令调用。
方式三:工具直调(绕过模型)
当command-dispatch: tool被设置时,斜杠命令会直接路由到指定的工具,完全绕过模型推理。这种方式适用于确定性操作,可以节省Token和响应时间:
---
name: uptime
description: Show system uptime
command-dispatch: tool
command-tool: exec
command-arg-mode: raw
---
4.3 Agent允许列表
在多Agent配置中,你可能想限制某些Agent只能使用特定的Skill。通过agents.list[].skills配置可以实现这一点:
{
agents: {
defaults: {
skills: ["github", "weather"], // 所有Agent共享的基线技能
},
list: [
{ id: "writer", skills: undefined }, // 继承defaults
{ id: "docs", skills: ["docs-search"] }, // 完全替换defaults
{ id: "locked-down", skills: [] }, // 无技能
],
},
}
允许列表的规则如下:
- 省略
agents.defaults.skills则所有技能不限制 - 省略
agents.list[].skills则继承defaults - 设置
agents.list[].skills: []则该Agent无技能 - 非空的
agents.list[].skills列表是最终集合,不会与defaults合并
4.4 描述字段触发优化技巧
由于当前Agent模型倾向于"低触发"——即在该用Skill时有时不会使用——OpenClaw社区总结了一些提高触发率的实用技巧:
| 技巧 | 示例 |
|---|---|
| 列出同义词和触发词 | “weather, temperature, 天气, 气温, forecast” |
| 包含隐性场景 | “Use when planning travel, even if user doesn’t say ‘weather’” |
| 适当扩展适用范围 | “even if they don’t explicitly ask for a ‘dashboard’” |
| 使用具体动词 | “Search, fetch, download, analyze” 而非 “Handle” |
| 避免模糊描述 | “Manage todo items” → “Create, update, delete, and list todo items” |
五、内置Skill概览
OpenClaw随安装包附带了丰富的内置Skill,覆盖了日常开发和使用中最常见的场景。下面按功能分类介绍主要内置Skill。
5.1 核心工具类Skill
| Skill名 | 功能说明 | 典型触发词 |
|---|---|---|
browser-automation |
多步骤浏览器控制,处理登录、标签页、超时恢复 | 浏览器操作、网页自动化、登录流程 |
feishu-doc |
飞书文档读写操作 | 飞书文档、云文档、docx链接 |
feishu-drive |
飞书云存储文件管理 | 云空间、文件夹、drive |
feishu-wiki |
飞书知识库导航 | 知识库、wiki、wiki链接 |
feishu-perm |
飞书文档权限管理 | 分享、权限、协作者 |
wecom-msg |
企业微信消息收发 | 查看消息、聊天记录、发消息 |
wecom-schedule |
企业微信日程管理 | 日程、会议安排、闲忙查询 |
wecom-edit-todo |
企业微信待办编辑 | 创建待办、分派任务、标记完成 |
5.2 效率工具类Skill
| Skill名 | 功能说明 | 典型触发词 |
|---|---|---|
downloader |
从URL下载文件到本地 | 下载文件、保存远程资源 |
uploader |
上传文件到Astron Claw Bridge获取公开URL | 上传文件、获取下载链接 |
hot-finder |
多源热门内容搜索+Excel导出 | 热点、热门视频、找爆款、trending |
podcast-gen |
播客脚本生成+TTS音频合成 | 生成播客、podcast、做节目 |
weather |
天气查询与预报 | 天气、温度、下雨、forecast |
5.3 AI增强类Skill
| Skill名 | 功能说明 | 典型触发词 |
|---|---|---|
xfyun-search |
讯飞万搜/聚合搜索 | 搜索、web search、搜索中文内容 |
xfyun-tts |
讯飞超拟人语音合成 | 文字转语音、TTS、生成音频 |
xfyun-ocr |
讯飞OCR大模型识别 | OCR、图片识别、文档识别 |
xfyun-image-understanding |
讯飞图片理解 | 图片理解、分析图片 |
humanizer |
去除AI写作痕迹 | 润色、去除AI味、人性化改写 |
5.4 开发者工具类Skill
| Skill名 | 功能说明 | 典型触发词 |
|---|---|---|
skill-creator |
创建/修改/评测Skill | 创建技能、修改技能、跑评估 |
agent-team |
多Agent团队编排 | Team模式、多智能体、协作任务 |
csdn-article |
CSDN高质量技术文章写作 | 写CSDN文章、技术博客 |
csdn-publisher |
写文章并发布到CSDN | 发布CSDN、CSDN发布 |
canvas-design |
可视化设计(海报/图/PDF) | 做海报、设计、生成图片 |
capability-evolver |
Agent自我进化引擎 | 自我进化、能力提升 |
5.5 平台与运维类Skill
| Skill名 | 功能说明 | 典型触发词 |
|---|---|---|
healthcheck |
主机安全审计与加固 | 安全检查、SSH审计、防火墙 |
node-connect |
节点配对诊断 | 节点连接、配对失败、QR码 |
taskflow |
多步骤持久化任务协调 | 任务流、多步骤任务、持久任务 |
cloud-local-communication |
云端与本地机器通信桥 | 我的电脑、本地文件、桌面操作 |
六、第三方Skill与ClawHub生态
6.1 ClawHub简介
ClawHub(clawhub.ai)是OpenClaw的公共技能注册中心,类似于npm之于Node.js、PyPI之于Python。你可以在ClawHub上搜索、安装、更新和发布Skill,与全球开发者共享你的创作。
此外还有ClawdHub(clawdhub.com),它是另一个社区驱动的Skill注册中心,使用独立的CLI工具。
6.2 安装第三方Skill
使用openclaw skills命令管理Skill的安装和更新:
| 操作 | 命令 |
|---|---|
| 安装到工作区 | openclaw skills install <slug> |
| 从Git仓库安装 | openclaw skills install git:owner/repo@ref |
| 从本地目录安装 | openclaw skills install ./path/to/skill --as my-tool |
| 全局安装(所有Agent可用) | openclaw skills install <slug> --global |
| 更新所有工作区Skill | openclaw skills update --all |
| 更新全局托管Skill | openclaw skills update <slug> --global |
| 验证Skill信任信封 | openclaw skills verify <slug> |
| 查看Skill Card | openclaw skills verify <slug> --card |
6.3 使用ClawdHub CLI
ClawdHub提供了独立的CLI工具,支持搜索、安装、更新和发布操作:
# 安装ClawdHub CLI
npm i -g clawdhub
# 搜索技能
clawdhub search "postgres backups"
# 安装技能
clawdhub install my-skill
# 安装指定版本
clawdhub install my-skill --version 1.2.3
# 查看已安装列表
clawdhub list
# 更新所有技能
clawdhub update --all
6.4 Skill Workshop:提案式审查
对于Agent起草的Skill或需要人工审查的场景,OpenClaw提供了Skill Workshop机制。Agent不会直接写入SKILL.md文件,而是创建一个提案(Proposal),由你审查通过后才正式生效:
# 查看提案列表
openclaw skills workshop list
# 检查提案内容
openclaw skills workshop inspect <proposal-id>
# 批准并应用提案
openclaw skills workshop apply <proposal-id>
这种机制在团队协作中特别有用——你可以让Agent自动识别可复用的工作模式并起草Skill提案,团队成员审查后一键应用。
七、Skill调试:本地测试与日志排查
7.1 验证Skill是否加载
编写完Skill后,第一步是确认它是否被正确加载。使用以下命令查看当前已加载的Skill列表:
openclaw skills list
如果列表中出现了你的Skill名称,说明元数据解析和门控检查都通过了。如果没有出现,可能的原因包括:
- 目录位置不对:确认SKILL.md文件在正确的skills根目录下
- 门控条件不满足:检查
requires.bins、requires.env等条件 - YAML格式错误:检查frontmatter的缩进和语法
- name字段冲突:如果与高优先级Skill同名,你的版本会被覆盖
7.2 测试Skill触发
确认Skill已加载后,下一步测试它能否被正确触发:
# 方式一:使用Agent命令行测试
openclaw agent --message "帮我查一下北京的天气"
# 方式二:在Web控制台中对话测试
openclaw dashboard
# 方式三:使用斜杠命令显式触发
/weather 北京
如果自动触发失败但斜杠命令成功,问题通常出在description字段——Agent无法从用户消息中匹配到你的Skill。这时需要优化description的触发关键词。
7.3 常见调试场景
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| Skill不在列表中 | 门控条件不满足 | 检查bins/env/os条件,或设置always: true |
| Skill不自动触发 | description不够明确 | 添加更多触发词和场景描述 |
| Skill触发但执行失败 | 脚本路径错误 | 使用{baseDir}代替硬编码路径 |
| 旧版本仍在生效 | 优先级覆盖 | 检查是否有高优先级同名Skill |
| 脚本权限不足 | 文件不可执行 | chmod +x scripts/*.sh |
| 修改后未生效 | 会话缓存 | 使用/new新建会话或重启Gateway |
7.4 日志排查
当Skill执行出现问题时,查看Gateway日志是最直接的排查方式:
# 查看Gateway实时日志
openclaw gateway logs
# 只看Skill相关的日志
openclaw gateway logs | grep -i skill
# 查看Agent决策日志
openclaw gateway logs | grep -i "skill.*trigger"
在日志中,你可以看到:
- Skill的加载和注册过程
- Agent选择Skill的决策依据
- Skill执行的详细步骤和输出
- 错误信息和堆栈跟踪
7.5 会话刷新技巧
修改SKILL.md后,如果Agent似乎没有使用新版本,可能是因为当前会话使用了缓存的Skill列表。解决方法:
# 在对话中输入斜杠命令
/new
# 或者重启Gateway
openclaw gateway restart
通常OpenClaw会自动监视SKILL.md文件变化并热更新,但在某些情况下(如编辑器保存触发事件丢失),手动刷新是必要的。
八、实战案例1:开发天气查询Skill
现在让我们动手开发第一个自定义Skill——天气查询技能。这个Skill将调用OpenClaw内置的weather技能逻辑,展示从零搭建的完整过程。
8.1 需求分析
我们的天气查询Skill需要满足以下功能:
- 接受城市名作为输入
- 返回当前天气、温度、降水概率
- 支持3天天气预报
- 支持中文和英文城市名
- 输出格式清晰易读
8.2 创建Skill目录
mkdir -p ~/.openclaw/workspace/skills/weather-query/scripts
8.3 编写查询脚本
创建scripts/weather.py,使用免费天气API获取数据:
#!/usr/bin/env python3
"""Weather query skill script for OpenClaw."""
import json
import sys
import urllib.request
import urllib.parse
def get_weather(city: str) -> dict:
"""Fetch weather data from wttr.in API."""
encoded = urllib.parse.quote(city)
url = f"https://wttr.in/{encoded}?format=j1"
try:
req = urllib.request.Request(url, headers={"User-Agent": "curl/7.68.0"})
with urllib.request.urlopen(req, timeout=10) as resp:
return json.loads(resp.read().decode())
except Exception as e:
return {"error": str(e)}
def format_weather(data: dict, city: str) -> str:
"""Format weather data into readable output."""
if "error" in data:
return f"❌ 查询失败: {data['error']}"
current = data.get("current_condition", [{}])[0]
area = data.get("nearest_area", [{}])[0]
lines = [
f"🌍 {area.get('areaName', [{}])[0].get('value', city)}",
f"🌤 天气: {current.get('weatherDesc', [{}])[0].get('value', 'N/A')}",
f"🌡 温度: {current.get('temp_C', 'N/A')}°C (体感 {current.get('FeelsLikeC', 'N/A')}°C)",
f"💧 湿度: {current.get('humidity', 'N/A')}%",
f"💨 风速: {current.get('windspeedKmph', 'N/A')} km/h",
f"🌧 降水: {current.get('precipMM', 'N/A')} mm",
]
# 3-day forecast
for day in data.get("weather", [])[:3]:
date = day.get("date", "N/A")
max_t = day.get("maxtempC", "N/A")
min_t = day.get("mintempC", "N/A")
desc = day.get("hourly", [{}])[4].get(
"weatherDesc", [{}])[0].get("value", "N/A"
)
lines.append(f"📅 {date}: {desc}, {min_t}~{max_t}°C")
return "\n".join(lines)
if __name__ == "__main__":
city = " ".join(sys.argv[1:]) if len(sys.argv) > 1 else "Beijing"
data = get_weather(city)
print(format_weather(data, city))
上面的脚本使用Python标准库(无需pip安装),调用wttr.in的免费天气API,返回结构化的天气数据并格式化输出。代码约55行,包含错误处理和3天预报。
8.4 编写SKILL.md
---
name: weather-query
description: Get current weather, temperature, rain forecast for any city. Use when user mentions weather, 天气, 温度, 下雨, forecast, or asks about travel conditions, even if they don't explicitly say 'weather'.
metadata:
openclaw:
requires:
bins: ["python3"]
---
# Weather Query Skill
When the user asks about weather for a location, run the weather script.
## Execution
python3 "{baseDir}/scripts/weather.py" "<city_name>"
## Guidelines
- Replace `<city_name>` with the city the user mentioned
- Support both Chinese and English city names (e.g., "北京" or "Beijing")
- If user doesn't specify a city, default to their last mentioned location
- Present results in a clear, formatted way
- For travel planning, include the 3-day forecast section
## Example
User: "北京明天天气怎么样"
python3 "{baseDir}/scripts/weather.py" "北京"
## Error Handling
- If the API call fails, inform the user and suggest trying again
- If the city name is ambiguous, ask the user to clarify
- Network timeout: default is 10 seconds, suggest checking connection
8.5 测试Skill
# 验证加载
openclaw skills list | grep weather
# 命令行测试
openclaw agent --message "上海今天天气怎么样"
# 斜杠命令测试
/weather-query 上海
预期输出:
🌍 上海
🌤 天气: Partly cloudy
🌡 温度: 28°C (体感 31°C)
💧 湿度: 72%
💨 风速: 15 km/h
🌧 降水: 0.0 mm
📅 2026-06-20: Partly cloudy, 25~32°C
📅 2026-06-21: Light rain, 23~29°C
📅 2026-06-22: Cloudy, 24~30°C
九、实战案例2:开发待办管理Skill
第二个实战案例我们开发一个待办管理Skill,它支持创建、查看、完成和删除待办事项,数据持久化到本地JSON文件。
9.1 需求分析
- 创建待办事项(标题+可选截止时间)
- 列出所有待办事项(按状态分组)
- 标记待办为已完成
- 删除待办事项
- 数据持久化到JSON文件
9.2 创建目录和脚本
mkdir -p ~/.openclaw/workspace/skills/todo-manager/scripts
创建scripts/todo.py:
#!/usr/bin/env python3
"""Simple todo manager for OpenClaw Skill."""
import json
import sys
import os
from datetime import datetime
DATA_FILE = os.path.join(os.path.dirname(__file__), "..", "data", "todos.json")
def load_todos():
os.makedirs(os.path.dirname(DATA_FILE), exist_ok=True)
if os.path.exists(DATA_FILE):
with open(DATA_FILE, "r", encoding="utf-8") as f:
return json.load(f)
return []
def save_todos(todos):
os.makedirs(os.path.dirname(DATA_FILE), exist_ok=True)
with open(DATA_FILE, "w", encoding="utf-8") as f:
json.dump(todos, f, ensure_ascii=False, indent=2)
def add_todo(title, deadline=None):
todos = load_todos()
todo = {
"id": len(todos) + 1,
"title": title,
"deadline": deadline,
"done": False,
"created": datetime.now().isoformat(),
}
todos.append(todo)
save_todos(todos)
return f"✅ 已创建待办 #{todo['id']}: {title}"
def list_todos():
todos = load_todos()
if not todos:
return "📋 暂无待办事项"
pending = [t for t in todos if not t["done"]]
done = [t for t in todos if t["done"]]
lines = []
if pending:
lines.append("📌 待完成:")
for t in pending:
dl = f" (截止: {t['deadline']})" if t.get("deadline") else ""
lines.append(f" #{t['id']}: {t['title']}{dl}")
if done:
lines.append("\n✅ 已完成:")
for t in done:
lines.append(f" #{t['id']}: {t['title']} ✓")
return "\n".join(lines)
def complete_todo(todo_id):
todos = load_todos()
for t in todos:
if t["id"] == todo_id:
t["done"] = True
save_todos(todos)
return f"🎉 待办 #{todo_id} 已完成: {t['title']}"
return f"❌ 未找到待办 #{todo_id}"
def delete_todo(todo_id):
todos = load_todos()
original = len(todos)
todos = [t for t in todos if t["id"] != todo_id]
if len(todos) < original:
save_todos(todos)
return f"🗑 已删除待办 #{todo_id}"
return f"❌ 未找到待办 #{todo_id}"
if __name__ == "__main__":
if len(sys.argv) < 2:
print("用法: todo.py [add|list|done|delete] [args...]")
sys.exit(1)
cmd = sys.argv[1]
if cmd == "add":
title = " ".join(sys.argv[2:]) if len(sys.argv) > 2 else "Untitled"
print(add_todo(title))
elif cmd == "list":
print(list_todos())
elif cmd == "done":
print(complete_todo(int(sys.argv[2])))
elif cmd == "delete":
print(delete_todo(int(sys.argv[2])))
else:
print(f"❌ 未知命令: {cmd}")
上面的脚本实现了完整的CRUD操作,使用JSON文件持久化数据。代码约75行,纯Python标准库实现。
9.3 编写SKILL.md
---
name: todo-manager
description: Create, list, complete, and delete todo items. Use when user says 帮我创建待办、查看待办列表、标记完成、删掉待办、我的任务、todo、task management, or mentions checking off items, task tracking.
metadata:
openclaw:
requires:
bins: ["python3"]
---
# Todo Manager Skill
Manage personal todo items with create, list, complete, and delete operations.
## Commands
### Create a todo
python3 "{baseDir}/scripts/todo.py" add "Buy groceries"
### List all todos
python3 "{baseDir}/scripts/todo.py" list
### Mark todo as complete
python3 "{baseDir}/scripts/todo.py" done 3
### Delete a todo
python3 "{baseDir}/scripts/todo.py" delete 3
## Behavior Rules
1. When user says "创建待办" or "add todo", extract the title and run `add`
2. When user says "查看待办" or "list todos", run `list`
3. When user says "完成了" or "mark done", extract the ID and run `done`
4. When user says "删除" or "delete", extract the ID and run `delete`
5. If user provides a deadline, include it in the add command
6. Always confirm the action result with the user
7. After adding, show the updated list
## Error Handling
- Invalid ID: tell user the ID doesn't exist and show the list
- Empty title: ask user to provide a title
- Missing arguments: show usage help
9.4 测试
# 创建待办
openclaw agent --message "帮我创建一个待办:完成周报"
# 查看列表
openclaw agent --message "我有哪些待办"
# 标记完成
openclaw agent --message "把待办1标记为完成"
# 删除
openclaw agent --message "删掉待办2"
十、实战案例3:发布Skill到ClawHub市场
当你开发了一个高质量的Skill并希望分享给社区时,可以发布到ClawHub市场。下面介绍完整的发布流程。
10.1 发布前检查清单
在发布之前,请确认以下事项:
- ✅ SKILL.md包含完整的
name和description - ✅
description描述清晰,包含触发关键词 - ✅ 门控条件(
requires)已正确设置 - ✅ 所有脚本都有执行权限(
chmod +x scripts/*) - ✅ 已在本地充分测试
- ✅ 不包含敏感信息(API密钥、个人数据等)
- ✅ 添加了
homepage字段(如有项目主页)
10.2 使用ClawdHub CLI发布
# 安装ClawdHub CLI
npm i -g clawdhub
# 登录ClawHub账户
clawdhub login
# 验证登录状态
clawdhub whoami
# 发布Skill
clawdhub publish ./my-skill \
--slug my-skill \
--name "My Skill" \
--version 1.0.0 \
--changelog "Initial release"
发布命令的参数说明:
| 参数 | 说明 |
|---|---|
--slug |
Skill在注册中心唯一标识符 |
--name |
Skill的人类可读名称 |
--version |
语义化版本号(遵循semver) |
--changelog |
版本变更说明 |
10.3 版本更新流程
当你修改了Skill并需要发布新版本时:
# 更新已有Skill
clawdhub publish ./my-skill \
--slug my-skill \
--name "My Skill" \
--version 1.1.0 \
--changelog "Added forecast feature, fixed timeout issue"
版本号遵循语义化版本规范:
- 补丁版本(1.0.x):Bug修复,无新功能
- 次版本(1.x.0):新增功能,向后兼容
- 主版本(x.0.0):破坏性变更
10.4 使用openclaw skills命令发布
除了ClawdHub CLI,你也可以使用OpenClaw内置的skills命令来管理和同步:
# 同步所有Skill到ClawHub
clawhub sync --all
# 安装Skill到工作区
openclaw skills install my-skill
# 从Git仓库安装
openclaw skills install git:username/skill-repo@main
# 验证Skill
openclaw skills verify my-skill
# 查看Skill Card
openclaw skills verify my-skill --card
10.5 发布最佳实践
发布高质量Skill的建议:
- Description是门面:花时间打磨description,它决定了Skill能否被发现和正确触发
- 渐进式复杂度:最简版本先发布,后续迭代增加功能
- 错误处理优先:网络超时、API限流、参数缺失都要处理
- 纯标准库优先:尽量使用Python/Shell标准库,减少用户安装依赖
- 示例即文档:在SKILL.md中提供完整的命令示例
- 版本管理:使用semver,每次发布都写清楚changelog
总结与展望
核心要点回顾
通过本文,我们系统地学习了OpenClaw Skill开发的完整知识体系:
- 架构理解:Skill是Agent能力的核心载体,采用渐进式加载的三层架构
- 配置精通:SKILL.md的YAML前置元数据控制Skill的注册、触发和门控行为
- 触发优化:description字段是触发机制的关键,需要精心编写触发词和场景描述
- 目录规范:遵循标准目录结构,使用
{baseDir}引用资源,确保可移植性 - 调试技巧:从加载验证到日志排查,掌握完整的调试工作流
- 生态参与:通过ClawHub发布和安装Skill,与社区共享成果
Skill系统的发展方向
OpenClaw的Skill系统仍在快速演进中,未来可能会看到以下方向的发展:
- Skill组合:多个Skill协同工作,形成更复杂的工作流
- Skill市场评分:社区评分和评价机制,帮助用户选择高质量Skill
- 可视化编辑器:拖拽式Skill构建工具,降低开发门槛
- Skill沙箱化:更严格的安全隔离,确保Skill执行不影响宿主环境
- 自动Skill生成:Agent自动识别可复用模式,起草并提交Skill提案
参考资源
- 📖 OpenClaw官方文档:https://docs.openclaw.ai
- 📦 Skill配置详解:https://docs.openclaw.ai/tools/skills
- 🛠 创建Skill指南:https://docs.openclaw.ai/tools/creating-skills
- 🌐 ClawHub市场:https://clawhub.ai
- 🔧 ClawdHub CLI:https://clawdhub.com
💡 最后的建议:最好的学习方式是动手实践。从修改一个内置Skill开始,逐步过渡到自己创建新Skill。当你发现自己反复执行某个操作时,就是创建Skill的最佳时机。记住——每一个重复操作,都是一个Skill的种子 🌱
更多推荐

所有评论(0)