【OpenClaw 实战】手把手教你开发 AI Agent Skills——从入门到精通

摘要:本文详细介绍 OpenClaw Skills 插件系统的完整开发流程,包括创建、加载、使用、调试全流程。通过本文,你将掌握如何为 AI Agent 扩展功能,实现自动化任务。附带完整代码示例,可直接上手实践。

关键词:OpenClaw、AI Agent、Skills 开发、插件系统、自动化


📌 前言

为什么需要 Skills?

在使用 OpenClaw 搭建 AI Agent 的过程中,你是否遇到过这些问题:

  • ❌ AI 只能聊天,不能执行实际任务
  • ❌ 每次都要详细描述步骤,不能一键执行
  • ❌ 同样的操作重复多次,无法自动化
  • ❌ 想扩展功能,不知道从哪里入手

Skills(技能)系统就是为了解决这些问题而生的!

什么是 Skills?

简单来说,Skills = AI 的双手

  • LLM(大模型) = AI 的大脑(思考、决策)
  • Skills = AI 的双手(执行、操作)

有了 Skills,你的 AI Agent 可以:

  • ✅ 自动生成视频
  • ✅ 查询实时天气/金价
  • ✅ 定时推送早报
  • ✅ 执行任意脚本和命令

本文你将学到

  1. Skills 的核心概念和作用
  2. 从零创建一个完整 Skill
  3. Skills 的加载和触发机制
  4. 调试技巧和最佳实践
  5. 完整可运行的示例代码

适合人群:有一定 JavaScript/Node.js 基础的开发者


一、Skills 系统概述

1.1 核心概念

Skills 是 OpenClaw 的插件系统,让 AI 能够执行特定任务。

组成结构

Skill = 触发词 + 执行脚本 + 说明文档

1.2 工作原理

用户说"生成视频"
    ↓
OpenClaw 匹配触发词
    ↓
找到 video-generator 技能
    ↓
执行 scripts/generate.js
    ↓
返回结果给用户

1.3 官方 Skills 示例

技能 功能 触发词
video-generator 视频生成 “生成视频”
daily-briefing 每日早报 “日报”
gold-price-converter 金价换算 “金价”
search 网络搜索 “搜索”

二、Skills 目录结构

2.1 标准结构

workspace/skills/
└── your-skill-name/          # 技能文件夹(名称唯一)
    ├── SKILL.md              # ⭐ 技能说明文档
    ├── _meta.json            # ⭐ 元数据配置
    ├── scripts/              # ⭐ 脚本目录
    │   ├── main.js           # 主入口脚本
    │   └── utils.js          # 工具函数(可选)
    ├── assets/               # 资源文件(可选)
    └── results/              # 输出结果(可选)

2.2 核心文件说明

文件 必需 作用
SKILL.md 技能说明文档(功能、用法、配置)
_meta.json 元数据(触发词、入口脚本)
scripts/main.js 主执行脚本

三、实战:从零创建 Weather 技能

3.1 创建目录

# 进入 skills 目录
cd C:\Users\29046\.openclaw\workspace\skills

# 创建技能文件夹
mkdir weather-query
cd weather-query

# 创建子目录
mkdir scripts

3.2 编写 _meta.json

{
  "name": "weather-query",
  "version": "1.0.0",
  "description": "查询实时天气信息",
  "author": "你的名字 <email@example.com>",
  "license": "MIT",
  "homepage": "https://github.com/yourname/weather-query",
  "keywords": ["weather", "api", "query"],
  "main": "scripts/query.js",
  "scripts": {
    "run": "node scripts/query.js"
  },
  "triggers": [
    "查询天气",
    "今天天气",
    "天气怎么样",
    "查天气"
  ],
  "autoExecute": true
}

关键字段说明

字段 说明 注意事项
name 技能名称(唯一标识) 小写 + 连字符
main 入口脚本路径 相对于技能目录
triggers 触发词列表 3-5 个为宜
autoExecute 是否自动执行 true=直接执行

3.3 编写 SKILL.md

---
name: weather-query
description: 查询实时天气信息,支持任意城市
homepage: https://github.com/yourname/weather-query
metadata:
  openclaw:
    requires:
      bins:
        - node
---

# 天气查询技能

## 功能
- ✅ 查询指定城市实时天气
- ✅ 显示温度、湿度、风力
- ✅ 自动定位(可选)

## 使用方式
当用户说"查询天气"、"今天天气"时自动执行。

## 配置
无需配置,使用公开 API(wttr.in)。

## 示例

### 示例 1:查询北京天气

用户:查询天气
AI:🌤️ 北京 晴 25°C 湿度 60%


### 示例 2:查询上海天气

用户:上海天气
AI:🌧️ 上海 小雨 22°C 湿度 80%


## 错误处理
- 网络错误:提示检查网络连接
- 城市不存在:提示输入正确城市名

3.4 编写主脚本

#!/usr/bin/env node
/**
 * 天气查询技能
 * 作者:你的名字
 * 日期:2026-03-05
 * 
 * 功能:查询实时天气信息
 */

const https = require('https');
const fs = require('fs');
const path = require('path');

// ==================== 配置区 ====================
const DEFAULT_CITY = '北京';
const TIMEOUT = 10000; // 超时 10 秒

// ==================== 主函数 ====================
async function main() {
  console.log();
  console.log('='.repeat(50));
  console.log('🌤️  天气查询');
  console.log('='.repeat(50));
  console.log();

  const city = process.argv[2] || DEFAULT_CITY;
  console.log(`📍 查询城市:${city}`);

  try {
    const weather = await fetchWeather(city);
    
    console.log();
    console.log('📊 天气信息:');
    console.log(`   温度:${weather.temp}°C`);
    console.log(`   体感:${weather.feelsLike}°C`);
    console.log(`   湿度:${weather.humidity}%`);
    console.log(`   风力:${weather.wind} km/h`);
    console.log(`   描述:${weather.description}`);
    console.log();
    console.log('✅ 查询完成!');
    
  } catch (error) {
    console.error();
    console.error('❌ 查询失败:' + error.message);
    console.error('💡 建议:检查网络连接或城市名称');
    console.error();
    process.exit(1);
  }
}

// ==================== 辅助函数 ====================

/**
 * 获取天气数据
 * @param {string} city - 城市名称
 * @returns {Promise<Object>} 天气数据
 */
function fetchWeather(city) {
  return new Promise((resolve, reject) => {
    const url = `https://wttr.in/${encodeURIComponent(city)}?format=j1`;
    
    const req = https.get(url, { timeout: TIMEOUT }, (res) => {
      let data = '';
      
      res.on('data', chunk => data += chunk);
      res.on('end', () => {
        try {
          const json = JSON.parse(data);
          const current = json.current_condition[0];
          
          resolve({
            temp: current.temp_C,
            feelsLike: current.FeelsLikeC,
            humidity: current.humidity,
            wind: current.windspeedKmph,
            description: current.weatherDesc[0].value
          });
        } catch (error) {
          reject(new Error('JSON 解析失败:' + error.message));
        }
      });
    });
    
    req.on('error', reject);
    req.on('timeout', () => {
      req.destroy();
      reject(new Error('请求超时(>' + TIMEOUT/1000 + '秒)'));
    });
  });
}

// ==================== 执行 ====================
main().then(() => {
  process.exit(0);
}).catch(error => {
  console.error('未捕获的错误:', error.message);
  process.exit(1);
});

3.5 测试技能

# 方式 1:直接运行脚本
node scripts/query.js

# 方式 2:带参数运行
node scripts/query.js 上海

# 方式 3:在聊天中触发
(说"查询天气"

预期输出

==================================================
🌤️  天气查询
==================================================

📍 查询城市:北京

📊 天气信息:
   温度:25°C
   体感:26°C
   湿度:60%
   风力:15 km/h
   描述:晴

✅ 查询完成!

四、Skills 加载机制详解

4.1 完整加载流程

┌─────────────────────────────────────────┐
│  1. OpenClaw 启动                        │
│     - 读取 openclaw.json                │
│     - 初始化 Gateway                     │
└─────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────┐
│  2. 扫描 Skills 目录                      │
│     - 路径:workspace/skills/           │
│     - 遍历所有子目录                     │
│     - 查找 _meta.json                   │
└─────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────┐
│  3. 解析每个 Skill                        │
│     - 读取 name, main, triggers         │
│     - 读取 SKILL.md                     │
└─────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────┐
│  4. 注册触发词                            │
│     - 建立索引:触发词 → Skill          │
└─────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────┐
│  5. 等待用户消息                          │
│     - 监听渠道消息                       │
│     - 匹配触发词                         │
└─────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────┐
│  6. 触发 Skill 执行                       │
│     - 检查 autoExecute                  │
│     - 执行入口脚本                       │
└─────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────┐
│  7. 返回结果                              │
│     - 捕获脚本输出                       │
│     - 发送给用户                         │
└─────────────────────────────────────────┘

4.2 触发词匹配规则

// 1. 精确匹配(优先级最高)
用户:"查询天气"
匹配:triggers: ["查询天气"]// 2. 模糊匹配
用户:"帮我查询天气"
匹配:包含"查询天气"// 3. 同义词匹配
用户:"今天天气怎么样"
匹配:triggers: ["今天天气", "天气怎么样"]

4.3 autoExecute 行为

行为 适用场景
true 直接执行,无需确认 查询、搜索等安全操作
false 询问用户确认 删除、发送等危险操作

五、调试技巧

5.1 本地调试

# 直接运行脚本
node scripts/main.js

# 带调试参数
node scripts/main.js --debug

# 使用 nodemon 自动重启
nodemon scripts/main.js

5.2 日志输出规范

// ✅ 推荐:使用 emoji 标记
console.log('📍 开始执行...');
console.log('✅ 步骤 1 完成');
console.log('❌ 错误:', error.message);
console.log('💡 建议:检查网络连接');

// ❌ 不推荐:没有标记
console.log('开始');
console.log('完成');

5.3 错误处理模板

try {
  const result = await doSomething();
  console.log('✅ 成功');
} catch (error) {
  console.error(`❌ 错误:${error.message}`);
  console.error(`💡 建议:检查配置`);
  process.exit(1);
}

5.4 保存运行结果

const fs = require('fs');
const path = require('path');

const results = { success: true, data: 'xxx' };
const filepath = path.join(__dirname, 'results', `result-${Date.now()}.json`);

// 确保目录存在
fs.mkdirSync(path.dirname(filepath), { recursive: true });

// 保存结果
fs.writeFileSync(filepath, JSON.stringify(results, null, 2));

console.log(`📁 结果已保存到:${filepath}`);

六、最佳实践

6.1 命名规范

// ✅ 推荐
video-generator, daily-briefing, gold-price-converter

// ❌ 避免
VideoGenerator, video_generator, VIDEO_GENERATOR

6.2 触发词设计

// ✅ 好的触发词(具体、不易误触发)
triggers: ["生成视频", "做个视频", "创建视频"]

// ❌ 不好的触发词(太短、容易误触发)
triggers: ["视频", "生成"]

6.3 代码结构

// 1. 导入依赖
const fs = require('fs');

// 2. 配置
const CONFIG = { timeout: 30000 };

// 3. 主函数
async function main() { ... }

// 4. 辅助函数
function helper() { ... }

// 5. 执行
main().then(() => process.exit(0));

6.4 安全性

// ✅ 验证输入
if (!isValidUrl(url)) {
  throw new Error('无效的 URL');
}

// ❌ 危险:直接执行用户输入
exec(userInput);

七、常见问题解答

Q1: Skill 不触发怎么办?

检查清单

  • _meta.json 中 triggers 是否正确
  • 触发词是否匹配(大小写、空格)
  • autoExecute 是否为 true
  • OpenClaw 是否重启(修改后需要重启)
  • 技能目录是否在 skills/ 下

Q2: 脚本执行报错怎么办?

检查清单

  • Node.js 是否安装(node -v)
  • 依赖是否安装
  • 路径是否正确(使用绝对路径)
  • 权限是否足够
  • 环境变量是否配置

Q3: 如何处理长时间任务?

// ✅ 推荐:进度日志
async function longTask() {
  console.log('📍 开始执行...');
  
  for (let i = 0; i < 10; i++) {
    await step(i);
    console.log(`🔄 进度:${i + 1}/10`);
  }
  
  console.log('✅ 完成!');
}

Q4: 如何依赖外部 API?

// 1. 在 SKILL.md 中声明
metadata:
  openclaw:
    requires:
      env:
        - API_KEY

// 2. 在脚本中读取
const apiKey = process.env.API_KEY;

八、总结

核心要点

  1. Skills 是什么:AI Agent 的插件系统,扩展执行能力
  2. 核心文件:_meta.json(配置)、SKILL.md(文档)、scripts/(代码)
  3. 加载流程:扫描 → 解析 → 注册 → 匹配 → 执行 → 返回
  4. 触发方式:关键词触发、定时触发、手动调用

开发流程

创建目录 → 编写配置 → 编写文档 → 编写脚本 → 测试 → 发布

下一步

  • 尝试修改 weather-query 技能,添加更多城市支持
  • 参考官方 Skills 学习更多示例
  • 发布你的 Skill 到 ClawHub 社区

📚 参考资料


觉得有用请点赞收藏⭐,有问题欢迎评论区留言!

关注我,获取更多 AI Agent 开发干货!


版权声明:本文为原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐