为什么需要自己开发OpenClaw技能?
用OpenClaw三个月,我发现一个规律:官方Skills商店里的技能虽然丰富,但真正贴合自己工作流的,往往需要自己动手开发。就像手机App Store里有成千上万应用,但真正帮你提效的,还是那些自己定制的自动化脚本。
我第一次萌生开发技能的念头,是因为一个很小的需求:每天定时从某个内部系统抓取数据并生成报告。市面上没有现成的技能支持这个内部系统的API,而我又不想每次手动登录复制粘贴。于是我开始研究OpenClaw的技能开发机制,踩了一堆坑之后,终于跑通了第一个技能。
这篇文章是我开发技能过程中积累的实战经验,不讲虚的概念,只讲怎么动手做。从目录结构到调试技巧,从API调用到错误处理,覆盖开发一个完整技能所需的全流程。
先搞清楚:技能是什么?不是什么?
很多人把技能理解成"插件",这个理解对了一半。技能确实像插件一样扩展功能,但它的本质是一套Prompt + 工具 + 工作流的组合。用代码类比:
- Prompt:相当于函数的逻辑,定义了AI应该怎么理解和执行任务
- 工具(Tools):相当于函数调用的外部能力,比如读写文件、发送请求、操作数据库
- 工作流(Workflow):相当于函数的执行流程,定义了任务的步骤和分支
技能不是独立的程序,而是运行在OpenClaw框架内的任务模块。它依赖OpenClaw提供的上下文(比如对话历史、用户配置、运行环境),不能脱离框架单独运行。
技能的目录结构:一眼看懂骨架
一个标准的技能目录结构是这样的:
.
my-first-skill/
├── SKILL.md # 技能主文件(必需)
├── package.json # 依赖声明(可选)
├── scripts/ # 脚本文件
│ ├── main.py # Python脚本
│ └── helper.js # JS脚本
├── templates/ # 模板文件
│ └── report.html # HTML模板
└── tests/ # 测试文件
└── test_main.py
核心是SKILL.md,这个文件定义了技能的一切:名称、描述、触发词、Prompt、工具列表。其他文件都是辅助,可以根据需要添加。
我第一次开发时犯的错误是直接写Python脚本,忘了写SKILL.md,结果OpenClaw根本识别不到这个技能。记住:SKILL.md是技能的身份证,没有它,技能不存在。
实战一:写一个简单的数据抓取技能
需求:每天早上8点,从某个API抓取数据并保存为JSON文件。这是一个典型的"定时任务+API调用+文件写入"场景。
步骤1:创建目录和SKILL.md
mkdir -p ~/.qclaw/skills/daily-fetch cd ~/.qclaw/skills/daily-fetch touch SKILL.md
步骤2:编写SKILL.md内容
--- name: daily-fetch description: 每日数据抓取技能,定时从指定API获取数据并保存本地 triggers: - "抓取数据" - "更新数据" - "获取最新" --- # 技能说明 这是一个定时数据抓取技能。当用户说"抓取数据"时,会执行以下流程: 1. 调用目标API获取JSON数据 2. 解析数据并提取关键字段 3. 保存到本地文件(带时间戳) 4. 返回简要摘要 ## 工具需求 - `web_fetch`: 发送HTTP请求 - `file_write`: 写入本地文件 ## 错误处理 - API请求失败 → 重试3次,间隔5秒 - 数据解析失败 → 记录错误日志,返回原始响应 - 文件写入失败 → 使用临时目录作为备选
注意:SKILL.md分成两部分。顶部的YAML front matter定义了技能的元数据,下面的Markdown内容是给AI看的Prompt。OpenClaw会把整个文件内容作为Prompt的一部分传给大模型。
实战二:让技能更智能——加入参数解析
上面的技能太死板:API地址、抓取频率都是写死的。真正的技能应该能根据用户的具体指令动态调整。比如:
- "抓取百度热搜数据" → 从百度API抓取
- "抓取GitHub趋势" → 从GitHub API抓取
- "每小时抓取一次" → 调整频率
这需要技能具备意图识别和参数提取能力。修改SKILL.md:
---
name: smart-fetch
description: 智能数据抓取技能,支持多种数据源和自定义频率
triggers:
- "抓取"
- "更新"
- "获取"
---
# 技能说明
当用户请求抓取数据时,按以下流程执行:
## 第一步:识别数据源
从用户指令中提取目标数据源:
- 百度/热搜/Baidu → `https://top.baidu.com/api`
- GitHub/趋势/热门 → `https://api.github.com/search/repositories`
- 微博/热搜/话题 → `https://weibo.com/ajax/statuses/hot`
如果用户未指定数据源,询问:"请指定数据源:百度热搜、GitHub趋势、微博热搜?"
## 第二步:解析频率
从用户指令中提取抓取频率:
- 每小时/每小时一次 → 间隔3600秒
- 每天/每天一次 → 每天早上8点执行
- 实时/立即 → 立即执行一次
- 未指定 → 默认每天一次
## 第三步:执行抓取
调用 `web_fetch` 工具,传入解析后的API地址。
处理响应:解析JSON,提取标题、链接、热度等字段。
## 第四步:保存与返回
保存到 `~/data/fetch_${source}_${timestamp}.json`
返回简要摘要:"已抓取X条数据,热门前三:1.XXX 2.XXX 3.XXX"
关键改进:在Prompt里加入了逻辑判断和参数提取的规则。AI会根据这些规则,先分析用户意图,再决定用什么参数执行。这就是"Prompt即代码"的威力。
实战三:处理复杂场景——多步骤工作流
真实需求往往不是单步操作,而是多步骤串联。比如"抓取数据→分析数据→生成报告→发送通知"。这需要技能支持工作流编排。
OpenClaw的技能可以通过调用其他技能或使用脚本来实现复杂工作流。这里演示用Python脚本串联多步骤:
步骤1:创建Python脚本 `scripts/workflow.py`
#!/usr/bin/env python3
import json
import requests
from datetime import datetime
import subprocess
def fetch_data(api_url):
"""抓取数据"""
resp = requests.get(api_url, timeout=10)
resp.raise_for_status()
return resp.json()
def analyze_data(data):
"""分析数据"""
# 提取关键字段并排序
items = data.get('items', [])
sorted_items = sorted(items, key=lambda x: x.get('score', 0), reverse=True)
return {
'total': len(sorted_items),
'top5': sorted_items[:5],
'avg_score': sum(x.get('score', 0) for x in sorted_items) / len(sorted_items) if sorted_items else 0
}
def generate_report(analysis):
"""生成报告"""
template = f"""
数据抓取报告 - {datetime.now().strftime('%Y-%m-%d %H:%M')}
总条数: {analysis['total']}
平均得分: {analysis['avg_score']:.2f}
热门前5:
{chr(10).join(f"{i+1}. {item['title']} (得分: {item['score']})" for i, item in enumerate(analysis['top5']))}
"""
return template
def send_notification(report):
"""发送通知(模拟)"""
print("通知已发送:")
print(report)
def main(api_url):
try:
# 步骤1:抓取
print("正在抓取数据...")
data = fetch_data(api_url)
# 步骤2:分析
print("正在分析数据...")
analysis = analyze_data(data)
# 步骤3:生成报告
print("正在生成报告...")
report = generate_report(analysis)
# 步骤4:发送通知
send_notification(report)
# 保存结果
with open(f"/tmp/report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt", 'w') as f:
f.write(report)
return "工作流执行成功"
except Exception as e:
return f"执行失败: {str(e)}"
if __name__ == "__main__":
import sys
api_url = sys.argv[1] if len(sys.argv) > 1 else "https://api.example.com/data"
result = main(api_url)
print(result)
步骤2:在SKILL.md中调用脚本
---
name: workflow-fetch
description: 数据抓取分析工作流
---
# 工作流技能
当用户请求"抓取并分析数据"时,执行以下流程:
```bash
python3 scripts/workflow.py ${API_URL}
```
其中 ${API_URL} 从用户指令中解析。
如果执行成功,返回报告摘要。
如果执行失败,返回错误信息并建议用户检查网络连接。
注意:在模板字符串中,${API_URL} 需要转义为 \${API_URL},否则会被JavaScript提前解析。这是我在实际开发中踩过的一个坑,导致变量无法正确传递。
踩坑实录:我遇到的问题和解法
开发技能的过程中,我踩了不少坑,记录几个最典型的:
坑1:权限不足导致文件写入失败。技能默认只能写入特定目录(如~/data/)。如果尝试写入系统目录(如/etc/),会报权限错误。解法:只写入用户目录下的文件,或者在SKILL.md中声明需要提权(不推荐,有安全风险)。
坑2:API调用超时。有些API响应很慢,默认超时时间不够。解法:在脚本中显式设置超时时间(如timeout=30),或者在SKILL.md中提醒用户耐心等待。
坑3:编码问题导致中文乱码。处理中文数据时,JSON解析偶尔会乱码。解法:在脚本中显式指定UTF-8编码,或者在读取响应时加encoding='utf-8'。
坑4:变量替换失败。在SKILL.md中使用${变量}语法时,如果是在JavaScript的模板字符串中,需要转义为\${变量},否则会被JS提前解析成undefined。这个坑我踩了两次才记住。
技能调试技巧:快速定位问题
开发技能最痛苦的是调试。不像普通代码可以打断点,技能的调试更多靠"观察+推断"。我总结了几个实用技巧:
技巧1:分段测试。不要一开始就跑完整工作流。先测试API调用是否成功,再测试数据解析,最后测试文件写入。每一步都单独验证,出错时能快速定位。
技巧2:日志输出。在脚本的每一步都加print语句,输出中间结果。OpenClaw会捕获这些输出,方便你看到执行过程。例如:
print(f"DEBUG: API返回数据条数: {len(data)}")
print(f"DEBUG: 解析后的前5条: {data[:5]}")
技巧3:模拟输入。在脚本中硬编码测试数据,先确保逻辑正确,再接入真实API。这样可以排除API问题,专注调试脚本逻辑。
技巧4:检查环境变量。有些技能需要API Key等环境变量。在SKILL.md开头检查这些变量是否存在,如果不存在就提前报错,避免执行到一半才失败。
从成本角度算一笔账
很多人担心技能开发成本高。实际上,一个简单技能的开发时间通常在1-2小时,复杂技能也就在半天内。而一旦开发完成,它可以重复使用无数次,边际成本几乎为零。
以我的daily-fetch技能为例:开发时间1.5小时,之后每天自动运行,节省了手动操作的时间。假设每天节省5分钟,一个月就是150分钟(2.5小时)。开发成本在第一周就收回了。
| 成本项 | 开发简单技能 | 开发复杂技能 |
|---|---|---|
| 时间成本 | 1-2小时 | 4-8小时 |
| 维护成本 | 每周10分钟 | 每周30分钟 |
| 运行成本 | 几乎为0(本地运行) | API调用可能产生费用 |
| 收益 | 每天节省5-10分钟 | 每天节省30-60分钟 |
写在最后
技能开发不是程序员的专利。只要你愿意花时间理解SKILL.md的结构和Prompt的写法,就能开发出贴合自己需求的技能。门槛比想象中低,收益比想象中高。
建议从最简单的需求开始:一个数据抓取、一个文件处理、一个定时提醒。跑通第一个技能后,再逐步扩展功能。不要一开始就追求复杂工作流,那样容易在调试中失去信心。
我在OpenClaw上开发了十几个技能,从数据抓取到报告生成,从定时通知到自动化测试。每个技能都解决了一个具体的痛点,加起来每天能节省1-2小时重复劳动。这就是技能开发的真正价值:把时间留给更有创造性的工作。
相关文章:Agent教程:从零开始掌握AI智能体开发 | OpenClaw安装与配置完整指南 | AI Agent自动处理Excel表格实战
版权声明
本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论