从零开始:如何开发Skill并上传到ClawHub完整教程

张开发
2026/5/31 13:20:52 15 分钟阅读
从零开始:如何开发Skill并上传到ClawHub完整教程
一、什么是ClawHub和SkillClawHub是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参数说明参数类型必填说明citystring是城市名称中文或英文--daysint否预报天数1-7默认1--formatstring否输出格式text/json默认text输出示例文本格式北京天气 温度22°C 天气晴 湿度45% 更新时间2026-04-08T10:30:00JSON格式{ 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, paramsparams, timeout10) 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}, filesys.stderr) return None def get_weather_data(lat, lon, days1): 获取天气数据 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, paramsparams, timeout10) response.raise_for_status() return response.json() except Exception as e: print(f获取天气数据错误{e}, filesys.stderr) return None def format_text_output(city, current, dailyNone): 格式化文本输出 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, dailyNone): 格式化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_asciiFalse, indent2) def main(): parser argparse.ArgumentParser(description天气查询工具) parser.add_argument(city, help城市名称) parser.add_argument(--days, typeint, default1, help预报天数1-7默认1) parser.add_argument(--format, choices[text, json], defaulttext, help输出格式) args parser.parse_args() # 验证天数 if args.days 1 or args.days 7: print(错误预报天数必须在1-7之间, filesys.stderr) sys.exit(1) # 地理编码 print(f正在查询 {args.city} 的天气..., filesys.stderr) location geocode_city(args.city) if not location: print(f错误找不到城市 {args.city}, filesys.stderr) sys.exit(1) # 获取天气数据 weather_data get_weather_data( location[latitude], location[longitude], args.days ) if not weather_data: print(错误获取天气数据失败, filesys.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​​可选requests2.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环境变量, filesys.stderr) sys.exit(1) # API请求失败 try: response requests.get(url, timeout10) response.raise_for_status() except requests.exceptions.Timeout: print(错误请求超时请检查网络连接, filesys.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 北京七、常见问题FAQQ1Skill审核需要多久AClawHub采用无门槛发布策略无需审核即时发布。Q2可以收费吗A可以支持$1-99的定价策略。Q3如何测试SkillA使用OpenClaw的测试命令openclaw skills check openclaw skills info weather-queryQ4Skill被标记为可疑怎么办AClawHub通过标注机制区分可信与可疑技能确保代码质量即可。八、总结开发并上传Skill到ClawHub的完整流程设计Skill确定功能和触发条件创建目录准备SKILL.md和脚本编写代码实现核心功能本地测试确保功能正常上传ClawHub填写表单发布技能维护更新根据反馈迭代收益分享你的专业知识帮助全球开发者可能获得收入ClawHub支持付费Skill提升个人技术影响力

更多文章