preface

  • In the first day of the tutorial “Tmall Genie Voice Development – Day 1” we already tried to develop a Hello World
  • In the second day of the course “Tmall Genie Voice Development – The second day”, we have tried to develop a voice skill to query the weather.
  • In the third day of the course “Tmall Genie Voice Development – Day 3”, we tried to develop a multi-intention associated voice skill for air quality query

process

  • Foreground Configuration Process
    • The ability to create a geography mini-encyclopedia
  • Background development process
    • Modify the underlying code as required
    • Submit the code and deploy to live
  • The front desk checks the automatic generation process
    • Check for auto-generated intents
    • Check the conversational corpus and notes
  • Voice test
  • The project offline

Foreground Configuration Process

The ability to create a geography mini-encyclopedia

Background development process

Instead of creating the voice interaction model this time, I will directly jump to the back-end service to create the application and log in to the Aliyun Cloud development platform (website: workbench.aliyun.com) to develop functions based on the code of the default template

Modify the underlying code based on the actual situation

Revised source code

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;

/ * * *@DescriptionTmall elves skill function entry, FC handler: com. Alibaba. Ailabs. GenieEntry: : handleRequest *@Version1.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(
            "World heat Pole: Highest recorded 58.8C in Basra (Iraq)"."World cold Pole: Lowest recorded at Eastern Station (South Pole) -89.2 degrees Celsius"."Wet Pole of the world: Waiele Aleae (an island in the Pacific Ocean) receives an average of 335 days of rain per year, with an annual precipitation of 12,244 mm."."Dry pole of the World: The Atacama Desert (South America) has an average annual rainfall of less than 0.1 mm. It did not rain for 91 years from 1845 to 1936."."Highest mountain: Mount Qomolangma (8844.43 m)"."地球上体积最大的山及火山:冒纳罗亚火山(MaunaLoa,夏威夷岛,海拔4169米,火山体积达7万5000立方公里)"."Earth's highest active volcano: Ojos del Salado (6,893 meters)."."Tallest and largest known mountain and volcano in the solar system: Olympus Mons (about 27 kilometers high on Mars)."."Largest island: Greenland (2,166,086 sq km)"."Most populated island: Java (population: 124 million)"."The only island belonging to three countries: Kalimantan."."Largest lake and saltwater lake: Caspian Sea (371,000 square kilometers)"."Largest freshwater lake: Lake Tanganyika (Africa)"."Deepest lake and fresh water lake: Baikal (1,940m depth)"."Lowest lake: The Dead Sea (-392 m above sea level, the lowest point of exposed land)"."Saltiest lake: The Dead Sea (with a salinity of 300‰, 8.6 times that of normal water)"."Oldest lake: Lake Baikal (over 25 million years on Earth)."."Longest river: Nile (6,671 km)"."Largest river basin: Amazon (7,050,000 square kilometers)"."River with highest sediment content: Yellow River (highest recorded in 1977 with 920 kg/m3 of sediment)"."River that flows through most countries: Danube (flows through 18 countries from Western to Eastern Europe)"."Earliest canal: The Ancient Suez Canal (built in 19th century BC, completed 500 BC, abandoned in 8th century, rebuilt in 19th century) "."Highest river: Brahmaputra (average riverbed above 3000 m)"."Largest known Canyon in the Solar System: Mariner Canyon (Mars, 4500 km long, 200 km wide, 11 km deep)."."Largest desert: Sahara desert (more than 9.6 million square kilometers)"."Largest basin: Congo Basin."."The world's largest known freestanding rock by volume: Ayers Rock (348 m high, 9400 m in circumference at base, covering an area of 1200 hectares)."."Most massive planet: Jupiter (about twice the mass of the other eight planets combined)."."Largest moon in the solar System: Ganymede."."Deepest trench: Mariana Trench (11,034m deep)"."Longest current: Antarctic Gyre (21,000 km long)"
        );
    }

    @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);

        // The intent or user cache data is welcome to be null
        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));
        }

        // Next intention, select a content reply at random and append index to the end of the LinkedList collection of user data
        if ("next".equals(taskQuery.getIntentName())) {
            int randomIndex = random.nextInt(KNOWLEDGE.size());
            list.addLast(randomIndex);
            return intentChangeReply(KNOWLEDGE.get(randomIndex));
        }

        // Remove the last index from the LinkedList collection of user data and return the contents of that index. The first step is to determine whether there are any elements in the set. If there are no elements, they do not need to be removed
        if ("prev".equals(taskQuery.getIntentName())) {
            if (list.size() > 0) {
                list.removeLast();
            }
            
            if (list.size() == 0) {
                return intentChangeReply("This is already the first one.");
            }

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

        // Exit intent, clear user cache
        if ("exit".equals(taskQuery.getIntentName())) {
            USER_MAP.remove(userId);
            return reply("You are out. Goodbye.");
        }

        return reply("Check that the intent name is correct, or that the new intent does not add a corresponding processing branch to the code.");
    }

    /** * the speaker closes the mic */
    private ResultModel<TaskResult> reply(String reply) {
        return getResult(reply, ResultType.RESULT);
    }

    /** * No query parameter is specified, the speaker automatically opens the mic, the user's answer can jump to other intention */
    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);
        returnres; }}Copy the code

Submit the code and deploy to live

  • Commit code using Git
  • Choose a pre-delivery environment to deploy online, see the first day tutorial for details

The front desk checks the automatic generation process

Check for auto-generated intents

Check the automatically generated conversational corpus

Submit the code and deploy to live

Voice test

Enter the online test to test

Ps: At present, because there is no physical machine, so it is not real machine test.

The project offline

After the online test is completed, I need to offline the deployed application in the cloud development platform in time, because the free amount is limited, if not offline in time, unnecessary fees will be incurred