天天看點

天貓精靈語音開發-終篇

## 前言

流程

  • 前台配置流程
    - 建立地理小百科技能           
  • 背景開發流程
    - 根據實際情況修改基礎代碼
    - 送出代碼并部署上線           
  • 前台檢查自動生成流程
    • 檢查自動生成的意圖
    • 檢查對話語料和标注
  • 語音測試
  • 項目下線

建立地理小百科技能

天貓精靈語音開發-終篇

本次不再建立語音互動模型,直接跳到後端服務建立應用并登入阿裡雲雲開發平台(網址:workbench.aliyun.com)基于預設模闆的代碼進行功能開發

天貓精靈語音開發-終篇
天貓精靈語音開發-終篇

基于實際情況修改基礎代碼

修改後的源碼
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送出代碼
  • 選擇預發環境部署上線,詳情請看第一天教程

天貓精靈語音開發-終篇

檢查自動生成的對話語料

天貓精靈語音開發-終篇

進入線上測試進行測試
天貓精靈語音開發-終篇

ps: 目前因為沒有實體機是以就不實機測試了。

線上測試完成後,要在雲開發平台中我的應用及時将部署的應用下線,因為免費額度有限,不及時下線将會産生不必要的費用

天貓精靈語音開發-終篇
天貓精靈語音開發-終篇