🔑 摘要: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代理三件事:

  1. 何时触发——在什么场景下应该激活这个技能
  2. 做什么——具体执行什么操作、遵循什么流程
  3. 怎么做——调用哪些工具、使用什么参数、遵循什么规范

Skill本质上是一种声明式的能力注入机制。你不需要修改OpenClaw的源代码,只需要在指定目录放置一个SKILL.md文件,Agent就自动获得了新能力。这种设计让OpenClaw的扩展性极强——任何人都可以为Agent添加新技能,就像给手机安装App一样简单。

从技术角度看,Skill系统采用渐进式加载(Progressive Disclosure)策略,将信息分为三个层次:

📋 元数据层
name + description
约100词,始终在上下文中

📖 SKILL.md正文
完整指令
建议不超过500行

📦 资源文件层
scripts/references/assets
按需加载,无大小限制

这种分层设计的好处显而易见:Agent不需要每次都把所有Skill的完整内容塞进上下文,而是先看元数据决定是否触发,再按需读取正文和资源文件,大幅节省了Token消耗。

1.2 Skill在OpenClaw架构中的位置

OpenClaw的整体架构可以简化为以下流程:用户通过各类渠道(Discord、Telegram、飞书、WhatsApp等)发送消息,Gateway接收并路由到Agent,Agent根据Skill指令调用工具执行任务,最终将结果返回用户。

OpenClaw核心

用户侧

Discord

Telegram

飞书

WhatsApp

Gateway
网关路由

Agent
智能代理

Skills
技能系统

Tools
工具层

执行结果

在这个架构中,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集合,互不干扰

加载优先级从高到低

🥇 工作区 skills/

🥈 项目 .agents/skills/

🥉 个人 ~/.agents/skills/

4️⃣ 托管 ~/.openclaw/skills/

5️⃣ 内置 bundled

6️⃣ 额外目录 + 插件

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看的指令,编写时需要注意以下几点:

  1. 清晰的触发条件:在正文开头明确说明何时使用该Skill
  2. 具体的执行步骤:用编号或步骤列出操作流程
  3. 参数说明:说明每个参数的含义和取值范围
  4. 示例输出:展示典型的输出格式
  5. 错误处理:说明可能出现的错误和应对方式
  6. 使用{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提案,团队成员审查后一键应用。

通过

拒绝

Agent识别
可复用模式

起草Skill
Proposal

Workshop
审查队列

人工审查

应用Proposal
生成SKILL.md

退回修改


七、Skill调试:本地测试与日志排查

7.1 验证Skill是否加载

编写完Skill后,第一步是确认它是否被正确加载。使用以下命令查看当前已加载的Skill列表:

openclaw skills list

如果列表中出现了你的Skill名称,说明元数据解析和门控检查都通过了。如果没有出现,可能的原因包括:

  • 目录位置不对:确认SKILL.md文件在正确的skills根目录下
  • 门控条件不满足:检查requires.binsrequires.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包含完整的namedescription
  • 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 发布最佳实践

30% 20% 15% 15% 10% 10% Skill质量要素分布 功能完整性 描述准确性 错误处理 文档质量 代码风格 测试覆盖

发布高质量Skill的建议:

  1. Description是门面:花时间打磨description,它决定了Skill能否被发现和正确触发
  2. 渐进式复杂度:最简版本先发布,后续迭代增加功能
  3. 错误处理优先:网络超时、API限流、参数缺失都要处理
  4. 纯标准库优先:尽量使用Python/Shell标准库,减少用户安装依赖
  5. 示例即文档:在SKILL.md中提供完整的命令示例
  6. 版本管理:使用semver,每次发布都写清楚changelog

总结与展望

核心要点回顾

通过本文,我们系统地学习了OpenClaw Skill开发的完整知识体系:

  1. 架构理解:Skill是Agent能力的核心载体,采用渐进式加载的三层架构
  2. 配置精通:SKILL.md的YAML前置元数据控制Skill的注册、触发和门控行为
  3. 触发优化:description字段是触发机制的关键,需要精心编写触发词和场景描述
  4. 目录规范:遵循标准目录结构,使用{baseDir}引用资源,确保可移植性
  5. 调试技巧:从加载验证到日志排查,掌握完整的调试工作流
  6. 生态参与:通过ClawHub发布和安装Skill,与社区共享成果

Skill系统的发展方向

OpenClaw的Skill系统仍在快速演进中,未来可能会看到以下方向的发展:

  • Skill组合:多个Skill协同工作,形成更复杂的工作流
  • Skill市场评分:社区评分和评价机制,帮助用户选择高质量Skill
  • 可视化编辑器:拖拽式Skill构建工具,降低开发门槛
  • Skill沙箱化:更严格的安全隔离,确保Skill执行不影响宿主环境
  • 自动Skill生成:Agent自动识别可复用模式,起草并提交Skill提案

参考资源

💡 最后的建议:最好的学习方式是动手实践。从修改一个内置Skill开始,逐步过渡到自己创建新Skill。当你发现自己反复执行某个操作时,就是创建Skill的最佳时机。记住——每一个重复操作,都是一个Skill的种子 🌱

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐