一、什么是ClawHub和Skill?
ClawHub是OpenClaw官方维护的技能(Skill)注册中心,类似于AI智能体的"应用商店"。目前已有13000+ Skills,开发者可以在这里分享和安装各种可复用的自动化能力单元。
Skill到底是什么?
Skill是一个可插拔的任务指令集,它让AI Agent能够处理特定领域的任务。简单来说:
- Tools(工具):决定Agent能不能做某类动作(如文件读写、网络请求)
- Skills(技能):给Agent增加特定能力(如天气查询、代码审查、网络搜索)
每个Skill是一个文件夹,核心是SKILL.md文件,包含技能元数据和使用指令。
二、Skill的目录结构
一个标准的Skill目录结构如下:
my-skill/
├── SKILL.md # 必需:技能定义文件
├── scripts/ # 可选:可执行脚本
│ └── main.py
├── references/ # 可选:参考文档
│ └── api-docs.md
└── assets/ # 可选:静态资源
└── template.html
核心文件说明:
SKILL.md:技能的核心定义,包含YAML frontmatter和Markdown指令scripts/:存放可执行脚本(Python、Node.js等)references/:参考文档,按需加载assets/:模板、图标等静态资源
三、实战案例:开发一个天气查询Skill
让我们从零开始开发一个实用的天气查询Skill。
步骤1:创建目录结构
mkdir -p weather-skill/{scripts,references,assets}
cd weather-skill
touch SKILL.md scripts/weather.py
步骤2:编写SKILL.md文件
SKILL.md是Skill的灵魂,包含两部分:YAML frontmatter (元数据)和Markdown正文(指令)。
---
name: weather-query
description: 查询任意城市的实时天气和未来7天预报。支持温度、湿度、天气状况等信息获取。
user-invocable: true
disable-model-invocation: false
metadata:
openclaw:
requires:
bins:
- python3
env: []
homepage: https://open-meteo.com/
---
# 天气查询技能
## 功能说明
本技能可以查询全球任意城市的实时天气和未来天气预报。
## 使用方法
### 基本查询
```bash
python3 {baseDir}/scripts/weather.py 北京
高级查询
python3 {baseDir}/scripts/weather.py 上海 --days 5 --format json
参数说明
|----------|--------|----|------------------------|
| 参数 | 类型 | 必填 | 说明 |
| city | string | 是 | 城市名称(中文或英文) |
| --days | int | 否 | 预报天数(1-7,默认1) |
| --format | string | 否 | 输出格式(text/json,默认text) |
输出示例
文本格式:
北京天气:
温度:22°C
天气:晴
湿度:45%
更新时间:2026-04-08T10:30:00
JSON格式:
{
"city": "北京",
"temperature": 22,
"condition": "晴",
"humidity": 45
}
相关文档
如需了解API详情,请读取:{baseDir}/references/api-docs.md
### 步骤3:编写可执行脚本
创建`scripts/weather.py`文件:
```python
#!/usr/bin/env python3
"""
天气查询脚本
使用Open-Meteo API(免费,无需API Key)
"""
import argparse
import json
import requests
from datetime import datetime
import sys
# 天气代码映射
WEATHER_CODES = {
0: "晴朗", 1: "主要晴朗", 2: "部分多云", 3: "多云",
45: "雾", 48: "雾凇", 51: "轻度毛毛雨", 53: "中度毛毛雨",
55: "重度毛毛雨", 61: "轻度雨", 63: "中度雨", 65: "大雨",
71: "轻度雪", 73: "中度雪", 75: "大雪", 77: "雪粒",
80: "轻度阵雨", 81: "中度阵雨", 82: "强阵雨",
95: "雷暴", 96: "雷暴带轻度冰雹", 99: "雷暴带重度冰雹"
}
def geocode_city(city_name):
"""获取城市的经纬度"""
url = "https://geocoding-api.open-meteo.com/v1/search"
params = {
"name": city_name,
"count": 1,
"language": "zh",
"format": "json"
}
try:
response = requests.get(url, params=params, timeout=10)
data = response.json()
if not data.get("results"):
return None
return {
"latitude": data["results"][0]["latitude"],
"longitude": data["results"][0]["longitude"],
"name": data["results"][0]["name"]
}
except Exception as e:
print(f"地理编码错误:{e}", file=sys.stderr)
return None
def get_weather_data(lat, lon, days=1):
"""获取天气数据"""
url = "https://api.open-meteo.com/v1/forecast"
params = {
"latitude": lat,
"longitude": lon,
"current": [
"temperature_2m",
"relative_humidity_2m",
"weather_code",
"wind_speed_10m"
],
"daily": [
"temperature_2m_max",
"temperature_2m_min",
"weather_code",
"sunrise",
"sunset"
],
"timezone": "auto",
"forecast_days": days
}
try:
response = requests.get(url, params=params, timeout=10)
response.raise_for_status()
return response.json()
except Exception as e:
print(f"获取天气数据错误:{e}", file=sys.stderr)
return None
def format_text_output(city, current, daily=None):
"""格式化文本输出"""
output = []
output.append(f"\n{city}天气:")
output.append(f" 温度:{current['temperature_2m']}°C")
output.append(f" 天气:{WEATHER_CODES.get(current['weather_code'], '未知')}")
output.append(f" 湿度:{current['relative_humidity_2m']}%")
output.append(f" 风速:{current['wind_speed_10m']} km/h")
if daily:
output.append("\n未来预报:")
for i, day in enumerate(daily['time'])::
max_temp = daily['temperature_2m_max'][i]
min_temp = daily['temperature_2m_min'][i]
condition = WEATHER_CODES.get(daily['weather_code'][i], '未知')
output.append(f" {day}: {min_temp}°C - {max_temp}°C {condition}")
return "\n".join(output)
def format_json_output(city, current, daily=None):
"""格式化JSON输出"""
result = {
"city": city,
"temperature": current['temperature_2m'],
"condition": WEATHER_CODES.get(current['weather_code'], '未知'),
"humidity": current['relative_humidity_2m'],
"wind_speed": current['wind_speed_10m'],
"update_time": datetime.now().isoformat()
}
if daily:
result["forecast"] = []
for i in range(len(daily['time'])):
result["forecast"].append({
"date": daily['time'][i],
"max_temp": daily['temperature_2m_max'][i],
"min_temp": daily['temperature_2m_min'][i],
"condition": WEATHER_CODES.get(daily['weather_code'][i], '未知')
})
return json.dumps(result, ensure_ascii=False, indent=2)
def main():
parser = argparse.ArgumentParser(description="天气查询工具")
parser.add_argument("city", help="城市名称")
parser.add_argument("--days", type=int, default=1,
help="预报天数(1-7,默认1)")
parser.add_argument("--format", choices=["text", "json"],
default="text", help="输出格式")
args = parser.parse_args()
# 验证天数
if args.days < 1 or args.days > 7:
print("错误:预报天数必须在1-7之间", file=sys.stderr)
sys.exit(1)
# 地理编码
print(f"正在查询 {args.city} 的天气...", file=sys.stderr)
location = geocode_city(args.city)
if not location:
print(f"错误:找不到城市 '{args.city}'", file=sys.stderr)
sys.exit(1)
# 获取天气数据
weather_data = get_weather_data(
location["latitude"],
location["longitude"],
args.days
)
if not weather_data:
print("错误:获取天气数据失败", file=sys.stderr)
sys.exit(1)
# 格式化输出
if args.format == "json":
output = format_json_output(
location["name"],
weather_data["current"],
weather_data.get("daily")
)
else:
output = format_text_output(
location["name"],
weather_data["current"],
weather_data.get("daily")
)
print(output)
if __name__ == "__main__":
main()
步骤4:添加依赖文件
创建requirements.txt(可选):
requests>=2.28.0
步骤5:本地测试Skill
# 安装依赖
pip install requests
# 测试基本功能
python3 scripts/weather.py 北京
# 测试JSON输出
python3 scripts/weather.py 上海 --days 3 --format json
# 测试错误处理
python3 scripts/weather.py 不存在的城市
预期输出:
北京天气:
温度:22°C
天气:晴朗
湿度:45%
风速:12 km/h
四、上传Skill到ClawHub
方式一:直接上传文件夹(推荐新手)
第一步:准备上传文件
确保你的文件夹结构完整,只包含纯文本文件:
# 清理不必要的文件
cd weather-skill
rm -rf .git __pycache__ *.pyc
注意: ClawHub不接受二进制文件、图片等,只支持SKILL.md和纯文本文件。
第二步:访问ClawHub发布页面
- 打开浏览器访问:https://clawhub.ai/import
- 使用GitHub账号登录(如果没有账号,先注册)
第三步:填写发布表单
|------------------|---------------------|---------------------|
| 字段 | 填写说明 | 示例 |
| Slug | 技能的URL标识符(小写字母+短横线) | weather-query |
| Display name | 显示名称(支持中文) | 天气查询助手 |
| Version | 版本号(遵循语义化版本) | 1.0.0 |
| Tags | 版本标签(默认latest) | latest |
⚠️ 重要提示: Slug必须是小写字母+短横线,不能有大写字母!
第四步:上传文件夹
- 点击"Drop a folder"区域
- 选择你的
weather-skill文件夹 - 系统会自动检测SKILL.md文件
第五步:处理验证
ClawHub会自动验证:
- ✅ SKILL.md是否存在
- ✅ frontmatter是否包含name和description
- ✅ 文件是否为纯文本
常见错误及解决:
Slug must be lowercase:改为全小写Remove non-text files:删除.git、LICENSE等非文本文件SKILL.md not found:确保文件夹根目录有SKILL.md
第六步:确认许可证
默认使用MIT-0许可证(最宽松的开源许可证):
- 允许任何人免费使用、修改和重新分发
- 无需署名
勾选同意条款。
第七步:填写Changelog并发布
Initial release of Weather Query Skill
- 支持全球城市天气查询
- 支持1-7天预报
- 支持文本和JSON输出格式
点击"Publish skill"按钮。
方式二:从GitHub导入(适合已有仓库)
如果你已将代码推送到GitHub:
# 初始化Git仓库
cd weather-skill
git init
git add .
git commit -m "Initial commit"
# 创建GitHub仓库并推送
gh repo create weather-query --public --source=. --push
然后在ClawHub选择"Import from GitHub",输入仓库地址即可。
五、发布后的管理
查看你的Skill
发布成功后,可以访问:
https://clawhub.ai/你的用户名/weather-query
用户如何安装
用户可以通过以下命令安装你的Skill:
# 通过ClawHub CLI安装
clawhub install 你的用户名/weather-query
# 或使用OpenClaw命令
openclaw skills install 你的用户名/weather-query
更新Skill
- 修改SKILL.md或脚本
- 递增版本号(如1.0.0 → 1.1.0)
- 重新上传文件夹
- 填写更新说明
六、Skill开发最佳实践
1. 编写优质的description
description字段是AI决定是否调用技能的唯一依据[[6]]:
❌ 不好的例子:
description: 天气查询
✅ 好的例子:
description: 查询任意城市的实时天气和未来7天预报。
当用户询问天气、气温、预报、下雨、穿衣建议时使用。
支持中文和英文城市名称。
2. 合理的错误处理
# 缺少API Key时
if not api_key:
print("错误:缺少API_KEY环境变量", file=sys.stderr)
sys.exit(1)
# API请求失败
try:
response = requests.get(url, timeout=10)
response.raise_for_status()
except requests.exceptions.Timeout:
print("错误:请求超时,请检查网络连接", file=sys.stderr)
sys.exit(1)
3. 输出Markdown格式
AI Agent能更好地解析Markdown格式:
print("## 天气报告")
print(f"- **城市**:{city}")
print(f"- **温度**:{temp}°C")
print(f"- **天气**:{condition}")
4. 使用{baseDir}变量
在SKILL.md中使用{baseDir}引用脚本路径,运行时会自动替换为实际路径:
python3 {baseDir}/scripts/weather.py 北京
七、常见问题FAQ
Q1:Skill审核需要多久? A:ClawHub采用"无门槛发布"策略,无需审核,即时发布。
Q2:可以收费吗? A:可以,支持$1-99的定价策略。
Q3:如何测试Skill? A:使用OpenClaw的测试命令:
openclaw skills check
openclaw skills info weather-query
Q4:Skill被标记为可疑怎么办? A:ClawHub通过标注机制区分可信与可疑技能,确保代码质量即可。
八、总结
开发并上传Skill到ClawHub的完整流程:
- 设计Skill:确定功能和触发条件
- 创建目录:准备SKILL.md和脚本
- 编写代码:实现核心功能
- 本地测试:确保功能正常
- 上传ClawHub:填写表单,发布技能
- 维护更新:根据反馈迭代
收益:
- 分享你的专业知识
- 帮助全球开发者
- 可能获得收入(ClawHub支持付费Skill)
- 提升个人技术影响力