Skip to content

OpenClaw 本地技能封装开发指南

🎯 技能开发概述

什么是 OpenClaw 技能?

OpenClaw 技能是可复用的功能模块,封装了特定领域的能力,可以被不同的 Agent 调用。技能通过标准化的目录结构和配置文件实现插拔式集成。

技能核心特性

  • 模块化设计:每个技能独立封装,互不干扰
  • 标准接口:统一的调用方式和参数规范
  • 配置驱动:通过配置文件控制行为
  • 易于分发:支持本地和远程安装

📁 技能目录结构

标准目录结构

skill-name/
├── SKILL.md                    # 技能说明文档(必需)
├── scripts/                    # 执行脚本目录
│   ├── main.sh                 # 主执行脚本
│   ├── config.json             # 配置文件
│   └── utils/                  # 工具函数目录
├── references/                 # 参考文档
│   ├── api_reference.md        # API 参考
│   ├── examples.md             # 使用示例
│   └── troubleshooting.md      # 故障排除
├── test/                       # 测试脚本
│   └── test_main.sh            # 测试脚本
└── assets/                     # 静态资源(可选)
    ├── images/
    └── templates/

SKILL.md 文档规范

markdown
# 技能名称

**简短描述** - 一句话说明技能功能

## 📋 功能特性

### 核心功能
- 功能点1
- 功能点2

### 技术优势
- 优势1
- 优势2

## 🏗️ 架构设计

### 组件结构

目录结构说明


### 数据流程
1. 步骤1
2. 步骤2

## 🛠️ 安装与配置

### 前置要求
```bash
# 依赖安装命令

安装步骤

  1. 步骤1
  2. 步骤2

🚀 使用指南

基础使用

bash
# 示例命令

高级配置

json
{
  "配置项": "说明"
}

⚙️ 配置参考

配置文件详解

  • 配置项1: 说明
  • 配置项2: 说明

🔧 维护与更新

更新日志

  • 版本1.0.0: 初始版本

已知问题

  • 问题1: 解决方案

## 🛠️ 技能开发实战

### 1. 创建技能模板
```bash
# 创建技能目录结构
mkdir -p my-skill/{scripts,references,test,assets}
cd my-skill

# 创建SKILL.md
cat > SKILL.md << 'EOF'
# My Skill

**简短描述** - 一句话说明技能功能

## 📋 功能特性
...

EOF

# 创建主脚本
cat > scripts/main.sh << 'EOF'
#!/bin/bash
# 主执行脚本

set -e

# 加载配置
CONFIG_FILE="$(dirname "$0")/config.json"
if [ -f "$CONFIG_FILE" ]; then
    source <(jq -r 'to_entries|map("export \(.key)=\(.value|tostring)")|.[]' "$CONFIG_FILE")
fi

# 主逻辑
main() {
    echo "技能执行开始"
    # 业务逻辑
    echo "技能执行完成"
}

main "$@"
EOF

# 创建配置文件
cat > scripts/config.json << 'EOF'
{
  "enabled": true,
  "timeout": 30,
  "log_level": "info"
}
EOF

2. 技能参数设计

bash
# 支持命令行参数
#!/bin/bash

# 默认参数
DEFAULT_TIMEOUT=30
DEFAULT_OUTPUT="result.json"

# 解析参数
while [[ $# -gt 0 ]]; do
    case $1 in
        --timeout)
            TIMEOUT="$2"
            shift 2
            ;;
        --output)
            OUTPUT="$2"
            shift 2
            ;;
        --help)
            show_help
            exit 0
            ;;
        *)
            echo "未知参数: $1"
            exit 1
            ;;
    esac
done

3. 错误处理与日志

bash
#!/bin/bash

# 日志函数
log_info() {
    echo "[INFO] $(date '+%Y-%m-%d %H:%M:%S') - $*"
}

log_error() {
    echo "[ERROR] $(date '+%Y-%m-%d %H:%M:%S') - $*" >&2
}

# 错误处理
trap 'cleanup_on_error' ERR

cleanup_on_error() {
    log_error "脚本执行失败"
    # 清理资源
    exit 1
}

# 重试机制
retry_command() {
    local max_attempts=3
    local attempt=1
    
    while [ $attempt -le $max_attempts ]; do
        if "$@"; then
            return 0
        fi
        
        log_error "尝试 $attempt/$max_attempts 失败"
        ((attempt++))
        sleep 2
    done
    
    log_error "所有重试均失败"
    return 1
}

🔌 技能集成模式

1. 直接调用模式

bash
# 在Agent中直接调用技能脚本
#!/bin/bash

SKILL_DIR="$HOME/.openclaw/skills/my-skill"

# 检查技能是否存在
if [ -f "$SKILL_DIR/scripts/main.sh" ]; then
    # 执行技能
    "$SKILL_DIR/scripts/main.sh" --param1 value1 --param2 value2
else
    echo "技能未安装: my-skill"
    exit 1
fi

2. 配置驱动模式

json
{
  "skills": {
    "my-skill": {
      "enabled": true,
      "schedule": "0 9 * * *",
      "params": {
        "timeout": 60,
        "output_format": "markdown"
      }
    }
  }
}

3. 事件驱动模式

bash
#!/bin/bash

# 监听事件并触发技能
EVENT_TYPE="$1"
EVENT_DATA="$2"

case "$EVENT_TYPE" in
    "message_received")
        # 消息接收事件
        if echo "$EVENT_DATA" | grep -q "关键词"; then
            "$SKILL_DIR/scripts/main.sh" --trigger "message"
        fi
        ;;
    "schedule_trigger")
        # 定时触发事件
        "$SKILL_DIR/scripts/main.sh" --trigger "schedule"
        ;;
    *)
        echo "未知事件类型: $EVENT_TYPE"
        ;;
esac

📊 技能配置管理

配置文件设计

json
{
  "skill": {
    "name": "my-skill",
    "version": "1.0.0",
    "description": "技能描述",
    "author": "作者",
    "license": "MIT"
  },
  "runtime": {
    "timeout": 30,
    "memory_limit": "256M",
    "retry_count": 3
  },
  "parameters": {
    "required": ["api_key", "endpoint"],
    "optional": {
      "format": "json",
      "verbose": false
    }
  },
  "triggers": {
    "schedule": "0 9 * * *",
    "events": ["message_received", "file_uploaded"]
  },
  "output": {
    "format": "markdown",
    "destination": "stdout"
  }
}

环境变量配置

bash
# 技能环境变量
export MY_SKILL_API_KEY="your-api-key"
export MY_SKILL_ENDPOINT="https://api.example.com"
export MY_SKILL_DEBUG="false"

# 在脚本中使用
API_KEY="${MY_SKILL_API_KEY:-default-key}"
ENDPOINT="${MY_SKILL_ENDPOINT:-https://default.endpoint}"

🧪 技能测试

单元测试脚本

bash
#!/bin/bash
# test/test_main.sh

set -e

# 测试环境设置
TEST_DIR="$(dirname "$0")/.."
cd "$TEST_DIR"

# 测试函数
test_basic_function() {
    echo "测试基本功能..."
    
    # 执行技能
    result=$(scripts/main.sh --test)
    
    # 验证结果
    if echo "$result" | grep -q "成功"; then
        echo "✅ 测试通过"
    else
        echo "❌ 测试失败"
        return 1
    fi
}

test_error_handling() {
    echo "测试错误处理..."
    
    # 测试错误情况
    set +e
    result=$(scripts/main.sh --invalid-param 2>&1)
    set -e
    
    if echo "$result" | grep -q "错误"; then
        echo "✅ 错误处理正常"
    else
        echo "❌ 错误处理异常"
        return 1
    fi
}

# 运行所有测试
run_tests() {
    local tests_passed=0
    local tests_failed=0
    
    for test_func in test_basic_function test_error_handling; do
        if $test_func; then
            ((tests_passed++))
        else
            ((tests_failed++))
        fi
    done
    
    echo "测试完成: $tests_passed 通过, $tests_failed 失败"
    return $tests_failed
}

run_tests

集成测试

bash
#!/bin/bash
# test/integration_test.sh

# 模拟Agent调用
AGENT_CALL="openclaw exec --command 'bash scripts/main.sh'"

# 测试不同参数组合
test_cases=(
    "--help"
    "--version"
    "--input test.json --output result.json"
    "--timeout 10 --verbose"
)

for test_case in "${test_cases[@]}"; do
    echo "测试用例: $test_case"
    eval "$AGENT_CALL $test_case"
    echo "---"
done

📦 技能打包与分发

打包脚本

bash
#!/bin/bash
# package-skill.sh

SKILL_NAME="my-skill"
VERSION="1.0.0"
PACKAGE_DIR="dist/$SKILL_NAME-$VERSION"

# 创建打包目录
mkdir -p "$PACKAGE_DIR"

# 复制必要文件
cp -r scripts references test SKILL.md "$PACKAGE_DIR/"

# 移除开发文件
rm -f "$PACKAGE_DIR/scripts/config.local.json"
rm -rf "$PACKAGE_DIR/test/tmp/"

# 创建安装脚本
cat > "$PACKAGE_DIR/install.sh" << 'EOF'
#!/bin/bash

set -e

echo "安装 $SKILL_NAME v$VERSION"

# 检查目标目录
TARGET_DIR="$HOME/.openclaw/skills/$SKILL_NAME"
if [ -d "$TARGET_DIR" ]; then
    echo "警告: 技能已存在,将进行备份"
    BACKUP_DIR="$TARGET_DIR.backup.$(date +%s)"
    mv "$TARGET_DIR" "$BACKUP_DIR"
    echo "已备份到: $BACKUP_DIR"
fi

# 复制文件
cp -r . "$TARGET_DIR"
chmod +x "$TARGET_DIR/scripts/"*.sh

echo "✅ 安装完成"
EOF

chmod +x "$PACKAGE_DIR/install.sh"

# 创建压缩包
tar -czf "dist/$SKILL_NAME-$VERSION.tar.gz" -C dist "$SKILL_NAME-$VERSION"

echo "打包完成: dist/$SKILL_NAME-$VERSION.tar.gz"

分发清单

yaml
# skill-manifest.yaml
name: my-skill
version: 1.0.0
description: 技能描述
author: 作者
license: MIT
homepage: https://github.com/username/my-skill
repository: https://github.com/username/my-skill.git

dependencies:
  - name: jq
    type: system
    check: "which jq"
  - name: curl
    type: system
    check: "which curl"

files:
  - SKILL.md
  - scripts/
  - references/
  - test/

install: ./install.sh
uninstall: ./uninstall.sh

🔄 技能更新机制

版本管理

bash
#!/bin/bash
# scripts/update.sh

CURRENT_VERSION="1.0.0"
LATEST_VERSION=$(curl -s https://api.github.com/repos/username/my-skill/releases/latest | jq -r '.tag_name')

if [ "$CURRENT_VERSION" != "$LATEST_VERSION" ]; then
    echo "发现新版本: $LATEST_VERSION"
    echo "当前版本: $CURRENT_VERSION"
    
    # 下载新版本
    wget "https://github.com/username/my-skill/releases/download/$LATEST_VERSION/$SKILL_NAME-$LATEST_VERSION.tar.gz"
    
    # 安装新版本
    tar -xzf "$SKILL_NAME-$LATEST_VERSION.tar.gz"
    cd "$SKILL_NAME-$LATEST_VERSION"
    ./install.sh
    
    echo "✅ 更新完成"
else
    echo "已是最新版本"
fi

配置迁移

bash
#!/bin/bash
# scripts/migrate-config.sh

# 备份旧配置
if [ -f "config.json" ]; then
    cp config.json "config.json.backup.$(date +%s)"
fi

# 迁移配置
if [ -f "config.old.json" ]; then
    jq '.new_field = .old_field // "default"' config.old.json > config.json
    echo "配置迁移完成"
fi

📈 性能优化

缓存机制

bash
#!/bin/bash

CACHE_DIR="/tmp/$SKILL_NAME-cache"
CACHE_TTL=3600  # 1小时

# 获取缓存
get_cache() {
    local key="$1"
    local cache_file="$CACHE_DIR/$key"
    
    if [ -f "$cache_file" ]; then
        local age=$(($(date +%s) - $(stat -f %m "$cache_file")))
        if [ $age -lt $CACHE_TTL ]; then
            cat "$cache_file"
            return 0
        fi
    fi
    return 1
}

# 设置缓存
set_cache() {
    local key="$1"
    local value="$2"
    local cache_file="$CACHE_DIR/$key"
    
    mkdir -p "$CACHE_DIR"
    echo "$value" > "$cache_file"
}

并发控制

bash
#!/bin/bash

LOCK_FILE="/tmp/$SKILL_NAME.lock"

# 获取锁
acquire_lock() {
    exec 200>"$LOCK_FILE"
    flock -n 200 || {
        echo "另一个实例正在运行"
        exit 1
    }
    echo $$ >&200
}

# 释放锁
release_lock() {
    flock -u 200
    rm -f "$LOCK_FILE"
}

# 使用锁
acquire_lock
trap release_lock EXIT

# 业务逻辑
main_function

🛡️ 安全最佳实践

输入验证

bash
#!/bin/bash

# 验证参数
validate_input() {
    local input="$1"
    
    # 检查空值
    if [ -z "$input" ]; then
        echo "错误: 输入不能为空"
        return 1
    fi
    
    # 检查特殊字符
    if echo "$input" | grep -q '[<>|&;`$]'; then
        echo "错误: 输入包含非法字符"
        return 1
    fi
    
    # 检查长度
    if [ ${#input} -gt 1000 ]; then
        echo "错误: 输入过长"
        return 1
    fi
    
    return 0
}

权限控制

bash
#!/bin/bash

# 检查执行权限
check_permissions() {
    # 不能以root运行
    if [ "$(id -u)" -eq 0 ]; then
        echo "错误: 不应以root权限运行"
        exit 1
    fi
    
    # 检查文件权限
    for file in scripts/*.sh; do
        if [ ! -x "$file" ]; then
            chmod +x "$file"
        fi
    done
}

结构分析

github-trending/
├── SKILL.md                    # 完整文档
├── scripts/
│   ├── github_trending.sh      # 主脚本:数据获取与处理
│   ├── format_message.py       # 辅助脚本:消息格式化
│   └── config.json             # 配置文件
├── references/
│   ├── api_reference.md        # GitHub API参考
│   └── examples.md             # 使用示例
└── test/
    └── test_github_trending.sh # 测试脚本

关键设计模式

  1. 模块化设计:主脚本负责业务逻辑,辅助脚本负责格式化
  2. 配置驱动:通过config.json控制行为
  3. 错误处理:完善的错误处理和重试机制
  4. 测试覆盖:包含完整的测试脚本

可复用组件

  • 定时任务集成:支持OpenClaw cron调度
  • 消息格式化:生成飞书卡片格式
  • 缓存机制:避免重复