首页/@claw-academy

"创建第一个 Skill"

龙虾学堂
龙虾学堂2026年5月7日

"从零开始创建 OpenClaw Skill:掌握 SKILL.md 编写规范和工具函数实现,让你的 Agent 拥有自定义能力。"

创建第一个 Skill

本文聚焦:SKILL.md 编写规范 + 工具函数实现

前置知识:什么是 Skill 下一篇:安装 Skills

知识点 1:SKILL.md 编写规范

是什么

SKILL.md 是 Skill 的核心定义文件,它用 Markdown 格式描述 Skill 的功能、工具、使用场景和注意事项。Agent 通过读取 SKILL.md 来理解何时以及如何使用这个 Skill。

为什么需要规范

规范的 SKILL.md 能让 Agent:

  1. 准确理解 Skill 的用途和触发条件
  2. 正确使用 工具,避免参数错误
  3. 处理异常 情况,知道何时该放弃或重试
  4. 提供示例 供用户参考

标准结构模板

# Skill 名称

## 描述
一句话说明这个 Skill 是做什么的。

## 适用场景
- 场景 1:具体描述
- 场景 2:具体描述

## 工具清单

### tool_name_1
详细描述这个工具的作用。

**参数:**
- `param1` (string, 必需): 参数说明
- `param2` (number, 可选): 参数说明,默认值:xxx

**返回值:**
- 成功:返回什么
- 失败:返回什么

**示例:**
```json
{
  "tool": "tool_name_1",
  "arguments": {
    "param1": "value",
    "param2": 123
  }
}

tool_name_2

...

注意事项

  • 注意点 1
  • 注意点 2

权限声明

  • read: 读取文件
  • exec: 执行命令

### 关键字段详解

#### 1. 描述(Description)

**要求**:简洁、准确、包含关键词

❌ 差示例:"这是一个很有用的工具"

✅ 好示例:"将文本转换为语音并自动播放,支持 ElevenLabs 和 OpenAI TTS 服务"

#### 2. 适用场景(Use Cases)

**要求**:列出 2-5 个具体场景,帮助 Agent 判断何时调用

```markdown
## 适用场景
- 用户说"播放这段文字"或"读给我听"
- 需要为故事、新闻摘要添加语音效果
- 生成播客或语音消息内容

3. 工具参数定义

参数类型标记

  • (string, 必需) - 必须提供
  • (number, 可选) - 可选,需注明默认值
  • (boolean, 可选) - 布尔值,默认 false
  • (array, 必需) - 数组类型
  • (object, 可选) - 对象类型

示例

**参数:**
- `text` (string, 必需): 要转换为语音的文本内容
- `voice` (string, 可选): 语音类型,可选值:"nova" | "echo" | "onyx",默认:"nova"
- `speed` (number, 可选): 语速倍数,范围 0.5-2.0,默认:1.0

4. 示例代码块

要求:提供完整、可运行的示例

**示例:**
```json
{
  "tool": "tts",
  "arguments": {
    "text": "你好,这是测试语音",
    "voice": "nova",
    "speed": 1.0
  }
}

### 常见陷阱

**陷阱 1:参数描述模糊**

❌ 错误:
```markdown
**参数:**
- `input`: 输入内容
- `mode`: 模式

✅ 正确:

**参数:**
- `input` (string, 必需): 要处理的文本内容,最大长度 4000 字符
- `mode` (string, 可选): 处理模式,可选值:"fast" | "accurate",默认:"fast"

陷阱 2:缺少错误处理说明

❌ 错误:只写成功示例

✅ 正确:包含错误场景

**返回值:**
- 成功:`{ "success": true, "url": "https://..." }`
- 失败:`{ "success": false, "error": "Rate limit exceeded" }`

**常见错误:**
- 429: 请求频率过高,请等待 60 秒后重试
- 400: 文本内容为空或超过长度限制

陷阱 3:权限声明不完整

❌ 错误:完全不提权限

✅ 正确:明确声明

## 权限声明
本 Skill 需要以下权限:
- `read`: 读取配置文件 `~/.config/my-skill/config.json`
- `exec`: 执行系统命令 `curl` 进行网络请求
- `write`: 写入临时文件到 `/tmp/my-skill/`

知识点 2:工具函数实现

Skill 的执行方式

OpenClaw 支持两种 Skill 实现方式:

方式说明适用场景
纯 Markdown仅 SKILL.md,无代码文档型 Skill、知识库
Markdown + 脚本SKILL.md + scripts/ 目录需要执行逻辑的 Skill

脚本目录结构

my-skill/
├── SKILL.md              # 技能定义
├── scripts/
│   ├── main.py          # 主入口(可选)
│   ├── utils.py         # 工具函数
│   └── config.json      # 配置文件
└── references/
    └── api-docs.md      # 参考资料

实战示例:创建一个天气查询 Skill

步骤 1:创建目录

mkdir -p ~/.openclaw/skills/weather-query/scripts
cd ~/.openclaw/skills/weather-query

步骤 2:编写 SKILL.md

# 天气查询

## 描述
查询指定城市的实时天气信息,支持国内外主要城市。

## 适用场景
- 用户询问"今天天气怎么样"
- 需要获取某个城市的温度和天气状况
- 出行前查看目的地天气

## 工具清单

### get_weather
获取指定城市的实时天气数据。

**参数:**
- `city` (string, 必需): 城市名称,如"北京"、"Shanghai"
- `unit` (string, 可选): 温度单位,可选值:"celsius" | "fahrenheit",默认:"celsius"

**返回值:**
- 成功:返回天气对象
  ```json
  {
    "city": "北京",
    "temperature": 25,
    "condition": "晴",
    "humidity": "45%",
    "wind": "东南风 3级"
  }
  • 失败:返回错误信息
    { "error": "城市不存在或暂不支持" }
    

示例:

{
  "tool": "get_weather",
  "arguments": {
    "city": "上海",
    "unit": "celsius"
  }
}

注意事项

  • 城市名称支持中文和英文
  • 部分偏远城市可能无法查询
  • API 有频率限制,请勿频繁调用

权限声明

  • exec: 执行脚本查询天气 API
  • read: 读取本地城市代码映射表

#### 步骤 3:编写脚本

创建 `scripts/weather.py`:

```python
#!/usr/bin/env python3
import sys
import json
import urllib.request
import urllib.parse

def get_weather(city, unit="celsius"):
    """查询城市天气"""
    try:
        # 这里使用示例 API(实际开发需替换为真实天气 API)
        encoded_city = urllib.parse.quote(city)
        url = f"https://api.example.com/weather?city={encoded_city}&unit={unit}"
        
        # 模拟 API 响应(实际开发中替换为真实请求)
        # with urllib.request.urlopen(url, timeout=10) as response:
        #     data = json.loads(response.read().decode('utf-8'))
        
        # 模拟数据
        mock_data = {
            "city": city,
            "temperature": 25 if unit == "celsius" else 77,
            "condition": "晴",
            "humidity": "45%",
            "wind": "东南风 3级",
            "unit": unit
        }
        
        return {"success": True, "data": mock_data}
        
    except Exception as e:
        return {"success": False, "error": str(e)}

if __name__ == "__main__":
    # 从命令行参数读取输入
    if len(sys.argv) < 2:
        print(json.dumps({"error": "缺少参数"}, ensure_ascii=False))
        sys.exit(1)
    
    # 解析参数
    try:
        params = json.loads(sys.argv[1])
        city = params.get("city")
        unit = params.get("unit", "celsius")
        
        if not city:
            print(json.dumps({"error": "city 参数不能为空"}, ensure_ascii=False))
            sys.exit(1)
        
        result = get_weather(city, unit)
        print(json.dumps(result, ensure_ascii=False))
        
    except json.JSONDecodeError:
        print(json.dumps({"error": "参数格式错误,需要 JSON 格式"}, ensure_ascii=False))
        sys.exit(1)

步骤 4:测试 Skill

# 给脚本添加执行权限
chmod +x scripts/weather.py

# 测试脚本
python3 scripts/weather.py '{"city": "北京", "unit": "celsius"}'

# 预期输出
{"success": true, "data": {"city": "北京", "temperature": 25, ...}}

步骤 5:重启 Gateway

openclaw gateway restart

重启后,Agent 就能识别并使用这个 Skill 了。

脚本编写最佳实践

1. 输入输出规范

# 输入:从命令行参数读取 JSON
params = json.loads(sys.argv[1])

# 输出:始终输出 JSON 到 stdout
print(json.dumps(result, ensure_ascii=False))

2. 错误处理

try:
    result = do_something()
    print(json.dumps({"success": True, "data": result}))
except Exception as e:
    print(json.dumps({"success": False, "error": str(e)}))
    sys.exit(1)

3. 超时处理

import socket
socket.setdefaulttimeout(30)  # 全局超时 30 秒

# 或使用 urllib 的 timeout
urllib.request.urlopen(url, timeout=10)

常见陷阱

陷阱 1:脚本没有执行权限

❌ 错误:直接运行脚本提示 Permission denied

✅ 解决:

chmod +x scripts/*.py

陷阱 2:输出格式不统一

❌ 错误:有时输出字符串,有时输出 JSON

✅ 正确:始终输出 JSON 格式

# 错误
print("操作成功")

# 正确
print(json.dumps({"success": True, "message": "操作成功"}))

陷阱 3:中文编码问题

❌ 错误:输出中文显示为 \uXXXX

✅ 正确:使用 ensure_ascii=False

print(json.dumps(data, ensure_ascii=False))

实践建议

  1. 从简单开始

    • 第一个 Skill 只做一件事,把它做好
    • 不要一开始就追求复杂功能
  2. 充分测试

    • 在本地反复测试脚本
    • 模拟各种异常情况(网络失败、参数错误等)
  3. 文档先行

    • 先写 SKILL.md,明确 Skill 要做什么
    • 再写代码实现,避免方向偏离
  4. 版本管理

    • 使用 Git 管理 Skill 代码
    • 打标签标记稳定版本
  5. 分享与反馈

    • 好用的 Skill 可以分享到 ClawHub
    • 收集用户反馈持续改进

相关阅读

创建 Skill 是扩展 OpenClaw 能力的核心方式。掌握 SKILL.md 规范和脚本实现,你就能为 Agent 赋予无限可能。

#["skill"#"开发"#"教程"]