最近遇到了这么一个需求,大概就是根据用户的语音输入来操作我们的软件。具体来说有点像是手机的智能助手,比如你说“把空调调低1度”,然后我接收到指令后发送信号给空调去调低1度。
以下就是这个语音控制空调的例子,来自讯飞官方的DEMO。
语音输入:把空调调低1度
返回结果
{
"intent": "CONTROL",
"slots": [
{
"name": "device",
"normValue": "airconditioner",
"value": "空调"
},
{
"name": "insType",
"normValue": "set",
"value": "调小"
},
{
"name": "attr",
"normValue": "temperature",
"value": "温度"
},
{
"name": "attrValue",
"normValue": "1",
"value": "1"
}
],
"sample": "把空调调低1度"
}
步骤拆解
要达成这么一个需求,我们把它拆分成几个步骤看看具体的难点是什么。
-
语音输入的方式,可以是按住说话也可以是语音唤醒
-
录音输入,并转成文字
-
提取出意图,并转换成JSON格式的指令
-
执行指令,实现用户的操作
为什么需要AI
其实我相信很多人第一反应是为什么看起来挺简单一个需求为什么需要AI来做,看起来只需要提取出文字中的指令即可,用代码来做匹配,包括近义词匹配、模糊匹配,也能够解析出用户的指令。
确实只靠代码也能够解析出一些简单的指令,但是我觉得难点在于用户的输入是千奇百怪的,比较难以每种情况都匹配到,比如同样是调低空调的温度,有很多种可能的表达方式。
把空调调低1度
请调小空调温度1度
请把格力品牌的空调调低1度
让卧室的空调温度低1度
当然也有一种方式,就是把所有的可能输入都列举出来,识别率会进一步提高,但这样需要花费大量的时间和人力进行调试和测试,如果更加深入的话就像是用自然语言处理来做一样。所以我们选择效果更高效的方式来实现这一需求。
Prompt实现
语音转文字这部分我们就不讲了,这个很好实现,用讯飞转文字之类的服务,基本上可以达到比较高的识别率,语音唤醒也同样用的讯飞服务,按装机量付费即可。
我第一反应是直接把需求写进prompt的方式让AI理解需求并解析输入,返回具体的指令,我们来试一下是否可行:
我们的智能家居软件要做一个用户语音输入来操作家用电器的功能,接下来请根据我每次的文字输入,推测出用户的意图,返回具体的json指令。举个例子:用户的输入是:把空调调低一度,你返回我{“intent”:“CONTROL”,“slots”:[{“name”:“device”,“normValue”:“airconditioner”,“value”:“空调”},{“name”:“insType”,“normValue”:“set”,“value”:“调小”},{“name”:“attr”,“normValue”:“temperature”,“value”:“温度”},{“name”:“attrValue”,“normValue”:“1”,“value”:“1”}],“sample”:“把空调调低1度”}。我的输入是把空气净化器的湿度调高1度。
返回结果
根据您提供的信息,用户的意图是调整空气净化器的湿度。具体的json指令如下:
json
复制代码运行
{
"intent": "CONTROL",
"slots": [
{
"name": "device",
"normValue": "air purifier",
"value": "空气净化器"
},
{
"name": "insType",
"normValue": "set",
"value": "调高"
},
{
"name": "attr",
"normValue": "humidity",
"value": "湿度"
},
{
"name": "attrValue",
"normValue": "1",
"value": "1"
}
],
"sample": "把空气净化器的湿度调高1度"
}
这是用讯飞Spark Pro大模型进行的测试,返回的结果我还挺满意的,几乎是能够满足我们的需求。当然如果想要实现最好的效果还是需要给它举更多的例子,比如温度、湿度、设备名字等,这样返回的normValue值更准确。当AI返回这样的JSON结构,我们很容易就解析出来,执行到具体发信号的步骤了。
在线训练大模型
如果指令集内容比较少,比如能操作的设备和参数只有几个的话,以上方式已经能够满足基本需求了。但实际项目中指令集非常庞大,比如涉及到空调、热水器、电扇、空气净化器,再加上品牌、位置、以及各种参数的调节,AI就很难根据我们输入简单的Prompt来工作了,我们也不可能把一堆例子全写在prompt里,因为输入是上限的,越长的输入响应时间越长,资费也就越高。
于是我们可以使用训练集训练大模型的方式来实现这一需求,把所有想到的指令都写入一个json文件,包括具体的输入,以及想要得到的结果,差不多2000条以上,然后交给大模型训练,就能得到一个更加精准的定制化模型。
{“input”:“一小时后帮我把空气净化器的湿度降低到最低”,“output”:"{"intent":"CONTROL","slots":[{"name":"device","normValue":"airCleaner","value":"空气净化器"},{"name":"insType","normValue":"降低","value":"降低"},{"name":"attr","normValue":"humidity","value":"湿度"},{"name":"attrValue","normValue":"最低","value":"最低"},{"name":"datatime","normValue":"一小时后","value":"一小时后"}],"sample":"一小时后帮我把空气净化器的湿度降低到最低"}"}
经过训练后,我们再次调用大模型时就不用以上那些很长的prompt了,我们直接把用户的输入传给大模型,就能得到最终的结果了。
总结
当然这不是一个广告贴,讯飞也没给我一分钱。确实是在实际项目种遇到了这个需求,然后通过这样的解决方案较好地完成了任务,所以写了这么一篇博客希望可以帮助到遇到这样的需求的人。对于我们在生产中使用生成式AI的来说,返回的结果更加可控可靠,有很高的准确率,才是我们想要的AI服务。