OpenClaw 插件开发实战:从 plugin.json、工具注册到热重载的完整链路 原创
温馨提示:
本文最后更新于 2026-10-22,已超过 0 天没有更新。
若文章内的图片失效(无法正常加载),请留言反馈或直接 联系我。
OpenClaw 的插件系统不是简单的「写个 Python 文件」——它是一套完整的能力注册机制:plugin.json 声明元数据、工具自动注册到 LLM、生命周期钩子管理状态、热重载支持不停机更新。这篇从开发者的角度,讲清楚一个插件从创建到上线的完整流程。
一、plugin.json:插件的身份证
每个插件都必须有一个 plugin.json,声明基本元数据和入口:
{
"name": "weather",
"version": "1.0.0",
"description": "查询天气信息",
"author": "your-name",
"license": "MIT",
"entry": "main.py",
"tools": [
{
"name": "get_weather",
"description": "获取指定城市的当前天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如 '北京'"
}
},
"required": ["city"]
}
}
],
"dependencies": {
"python": ["requests>=2.28.0"]
},
"config": {
"api_key": {
"type": "string",
"description": "OpenWeatherMap API Key",
"secret": true
}
}
}
二、工具注册:让 LLM 能调用你的代码
plugin.json 里声明的 tools 会被 OpenClaw 自动注册到 LLM 的工具列表。LLM 看到 get_weather 的描述后,会在需要时生成调用:
# main.py
import requests
from openclaw.plugin import tool, config
@tool("get_weather")
def get_weather(city: str) -> str:
"""获取指定城市的当前天气"""
api_key = config("api_key")
if not api_key:
return "错误:未配置 API Key"
url = f"https://api.openweathermap.org/data/2.5/weather"
params = {
"q": city,
"appid": api_key,
"units": "metric",
"lang": "zh_cn"
}
resp = requests.get(url, params=params, timeout=10)
data = resp.json()
if resp.status_code != 200:
return f"查询失败:{data.get('message', '未知错误')}"
return f"{city}当前天气:{data['weather'][0]['description']},温度 {data['main']['temp']}°C,湿度 {data['main']['humidity']}%"
关键点:
@tool("get_weather")装饰器把函数注册为工具- 函数签名必须和 plugin.json 里的
parameters匹配 - 返回值是字符串,LLM 会把它作为工具结果
config("api_key")读取用户配置,支持 secret 类型
三、生命周期钩子:不只是工具调用
插件可以注册 4 个生命周期钩子:
from openclaw.plugin import hook
@hook("on_load")
def on_load():
"""插件加载时调用"""
print("Weather plugin loaded")
@hook("on_unload")
def on_unload():
"""插件卸载时调用"""
print("Weather plugin unloaded")
@hook("on_session_start")
def on_session_start(session_id: str):
"""新会话开始时调用"""
print(f"New session: {session_id}")
@hook("on_session_end")
def on_session_end(session_id: str):
"""会话结束时调用"""
print(f"Session ended: {session_id}")
四、热重载:改完代码不用重启
OpenClaw 支持插件热重载,修改代码后无需重启 Gateway:
# 方式 1:命令行
openclaw plugins reload weather
# 方式 2:API
curl -X POST http://localhost:3000/api/plugins/weather/reload
# 方式 3:自动监听文件变化(开发模式)
openclaw plugins dev weather --watch
热重载会:
- 调用
on_unload钩子 - 重新加载 Python 模块
- 重新注册工具
- 调用
on_load钩子
五、实战:做一个「翻译插件」
完整示例,支持中英文互译:
# plugin.json
{
"name": "translator",
"version": "1.0.0",
"description": "中英互译工具",
"entry": "main.py",
"tools": [
{
"name": "translate",
"description": "翻译文本,自动检测语言",
"parameters": {
"type": "object",
"properties": {
"text": {"type": "string", "description": "要翻译的文本"},
"target": {"type": "string", "description": "目标语言:zh 或 en", "enum": ["zh", "en"]}
},
"required": ["text", "target"]
}
}
]
}
# main.py
from openclaw.plugin import tool
@tool("translate")
def translate(text: str, target: str) -> str:
"""翻译文本"""
# 简单实现:调用本地 Ollama 模型
import requests
prompt = f"将以下文本翻译成{'中文' if target == 'zh' else '英文'}:\n{text}"
resp = requests.post("http://localhost:11434/api/generate", json={
"model": "qwen2.5:7b",
"prompt": prompt,
"stream": False
})
if resp.status_code == 200:
return resp.json()["response"]
else:
return "翻译失败"
六、调试技巧
插件出问题时,按这个顺序排查:
- plugin.json 语法错误:
openclaw plugins validate weather - Python 导入错误:查看
~/.openclaw/logs/plugins/weather.log - 工具注册失败:检查函数签名是否匹配 plugin.json
- LLM 不调用:检查 tool description 是否清晰,参数是否必填
- 返回值格式错误:必须是字符串,不能是 dict/list
结语
OpenClaw 插件系统的价值在于把 LLM 的能力边界从「对话」扩展到「执行」。通过 plugin.json 声明工具、Python 实现逻辑、生命周期钩子管理状态,开发者可以快速构建从「查询天气」到「操作数据库」的各种能力。热重载机制让开发调试变得高效,而统一的工具注册协议保证了 LLM 能正确理解和调用你的代码。