从 0 到发布:在 ClawHub 上开发和分享 OpenClaw Skill

本文是 OpenClaw 系列的第 5 篇深度指南。
📚 本系列其他文章: [第1篇] | [第2篇] | [第3篇] | [第4篇]


前言

你有没有想过,为什么 OpenClaw 能轻松支持飞书、Telegram、Discord 等多个平台?

答案就在 Skill 系统

Skill 是 OpenClaw 的模块化扩展机制,让开发者能够将专业知识、工作流、甚至 AI 工具打包成可复用的单元。它像是为 AI 助手编写"操作手册"——告诉它如何完成特定任务。

本文将揭示:

  • Skill 是如何让 OpenClaw 生态如此强大的
  • 你如何在 5 分钟内开发一个可用的 Skill
  • 如何发布到 ClawHub,让全球开发者使用你的代码

第一部分:Skill 系统的价值

什么是 Skill?

简单来说,Skill 是一个自包含的代码包,包含:

  1. 元数据(SKILL.md)- 说明这个 Skill 做什么
  2. 实现代码(index.js 等)- 核心逻辑
  3. 配置文件(package.json)- 依赖声明
  4. 可选资源(脚本、文档、资产文件)- 增强功能
weather-skill/
├── SKILL.md                 # 元数据与文档
├── index.js                 # 核心实现
├── package.json             # 依赖配置
├── scripts/
│   └── fetch_weather.py     # 天气数据抓取脚本
├── references/
│   └── api_docs.md          # API 参考文档
└── assets/
    └── weather_icon.png     # 天气图标

Skill vs 普通代码库有什么区别?

维度 Skill 普通代码库
目标 给 AI 代理赋能 通用软件开发
大小 小而精(<100KB) 可任意大小
复用性 一键集成到 OpenClaw 需要手动集成
文档 AI 友好的结构化文档 人类友好的 README
分发 ClawHub 市场 npm/GitHub
价值 专业知识打包 通用组件库

为什么开发 Skill?

对个人开发者:

  • 💰 赚取版税(ClawHub 热门 Skill 可获收益)
  • 📢 建立个人品牌(被全球 OpenClaw 用户使用)
  • 🎓 深化技术理解(通过打包知识)

对企业:

  • 🔒 私有 Skill 库(企业内部知识积累)
  • ⚡ 降低定制成本(复用而非重写)
  • 🚀 加速迭代(模块化开发)

实际数据:
ClawHub 上已有 3000+ Skill,月下载量超过 50 万次。排名前 10 的 Skill 月均下载超过 1 万次。


第二部分:Skill 的结构与标准

必需文件详解

1. SKILL.md - 元数据与文档

这是 AI 代理理解你 Skill 的窗口。结构如下:

---
name: skill-name
description: |
  清晰描述 Skill 做什么,以及什么时候应该用它。
  包含具体的使用场景和触发条件。
---

# Skill 标题

## 概述
[简洁介绍]

## 核心工作流
[步骤式说明]

## 代码示例
[实际代码片段]

## 参考资源
- [文件1](references/api.md)
- [文件2](references/schema.md)

关键原则:简洁是金。AI 代理已经很聪明,你只需提供它不知道的东西。

2. package.json - 依赖声明
{
  "name": "openclaw-skill-weather",
  "version": "1.0.0",
  "description": "Real-time weather query skill using OpenWeatherMap API",
  "main": "index.js",
  "keywords": ["weather", "openclaw", "skill"],
  "author": "Your Name",
  "license": "MIT",
  "dependencies": {
    "axios": "^1.4.0"
  }
}

命名规则openclaw-skill-{name}(加这个前缀,便于 ClawHub 识别)

3. index.js - 核心实现

Skill 的入口点。必须导出一个异步函数:

// index.js
module.exports = async function weather(city) {
  // 1. 参数验证
  if (!city || typeof city !== 'string') {
    throw new Error('城市名称必须是字符串');
  }
  
  // 2. 核心逻辑
  const apiKey = process.env.OPENWEATHER_API_KEY;
  const response = await fetch(
    `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=metric`
  );
  
  if (!response.ok) {
    throw new Error(`天气 API 调用失败: ${response.statusText}`);
  }
  
  const data = await response.json();
  
  // 3. 格式化输出
  return {
    city: data.name,
    temperature: data.main.temp,
    condition: data.weather[0].main,
    description: data.weather[0].description,
    humidity: data.main.humidity,
    wind_speed: data.wind.speed
  };
};

目录结构最佳实践

my-skill/
├── SKILL.md                     # 必需
├── index.js                     # 必需
├── package.json                 # 必需
├── scripts/                     # 可选 - 辅助脚本
│   ├── test.sh
│   └── generate_data.py
├── references/                  # 可选 - 参考文档
│   ├── api_docs.md
│   └── schema.md
└── assets/                      # 可选 - 资源文件
    ├── logo.png
    └── templates/
        └── example.json

重要提醒

  • ❌ 不要包含 README.md(用 SKILL.md 代替)
  • ❌ 不要包含 CHANGELOG(版本管理交给 npm)
  • ❌ 不要包含 node_modules(用 package.json 声明)

第三部分:开发第一个 Skill - 天气查询

现在让我们实战,一步步开发一个真正可用的 Skill。

步骤 1:初始化项目

# 创建项目目录
mkdir openclaw-skill-weather
cd openclaw-skill-weather

# 初始化 npm
npm init -y

# 更新 package.json
npm pkg set name="openclaw-skill-weather"
npm pkg set description="Real-time weather query with OpenWeatherMap API"
npm pkg set main="index.js"

# 安装依赖
npm install axios dotenv

步骤 2:创建 SKILL.md

---
name: weather
description: |
  Query real-time weather information for any city worldwide.
  Use when: (1) User asks about weather in a location, 
  (2) Need current temperature/humidity/wind speed, 
  (3) Planning activities based on weather conditions
---

# Weather Query Skill

Real-time weather information powered by OpenWeatherMap API.

## Quick Start

```javascript
const weather = require('openclaw-skill-weather');
const result = await weather('San Francisco');
// Output: { city: 'San Francisco', temperature: 15.2, ... }

Usage

Call with a city name:

```
weather(‘Tokyo’)
weather(‘London’)
weather(‘Sydney’)
```

Returns:

  • city: City name
  • temperature: Current temperature (°C)
  • condition: Weather condition (Clear, Rainy, etc.)
  • humidity: Humidity percentage
  • wind_speed: Wind speed (m/s)

Configuration

Set environment variable:
```bash
export OPENWEATHER_API_KEY=your_api_key_here
```

Get free API key at: https://openweathermap.org/api


### 步骤 3:实现 index.js

```javascript
// index.js
require('dotenv').config();
const axios = require('axios');

module.exports = async function weather(city) {
  // 参数验证
  if (!city || typeof city !== 'string') {
    throw new Error('City name must be a non-empty string');
  }
  
  if (!process.env.OPENWEATHER_API_KEY) {
    throw new Error('OPENWEATHER_API_KEY environment variable not set');
  }
  
  try {
    // 调用 OpenWeatherMap API
    const response = await axios.get('https://api.openweathermap.org/data/2.5/weather', {
      params: {
        q: city,
        appid: process.env.OPENWEATHER_API_KEY,
        units: 'metric'
      }
    });
    
    const data = response.data;
    
    // 格式化返回结果
    return {
      city: data.name,
      country: data.sys.country,
      temperature: Math.round(data.main.temp * 10) / 10,
      feels_like: Math.round(data.main.feels_like * 10) / 10,
      condition: data.weather[0].main,
      description: data.weather[0].description,
      humidity: data.main.humidity,
      wind_speed: data.wind.speed,
      cloudiness: data.clouds.all,
      timestamp: new Date(data.dt * 1000).toISOString()
    };
    
  } catch (error) {
    if (error.response?.status === 404) {
      throw new Error(`City not found: ${city}`);
    }
    if (error.response?.status === 401) {
      throw new Error('Invalid OpenWeatherMap API key');
    }
    throw new Error(`Weather API error: ${error.message}`);
  }
};

步骤 4:测试本地 Skill

# 创建 .env 文件
echo "OPENWEATHER_API_KEY=your_free_api_key" > .env

# 创建 test.js
cat > test.js << 'EOF'
const weather = require('./index.js');

(async () => {
  try {
    const result = await weather('Tokyo');
    console.log('✅ 天气查询成功:', result);
  } catch (error) {
    console.error('❌ 错误:', error.message);
  }
})();
EOF

# 运行测试
node test.js

预期输出:

✅ 天气查询成功: {
  city: 'Tokyo',
  country: 'JP',
  temperature: 18.5,
  feels_like: 16.2,
  condition: 'Partly cloudy',
  description: 'partly cloudy',
  humidity: 65,
  wind_speed: 3.2,
  cloudiness: 40,
  timestamp: '2024-03-11T15:30:00.000Z'
}

步骤 5:添加参考文档(可选)

创建 references/api_docs.md

# OpenWeatherMap API Reference

## Free Tier Limits

- API calls: 1,000 per day
- Response time: ~200ms
- Coverage: 200,000+ cities worldwide

## Response Schema

\`\`\`json
{
  "name": "Tokyo",
  "sys": { "country": "JP" },
  "main": {
    "temp": 18.5,
    "feels_like": 16.2,
    "humidity": 65
  },
  "weather": [{
    "main": "Partly cloudy",
    "description": "partly cloudy"
  }],
  "wind": { "speed": 3.2 },
  "clouds": { "all": 40 },
  "dt": 1710153000
}
\`\`\`

## Error Codes

- 404: City not found
- 401: Invalid API key
- 429: Rate limit exceeded

第四部分:发布到 ClawHub

前置条件

  1. npm 账户:在 npmjs.com 注册
  2. ClawHub 账户:在 clawhub.com 注册(可关联 npm)
  3. 本地认证:运行 npm login

发布流程

1. 验证 Skill 结构
# 确保项目文件完整
ls -la
# 应该看到:
# SKILL.md ✅
# index.js ✅
# package.json ✅
2. 更新版本号
# 首次发布用 1.0.0
npm version 1.0.0

# 后续更新:
npm version patch   # 1.0.0 → 1.0.1 (bug 修复)
npm version minor   # 1.0.0 → 1.1.0 (新功能)
npm version major   # 1.0.0 → 2.0.0 (破坏性变更)
3. 发布到 npm
npm publish

输出示例:

npm notice 📦 openclaw-skill-weather@1.0.0
npm notice === Tarball Contents ===
npm notice 2.3 kB      SKILL.md
npm notice 1.8 kB      index.js
npm notice 1.1 kB      package.json
npm notice === Tarball Details ===
npm notice name:          openclaw-skill-weather
npm notice version:       1.0.0
npm notice package size:  5.2 kB
npm notice unpacked size: 12.5 kB
npm notice shasum:        abc123xyz...
npm notice integrity:     sha512-abc123xyz...
npm notice total files:   4
npm notice
npm notice Publishing to https://registry.npmjs.org/ with tag latest and public access
npm notice
✨  Done in 2.34s
4. 在 ClawHub 注册 Skill

访问 clawhub.com,填写表单:

字段 示例
Skill 名称 Weather Query
npm 包名 openclaw-skill-weather
描述 Real-time weather for 200k+ cities
分类 Utilities / Data
标签 weather, api, openweathermap
开源协议 MIT

✅ 提交后,Skill 将在 ClawHub 市场上线(通常 1-2 小时)

验证发布

# 1. 检查 npm 包
npm view openclaw-skill-weather

# 2. 在 ClawHub 网站搜索
# 访问 clawhub.com/skills?q=weather

# 3. 用户安装测试
npm install openclaw-skill-weather

第五部分:维护与更新

处理用户反馈

假设用户反馈:“需要支持华氏温度”

修复步骤:

// index.js - 添加参数
module.exports = async function weather(city, options = {}) {
  // 默认摄氏度,但支持华氏度
  const units = options.unit === 'F' ? 'imperial' : 'metric';
  
  // ...API 调用...
  
  // 根据单位格式化温度
  const temp = units === 'F' 
    ? Math.round(data.main.temp * 10) / 10
    : Math.round(data.main.temp * 10) / 10;
    
  return { temperature: temp, unit: units === 'F' ? '°F' : '°C' };
};

发布修复版本:

# 更新版本到 1.0.1(Patch)
npm version patch

# 重新发布
npm publish

# ClawHub 会在 5 分钟内自动检测并更新

语义化版本(Semver)

版本 场景 示例
Patch Bug 修复 1.0.0 → 1.0.1
Minor 新功能(向后兼容) 1.0.0 → 1.1.0
Major 破坏性变更 1.0.0 → 2.0.0

更新 SKILL.md 中的新功能:

---
name: weather
description: Query weather in any city, supporting both Celsius and Fahrenheit.
---

## Temperature Units

By default, returns Celsius. Specify `unit: 'F'` for Fahrenheit:

\`\`\`javascript
const result = await weather('Tokyo', { unit: 'F' });
// { temperature: 64.9, unit: '°F' }
\`\`\`

性能优化案例

场景:用户反馈 API 响应慢

优化方案:添加本地缓存

const NodeCache = require('node-cache');
const cache = new NodeCache({ stdTTL: 600 }); // 缓存 10 分钟

module.exports = async function weather(city, options = {}) {
  // 检查缓存
  const cacheKey = `weather:${city}`;
  const cached = cache.get(cacheKey);
  
  if (cached && !options.nocache) {
    return { ...cached, cached: true };
  }
  
  // 调用 API(原有逻辑)...
  const result = { /* API 响应 */ };
  
  // 缓存结果
  cache.set(cacheKey, result);
  
  return { ...result, cached: false };
};

第六部分:设计原则与最佳实践

✅ DO(应该做)

原则 示例
保持轻量 Skill <100KB,脚本 <50KB
清晰的错误处理 提供有意义的错误消息
完善的文档 SKILL.md 要让 AI 看懂
版本管理 遵循 Semver,每次都更新版本
安全考虑 敏感信息用环境变量

❌ DON’T(不应该做)

反例 原因
依赖过多 增加安装时间和冲突风险
硬编码密钥 安全风险
过度设计 让代码难以维护
忘记更新版本 用户安装不到新功能
缺少错误处理 AI 代理无法有效处理故障

安全检查清单

在发布前,运行:

# 1. 检查敏感信息
grep -r "password\|secret\|token" . --exclude-dir=node_modules

# 2. 检查依赖安全
npm audit

# 3. 检查文件大小
du -sh .

# 4. 检查 package.json 版本
npm view openclaw-skill-weather@latest

常见问题与故障排除

Q1:发布时出现 “ERR! 404 not found”?

原因:npm 包名不符合命名规范

解决

# 检查 package.json
cat package.json | grep '"name"'

# 应该是 openclaw-skill-{name}
npm pkg set name="openclaw-skill-weather"
npm publish

Q2:用户安装后无法导入?

原因:index.js 没有正确导出

解决

// 正确的导出方式
module.exports = async function mySkill(params) {
  // 实现
};

// 测试导入
const skill = require('./index.js');
console.log(typeof skill); // 应输出 "function"

Q3:如何让 Skill 在 OpenClaw 中自动加载?

:无需特殊配置。用户只需:

openclaw install openclaw-skill-weather

然后在 Skill 中直接使用。

Q4:能否创建付费 Skill?

:ClawHub 支持多种商业模式:

  • 🟢 免费 - 完全开源
  • 🟡 Freemium - 基础功能免费,高级功能付费
  • 🔴 商业 - 企业授权

详见 clawhub.com/monetization


成功案例

Case 1:翻译 Skill(下载 50k+)

// 核心功能:多语言翻译
module.exports = async function translate(text, targetLang = 'en') {
  // 使用 Google Translate API
};

关键成功因素

  • ✅ 支持 100+ 语言
  • ✅ 快速响应 (<200ms)
  • ✅ 定期维护(月均 3-5 次更新)
  • ✅ 清晰的错误消息

Case 2:数据库查询 Skill(月均 2k 下载)

// 支持多数据库
module.exports = async function dbQuery(sql, dbType = 'postgres') {
  // PostgreSQL, MySQL, MongoDB, etc.
};

关键成功因素

  • ✅ 模块化设计(每个数据库一个脚本)
  • ✅ 详细的参考文档(references/)
  • ✅ 安全的连接管理
  • ✅ 社区反馈快速响应

总结与下一步

你现在知道了

✅ Skill 系统如何赋能 OpenClaw 生态
✅ 如何从零开发一个完整的 Skill
✅ 如何发布并维护 Skill
✅ 设计原则和最佳实践

建议的下一步

  1. 立即实践:开发你自己的 Skill(15-30 分钟)
  2. 发布到 ClawHub:分享给全球 5 万+ OpenClaw 用户
  3. 迭代优化:根据用户反馈持续改进
  4. 探索商业化:考虑付费或企业授权

资源链接

资源 链接
ClawHub 市场 https://clawhub.com
OpenClaw 文档 https://docs.openclaw.ai
Skill 开发指南 https://docs.openclaw.ai/skills/create
npm 包管理 https://npmjs.com
示例 Skill https://github.com/openclaw/example-skills

推荐阅读


关于作者

本文作者通过 OpenClaw + Skill 系统,已发布 15+ 个开源 Skill,月均下载 10k+ 次,获得社区好评。

原创发布于 CSDN | 欢迎转载(请注明出处)


最后更新:2024 年 3 月 11 日
如有问题,欢迎在评论区讨论! 🚀

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐