共计 2699 个字符,预计需要花费 7 分钟才能阅读完成。
理解 Qoder 平台中的 Skill
Skill 是 Qoder 平台上可复用的功能模块,类似于手机上的小程序。它允许开发者通过预定义的接口快速构建特定场景的智能服务。一个典型的 Skill 由三个核心部分组成:

- 意图识别:解析用户输入的语义(例如 ” 查询北京天气 ”)
- 业务逻辑:处理核心功能(如调用天气 API)
- 响应生成:返回结构化响应(语音 / 文本 / 卡片)
与传统的 API 开发不同,Skill 采用事件驱动模型。当用户触发技能时,平台会将用户请求包装成标准化事件对象,开发者只需关注如何处理这些事件。
开发环境配置
-
安装 Qoder CLI 工具(要求 Node.js 14+ 环境):
npm install -g @qoder/cli -
初始化项目:
qoder init weather-skill --template=basic cd weather-skill -
配置文件说明:
skill.json:技能元数据(名称 / 版本 / 权限等)handlers/:业务逻辑处理目录models/:数据模型定义tests/:单元测试用例
天气查询 Skill 实战
1. 创建基础结构
在 handlers 目录新建weatherHandler.js:
// 引入 SDK 核心模块
const {BaseHandler} = require('@qoder/sdk');
class WeatherHandler extends BaseHandler {async handle(event) {
// 解析用户查询城市
const city = event.slotValue('city') || '北京';
// 调用天气 API(示例使用 Mock 数据)const weather = await this._getWeather(city);
// 构造语音响应
return this.response()
.say(`${city}今天天气 ${weather.condition}, 气温 ${weather.temp}度 `)
.card({title: `${city}天气预报 `,
content: ` 湿度: ${weather.humidity}% | 风速: ${weather.wind}km/h`
});
}
// 私有方法:模拟 API 调用
async _getWeather(city) {
return {condition: ['晴','多云','雨'][Math.floor(Math.random()*3)],
temp: 15 + Math.floor(Math.random()*15),
humidity: 30 + Math.floor(Math.random()*50),
wind: 5 + Math.floor(Math.random()*20)
};
}
}
module.exports = WeatherHandler;
2. 注册技能路由
在 skill.json 中添加:
{
"handlers": {
"weather_query": {
"file": "./handlers/weatherHandler",
"intents": ["query_weather"]
}
}
}
3. 本地测试
启动调试服务:
qoder dev --port 3000
使用 curl 测试:
curl -X POST \
http://localhost:3000/ \
-H 'Content-Type: application/json' \
-d '{"intent":"query_weather","slots":{"city":" 上海 "}}'
常见问题解决方案
- Slot 取值失败
- 现象:
event.slotValue()返回 undefined -
解决:检查技能控制台的意图定义,确保 slot 名称与代码一致
-
权限不足
- 现象:调用外部 API 时返回 403
-
解决:在
skill.json的permissions字段中添加所需权限 -
响应超时
- 现象:技能响应超过 5 秒限制
-
解决:对耗时操作使用异步处理,或实现分步响应
-
内存泄漏
- 现象:长时间运行后进程崩溃
-
解决:使用
qoder monitor工具分析内存使用情况 -
版本冲突
- 现象:本地测试正常但部署失败
- 解决:检查
package.json中 SDK 版本与平台要求是否匹配
性能优化技巧
-
缓存热点数据
// 使用 Qoder 内置缓存(默认 TTL 300 秒)const cachedWeather = await this.cache.get(city); if (!cachedWeather) {const freshData = await this._getWeather(city); await this.cache.set(city, freshData); return freshData; } return cachedWeather; -
精简依赖包
- 使用
qoder analyze命令检查无用依赖 -
优先选用平台内置工具方法
-
批量处理设计
对于支持多城市查询的场景:async handle(event) {const cities = event.slotValue('cities').split('和'); const results = await Promise.all(cities.map(city => this._getWeather(city.trim())) ); // ... 合并结果逻辑 }
扩展建议
-
多语言支持
在skill.json中配置:{ "i18n": {"locales": ["zh-CN", "en-US"], "defaultLocale": "zh-CN" } } -
接入真实 API
改造_getWeather方法:const API_KEY = process.env.WEATHER_API_KEY; async _getWeather(city) { const response = await fetch(`https://api.weather.com/v3?city=${encodeURIComponent(city)}&key=${API_KEY}` ); return response.json();} -
添加用户偏好记忆
利用 Qoder 的用户上下文特性:// 存储用户最后查询的城市 await this.user.set('last_city', city); // 下次可直接使用 const lastCity = await this.user.get('last_city');
总结
通过这个天气查询案例,我们完成了从零开发一个完整 Skill 的全过程。建议在掌握基础模式后,尝试以下进阶路线:
- 为技能添加可视化数据图表
- 实现基于位置的自动天气推送
- 结合 Qoder 的对话管理功能设计多轮交互
- 发布到技能市场获取实际用户反馈
开发过程中遇到问题时,可以查阅 Qoder 官方文档的Skill 开发指南,或加入开发者社区的 Slack 频道交流实战经验。
