OpenClaw技能开发入门:为Qwen3-32B编写天气查询插件
OpenClaw技能开发入门:为Qwen3-32B编写天气查询插件
1. 为什么需要自定义技能?
去年冬天,我发现自己每天早晨都要重复同样的动作:打开天气APP查看温度,然后根据天气决定穿什么衣服。作为一个懒人程序员,我开始思考——能不能让我的OpenClaw助手自动完成这个任务?
这就是自定义技能的用武之地。OpenClaw的核心优势在于它的可扩展性,通过开发技能(Skill),我们可以让AI助手具备处理特定任务的能力。不同于简单的脚本调用,技能可以:
- 通过自然语言交互触发
- 整合到更复杂的工作流中
- 复用OpenClaw已有的基础设施(如认证、日志、错误处理)
2. 开发环境准备
2.1 基础工具链
在开始前,确保你已经具备:
- 运行中的OpenClaw实例(我使用的是v2.3.1)
- Node.js 18+环境(技能开发主要使用JavaScript/TypeScript)
- 一个可用的Qwen3-32B模型端点(我使用的是本地部署的RTX4090D优化版)
# 验证环境 node -v npm -v openclaw --version2.2 创建技能项目
使用OpenClaw官方脚手架快速初始化项目:
npx @openclaw/create-skill weather-query cd weather-query这会生成以下目录结构:
weather-query/ ├── manifest.json # 技能元数据 ├── package.json ├── src/ │ ├── index.ts # 主逻辑入口 │ └── types.ts # 类型定义 └── test/ # 测试用例3. 核心开发步骤
3.1 定义技能清单(manifest.json)
这个文件相当于技能的"身份证",我的配置如下:
{ "id": "weather-query", "name": "天气查询", "description": "查询实时天气信息", "version": "0.1.0", "author": "你的名字", "entry": "dist/index.js", "events": ["message"], "permissions": ["http"], "dependencies": { "@openclaw/sdk": "^2.3.0" } }关键字段说明:
events: 声明技能监听的消息类型permissions: 声明需要的权限(这里需要网络访问)entry: 编译后的入口文件路径
3.2 实现核心逻辑
在src/index.ts中,我们需要处理三个关键环节:
import { Skill, EventContext } from '@openclaw/sdk'; // 1. 初始化技能实例 const skill = new Skill(); // 2. 注册消息处理器 skill.on('message', async (ctx: EventContext) => { const { content } = ctx.payload; // 匹配天气查询意图 if (!content.includes('天气') && !content.includes('weather')) { return; // 不是天气查询就跳过 } // 3. 提取查询城市 const city = extractCity(content); // 简单的正则提取 try { // 调用天气API const weatherData = await fetchWeather(city); // 格式化响应 const reply = formatWeather(weatherData); // 返回结果 await ctx.reply(reply); } catch (err) { await ctx.reply(`查询失败: ${err.message}`); } }); // 启动技能 skill.start();3.3 对接天气API
我选择使用和风天气的免费API,需要先注册获取KEY:
async function fetchWeather(city: string) { const API_KEY = process.env.WEATHER_API_KEY; const url = `https://devapi.qweather.com/v7/weather/now?location=${encodeURIComponent(city)}&key=${API_KEY}`; const response = await fetch(url); if (!response.ok) { throw new Error(`API请求失败: ${response.status}`); } return response.json(); }注意将API_KEY存储在环境变量中,不要硬编码在代码里。
3.4 结果格式化
为了让Qwen3-32B生成的回复更友好,我设计了这样的格式:
function formatWeather(data: any) { const { now, location } = data; return ` 当前${location.name}天气: - 状况:${now.text} - 温度:${now.temp}℃ - 体感温度:${now.feelsLike}℃ - 风向:${now.windDir} - 风力:${now.windScale}级 - 湿度:${now.humidity}% - 降水量:${now.precip}mm 更新时间:${now.obsTime} `.trim(); }4. 调试与部署
4.1 本地测试
使用OpenClaw CLI进行本地测试:
# 编译TypeScript npm run build # 本地运行技能 openclaw skill run ./dist然后在OpenClaw控制台发送"北京天气如何",应该能看到格式化的回复。
4.2 常见问题排查
我遇到的两个典型问题及解决方案:
API调用失败
- 检查网络连接
- 验证API_KEY是否正确
- 确认城市名称是否被API支持
中文乱码
- 确保HTTP请求头包含
Accept-Charset: utf-8 - 检查终端/控制台的编码设置
- 确保HTTP请求头包含
4.3 发布到ClawHub
完成开发后,可以发布到技能市场:
# 登录ClawHub clawhub login # 发布技能 clawhub publish --access public发布后其他用户可以通过clawhub install weather-query安装你的技能。
5. 进阶优化方向
在实际使用几周后,我发现几个可以改进的点:
多城市查询修改正则表达式支持"北京和上海天气"这样的查询
天气预报扩展API调用,支持未来3天预报
缓存机制对相同城市的查询结果缓存10分钟,减少API调用
单位转换根据用户偏好显示摄氏/华氏温度
这些改进都可以通过迭代manifest.json和核心逻辑来实现。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
