卜木是一位工作三年的工程师,主营 PHP web。作为一个典型的硬件爱好开发者,他对各种硬件、软件都很感兴趣,搭建过树莓派私人服务器,也参与过某大型企业智能空气净化器物联软件开发。
注意到 Rokid ALL in ONE 全栈智能语音开发套件后,卜木开启了一段与 Rokid 的奇妙之旅。他以 xqbumu 在 Rokid 开放平台注册,开发了名为记事本的 Skill。开启这个技能,可以抛掉备忘录,动动嘴巴就能用若琪帮你做提醒。使用这个技能就相当于为自己配了一个低配版的贾维斯呢。
从拿到若琪开发套件到开发出一个属于自己的人工智能助手,卜木好好钻研了一番若琪在 GitHub 开放的源代码,并把自己的劳动成果也分享到若琪的代码仓库。下面我们对他做一次简单的采访。
Q:拿到若琪开发套件的时候啥心情?
A:因为刚好是圣诞节收到的嘛,我一直把她当作圣诞礼物。
Q:拿到开发套件后都是怎么玩的呀?
A:看看上面装了些什么,统统体验了一下,看看能怎么玩。
Q:若琪开发套件功能非常多,什么对你来说最好玩?
A:主要是可以深度了解到rokid的代码,进行无限的探索,然后实践到开发板上!
Q:看到你开发了记事本的 Skill 也分享了源码。为什么想做记事本呀?
A:词事本是一个在功能应用上比较综合的技能,包含 Rokid 提供的 session、db 等基础设施和交互流程。通过这样一个技能的开发,能最快地了解 Rokid。
Q:那下一步打算怎么玩?
A:尝试 rss 订阅技能,看看自动播放、promise、async/await 这些特性,打好基础之后就开始向硬件交互、设备间通讯等方面研究。
以下摘录于卜木开发日记:
《我的 Rokid 之路 附:记事本技能全部源代码》
目前已开发的技能 记事本
* 基本功能框架完成
* 欢迎各位开发提交PR
本人遇坑及经验总结如下:
1、没迅速找到官方的开发指南,直接进官方文档就上,然后无法通过APP内置的点击6下的开发模式连接Rokid,查询官方文档,可得知,需要通过Pebble设备方式进行连接,如果以后还有其它问题建议先进入开发套件常见问题解决方案汇总。
2、在配置WiFi时,本人路由器名称设置了默认隐藏,因此在通过蓝牙配置WiFi连接时,一直无法配置通过,总结以往raspberry pi把玩经验,果断尝试关闭隐藏WiFi,得以解决无法配置连接WiFi的问题,导致该问题需要修改固件里的WiFi连接脚本,这个本人就先不尝试了,具体问题及解决方案已经发送到Rokid讨论里了,希望能改进无法正常连接隐藏的WiFi,解决资料。
3、如果在APP的配网蓝牙连接这里搜索不到设备,要么使用点击6下的方式进入配网流程,要么使用Pebble设备的配网流程。
4、CPU板正对USB Type-c 的按键就是刷机用的按键,先按住,再通电,看出USB_Burning_Tool上出现设备,就可以松了,比用Debug板进行刷机方便很多,很人性化。
5、在Windows下使用adb shell连接到开发板后,使用ls命令,如果出现类似如下的内容,可能是自带的字符串着色与Windows的console不兼容,登入shell后,执行 alias ls=‘busybox ls --color=never’ 即可。建议Rokid预安装bash作为备用选项,或者开发者自行下载使用Cmder软件,可解决以上问题。(不怎么直接使用sh,一直用的bash或者zsh,没有出现过类似问题)
关于WiFi连接及配网
坑走完之后就是Demo了,能正式配置Rokid的WiFi连接,剩下的就很方便了,通过官方开发指南先做一个简单的人机对话,在开发过程中与Rokid的直接交流语言的JavaScript,因此若要开发更为灵活的服务功能,需要依托其它的后台接口开发。
交互构建
原本只想简单的写一个记录语音内容的技能(其中还包含其它方面的简单功能,只是是简单的),最后发现给自己挖的坑比较多。
因此建议在开发技能前,最好能完成完整的交互流程,以方便对技能可能涉及到的业务有一个整体的把控。
语音交互内容比较单一,但在整体的把控上确没有常见的app或者web开发直观,因此再次说明了有一份完整的交互流程作为一个技能开发的唯一的直观可视依据是很有必要的。
技能流程
关于入口词的一些事
Rokid 中可能涉及的入口词问题,本人发现Rokid 是针对技能貌似是独占的,前期可能刺激开发者或者其他人员抢占入口词,建议平台针对这点进行入口词融合、增加针对用户或者设备调试不同技能的优先级功能。
关于语言交互的设置
词表
*Rokid 预定义词表
json
{
"intent": "RecordAny",
"slots": [
{
"name": "content",
"type": "ROKID.ANY"
}
],
"user_says": [
"!$content"
]
}
服务代码对应handler使用如下setConfirm语句:
javascript
this.setConfirm({
confirmIntent: 'RecordAny',
confirmSlot: 'content'
});
dbServer
dbServer.set(key, value, callback) 该方法为异步形式,因此涉及数据库操作时,应该将其后的业务逻辑放于callback中,否则数据还没取回就执行到后面的业务中。
get:Rokid.dbServer.get(key, callback)与Rokid.dbServer.delete(key,callback)是否为异步形式尚未验证,建议同样将数据库操作之后的业务逻辑放于callback中。
鉴于关于数据库操作为异步形式,因此建议相关开发者自建统一的数据库存取管理的相关代码以避免多层嵌套(具体参考代码稍后会以GitHub的形式放出),或者改写为Promise形式,目前尚未改写成功。
集成测试中的后端服务测试与服务列表中的测试用例在逻辑上不属于同一个会话,因此在调试中需要做区别,也就是数据库里的数据不共享,需要单独各自添加测试数据。
想要参与讨论,欢迎传送到>>>原文与开发者切磋。