插件开发教程 – 从零开发第一个 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:
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
本教程使用 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. 发现问题 – 找到 AI 不会的技能 -
2. 实现功能 – 写代码解决问题 -
3. 注册工具 – 让 AI 知道这个技能 -
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: #
夜雨聆风