赞
踩
在上一篇博文中,我们介绍了聆思的大模型平台。本篇博文我们将介绍如何使用在线编排能力,实现语音控制电梯的功能。在我们设计的智能电梯应用中,用户可以通过语音控制电梯所到的楼层,比如说“到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合成语音节点的,生成语音数据发送给开发板直接进行播放。
完成配置后,点击右上角部署
后返回应用
界面,打开刚才创建的应用,点击部署生产。
有关开发板程序的修改,将在下篇博文中介绍。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。