title: OpenClaw 技能开发:自定义扩展 AI Agent 能力边界 tags: [openclaw, 技能开发, 开发指南, 自定义]


OpenClaw 技能开发:自定义扩展 AI Agent 能力边界

OpenClaw 的核心竞争力在于其灵活的技能系统。OpenClaw 技能开发 让开发者能够根据具体业务需求,为 Agent 添加专属能力,真正实现"千人千面"的 AI 助手。本文将详细介绍技能开发的核心概念、开发流程和最佳实践。

技能系统概述

什么是技能(Skill)?

技能是 Agent 执行具体任务的能力单元。每个技能封装了特定的功能逻辑,可以被 Agent 按需调用。可以类比为:

Agent = 人的大脑
技能 = 人掌握的具体技能(如开车、编程、写作)

技能的核心组成

skill:
  metadata:        # 基本信息
    name: string
    description: string
    version: string

  inputs:          # 输入参数定义
    type: schema
    required: boolean
    default: any

  workflow:        # 执行流程
    steps: []

  outputs:         # 输出定义
    type: schema

  error_handling:  # 错误处理
    retry: object
    fallback: object

技能类型

类型 说明 示例
简单技能 单步操作 发送通知
复合技能 多步流程 生成文章
集成技能 调用外部 API 查询天气
AI 技能 调用大模型 内容生成

技能开发流程

第一步:规划技能

在开发技能前,需要明确:

  1. 功能目标:技能要解决什么问题?
  2. 输入参数:需要哪些输入?
  3. 输出格式:返回什么结果?
  4. 依赖资源:需要哪些外部依赖?

第二步:创建技能文件

# 技能文件结构
skills/
├── my-skill/
│   ├── skill.yaml       # 技能配置   ├── README.md        # 说明文档   ├── main.js          # 执行逻辑(可选)   └── tests/           # 测试用例       └── test.yaml

第三步:编写技能配置

# skills/email-sender/skill.yaml
name: email-sender
version: "1.0.0"
description: 发送邮件技能

# 作者信息
author:
  name: 开发者
  email: dev@example.com

# 标签(用于技能检索)
tags:
  - communication
  - email

# 输入参数定义
inputs:
  to:
    type: string
    format: email
    description: 收件人邮箱
    required: true

  subject:
    type: string
    description: 邮件主题
    required: true

  body:
    type: string
    description: 邮件正文
    required: true

  cc:
    type: array
    items:
      type: string
      format: email
    description: 抄送列表

  attachments:
    type: array
    items:
      type: object
      properties:
        filename:
          type: string
        content:
          type: string
          format: binary

# 输出定义
outputs:
  message_id:
    type: string
    description: 发送成功的消息ID

  status:
    type: string
    enum: [sent, failed, queued]

# 配置参数
config:
  # 超时设置
  timeout: 30000

  # 重试配置
  retry:
    max_attempts: 3
    delay: exponential

第四步:定义执行流程

# skills/email-sender/skill.yaml(续)

# 执行工作流
workflow:
  # 步骤1:验证输入
  - step: validate
    action: validate-input
    params:
      schema: ${inputs}

  # 步骤2:模板渲染
  - step: render
    action: template-render
    condition: ${inputs.template != null}
    params:
      template: ${inputs.template}
      variables: ${inputs.variables}

  # 步骤3:发送邮件
  - step: send
    action: http-request
    params:
      method: POST
      url: ${env.EMAIL_API_URL}
      headers:
        Authorization: Bearer ${env.EMAIL_API_KEY}
      body:
        to: ${inputs.to}
        subject: ${inputs.subject}
        body: ${steps.render.result || inputs.body}

  # 步骤4:记录日志
  - step: log
    action: file-append
    params:
      path: ./logs/email.log
      content: |
        [${timestamp}] Sent to ${inputs.to}
        Subject: ${inputs.subject}

# 错误处理
error_handling:
  retry:
    max_attempts: 3
    on: [timeout, rate_limit]

  fallback:
    - condition: ${error.code == 'quota_exceeded'}
      action: notify-admin
    - condition: ${error.code == 'invalid_email'}
      action: return-error

高级技能开发

使用 JavaScript 扩展逻辑

对于复杂的业务逻辑,可以使用 JavaScript 编写:

// skills/email-sender/main.js
module.exports = {
  // 预处理函数
  preProcess: async (inputs, context) => {
    // 验证邮箱格式
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(inputs.to)) {
      throw new Error('Invalid email format');
    }
    return inputs;
  },

  // 主执行函数
  execute: async (inputs, context) => {
    const { to, subject, body } = inputs;

    // 调用邮件服务
    const response = await context.fetch('https://api.email.com/send', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${context.config.apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ to, subject, body })
    });

    return {
      messageId: response.data.id,
      status: 'sent'
    };
  },

  // 后处理函数
  postProcess: async (result, context) => {
    // 记录发送历史
    await context.store.save('email_history', {
      ...result,
      timestamp: Date.now()
    });
    return result;
  }
};

技能组合与嵌套

# skills/marketing-email/skill.yaml
name: marketing-email
description: 营销邮件发送(组合技能)

# 依赖技能
dependencies:
  - email-sender
  - template-engine
  - analytics

# 执行流程
workflow:
  # 使用模板引擎生成内容
  - step: generate-content
    skill: template-engine
    inputs:
      template: ${inputs.template}
      data: ${inputs.data}

  # 发送邮件
  - step: send
    skill: email-sender
    inputs:
      to: ${inputs.recipient}
      subject: ${inputs.subject}
      body: ${steps.generate-content.html}

  # 记录分析数据
  - step: track
    skill: analytics
    inputs:
      event: email_sent
      data:
        campaign_id: ${inputs.campaign_id}
        recipient: ${inputs.recipient}

条件执行与分支

workflow:
  # 条件判断
  - step: classify
    action: llm-classify
    params:
      input: ${inputs.message}
      labels: [question, complaint, feedback, other]
    output:
      type: ${result.label}

  # 分支执行
  - step: handle
    branches:
      - condition: ${steps.classify.type == 'question'}
        skill: qa-handler
        inputs:
          question: ${inputs.message}

      - condition: ${steps.classify.type == 'complaint'}
        skill: complaint-handler
        inputs:
          content: ${inputs.message}

      - condition: ${steps.classify.type == 'feedback'}
        skill: feedback-collector
        inputs:
          feedback: ${inputs.message}

      - default: true
        skill: general-handler

实战案例:RSS 监控技能

让我们开发一个完整的 RSS 订阅监控技能:

# skills/rss-monitor/skill.yaml
name: rss-monitor
version: "1.0.0"
description: RSS 订阅监控与更新推送

# 输入参数
inputs:
  feed_url:
    type: string
    format: uri
    description: RSS 订阅地址
    required: true

  check_interval:
    type: number
    default: 3600
    description: 检查间隔(秒)

  keywords:
    type: array
    items:
      type: string
    description: 关键词过滤

  notify_channels:
    type: array
    items:
      type: string
      enum: [email, feishu, slack, webhook]
    default: [feishu]

# 配置
config:
  timeout: 60
  persistence: true

# 执行流程
workflow:
  # 步骤1:获取 RSS 内容
  - step: fetch
    action: http-request
    params:
      method: GET
      url: ${inputs.feed_url}
      headers:
        Accept: application/rss+xml
    output:
      raw_content: ${result.body}

  # 步骤2:解析 RSS
  - step: parse
    action: xml-parse
    params:
      xml: ${steps.fetch.raw_content}
    output:
      entries: ${result.channel.items}

  # 步骤3:过滤更新
  - step: filter
    action: script
    params:
      code: |
        const lastCheck = context.store.get('last_check_time');
        const entries = steps.parse.entries;

        // 过滤新条目
        const newEntries = entries.filter(entry => {
          const pubDate = new Date(entry.pubDate);
          return pubDate > new Date(lastCheck);
        });

        // 关键词过滤
        if (inputs.keywords && inputs.keywords.length > 0) {
          return newEntries.filter(entry => 
            inputs.keywords.some(kw => 
              entry.title.includes(kw) || 
              entry.description.includes(kw)
            )
          );
        }

        return newEntries;
    output:
      new_entries: ${result}

  # 步骤4:格式化通知
  - step: format
    action: template-render
    params:
      template: |
        🔔 RSS 更新提醒

        来源:${steps.parse.entries[0].channel.title}
        新增条目:${steps.filter.new_entries.length} 条

        {{#each steps.filter.new_entries}}
        ---
        【{{title}}】
        {{description}}
        链接:{{link}}
        {{/each}}
    output:
      message: ${result}

  # 步骤5:发送通知
  - step: notify
    action: parallel
    foreach: ${inputs.notify_channels}
    node:
      skill: notify-${item}
      inputs:
        message: ${steps.format.message}

  # 步骤6:更新检查时间
  - step: update-timestamp
    action: store-save
    params:
      key: last_check_time
      value: ${Date.now()}

# 定时触发配置
triggers:
  - type: schedule
    interval: ${inputs.check_interval}

技能测试

单元测试

# skills/rss-monitor/tests/test.yaml
name: rss-monitor-tests
description: RSS 监控技能测试

tests:
  - name: test-fetch
    description: 测试 RSS 获取
    input:
      feed_url: https://example.com/feed.xml
    expect:
      fetch.status: 200
      parse.entries: exists

  - name: test-keyword-filter
    description: 测试关键词过滤
    input:
      feed_url: https://example.com/feed.xml
      keywords: [AI, 技术]
    expect:
      filter.new_entries: exists
      filter.new_entries.*.title: contains(keywords)

  - name: test-notification
    description: 测试通知发送
    input:
      feed_url: https://example.com/feed.xml
      notify_channels: [feishu]
    expect:
      notify.feishu.status: success

运行测试

# 运行技能测试
openclaw skill test rss-monitor

# 运行单个测试用例
openclaw skill test rss-monitor --case test-keyword-filter

技能发布与分享

打包发布

# 打包技能
openclaw skill pack rss-monitor

# 发布到技能市场
openclaw skill publish rss-monitor

# 安装远程技能
openclaw skill install @user/rss-monitor

技能市场配置

# skill-market.yaml
registries:
  - name: official
    url: https://skills.openclaw.ai

  - name: community
    url: https://community.openclaw.ai/skills

最佳实践

1. 单一职责

每个技能只做一件事:

❌ email-manager(发送+接收+归档)
✅ email-sender(只负责发送)
✅ email-reader(只负责读取)

2. 参数校验

inputs:
  email:
    type: string
    format: email
    required: true

  count:
    type: number
    minimum: 1
    maximum: 100
    default: 10

3. 错误恢复

error_handling:
  retry:
    max_attempts: 3
    backoff: exponential

  fallback:
    - condition: ${error.type == 'network'}
      action: use-cache
    - condition: ${error.type == 'quota'}
      action: queue-for-later

4. 文档完善

# RSS Monitor Skill

## 功能
监控 RSS 订阅源,发现新内容时自动通知。

## 使用示例
```yaml
skill: rss-monitor
inputs:
  feed_url: https://blog.example.com/rss
  keywords: [AI, GPT]

注意事项

  • 需要配置 notify 技能
  • 建议检查间隔不小于 600 秒 ```

总结

OpenClaw 技能开发是扩展 AI Agent 能力的核心方式。通过本文,你应该已经掌握:

  • 技能系统的核心概念和组成
  • 技能开发的完整流程
  • 高级技能开发技巧(JS扩展、组合、条件分支)
  • 实战案例:RSS 监控技能
  • 技能测试和发布方法
  • 开发最佳实践

技能开发是 OpenClaw 最强大的扩展能力。掌握技能开发,你就能根据业务需求定制专属的 AI 能力,打造真正实用的 AI 应用。


相关阅读: - 「OpenClaw Agent 搭建」- Agent 整体架构 - 「OpenClaw 最佳实践」- 实战经验总结