OpenClaw Skill 编写规范 与示例
OpenClaw Skill 编写规范 与示例完整的 Skill 开发指南从基础结构到高级实践 一、目录结构标准结构~/.openclaw/workspace/skills/skill-name/ ├── SKILL.md # 必需技能定义文件 ├── scripts/ # 可选执行脚本 │ ├── main.py │ └── helper.sh ├── references/ # 可选参考文档 │ └── api_examples.md ├── assets/ # 可选静态资源 │ └── config_template.json └── README.md # 可选使用说明最小结构~/.openclaw/workspace/skills/skill-name/ └── SKILL.md # 唯一必需文件 二、SKILL.md 标准格式完整模板--- name: skill-name description: 一句话描述说明触发场景和功能 homepage: https://... # 可选项目主页 metadata: { openclaw: { emoji: emoji, os: [darwin, linux], # 可选支持的系统 requires: { bins: [curl, python3], # 必需的二进制 anyBins: [node, bun], # 任一存在即可 env: [API_KEY], # 必需的环境变量 config: [feature.enabled] # 必需的配置项 }, primaryEnv: API_KEY, # 主环境变量用于 apiKey 配置 skillKey: custom-key, # 可选自定义配置键 install: [ # 可选安装说明 { id: brew, kind: brew, formula: package-name, bins: [binary-name], label: Install Package (brew) }, { id: node, kind: node, package: scope/package, bins: [binary-name], label: Install Package (npm) } ] } } --- # Skill Name - 技能标题 简短介绍1-2 句话。 ## 使用场景 ✅ **USE when:** - 用户询问/请求 X - 需要执行 Y 操作 - 场景 Z ❌ **DONT use when:** - 情况 A用其他技能 - 情况 B超出范围 ## 快速开始 bash # 基本用法 command args # 进阶用法 command args --flag详细用法功能 1说明 示例命令。功能 2说明 示例命令。配置选项{option1:value,option2:123}参数说明默认值option1说明default错误处理错误处理方式API 失败重试 3 次使用缓存认证失败提示用户配置 API Key安全注意⚠️ 风险提示、限制条件、合规说明等。相关文件scripts/xxx.py- 说明references/yyy.md- 说明依赖安装# 安装依赖pipinstall...# 或npminstall...--- ## ️ 三、Frontmatter 字段详解 ### 必需字段 | 字段 | 类型 | 说明 | 示例 | |------|------|------|------| | name | string | 技能唯一标识小写下划线分隔 | stock_analyzer | | description | string | 触发场景 功能描述 | 股票分析。Use when user asks for stock... | ### metadata.openclaw 字段 | 字段 | 类型 | 必需 | 说明 | |------|------|------|------| | emoji | string | 推荐 | Skills UI 显示的 emoji | | os | string[] | 可选 | 支持的系统darwin/linux/win32 | | requires.bins | string[] | 可选 | 所有必需的二进制文件 | | requires.anyBins | string[] | 可选 | 任一存在即可的二进制 | | requires.env | string[] | 可选 | 必需的环境变量 | | requires.config | string[] | 可选 | 必需的 openclaw.json 配置路径 | | primaryEnv | string | 可选 | 主环境变量用于 apiKey 配置 | | skillKey | string | 可选 | 自定义配置键默认用 name | | install | object[] | 可选 | 安装程序定义 | ### 安装器格式 json { id: brew, // 安装器 ID kind: brew, // brew | node | go | uv | download formula: package-name, // kindbrew 时必需 package: scope/pkg, // kindnode 时必需 bins: [binary-name], // 安装后提供的二进制 label: Install (brew), // UI 显示文本 os: [darwin] // 可选仅限某些系统 } 四、技能类型判断判断流程图读 SKILL.md ↓ 有 metadata.requires 吗 ├─ 有 → 需要外部工具 │ ├─ bins: [curl] → 系统工具技能 │ ├─ bins: [oracle] → 外部 CLI 技能 │ └─ 调用 mcporter → MCP 工具技能 │ └─ 没有 → 纯文本技能 └─ 用 exec/web_fetch 等基础工具实现类型对比表类型特征例子调用方式系统工具requires.bins: [curl]weatherexec运行系统命令外部 CLIrequires.bins: [oracle] installoracle, himalayaexec运行 CLIMCP 工具调用mcporter callmcporterMCP 协议调用纯文本无 metadata.requires自定义业务逻辑exec/web_fetch组合 五、混合技能编写场景静态文本 HTTP MCP--- name: hybrid_skill description: 混合数据源技能 metadata: { openclaw: { requires: { bins: [curl, python3, mcporter], env: [API_KEY], config: [mcp.enabled] } } } --- # Hybrid Skill ## 数据源总览 | 类型 | 来源 | 调用方式 | |------|------|---------| | 静态文本 | 本技能文档 | 直接阅读 | | HTTP API | 公开 API | curl / python | | MCP 服务 | MCP 服务器 | mcporter call | ## 调用流程 1. **静态文本**读取配置规则 2. **HTTP 请求**抓取数据 bash curl https://api.example.com/dataMCP 服务获取实时数据mcporter call server.tool arg:value降级方案错误降级方式MCP 不可用降级到 HTTP APIHTTP 失败使用缓存数据--- ## 六、安全规范 ### 环境变量 json // ~/.openclaw/openclaw.json { skills: { entries: { my-skill: { enabled: true, apiKey: { source: env, provider: default, id: MY_API_KEY }, env: { MY_API_KEY: sk-xxx // 或用 SecretRef } } } } }安全清单✅ 不在 SKILL.md 中硬编码密钥✅ 敏感操作前要求用户确认✅ 外部输入需要验证/转义✅ 使用trash而非rm可恢复✅ 沙箱环境运行不受信代码 七、测试流程1. 创建技能mkdir-p~/.openclaw/workspace/skills/my-skill# 创建 SKILL.md2. 刷新技能# 方式 1重启 Gatewayopenclaw gateway restart# 方式 2等待自动刷新watcher 默认启用3. 测试技能# 测试触发openclaw agent--message使用 my-skill 做 XXX# 或直接在聊天中测试4. 调试# 查看技能加载状态openclaw skills list# 查看技能详情openclaw skills show my-skill 八、最佳实践命名规范✅snake_casestock_analyzer✅ 小写字母 下划线❌ 不要大写字母❌ 不要用空格或特殊字符描述写法# ✅ 好包含触发场景 description: 股票分析。Use when user asks for stock recommendations, financial news... # ❌ 差太模糊 description: 分析股票指令清晰# ✅ 好具体明确 使用 curl 调用 wttr.in API格式curl wttr.in/{city}?format3 # ❌ 差模糊 获取天气数据错误处理## 错误处理 | 错误 | 处理方式 | |------|---------| | HTTP 429 | 等待 60 秒后重试 | | HTTP 401 | 提示用户检查 API Key | | 超时 | 使用缓存数据如果有 |文档结构使用场景USE/DON’T USE快速开始最常用命令详细用法分功能配置选项错误处理安全注意相关文件 九、配置参考openclaw.json 完整示例{ skills: { // 仅允许列表中的 bundled skills allowBundled: [gemini, peekaboo], // 加载配置 load: { extraDirs: [~/Projects/my-skills], // 额外技能目录 watch: true, // 自动刷新 watchDebounceMs: 250 }, // 安装配置 install: { preferBrew: true, // 优先 brew nodeManager: npm // npm | pnpm | yarn | bun }, // 单个技能配置 entries: { my-skill: { enabled: true, apiKey: sk-xxx, // 或 SecretRef 对象 env: { MY_API_KEY: xxx }, config: { custom_option: value } }, another-skill: { enabled: false // 禁用 } } } } 十、参考资源官方文档Creating SkillsSkills ConfigClawHub - 技能市场示例技能# 系统自带技能ls/opt/homebrew/lib/node_modules/openclaw/skills/# 用户技能ls~/.openclaw/skills/# 工作区技能ls~/.openclaw/workspace/skills/优先级工作区技能 (最高) → ~/.openclaw/skills → bundled skills (最低) 十一、快速模板最简技能--- name: hello description: 打招呼技能。Use when user says hello or asks for a greeting. --- # Hello Skill 当用户打招呼时回复友好的问候语。 bash echo Hello! How can I help you today?### 完整技能 复制上面的 [完整模板](#完整模板) 开始编写。 --- --- ## 十二、完整案例天气活动规划师 这是一个**综合型技能**根据天气情况推荐去哪里玩、适合做什么活动。 ### 技能特点 - ✅ 使用 HTTP API 获取天气数据 - ✅ 静态文本定义活动规则什么天气适合什么活动 - ✅ 决策逻辑天气 → 活动推荐 - ✅ 多城市支持 - ✅ 降级方案API 失败时的处理 --- ### 目录结构~/.openclaw/workspace/skills/weather-activity-planner/├── SKILL.md├── scripts/│ └── fetch_weather.py├── references/│ └── activity_rules.md└── assets/└── cities.json--- ### SKILL.md 完整示例 markdown --- name: weather_activity_planner description: 根据天气推荐活动。Use when user asks where to go or what to do based on weather. 输入城市输出活动建议。 homepage: https://wttr.in/:help metadata: { openclaw: { emoji: , requires: { bins: [curl, python3] }, install: [ { id: pip, kind: pip, package: requests, label: Install Python deps } ] } } --- # Weather Activity Planner - 天气活动规划师 根据实时天气情况推荐适合的活动和去处。 ## 使用场景 ✅ **USE when:** - 今天天气适合干什么 - 推荐个地方去玩 - 周末去哪里玩比较好 - 这个天气适合户外活动吗 ❌ **DONT use when:** - 需要精确到小时的预报用专业天气 App - 极端天气警报查看官方预警 ## 数据源 | 类型 | 来源 | 调用方式 | |------|------|---------| | **天气数据** | wttr.in API | curl wttr.in/{city}?formatj1 | | **活动规则** | 本技能文档静态文本 | 直接阅读 | | **城市列表** | assets/cities.json | 读取文件 | ## 天气 → 活动映射规则 ### 晴天 (Sunny/Clear) | 温度范围 | 推荐活动 | 推荐地点 | |----------|---------|---------| | 25°C | 游泳、海滩、水上乐园 | 海边、水上公园 | | 15-25°C | 徒步、骑行、野餐、露营 | 公园、山区、郊外 | | 5-15°C | 城市漫步、摄影、放风筝 | 市中心、广场、公园 | | 5°C | 晒太阳、温泉 | 温泉度假村、露天咖啡厅 | ### ☁️ 多云 (Cloudy) | 温度范围 | 推荐活动 | 推荐地点 | |----------|---------|---------| | 20°C | 徒步、骑行、观光 | 山区、景点 | | 10-20°C | 城市探索、骑行 | 市区、古镇 | | 10°C | 室内景点、咖啡厅 | 博物馆、书店 | ### ️ 雨天 (Rainy) | 雨量 | 推荐活动 | 推荐地点 | |------|---------|---------| | 小雨 | 室内活动、雨中漫步带伞 | 商场、室内景点 | | 中雨 | 纯室内活动 | 博物馆、电影院、室内游乐场 | | 大雨 | 宅家、线上活动 | 家、酒店 | ### ❄️ 雪天 (Snowy) | 雪量 | 推荐活动 | 推荐地点 | |------|---------|---------| | 小雪 | 赏雪、拍照、堆雪人 | 公园、山区 | | 中雪 | 滑雪、温泉 | 滑雪场、温泉度假村 | | 大雪 | 避免外出 | 室内 | ### ️ 极端温度 | 情况 | 建议 | |------|------| | 35°C | 避免户外活动选择室内空调场所 | | 0°C | 保暖为主选择室内或温泉 | ## 快速开始 ### 基本用法 bash # 获取天气JSON 格式 curl -s wttr.in/Beijing?formatj1 # 使用 Python 脚本推荐自动解析 python {baseDir}/scripts/fetch_weather.py --city Beijing完整流程用户问“北京今天适合干什么”# 1. 获取天气数据curl-swttr.in/Beijing?formatj1/tmp/weather.json# 2. 解析天气使用 Python 脚本python{baseDir}/scripts/fetch_weather.py--cityBeijing--output/tmp/result.json# 3. 根据天气匹配活动规则参考本文档的映射表# 输出推荐结果脚本用法fetch_weather.py# 基本用法python{baseDir}/scripts/fetch_weather.py--cityBeijing# 指定日期0今天1明天2后天python{baseDir}/scripts/fetch_weather.py--cityBeijing--day1# 输出详细结果python{baseDir}/scripts/fetch_weather.py--cityBeijing--verbose# 保存结果python{baseDir}/scripts/fetch_weather.py--cityBeijing--outputresult.json参数说明参数说明默认值--city城市名英文或拼音必需--day日期0-20今天--output输出文件stdout--verbose详细输出false输出示例输入用户上海今天适合干什么输出 上海天气概览 ━━━━━━━━━━━━━━━━━━━━ ️ 天气多云 ️ 温度18°C (体感 17°C) 风力3 级 东北风 湿度65% ️ 降水概率10% ━━━━━━━━━━━━━━━━━━━━ 推荐活动 ━━━━━━━━━━━━━━━━━━━━ ✅ 最佳推荐城市探索、骑行 推荐地点 • 外滩城市漫步 • 法租界骑行 • 田子坊拍照 活动建议 • 温度适宜适合户外活动 • 多云天气拍照光线柔和 • 建议带薄外套早晚较凉 ⚠️ 注意事项 • 降水概率低无需带伞 • 风力适中不影响活动配置选项在assets/cities.json中配置热门城市{cities:[{name:北京,en:Beijing,region:华北},{name:上海,en:Shanghai,region:华东},{name:广州,en:Guangzhou,region:华南}]}错误处理错误处理方式API 返回失败重试 3 次提示用户稍后再试城市名无效提示用户检查城市名建议用拼音无天气数据使用备用 API 或提示无法获取降级方案wttr.in API 失败 ↓ 尝试备用 API (Open-Meteo) ↓ 提示用户查看当地天气预报安全注意⚠️仅供参考- 实际出行前请查看最新天气预报⚠️极端天气- 暴雨、台风等请遵循官方指引⚠️个人差异- 老人、儿童、孕妇需额外注意相关文件scripts/fetch_weather.py- 天气获取脚本references/activity_rules.md- 详细活动规则assets/cities.json- 城市列表依赖安装# Python 依赖pipinstallrequests# 验证安装python-cimport requests; print(OK)扩展建议添加 MCP 服务可选如果有 MCP 本地生活服务可以整合# 调用 MCP 获取附近景点mcporter call local.get_attractions city:Beijingtype:outdoor# 调用 MCP 预订门票mcporter call local.book_ticket attraction:Great Walldate:2026-03-15添加用户偏好在配置中记录用户偏好{user_preferences:{prefer_outdoor:true,max_walking_distance:5km,budget:medium}}--- ### scripts/fetch_weather.py 示例 python #!/usr/bin/env python3 Weather Activity Planner - 天气获取脚本 根据天气数据推荐适合的活动 import requests import json import argparse from datetime import datetime # 天气 → 活动映射 ACTIVITY_MAP { sunny: { hot: {temp_min: 25, activities: [游泳, 海滩, 水上乐园], places: [海边, 水上公园]}, warm: {temp_min: 15, activities: [徒步, 骑行, 野餐, 露营], places: [公园, 山区, 郊外]}, cool: {temp_min: 5, activities: [城市漫步, 摄影, 放风筝], places: [市中心, 广场, 公园]}, cold: {temp_min: -999, activities: [晒太阳, 温泉], places: [温泉度假村, 露天咖啡厅]}, }, cloudy: { warm: {temp_min: 20, activities: [徒步, 骑行, 观光], places: [山区, 景点]}, cool: {temp_min: 10, activities: [城市探索, 骑行], places: [市区, 古镇]}, cold: {temp_min: -999, activities: [室内景点, 咖啡厅], places: [博物馆, 书店]}, }, rainy: { light: {activities: [室内活动, 雨中漫步], places: [商场, 室内景点]}, medium: {activities: [纯室内活动], places: [博物馆, 电影院, 室内游乐场]}, heavy: {activities: [宅家, 线上活动], places: [家, 酒店]}, }, } def get_weather(city, day0): 获取天气数据 url fhttps://wttr.in/{city}?formatj1 try: response requests.get(url, timeout10) response.raise_for_status() return response.json() except Exception as e: print(f❌ 获取天气失败{e}) return None def parse_weather(data, day0): 解析天气数据 if not data or current_condition not in data: return None current data[current_condition][0] forecast data[weather][day] if weather in data else None return { city: data.get(nearest_area, [{}])[0].get(areaName, [{}])[0].get(value, Unknown), condition: current.get(weatherDesc, [{}])[0].get(value, Unknown), condition_code: current.get(weatherCode, 0), temp_c: int(current.get(temp_C, 0)), feels_like: int(current.get(FeelsLikeC, 0)), humidity: current.get(humidity, 0), wind_speed: current.get(windspeedKmph, 0), wind_dir: current.get(winddir16Point, ), precip_prob: forecast.get(avgdailyChanceOfRain, 0) if forecast else 0, } def recommend_activity(weather): 根据天气推荐活动 condition weather[condition].lower() temp weather[temp_c] precip weather[precip_prob] # 判断天气类型 if rain in condition or precip 50: weather_type rainy if precip 70: rain_level heavy elif precip 30: rain_level medium else: rain_level light activities ACTIVITY_MAP.get(rainy, {}).get(rain_level, {}).get(activities, [室内活动]) places ACTIVITY_MAP.get(rainy, {}).get(rain_level, {}).get(places, [室内场所]) elif cloud in condition or overcast in condition: weather_type cloudy if temp 20: level warm elif temp 10: level cool else: level cold activities ACTIVITY_MAP.get(cloudy, {}).get(level, {}).get(activities, [室内活动]) places ACTIVITY_MAP.get(cloudy, {}).get(level, {}).get(places, [室内场所]) elif sun in condition or clear in condition: weather_type sunny if temp 25: level hot elif temp 15: level warm elif temp 5: level cool else: level cold activities ACTIVITY_MAP.get(sunny, {}).get(level, {}).get(activities, [室内活动]) places ACTIVITY_MAP.get(sunny, {}).get(level, {}).get(places, [室内场所]) else: activities [室内活动] places [室内场所] return { activities: activities, places: places, weather_type: weather_type, } def format_output(weather, recommendation): 格式化输出 output [] output.append(f {weather[city]}天气概览) output.append(━ * 40) output.append(f️ 天气{weather[condition]}) output.append(f️ 温度{weather[temp_c]}°C (体感 {weather[feels_like]}°C)) output.append(f 风力{weather[wind_speed]}km/h {weather[wind_dir]}) output.append(f 湿度{weather[humidity]}%) output.append(f️ 降水概率{weather[precip_prob]}%) output.append() output.append(━ * 40) output.append( 推荐活动) output.append(━ * 40) output.append() output.append(f✅ 最佳推荐{、.join(recommendation[activities])}) output.append() output.append( 推荐地点) for place in recommendation[places]: output.append(f • {place}) output.append() output.append( 活动建议) if weather[temp_c] 25: output.append( • 温度较高注意防晒补水) elif weather[temp_c] 10: output.append( • 温度较低注意保暖) else: output.append( • 温度适宜适合户外活动) if weather[precip_prob] 50: output.append( • 降水概率高建议带伞) else: output.append( • 降水概率低无需带伞) output.append() output.append(⚠️ 注意事项) output.append( • 仅供参考出行前请查看最新预报) output.append( • 极端天气请遵循官方指引) return \n.join(output) def main(): parser argparse.ArgumentParser(descriptionWeather Activity Planner) parser.add_argument(--city, requiredTrue, help城市名英文或拼音) parser.add_argument(--day, typeint, default0, help日期0今天1明天2后天) parser.add_argument(--output, help输出文件路径) parser.add_argument(--verbose, actionstore_true, help详细输出) args parser.parse_args() # 获取天气 if args.verbose: print(f 正在获取 {args.city} 的天气数据...) weather_data get_weather(args.city, args.day) if not weather_data: print(❌ 无法获取天气数据请稍后再试) return # 解析天气 weather parse_weather(weather_data, args.day) if not weather: print(❌ 无法解析天气数据) return if args.verbose: print(f✅ 天气数据获取成功) # 推荐活动 recommendation recommend_activity(weather) # 格式化输出 output format_output(weather, recommendation) # 输出结果 if args.output: with open(args.output, w, encodingutf-8) as f: f.write(output) print(f✅ 结果已保存到 {args.output}) else: print(output) if __name__ __main__: main()使用示例# 基本用法python{baseDir}/scripts/fetch_weather.py--cityBeijing# 明天天气python{baseDir}/scripts/fetch_weather.py--cityShanghai--day1# 保存结果python{baseDir}/scripts/fetch_weather.py--cityGuangzhou--outputresult.json# 详细模式python{baseDir}/scripts/fetch_weather.py--cityShenzhen--verbose这个案例展示了技能要素实现方式静态文本天气→活动映射规则表HTTP 请求curl wttr.in/{city}?formatj1本地脚本fetch_weather.py处理逻辑决策逻辑根据天气条件匹配活动降级方案API 失败→备用 API→提示用户配置选项cities.json城市列表错误处理超时、无效城市、无数据
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2408723.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!