【聆思CSK6语音大模型AI开发套件试用】语音控制电梯功能的在线编排
在中,我们介绍了聆思的大模型平台。本篇博文我们将介绍如何使用在线编排能力,实现语音控制电梯的功能。在我们设计的智能电梯应用中,用户可以通过语音控制电梯所到的楼层,比如说“到4层”,电梯就会自动运行到4层。而这之中语音识别、语音合成以及对用户的语言的理解都是在云平台上完成的。开发板只是做语音的采集、上传、接收云平台的处理结果,并播放语音和显示结果。
任务简介
在上一篇博文中,我们介绍了聆思的大模型平台。本篇博文我们将介绍如何使用在线编排能力,实现语音控制电梯的功能。在我们设计的智能电梯应用中,用户可以通过语音控制电梯所到的楼层,比如说“到4层”,电梯就会自动运行到4层。而这之中语音识别、语音合成以及对用户的语言的理解都是在云平台上完成的。开发板只是做语音的采集、上传、接收云平台的处理结果,并播放语音和显示结果。
流程设计
我们首先按照官方的文档搭建一个语音控制的基本流程:产品应用搭建 | 聆思文档中心 (listenai.com)。在这个例子中官方提供了上一篇博文文件,这个文件是用来实现官方示例的。不过这个文件只包括整体流程,不包括提示词和代码,这些内容要参照官方介绍自己输入。示例工程所对应的处理流程如下图所示。
这个流程可以分为两个主要部分。前面的部分是进行语音交互,将用户的语音输入识别为文字后利用第一个提示词(我称之为分类提示词)将用户语音命令进行意图分类。
后面一部分是根据前面的意图识别结果进行多分支处理。画图的分支是调用讯飞星火的文生图功能生成图片。控制修改背景的分支是再次使用提示词(我称之为背景设置提示词)调用讯飞星火大模型从用户语音内容中提取关键的控制信息,如颜色。还有个闲聊分支是完成基本的语音问答功能的。
我们在原有的大模型处理的三个分支基础上增加一个分支,也就是我们的电梯控制分支。
在落域控制部分也需要加上相应的分支选项。
增加电梯控制分支
为了让大家看得更清楚,我们将分支部分放大一下。这里我们的电梯控制分支是完全复制背景设置分支的。其中“前置处理”后两个分支:一个去TTS初始化,一个去提示词。我刚开始忘记画TTS初始化分支,导致在处理相关内容时无法给出用户语音提示。“后置处理”后也有两个分支:一个去TTS合成,一个去语音结果下发。TTS合成部分主要是负责合成“请稍等”、“处理完成”之类的语音提示。
整个处理流程必须严格按照图示进行连接,否则功能可能不正常。聆思平台最大的缺点是不方便调试,如果有问题,只能自己细心检查。
提示词设计
在与大模型交互时,提示词能控制大模型更好地达到你所期望的结果。设计好的提示词非常关键。
分类提示词
分类提示词是用于对用户提示词进行分类的,根据不同的分类来完成不同的任务。我们所使用的提示词如下:
你是一个分类专家,你需要将用户的句子归为“电梯控制”、“画画”、“设置背景”、“闲聊”中的一类,下面是一些例子:
用户:一幅海马进食
助手:画画
用户:把背景设置为蓝色
助手:设置背景
用户:电梯到第五层
助手:电梯控制
用户:到首层
助手:电梯控制
按照提示词的一般设计原则,首先要对大模型进行角色设定(“你是一个分类专家”)。然后对其进行任务设定(“你需要将用户的句子归为“电梯控制”、“画画”、“设置背景”、“闲聊”中的一类”)。接下来就是给大模型一些例子进行学习理解以提高分类的准确性。
电梯控制提示词
电梯控制提示词的作用是从用户的命令中提取我们感兴趣的参数,也就是目的楼层。用户的输入可能是各种各样的,采用自然语言处理比采用通配符匹配显然有更好的识别效果。我采用的电梯控制提示词如下:
你是一个电梯控制专家,我会给你一个设置电梯的要求,请你告诉要设置的楼层是什么,请用十进制数值表示结果,以下是一些例子:
用户:电梯到达五层
助手:5
用户:电梯到达首层
助手:1
用户:电梯到达地下2层
助手:-2
你只需要输出目标楼层的十进制表示,我的要求是:
用户:{{content}}
助手:
最后的识别结果会以一个有符号数来表示,后续的处理就简单了。
添加处理代码
需要添加的代码包括前置代码和后置代码,前置代码完全照抄背景设置分支即可。这里只介绍后置代码分支。
完整的代码如下:
//设置楼层成功的语音提示
const floorSucc = "已完成设置";
//设置楼层失败的语音提示,留空表示使用大模型的回复
const floorFail = "很抱歉,我可能还无法理解你想要的楼层";
//设置楼层异常的语音提示
const floorErr = "很抱歉,我暂时无法完成该操作";
//数据模版,不建议直接修改
const intentTemplate = {
"text": "",
"rc": 0,
"data": {
"result": [{
"id": "xxx",
"type": "Decimal",
"value": "1"
}]
},
"answer": {
"text": "已完成设置",
"type": "T"
},
"service": "floor",
"service_pkg": "media",
"category": "LISTENAI.floor"
}
//大模型回复内容
let content = msg.payload.choices[0]?.message?.content || '';
//正则匹配十进制值
if (/^[-+]?\d+$/.test(content)){
//正则表达式提取十进制值
let match = content.match(/^[-+]?\d+/);
let matchFloor;
if (match) {
matchFloor = match[0]; // 提取第一个匹配的十进制数字序列
} else {
matchFloor = null; // 如果没有找到匹配项,则设置为null
}
printInfo("匹配到楼层:", matchFloor);
intentTemplate.data.result[0].id = msg.payload.id;
intentTemplate.data.result[0].value = matchFloor;
intentTemplate.text = msg._asrResult;
//构造tts合成文本
let ttsMsg = RED.util.cloneMessage(msg);
ttsMsg.payload = {
text: floorSucc,
stream: true,
is_last: true
};
//构造设置楼层的数据帧给设备
let nluMsg = RED.util.cloneMessage(msg);
nluMsg.payload = {
type: "CUSTOM",
intent: intentTemplate
};
node.send([nluMsg, ttsMsg]);
} else {
printErr("匹配不到楼层:" , content);
//构造tts合成文本
let ttsMsg = RED.util.cloneMessage(msg);
ttsMsg.payload = {
text: floorFail || content || floorErr,
stream: true,
is_last: true
};
//若匹配不到楼层,只下发语音提示
node.send([null, ttsMsg]);
}
return;
/**
* 日志打印
*/
function printInfo(tips, data) {
let date = new Date();
let message = `[INFO] SID[${msg.queryParams?.sid || ''}] App[${msg.queryParams?.llmApp}] Device[${msg.queryParams.deviceId || ''}] Time[${`${date.getHours() + 8}:${date.getMinutes()}:${date.getSeconds()}.${date.getMilliseconds()}]`} ${tips}`;
if (data) {
if (typeof data === 'object') {
console.log(message, JSON.stringify(data))
} else {
console.log(message, data)
}
} else {
console.log(message)
}
}
/**
* 日志打印
*/
function printErr(tips, err) {
let date = new Date();
let message = `[ERR ] SID[${msg.queryParams?.sid || ''}] App[${msg.queryParams?.llmApp}] Device[${msg.queryParams.deviceId || ''}] Time[${`${date.getHours() + 8}:${date.getMinutes()}:${date.getSeconds()}.${date.getMilliseconds()}]`} ${tips}`;
console.error(message, err);
}
代码并不复杂,仅就关键点进行解释。正常情况下,节点将产生两个数据,其中nluMsg是一个JSON字符串,发送给开发板进行数据处理,其格式是由intentTemplate变量定义的,修改时要注意不要出错。而ttsMsg是发给TTS合成语音节点的,生成语音数据发送给开发板直接进行播放。
应用部署
完成配置后,点击右上角部署
后返回应用
界面,打开刚才创建的应用,点击部署生产。
有关开发板程序的修改,将在下篇博文中介绍。
更多推荐
所有评论(0)