从0到1制作一个DuerOS技能-猫语翻译

从0到1制作一个DuerOS技能-猫语翻译

dueros php   2018-11-23

DuerOS为百度的对话式人工智能操作系统

本练习主要为了体验在该平台上的技能开发流程

先在平台上注册申请为开发者 (需要一天审核时间)

平台地址: https://dueros.baidu.com/dbp

在技能平台里面新建一个新技能

配置一些基础信息

添加一个缺省意图: 这样所有的用户请求都会发送到skill

平台上基本配置好了, 我们接下来测试一下

使用模拟测试选项看看服务是否是通的

从服务端https://lab.derror.com/cat-speech/ 接收到的内容来看请求已经过来了

{"version":"v2.0","session":{"new":true,"sessionId":"4bdf0a19-e3a2-4ec0-b5ac-1dd17af565ba"},"context":{"System":{"user":{"userId":"33880555","userInfo":{"account":{}}},"application":{"applicationId":"5e3013c6-db00-af33-0ec1-856533ebfba9"},"device":{"deviceId":"90b55c34e169ad7d2c7af7e915e24109","supportedInterfaces":{"VoiceInput":{},"VoiceOutput":{},"AudioPlayer":{},"Display":{}},"TVControl":{"controlType":"DCSControl","controlStatus":0}},"apiAccessToken":"XlkUIqtH6L8wg8DDieZQfNq64Bgb3XFPGuHjdruJt7rC8WldbFVNiwA8cTN8sOa8AZwLkL8swGbzolXBnAQ3nONw8+OBE067ZXIIg/USbjwsYRAi8sr7DjjavISu2maBxPIG32Q4JRYZUTbhBrKuYtNmIj8OA1XZyXJ16Stow4cYPIIaqvgwrhEcOdTfc3M2ZX7mpbMS0+gxAPJOkppslVtFSZyTOiOXGqZNfO9o6cFy+V+IML8GxjHkK1Mf0BrX7IySXzdj9ep2H8kaYN9DlGmqWGRVJiNMC4SxjC+HReDmDcmc+gwJIG6iX3RjTJHbFP2LKCr0037ejJivlmsN44WF+6dlDIAn0yUChVqV2znxj/Q8ByNxsmRPqS1VU29/ABjvibfLEU4TsgjCtTlkVA==","apiEndPoint":"https://xiaodu.baidu.com","avaliableApplicationIds":["doudi_server","phone","aries_general","ai.dueros.bot.alarm","duer_weather","sac","restaurant_bot","o2o_satisfy","rent_car","travel_server","recharge","online_shopping","hotel","baojie","nba_search","sysprofile_service","audio_music","ai.dueros.bot.timer","audio_unicast","audio_live","ai.dueros.bot.vocal_joke","ai.dueros.bot.smarthome","speaker_hardware","audio_news"]}},"request":{"type":"LaunchRequest","requestId":"598e764faa5c40caa11c7648c8154c04_0#1_0","timestamp":"1542956711","dialogRequestId":"7b4fd4bb-ccb4-44d1-a6b3-63226bffbca7"}}

下面我们就可以在服务端解析请求协议, 并返回对应的话术来实现整个skill的功能了

我们使用php来开发, 官方提供了php的sdk

先安装nginx+php-fpm相关服务 php版本>5.6. 相关过程省略

官方文档地址:https://dueros.baidu.com/didp/doc/dueros-bot-platform/dbp-sdk/Installation_php_markdown

服务端(CentOS7)安装记录如下:

$ yum install composer
$ mkdir cat-speech
$ composer require dueros/bot-sdk
Using version ^2.1 for dueros/bot-sdk
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 2 installs, 0 updates, 0 removals
  - Installing monitor/bot-monitor (v1.4.0): Downloading (100%)         
  - Installing dueros/bot-sdk (v2.1.17): Downloading (100%)         
Writing lock file
Generating autoload files

index.php

<?php
require "CatSpeech.php";

$cat = new CatSpeech();

if($_SERVER['REQUEST_METHOD'] == 'HEAD'){
    header('HTTP/1.1 204 No Content');
}
header("Content-Type: application/json");
$cat->log->markStart('all_t');
$ret = $cat->run();
$cat->log->markEnd('all_t');
$cat->log->notice();

print $ret;

CatSpeech.php

<?php

require 'vendor/autoload.php';

use \Baidu\Duer\Botsdk\Card\TextCard;
use \Baidu\Duer\Botsdk\Card\StandardCard;

class CatSpeech extends Baidu\Duer\Botsdk\Bot{

    private static $pUrl = "https://lab.derror.com/cat-speech/banner.jpg";

    private static $audio = [
        "http://xxx.bj.bcebos.com/cat-speech/cat001.wav",
        "http://xxx.bj.bcebos.com/cat-speech/cat002.wav",
    ];

    private static $audioLen = 2;

    public function __construct($postData = []) {
        parent::__construct($postData);

        $this->log = new \Baidu\Duer\Botsdk\Log([
            //日志存储路径
            'path' => 'log/',
            'level' => \Baidu\Duer\Botsdk\Log::NOTICE,
        ]);

        //记录请求的query
        $this->log->setField('query', $this->request->getQuery());

        $this->addLaunchHandler(function () {
            $card = new StandardCard();
            $card->setTitle('猫语翻译')
                ->setContent('随便说点什么吧')
                ->setImage(self::$pUrl);
            $this->waitAnswer();
            return [
                'card' => $card,
                'reprompt' => '快说点什么吧',
                'outputSpeech' => '欢迎使用猫语翻译喵喵喵',
            ];
        });

        //添加对SessionEndedRequest 的处理函数
        $this->addSessionEndedHandler(function () {
            return [
                'card' => new TextCard('下次记得还来猫语翻译喵喵喵'),
                'outputSpeech' => '喵喵bye',
            ];
        });

        //添加对特定意图的处理函数
        $this->addIntentHandler('ai.dueros.common.default_intent', function () {
            $query = $this->request->getQuery();
            $this->log->setField('query', $query);
            $this->waitAnswer();
            $this->setExpectSpeech(true);
            return [
                'card' => new TextCard($query),
                'reprompt' => '喵喵没听清,随便说点什么吧',
                'outputSpeech' => $this->getSpeechByQuery($query),
            ];
        });

    }

    private function getSpeechByQuery($query) {
        $len = strlen($query);
        $len = $len > 64 ? 8 : floor($len/6) + 1;
        $md5 = md5($query);

        $r = '';
        for ($i=0; $i < $len; $i++) { 
            $hex = substr($md5, $i*4, 4);
            $index = hexdec($hex) % self::$audioLen;
            $r .= '<audio src="' . self::$audio[$index] . '"></audio>';
        }
        return '<speak>'.$r.'</speak>';
    }

}

编写好以上代码就能跑通基本服务了.

需要注意的是所有技能资源文件必须保存到百度云的BOS服务里面

猫语翻译有很多音频文件, 都已先上传到了BOS. 可以从BOS直接拿到url访问地址

为了展示skill的数据. 需要在 配置服务 里面启用 执行回调

Public Key的生成参考如下:

$ openssl
OpenSSL> genrsa -out rsa_private_key.pem 1024
Generating RSA private key, 1024 bit long modulus
..............................++++++
...........................................................................++++++
e is 65537 (0x10001)
OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
writing RSA key

rsa_public_key.pem 为公钥, 就是填写在平台配置里面

rsa_private_key.pem为私钥, 需要填写在代码里面

平台上配置 执行回调Public Key 即可

统计的sdk在sdk中已经集成好了, 具体代码实现可以看看/vendor/monitor/bot-monitor/src/BotMonitor.php

并且统计必须要有Private Key的传入

代码调整参考如下

经过上面的调整 平台上好像还是看不到统计数据. 有可能模拟数据不计算在内.

我们发布一个版本试试

发布的技能服务端部署必须支持https和head访问. 不然会提交不了申请.

发布的配置可以自己按照提示填写

然后就等待审核中...

1周后审核通过... 有点漫长... (;¬_¬)

上线后服务端的改动不需要重新提交上线. 但是如果涉及到服务器地址的改动,就需要重新提交上线了.

平台上技能数据里面就可以看到用户使用情况了. (〜^㉨^)〜