天猫精灵语音开发-终篇

简介: 图文详解如何开发天猫精灵语音应用,以及阿里云云开发平台的基本使用,最后将介绍如何把使用阿里云云开发平台做后台开发天猫精灵应用

## 前言

流程

  • 前台配置流程

    - 创建地理小百科技能
  • 后台开发流程

    - 根据实际情况修改基础代码
    - 提交代码并部署上线
  • 前台检查自动生成流程

    • 检查自动生成的意图
    • 检查对话语料和标注
  • 语音测试
  • 项目下线

前台配置流程

创建地理小百科技能

image.png

后台开发流程

本次不再创建语音交互模型,直接跳到后端服务创建应用并登录阿里云云开发平台(网址:workbench.aliyun.com)基于默认模板的代码进行功能开发

image.png

image.png

基于实际情况修改基础代码

修改后的源码
package com.alibaba.ailabs;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

import com.alibaba.ailabs.common.AbstractEntry;
import com.alibaba.da.coin.ide.spi.meta.ExecuteCode;
import com.alibaba.da.coin.ide.spi.meta.ResultType;
import com.alibaba.da.coin.ide.spi.standard.ResultModel;
import com.alibaba.da.coin.ide.spi.standard.TaskQuery;
import com.alibaba.da.coin.ide.spi.standard.TaskResult;
import com.alibaba.fastjson.JSON;

import com.aliyun.fc.runtime.Context;

/**
 * @Description 天猫精灵技能函数入口,FC handler:com.alibaba.ailabs.GenieEntry::handleRequest
 * @Version 1.0
 **/
public class GenieEntry extends AbstractEntry {

    private static final Map<String, LinkedList<Integer>> USER_MAP = new ConcurrentHashMap<>();

    private static final List<String> KNOWLEDGE;

    private static Random random = new Random();

    static {
        KNOWLEDGE = Arrays.asList(
            "世界热极:巴士拉(伊拉克)最高记录58.8摄氏度",
            "世界冷极:东方站(南极)最低记录-89.2摄氏度",
            "世界湿极:怀厄莱阿莱(太平洋上的一个岛屿)每年平均有335天下雨,年降水量达12244毫米",
            "世界干极:阿塔卡马沙漠(南美洲)平均年降水量小于0.1毫米,1845年~1936年的91年间未曾下雨",
            "海拔最高的山峰:珠穆朗玛峰(海拔8844.43米)",
            "地球上体积最大的山及火山:冒纳罗亚火山(MaunaLoa,夏威夷岛,海拔4169米,火山体积达7万5000立方公里)",
            "地球上最高的活火山:奥霍斯德尔萨拉多山(海拔6893米)",
            "太阳系内已知的最高、体积最大的山及火山:奥林帕斯火山(火星,高达约27公里)",
            "最大的岛屿:格陵兰岛(面积达2166086平方公里)",
            "人口最多的岛屿:爪哇岛(人口达12400万)",
            "唯一分属三个国家的岛屿:加里曼丹岛",
            "最大的湖泊及咸水湖:里海(面积达371000平方公里)",
            "最大的淡水湖:坦噶尼喀湖(非洲)",
            "最深的湖泊及淡水湖:贝加尔湖(水深达1940米)",
            "海拔最低的湖泊:死海(湖面海拔负392米,是已露出陆地的最低点)",
            "最咸的湖泊:死海(湖水盐度达300‰,为一般海水的8.6倍)",
            "最古老的湖泊:贝加尔湖(已经在地球上存在超过2500万年)",
            "最长的河流:尼罗河(全长6671公里)",
            "流域面积最大的河流:亚马逊河(面积达7050000平方公里)",
            "含沙最多的河流:黄河(1977年录得最高含沙量达每立方米920千克沙)",
            "流经最多国家的河流:多瑙河(流经西欧至东欧共18个国家)",
            "最早的运河:古苏伊士运河(建于公元前19世纪,完成于前500年,8世纪被毁弃,19世纪重建。)",
            "海拔最高的长河:雅鲁藏布江(河床海拔平均在3000米以上)",
            "太阳系已知的最大峡谷:水手号峡谷(火星,长达4500公里,阔200公里,深11公里)",
            "最大的沙漠:撒哈拉沙漠(面积约有960多万平方千米)",
            "面积最大的盆地:刚果盆地",
            "世界上已知体积最大的独立岩石:艾尔斯巨石(高348米,底沿周长约9400米,占地面积约1200公顷)",
            "质量最大的行星:木星(约为其余八大行星质量总和的2倍)",
            "太阳系中最大的卫星:木卫三",
            "最深的海沟:马里亚纳海沟(深11034米)",
            "最长的洋流:南极环流(长达21000公里)"
        );
    }

    @Override
    public ResultModel<TaskResult> execute(TaskQuery taskQuery, Context context) {
        context.getLogger().info("taskQuery: " + JSON.toJSONString(taskQuery));

        String userId = taskQuery.getRequestData().get("userOpenId");
        userId = userId == null ? "testUser" : userId;

        LinkedList<Integer> list = USER_MAP.get(userId);

        //欢迎意图 或 用户缓存数据为空
        if ("welcome".equals(taskQuery.getIntentName()) || list == null) {
            list = new LinkedList<>();
            int randomIndex = random.nextInt(KNOWLEDGE.size());
            list.addLast(randomIndex);
            USER_MAP.put(userId, list);
            return intentChangeReply(KNOWLEDGE.get(randomIndex));
        }

        //下一个意图,随机选择一个内容回复,并将index追加到用户数据的LinkedList集合最后
        if ("next".equals(taskQuery.getIntentName())) {
            int randomIndex = random.nextInt(KNOWLEDGE.size());
            list.addLast(randomIndex);
            return intentChangeReply(KNOWLEDGE.get(randomIndex));
        }

        //上一个意图,将用户数据的LinkedList集合中最后一个index移除,并返回该index的内容。首先要判断集合内是否有元素,没有则不需要移除
        if ("prev".equals(taskQuery.getIntentName())) {
            if (list.size() > 0) {
                list.removeLast();
            }
            
            if (list.size() == 0) {
                return intentChangeReply("这已经是第一个了。");
            }

            return intentChangeReply(KNOWLEDGE.get(list.get(list.size() - 1)));
        }

        //退出意图,清除用户缓存
        if ("exit".equals(taskQuery.getIntentName())) {
            USER_MAP.remove(userId);
            return reply("已为您退出,再见。");
        }

        return reply("请检查意图名称是否正确,或者新增的意图没有在代码里添加对应的处理分支。");
    }

    /**
     * 结束对话的回复,回复后音箱闭麦
     */
    private ResultModel<TaskResult> reply(String reply) {
        return getResult(reply, ResultType.RESULT);
    }

    /**
     * 未指定追问参数,音箱自动开麦,用户的回答可跳转到其它意图
     */
    private ResultModel<TaskResult> intentChangeReply(String reply) {
        return getResult(reply, ResultType.ASK_INF);
    }

    private ResultModel<TaskResult> getResult(String reply, ResultType askInf) {
        ResultModel<TaskResult> res = new ResultModel<>();
        TaskResult taskResult = new TaskResult();
        taskResult.setReply(reply);
        taskResult.setExecuteCode(ExecuteCode.SUCCESS);
        taskResult.setResultType(askInf);
        res.setReturnCode("0");
        res.setReturnValue(taskResult);
        return res;
    }
}

提交代码并部署上线

  • 使用Git提交代码
  • 选择预发环境部署上线,详情请看第一天教程

前台检查自动生成流程

检查自动生成的意图

image.png

检查自动生成的对话语料

image.png

提交代码并部署上线

语音测试

进入在线测试进行测试

image.png

ps: 目前因为没有实体机所以就不实机测试了。

项目下线

在线测试完成后,要在云开发平台中我的应用及时将部署的应用下线,因为免费额度有限,不及时下线将会产生不必要的费用

image.png

image.png

相关文章
|
Linux 开发工具 Windows
中国时间服务器,国内阿里云时间服务器
中国时间服务器,国内阿里云时间服务器很多用户使用的是国外VPS使用过程中常常遇到时间与国内不同步的情况好在阿里提供了7台NTP服务器,地址如下:阿里云提供了7个NTP时间服务器也就是Internet时间同步服务器地址 ntp1.
40780 0
|
3月前
|
数据安全/隐私保护 容器 Go
开源IM即时通讯系统调研
Lumen IM 是一款企业级开源即时通讯工具,前端采用 Vue3 + Naive UI,后端基于 Go 语言,使用 WebSocket 协议。支持 Docker + Nginx 快速部署,适合私有化环境。功能包括文本、图片、文件消息,内置笔记、群聊及消息历史记录。界面美观、功能完善,适用于企业沟通、团队协作及开发者学习。提供前后端源码,便于快速搭建 IM 系统。
开源IM即时通讯系统调研
|
SQL 关系型数据库 MySQL
使用OceanBase进行大规模数据迁移的最佳实践
【8月更文第31天】随着业务的不断扩展,数据迁移成为了企业日常运营中不可避免的任务之一。对于那些正在从传统的数据库系统向分布式数据库系统过渡的企业来说,数据迁移尤为重要。OceanBase 是一个由阿里巴巴集团开发的高性能分布式关系数据库,它以其高可用性、水平扩展能力和成本效益而闻名。本文将探讨如何使用 OceanBase 进行大规模数据迁移,并提供相关的最佳实践和代码示例。
1060 1
|
6月前
|
测试技术 API 异构计算
飞桨x昇腾生态适配方案:05_算子适配流程
本内容主要介绍Paddle针对非CPU和Nvidia GPU硬件(如NPU)的适配流程与方法。适配代码存于PaddleCustomDevice仓库,路径为`PaddleCustomDevice/backends/npu`,包含kernels(算子适配)和tests(单元测试)两个核心目录。适配流程分为算子注册、适配函数入参与主体实现三步,重点对齐Paddle与CANN算子参数。
221 0
|
10月前
|
算法 决策智能
基于遗传优化的货柜货物摆放优化问题求解matlab仿真
本项目采用MATLAB2022A实现基于遗传算法的货柜货物摆放优化,初始随机放置货物后通过适应度选择、交叉、变异及逆转操作迭代求解,最终输出优化后的货物分布图与目标函数变化曲线,展示进化过程中的最优解和平均解的变化趋势。该方法模仿生物进化,适用于复杂空间利用问题,有效提高货柜装载效率。
214 24
|
传感器 人工智能 搜索推荐
虚拟现实技术:元宇宙的基础构建
【9月更文挑战第29天】随着科技的飞速发展,元宇宙正从科幻概念走向现实。作为其基石的虚拟现实(VR)技术,通过模拟三维环境、提供全方位感知及自然交互体验,成为构建元宇宙的关键。本文探讨VR在元宇宙中的基础构建作用,包括沉浸式体验、社交互动及广泛应用,并展望其与人工智能、区块链等技术融合的未来趋势,以及硬件轻量化和内容生态的丰富化。
|
监控 安全 网络安全
.Lockbit3.0勒索病毒来袭:你的数据安全面临挑战
在数字化时代,网络安全威胁日益严峻,勒索病毒作为一类极具破坏性的恶意软件,正成为全球网络安全的重大挑战。Lockbit3.0勒索病毒凭借其高度模块化、隐蔽性强、传播速度快等特点,对个人用户、企业和国家的信息安全构成严重威胁。其高度模块化架构使其更具灵活性和难以检测性,增加了传统安全检测手段的难度。为应对这一挑战,我们需要加强安全意识、安装可靠的安全软件、定期备份数据并加强网络监控。如需数据恢复技术支持,请添加技术服务号(sjhf91)或关注“91数据恢复”。
253 0
|
小程序 前端开发 数据安全/隐私保护
微信小程序全栈开发中的身份认证与授权机制是一个重要而复杂的问题。
微信小程序作为业务拓展的新渠道,其全栈开发中的身份认证与授权机制至关重要。本文概览了身份认证方法,包括手机号码验证、微信及第三方登录;并介绍了授权机制,如角色权限控制、ACL和OAuth 2.0。通过微信登录获取用户信息,利用第三方登录集成其他平台,以及实施角色权限控制和ACL,开发者能有效保障小程序的安全性和提供良好用户体验。此外,还强调了在实现过程中需注重安全性、用户体验和合规性。
676 0
|
API 计算机视觉 开发者
【Python】已解决:(pip安装PIL库报错) ERROR: Could not find a version that satisfies the requirement PIL (from v
【Python】已解决:(pip安装PIL库报错) ERROR: Could not find a version that satisfies the requirement PIL (from v
2479 0
|
存储 弹性计算 安全
阿里云服务器2核4G、4核8G、8核16G配置最新收费标准及活动价格参考(2024更新)
阿里云个人和一般企业用户在购买阿里云服务器时通常比较喜欢购买2核4G、8核16G、4核8G等配置,这些配置既能满足各种图文类中小型网站和应用又能满足企业网站应用、批量计算、中小型数据库系统等场景,2核4G配置适合新手入门或初创企业,4核8G与8核16G兼具成本与性能优势,适合通用场景,本文介绍这些配置的最新购买价格,包含原价收费标准和最新活动价格。
1645 1
阿里云服务器2核4G、4核8G、8核16G配置最新收费标准及活动价格参考(2024更新)