当前位置:   article > 正文

【聆思CSK6语音大模型AI开发套件试用】语音控制电梯功能的在线编排_聆思大模型平台

聆思大模型平台

任务简介

上一篇博文中,我们介绍了聆思的大模型平台。本篇博文我们将介绍如何使用在线编排能力,实现语音控制电梯的功能。在我们设计的智能电梯应用中,用户可以通过语音控制电梯所到的楼层,比如说“到4层”,电梯就会自动运行到4层。而这之中语音识别、语音合成以及对用户的语言的理解都是在云平台上完成的。开发板只是做语音的采集、上传、接收云平台的处理结果,并播放语音和显示结果。

流程设计

我们首先按照官方的文档搭建一个语音控制的基本流程:产品应用搭建 | 聆思文档中心 (listenai.com)。在这个例子中官方提供了上一篇博文文件,这个文件是用来实现官方示例的。不过这个文件只包括整体流程,不包括提示词和代码,这些内容要参照官方介绍自己输入。示例工程所对应的处理流程如下图所示。

这个流程可以分为两个主要部分。前面的部分是进行语音交互,将用户的语音输入识别为文字后利用第一个提示词(我称之为分类提示词)将用户语音命令进行意图分类。

后面一部分是根据前面的意图识别结果进行多分支处理。画图的分支是调用讯飞星火的文生图功能生成图片。控制修改背景的分支是再次使用提示词(我称之为背景设置提示词)调用讯飞星火大模型从用户语音内容中提取关键的控制信息,如颜色。还有个闲聊分支是完成基本的语音问答功能的。

我们在原有的大模型处理的三个分支基础上增加一个分支,也就是我们的电梯控制分支。

在落域控制部分也需要加上相应的分支选项。

增加电梯控制分支

为了让大家看得更清楚,我们将分支部分放大一下。这里我们的电梯控制分支是完全复制背景设置分支的。其中“前置处理”后两个分支:一个去TTS初始化,一个去提示词。我刚开始忘记画TTS初始化分支,导致在处理相关内容时无法给出用户语音提示。“后置处理”后也有两个分支:一个去TTS合成,一个去语音结果下发。TTS合成部分主要是负责合成“请稍等”、“处理完成”之类的语音提示。

整个处理流程必须严格按照图示进行连接,否则功能可能不正常。聆思平台最大的缺点是不方便调试,如果有问题,只能自己细心检查。

提示词设计

在与大模型交互时,提示词能控制大模型更好地达到你所期望的结果。设计好的提示词非常关键。

分类提示词

分类提示词是用于对用户提示词进行分类的,根据不同的分类来完成不同的任务。我们所使用的提示词如下:

  1. 你是一个分类专家,你需要将用户的句子归为“电梯控制”、“画画”、“设置背景”、“闲聊”中的一类,下面是一些例子:
  2. 用户:一幅海马进食
  3. 助手:画画
  4. 用户:把背景设置为蓝色
  5. 助手:设置背景
  6. 用户:电梯到第五层
  7. 助手:电梯控制
  8. 用户:到首层
  9. 助手:电梯控制

按照提示词的一般设计原则,首先要对大模型进行角色设定(“你是一个分类专家”)。然后对其进行任务设定(“你需要将用户的句子归为“电梯控制”、“画画”、“设置背景”、“闲聊”中的一类”)。接下来就是给大模型一些例子进行学习理解以提高分类的准确性。

电梯控制提示词

电梯控制提示词的作用是从用户的命令中提取我们感兴趣的参数,也就是目的楼层。用户的输入可能是各种各样的,采用自然语言处理比采用通配符匹配显然有更好的识别效果。我采用的电梯控制提示词如下:

  1. 你是一个电梯控制专家,我会给你一个设置电梯的要求,请你告诉要设置的楼层是什么,请用十进制数值表示结果,以下是一些例子:
  2. 用户:电梯到达五层
  3. 助手:5
  4. 用户:电梯到达首层
  5. 助手:1
  6. 用户:电梯到达地下2
  7. 助手:-2
  8. 你只需要输出目标楼层的十进制表示,我的要求是:
  9. 用户:{{content}}
  10. 助手:

最后的识别结果会以一个有符号数来表示,后续的处理就简单了。

添加处理代码

需要添加的代码包括前置代码和后置代码,前置代码完全照抄背景设置分支即可。这里只介绍后置代码分支。

完整的代码如下:

  1. //设置楼层成功的语音提示
  2. const floorSucc = "已完成设置";
  3. //设置楼层失败的语音提示,留空表示使用大模型的回复
  4. const floorFail = "很抱歉,我可能还无法理解你想要的楼层";
  5. //设置楼层异常的语音提示
  6. const floorErr = "很抱歉,我暂时无法完成该操作";
  7. //数据模版,不建议直接修改
  8. const intentTemplate = {
  9. "text": "",
  10. "rc": 0,
  11. "data": {
  12. "result": [{
  13. "id": "xxx",
  14. "type": "Decimal",
  15. "value": "1"
  16. }]
  17. },
  18. "answer": {
  19. "text": "已完成设置",
  20. "type": "T"
  21. },
  22. "service": "floor",
  23. "service_pkg": "media",
  24. "category": "LISTENAI.floor"
  25. }
  26. //大模型回复内容
  27. let content = msg.payload.choices[0]?.message?.content || '';
  28. //正则匹配十进制值
  29. if (/^[-+]?\d+$/.test(content)){
  30. //正则表达式提取十进制值
  31. let match = content.match(/^[-+]?\d+/);
  32. let matchFloor;
  33. if (match) {
  34. matchFloor = match[0]; // 提取第一个匹配的十进制数字序列
  35. } else {
  36. matchFloor = null; // 如果没有找到匹配项,则设置为null
  37. }
  38. printInfo("匹配到楼层:", matchFloor);
  39. intentTemplate.data.result[0].id = msg.payload.id;
  40. intentTemplate.data.result[0].value = matchFloor;
  41. intentTemplate.text = msg._asrResult;
  42. //构造tts合成文本
  43. let ttsMsg = RED.util.cloneMessage(msg);
  44. ttsMsg.payload = {
  45. text: floorSucc,
  46. stream: true,
  47. is_last: true
  48. };
  49. //构造设置楼层的数据帧给设备
  50. let nluMsg = RED.util.cloneMessage(msg);
  51. nluMsg.payload = {
  52. type: "CUSTOM",
  53. intent: intentTemplate
  54. };
  55. node.send([nluMsg, ttsMsg]);
  56. } else {
  57. printErr("匹配不到楼层:" , content);
  58. //构造tts合成文本
  59. let ttsMsg = RED.util.cloneMessage(msg);
  60. ttsMsg.payload = {
  61. text: floorFail || content || floorErr,
  62. stream: true,
  63. is_last: true
  64. };
  65. //若匹配不到楼层,只下发语音提示
  66. node.send([null, ttsMsg]);
  67. }
  68. return;
  69. /**
  70. * 日志打印
  71. */
  72. function printInfo(tips, data) {
  73. let date = new Date();
  74. 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}`;
  75. if (data) {
  76. if (typeof data === 'object') {
  77. console.log(message, JSON.stringify(data))
  78. } else {
  79. console.log(message, data)
  80. }
  81. } else {
  82. console.log(message)
  83. }
  84. }
  85. /**
  86. * 日志打印
  87. */
  88. function printErr(tips, err) {
  89. let date = new Date();
  90. 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}`;
  91. console.error(message, err);
  92. }

代码并不复杂,仅就关键点进行解释。正常情况下,节点将产生两个数据,其中nluMsg是一个JSON字符串,发送给开发板进行数据处理,其格式是由intentTemplate变量定义的,修改时要注意不要出错。而ttsMsg是发给TTS合成语音节点的,生成语音数据发送给开发板直接进行播放。

应用部署

完成配置后,点击右上角部署后返回应用界面,打开刚才创建的应用,点击部署生产。

有关开发板程序的修改,将在下篇博文中介绍。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/905177
推荐阅读
相关标签
  

闽ICP备14008679号