乐于分享
好东西不私藏

插件开发教程 – 从零开发第一个 OpenClaw 插件

插件开发教程 – 从零开发第一个 OpenClaw 插件

官方功能不够用?那就自己写插件!


🤔 为什么要开发插件?

场景 1:查询天气

用户问:北京今天天气怎么样?

OpenClaw 默认不会,但你可以写一个天气插件!


场景 2:查询股票

用户问:苹果公司股票现在多少钱?

OpenClaw 默认不会,但你可以写一个股票查询插件!


场景 3:控制智能家居

用户说:打开客厅的灯

OpenClaw 默认不会,但你可以写一个 HomeKit 插件!


插件的价值:

让 OpenClaw 学会任何你想让它学会的技能


🎯 插件能做什么?

1. 查询类

  • • 天气查询
  • • 股票查询
  • • 汇率查询
  • • 新闻聚合
  • • 维基百科查询

2. 操作类

  • • 发送邮件
  • • 创建日历事件
  • • 控制智能家居
  • • 执行系统命令
  • • 操作数据库

3. 集成类

  • • Notion 集成
  • • Slack 集成
  • • GitHub 集成
  • • 飞书集成
  • • 企业微信集成

4. AI 增强类

  • • 图片生成
  • • 语音合成
  • • 文档总结
  • • 代码审查
  • • 翻译服务

只有想不到,没有做不到!


🛠️ 开发环境准备

第 1 步:安装 Python

# macOS
brew install python@3.11

# 验证安装

python3 --version
# Python 3.11.x

第 2 步:创建虚拟环境

# 创建工作目录
mkdir
 -p ~/openclaw-plugins
cd
 ~/openclaw-plugins

# 创建虚拟环境

python3 -m venv weather-plugin

# 激活虚拟环境

source
 weather-plugin/bin/activate

第 3 步:安装依赖

# 基础依赖
pip install requests python-dotenv

# 开发工具(可选)

pip install pytest black flake8

📝 实战:开发天气查询插件

效果展示

用户问:

北京今天天气怎么样?

插件回复:

北京今天天气:

🌤️ 晴转多云
🌡️ 温度:15°C - 25°C
💨 风力:东北风 2 级
💧 湿度:45%
🌫️ 空气质量:良 (AQI 65)

建议:天气不错,适合户外活动!

第 1 步:获取天气 API

推荐 API:

API
免费额度
注册链接
和风天气
每天 1000 次
https://dev.qweather.com
OpenWeatherMap
每分钟 60 次
https://openweathermap.org
wttr.in
完全免费
https://wttr.in

本教程使用 wttr.in(无需注册):

# 测试 API
curl wttr.in/Beijing?format=j1

第 2 步:创建插件结构

# 创建插件目录
mkdir
 -p weather-plugin/src
cd
 weather-plugin

# 创建文件结构

touch
 src/__init__.py
touch
 src/weather.py
touch
 .env
touch
 requirements.txt
touch
 README.md

目录结构:

weather-plugin/
├── src/
│   ├── __init__.py
│   └── weather.py      # 主要代码
├── .env                # 环境变量
├── requirements.txt    # 依赖
└── README.md          # 说明文档

第 3 步:编写插件代码

编辑 src/weather.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
天气查询插件

功能:查询指定城市的天气信息
"""


import
 requests
from
 typing import Optional
from
 datetime import datetime


def
 get_weather(city: str) -> dict:
    """
    获取城市天气

    Args:
        city: 城市名称(中文或英文)

    Returns:
        天气信息字典
    """

    # wttr.in API(免费,无需 key)

    url = f"https://wttr.in/{city}?format=j1"

    try
:
        response = requests.get(url, timeout=10)
        response.raise_for_status()
        data = response.json()

        # 解析数据

        current = data['current_condition'][0]
        astronomy = data['weather'][0]['astronomy'][0]

        return
 {
            'city'
: city,
            'temperature'
: current.get('temp_C', 'N/A'),
            'feels_like'
: current.get('FeelsLikeC', 'N/A'),
            'condition'
: current.get('lang_zh')[0]['value'],
            'humidity'
: current.get('humidity', 'N/A'),
            'wind_speed'
: current.get('windspeedKmph', 'N/A'),
            'wind_dir'
: current.get('winddir16Point', 'N/A'),
            'pressure'
: current.get('pressure', 'N/A'),
            'visibility'
: current.get('visibility', 'N/A'),
            'sunrise'
: astronomy.get('sunrise', 'N/A'),
            'sunset'
: astronomy.get('sunset', 'N/A'),
            'query_time'
: datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }

    except
 requests.RequestException as e:
        return
 {
            'error'
: f'查询失败:{str(e)}',
            'city'
: city
        }


def
 format_weather_report(data: dict) -> str:
    """
    格式化天气报告

    Args:
        data: 天气数据

    Returns:
        格式化的天气报告
    """

    if
 'error' in data:
        return
 f"❌ {data['error']}"

    # 构建报告

    report = f"""
🌤️ {data['city']}天气

🌡️ 温度:{data['temperature']}°C(体感 {data['feels_like']}°C)
☁️ 天气:{data['condition']}
💨 风力:{data['wind_dir']} {data['wind_speed']} km/h
💧 湿度:{data['humidity']}%
🌫️ 气压:{data['pressure']} hPa
👁️ 能见度:{data['visibility']} km
🌅 日出:{data['sunrise']}
🌇 日落:{data['sunset']}

🕐 查询时间:{data['query_time']}
"""


    # 添加建议

    temp = int(data['temperature']) if data['temperature'].isdigit() else 20

    if
 temp < 10:
        advice = "天气较冷,注意保暖!"
    elif
 temp < 20:
        advice = "温度适宜,穿薄外套即可。"
    elif
 temp < 30:
        advice = "天气温暖,穿短袖即可。"
    else
:
        advice = "天气炎热,注意防暑降温!"

    report += f"\n💡 建议:{advice}"

    return
 report.strip()


def
 query_weather(city: str) -> str:
    """
    查询天气并返回格式化报告

    Args:
        city: 城市名称

    Returns:
        格式化的天气报告
    """

    data = get_weather(city)
    return
 format_weather_report(data)


# 测试

if
 __name__ == '__main__':
    # 测试北京天气

    report = query_weather('Beijing')
    print
(report)

第 4 步:测试插件

# 运行测试
python src/weather.py

预期输出:

🌤️ 北京天气

🌡️ 温度:18°C(体感 17°C)
☁️ 天气:晴
💨 风力:西北 15 km/h
💧 湿度:35%
🌫️ 气压:1015 hPa
👁️ 能见度:10 km
🌅 日出:06:15 AM
🌇 日落:06:30 PM

🕐 查询时间:2026-03-25 15:00:00

💡 建议:温度适宜,穿薄外套即可。

第 5 步:创建 OpenClaw 工具注册

创建 src/__init__.py

"""
天气查询插件 - OpenClaw Tool
"""


from
 .weather import query_weather, get_weather, format_weather_report

# 注册为 OpenClaw 工具

def
 register_tools(registry):
    """
    注册工具到 OpenClaw

    Args:
        registry: 工具注册器
    """


    @registry.tool(
        name="query_weather",
        description="查询指定城市的天气信息",
        parameters={
            "type"
: "object",
            "properties"
: {
                "city"
: {
                    "type"
: "string",
                    "description"
: "城市名称,如 '北京'、'Beijing'"
                }
            },
            "required"
: ["city"]
        }
)

    def
 weather_tool(city: str) -> str:
        """查询天气"""

        return
 query_weather(city)

    return
 registry


# 导出函数

__all__ = ['query_weather', 'get_weather', 'format_weather_report', 'register_tools']

第 6 步:配置依赖

编辑 requirements.txt

requests>=2.28.0
python-dotenv>=1.0.0

安装依赖:

pip install -r requirements.txt

第 7 步:创建插件配置

创建 plugin.json

{
  "name"
: "weather-plugin",
  "version"
: "1.0.0",
  "description"
: "天气查询插件 - 查询全球任意城市天气",
  "author"
: "Your Name",
  "license"
: "MIT",
  "homepage"
: "https://github.com/yourname/weather-plugin",
  "tools"
: [
    {

      "name"
: "query_weather",
      "description"
: "查询指定城市的天气信息",
      "entry"
: "src:register_tools"
    }

  ]
,
  "dependencies"
: [
    "requests>=2.28.0"

  ]

}

第 8 步:安装插件到 OpenClaw

# 方法 1:本地安装
cd
 ~/openclaw-plugins/weather-plugin
pip install -e .

# 方法 2:复制到 OpenClaw 插件目录

cp
 -r src ~/.openclaw/plugins/weather-plugin/

# 方法 3:通过 OpenClaw CLI 安装

openclaw plugins install ~/openclaw-plugins/weather-plugin

第 9 步:配置 OpenClaw

编辑 ~/.openclaw/plugins.entries.json

{
  "plugins"
: [
    {

      "name"
: "weather-plugin",
      "path"
: "/Users/yourname/openclaw-plugins/weather-plugin",
      "enabled"
:true
    }

  ]

}

第 10 步:重启 OpenClaw

# 重启 Gateway
openclaw gateway restart

# 查看插件状态

openclaw plugins list

# 查看可用工具

openclaw tools list

第 11 步:测试插件

在聊天中问:

北京今天天气怎么样?

AI 会调用你的插件,回复:

🌤️ 北京天气

🌡️ 温度:18°C(体感 17°C)
☁️ 天气:晴
💨 风力:西北 15 km/h
💧 湿度:35%

💡 建议:温度适宜,穿薄外套即可。

🎓 进阶:开发股票查询插件

效果展示

用户问:

苹果公司股票现在多少钱?

插件回复:

📈 苹果公司 (AAPL)

💰 股价:$175.50
📊 涨跌:+$2.30 (+1.33%)
📉 今开:$173.20
📈 最高:$176.00
📉 最低:$172.80
📊 成交量:52.3M

更新时间:2026-03-25 15:30:00 (美股盘中)

快速实现

创建 stock-plugin/src/stock.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
股票查询插件
"""


import
 requests
from
 datetime import datetime


def
 get_stock_price(symbol: str) -> dict:
    """
    获取股票价格

    Args:
        symbol: 股票代码,如 'AAPL'、'GOOGL'

    Returns:
        股票信息字典
    """

    # 使用 Alpha Vantage API(免费)

    # 需要注册获取 API Key: https://www.alphavantage.co/support/#api-key

    api_key = "YOUR_API_KEY"  # 替换为你的 key
    url = f"https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol={symbol}&apikey={api_key}"

    try
:
        response = requests.get(url, timeout=10)
        response.raise_for_status()
        data = response.json()

        quote = data.get('Global Quote', {})

        return
 {
            'symbol'
: symbol,
            'price'
: quote.get('05. price', 'N/A'),
            'change'
: quote.get('09. change', 'N/A'),
            'change_percent'
: quote.get('10. change percent', 'N/A'),
            'open'
: quote.get('02. open', 'N/A'),
            'high'
: quote.get('03. high', 'N/A'),
            'low'
: quote.get('04. low', 'N/A'),
            'volume'
: quote.get('06. volume', 'N/A'),
            'update_time'
: quote.get('07. latest trading day', 'N/A'),
        }

    except
 requests.RequestException as e:
        return
 {
            'error'
: f'查询失败:{str(e)}',
            'symbol'
: symbol
        }


def
 format_stock_report(data: dict) -> str:
    """格式化股票报告"""

    if
 'error' in data:
        return
 f"❌ {data['error']}"

    report = f"""
📈 {data['symbol']}

💰 股价:${data['price']}
📊 涨跌:{data['change']} ({data['change_percent']})
📉 今开:${data['open']}
📈 最高:${data['high']}
📉 最低:${data['low']}
📊 成交量:{data['volume']}

更新时间:{data['update_time']}
"""


    return
 report.strip()


def
 query_stock(symbol: str) -> str:
    """查询股票并返回报告"""

    data = get_stock_price(symbol)
    return
 format_stock_report(data)


if
 __name__ == '__main__':
    # 测试苹果股票

    report = query_stock('AAPL')
    print
(report)

🔧 插件开发最佳实践

1. 错误处理

def safe_query(city: str) -> dict:
    """安全的查询,包含完整错误处理"""

    try
:
        # 参数验证

        if
 not city or not isinstance(city, str):
            return
 {'error': '城市名称不能为空'}

        # API 调用

        response = requests.get(url, timeout=10)
        response.raise_for_status()

        # 数据验证

        data = response.json()
        if
 not data:
            return
 {'error': '未找到数据'}

        return
 {'success': True, 'data': data}

    except
 requests.Timeout:
        return
 {'error': '请求超时'}
    except
 requests.ConnectionError:
        return
 {'error': '网络连接失败'}
    except
 Exception as e:
        return
 {'error': f'未知错误:{str(e)}'}

2. 缓存机制

from functools import lru_cache
from
 datetime import datetime, timedelta

# 简单缓存

cache = {}

def
 get_weather_cached(city: str) -> dict:
    """带缓存的天气查询"""

    now = datetime.now()
    key = f"weather:{city}"

    # 检查缓存(10 分钟内有效)

    if
 key in cache:
        data, timestamp = cache[key]
        if
 now - timestamp < timedelta(minutes=10):
            return
 data

    # 查询 API

    data = get_weather(city)

    # 更新缓存

    cache[key] = (data, now)

    return
 data

3. 日志记录

import logging

# 配置日志

logging.basicConfig(
    level=logging.INFO,
    format
='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

logger = logging.getLogger('weather-plugin')

def
 query_weather(city: str) -> str:
    logger.info(f"查询天气:{city}")

    try
:
        data = get_weather(city)
        logger.info(f"查询成功:{data}")
        return
 format_weather_report(data)
    except
 Exception as e:
        logger.error(f"查询失败:{e}")
        return
 f"查询失败:{e}"

4. 配置管理

from dotenv import load_dotenv
import
 os

# 加载环境变量

load_dotenv()

# 读取配置

API_KEY = os.getenv('WEATHER_API_KEY')
API_URL = os.getenv('WEATHER_API_URL', 'https://wttr.in')
CACHE_TTL = int(os.getenv('CACHE_TTL', '600'))  # 默认 10 分钟

def
 get_weather(city: str) -> dict:
    # 使用配置

    url = f"{API_URL}/{city}?format=j1"
    headers = {'key': API_KEY} if API_KEY else {}

    response = requests.get(url, headers=headers)
    # ...

5. 单元测试

# tests/test_weather.py
import
 pytest
from
 src.weather import get_weather, format_weather_report


def
 test_get_weather():
    """测试天气查询"""

    data = get_weather('Beijing')
    assert
 'city' in data
    assert
 data['city'] == 'Beijing'


def
 test_format_report():
    """测试报告格式化"""

    data = {
        'city'
: 'Beijing',
        'temperature'
: '20',
        'condition'
: '晴',
        'humidity'
: '50',
        # ... 其他字段

    }
    report = format_weather_report(data)
    assert
 '北京' in report or 'Beijing' in report
    assert
 '20' in report

📦 发布插件

第 1 步:准备发布

# 创建完整的目录结构
weather-plugin/
├── src/
│   ├── __init__.py
│   └── weather.py
├── tests/
│   └── test_weather.py
├── plugin.json
├── requirements.txt
├── README.md
├── LICENSE
└── .gitignore

第 2 步:编写 README

# Weather Plugin for OpenClaw

天气查询插件,支持全球任意城市。

## 安装


```bash
openclaw plugins install weather-plugin

使用

直接问:

  • • “北京天气怎么样?”
  • • “上海今天下雨吗?”
  • • “New York weather”

配置

复制 .env.example 为 .env,填写 API Key。

开发

pip install -r requirements.txt
python src/weather.py

License

MIT


---

### 第 3 步:发布到 ClawHub

```bash
# 提交到 GitHub
git init
git add .
git commit -m "Initial release"
git push origin main

# 发布到 ClawHub
openclaw plugins publish --repo https://github.com/yourname/weather-plugin

🎯 插件创意清单

入门级

  • • [ ] 天气查询 ✅
  • • [ ] 汇率查询
  • • [ ] 笑话大全
  • • [ ] 名人名言
  • • [ ] 历史上的今天

进阶级

  • • [ ] 股票查询
  • • [ ] 新闻聚合
  • • [ ] 文档总结
  • • [ ] 图片压缩
  • • [ ] 二维码生成

高阶级

  • • [ ] Notion 集成
  • • [ ] GitHub 集成
  • • [ ] 邮件发送
  • • [ ] 智能家居控制
  • • [ ] 自定义 AI 模型

⚠️ 注意事项

1. API 限流

# 添加请求间隔
import
 time

def
 rate_limited_request(url):
    time.sleep(1)  # 每秒最多 1 次请求
    return
 requests.get(url)

2. 敏感信息

# ❌ 错误:硬编码 API Key
API_KEY = "sk-xxxxx"

# ✅ 正确:使用环境变量

API_KEY = os.getenv('API_KEY')

3. 超时处理

# 始终设置超时
response = requests.get(url, timeout=10)

4. 用户隐私

# 不记录用户数据
# 不上传用户查询历史

# 明确告知用户数据用途

🎉 总结

插件开发的核心:

  1. 1. 发现问题 – 找到 AI 不会的技能
  2. 2. 实现功能 – 写代码解决问题
  3. 3. 注册工具 – 让 AI 知道这个技能
  4. 4. 测试优化 – 确保稳定可靠

记住:

每个插件,都是让 AI 变强大的一次升级!


🚀 下一步

  • • 入门系列完成! 🎉
  • • 进阶系列:Context Engine、Session 管理
  • • 案例系列:真实应用场景

🔗 相关资源

  • • OpenClaw 插件文档:https://docs.openclaw.ai/plugins
  • • 插件市场:https://clawhub.com
  • • 示例插件:https://github.com/openclaw/plugin-examples

📖 系列文章

  • • 入门 1[1]:5 分钟搭建你的私人 AI 助理
  • • 入门 2[1]:OpenClaw vs 其他 Agent 框架
  • • 入门 3[1]:自托管 AI 的安全优势
  • • 入门 4[1]:多 Agent 协作实战
  • • 入门 5[1]:定时任务自动化
  • • 入门 6:插件开发教程(本文)

作者:Mac ⚡\ 编辑:兵哥\ 发布时间:2026-03-25


入门系列完结!你学会了哪些技能?欢迎在评论区分享你的第一个插件!

引用链接

[1] 入门 1: #