科大讯飞AIUI智能语音体验

最近调研了一下科大讯飞智能语音服务AIUI,并基于官方Demo二次开发了一个比较简单的demo(Android->AIUI->服务器后处理),体验了一下功能。

官方的Android Demo中提供了“语音听写”、“语法识别”、“语义理解”、“语音合成”、“声纹密码”等功能,我个人主要使用了“语义理解”和“语音合成”

之前的文章介绍过Amazon的Alexa,AIUI应该想做类似的事情,但是目前AIUI的功能有限,开发文档也一般(大篇幅介绍网页控制台的操作,很多关键的地方描述的不清楚,比如“自定义技能”、“自定义实体”这些开发者非常关心的功能,开发文档只简单的介绍了一下怎么添加;“自定义实体”是个什么鬼都没说就over了);另外,官方DEMO功能都简单,尤其是第三方应用开发者需要用到的“后处理”功能,资料少之又少,官方只给出来一个简单的不能再简单的例子(只是实现了AIUI将语义分析结果转发给第三方的后处理,后处理收到了就没有了...看到那儿的时候真的很无语啊...后处理收到数据之后,要怎么处理,要用什么格式返回数据,返回的数据怎么用,一点儿没提,o(╯□╰)o服了)

目前AIUI适合的场景

语音引导:比如开放技能中“天气”这种通用的功能,查询时不需要跟用户信息关联、有可预知的关键字“天气”等(所谓的“自定义实体”)

屏幕快照 2017-09-20 下午5.25.21.png

AIUI不能满足的

无法提前设置语料库的情况,例如与账户关联的、语音信息录入(某个问诊APP,录入用户姓名等)

调研之前想实现的功能

  1. 语音引导:类似于ATM这种自助终端,用户通过语音来与终端交互;比如终端问“您好,有什么需要”,用户答“拍照”,然后终端进入拍照功能;

这种需求目前AIUI是可以满足的,怎么实现,文章后面会介绍

  1. 语音信息录入:通过用户的语音来完成信息录入,比如通过语音录入用户的姓名、年龄、患病情况等;

目前AIUI不适用这种场景,发音一样字不一样的情况太多了,比如wangxiaoer对应的名字可能是“王小二”、“王晓二”,这种情况下,用语音方式进行信息录入,可就得不偿失了。

自定义技能

image.png

开放技能中没有想要的功能时需要自己实现自定义技能,通过语义理解提取到关键字,在“后处理”服务器去执行一些操作。

比如在自定义技能中,设置语料“我尚”,当用户说“我尚”之后,AIUI会触发这个自定义技能,其中的query就是“我尚”,后处理服务收到这个语义后,可以做一些操作,返回数据;

{
    "category": "ISHANG.mHealth_demo:11.0",
    "intentType": "custom",
    "query": "我尚",
    "query_ws": "我/NP//  尚/ADD//",
    "rc": 0,
    "nlis": "true",
    "service": "ISHANG.mHealth_demo",
    "uuid": "atn000167dc@ch60f10d1d86686f2601",
    "vendor": "ISHANG",
    "version": "11.0",
    "semantic": [
        {
            "intent": "init",
            "score": 1,
            "slots": []
        }
    ],
    "sid": "atn000167dc@ch60f10d1d86686f2601",
    "text": "我尚"
}

这里注意rc字段,0表示语义理解成功,如果语义理解不成功是这样的(rc为4):

{
    "rc": 4,
    "uuid": "atn00016bf3@ch60f10d1d86f86f2601",
    "sid": "atn00016bf3@ch60f10d1d86f86f2601",
    "text": "大王"
}

自定义实体

自定义技能如果用"我是{name}",这个{name}就是一个自定义实体(可以理解为语料库),开放的自定义实体里有省、城市、歌曲名等等,如果没有,就自定义一个“张三”,在语义理解时,会出现在语义槽中

image.png
{
    "category": "ISHANG.mHealth_demo:11.0",
    "intentType": "custom",
    "query": "我是张三",
    "query_ws": "我/NP//  是/V_SHI//  张三/NPP//",
    "rc": 0,
    "nlis": "true",
    "service": "ISHANG.mHealth_demo",
    "uuid": "atn00016f72@ch0de90d1d87956f2a01",
    "vendor": "ISHANG",
    "version": "11.0",
    "semantic": [
        {
            "intent": "input_name",
            "score": 1,
            "slots": [
                {
                    "begin": 2,
                    "end": 4,
                    "name": "name",
                    "normValue": "张三",
                    "value": "张三"
                }
            ]
        }
    ],
    "sid": "atn00016f72@ch0de90d1d87956f2a01",
    "text": "我是张三"
}

这里注意,“张三”已经在自定义实体中添加过了,在json中出现在semantic[0].slots[0]这个字段,这就是语义理解的精髓所在了,就是需要你提前在语料库中添加好语料,在语义理解结果中,这个语料就可以单独提出来,在后处理作为业务逻辑参数使用

但是,语料库必须提前录入好,否则语义理解就失败了;但是有些时候——比如录入姓名——除非将全中国人的姓名做成语料库,否则语义理解就失败了,该怎么办?

image.png

如果是一个没有添加的实体,返回如下,rc为4也就是无法理解语义

image.png
{
    "rc": 4,
    "uuid": "atn000176af@ch0de90d1d88736f2a01",
    "sid": "atn000176af@ch0de90d1d88736f2a01",
    "text": "我是例子"
}

后处理

如果设置了后处理,AIUI服务器会将语义理解的结果转发给后处理服务器,在后处理服务器通过post方法接收AIUI转发请求的函数(或者方法)里,我们可以提取语义理解的结果,做一些查询等操作,然后返回;

post请求的数据

关键数据保存在Msg.Content字段,这里要注意的是SessionParams和Msg.Content是Base64编码之后的,使用时需要先解码,解码之后完整的请求数据如下:

{"MsgId":"cid6f1c2494@ch00270d1c09d20100101","CreateTime":1505803732,"AppId":"59bf6334","UserId":"d3146084944","SessionParams":{"dsrc":"sdk","dts":"1","dtype":"audio","msc.lat":"39.895252","msc.lng":"116.343834","scene":"main","scity":"ch","sid":"cid6f1c2494@ch00270d1c09d2010010","stmid":"audio-16","ver_type":"mobile_phone","wake_id":"15058037304161d1c41c87ab7cd3c"},"UserParams":"","FromSub":"kc","Msg":{"ContentType":"json","Type":"text","Content":{"intent":{"data":{"result":[{"airData":40,"airQuality":"优","city":"北京","date":"2017-09-19","dateLong":1505750400,"exp":{"ct":{"expName":"穿衣指数","level":"热","prompt":"天气热,建议着短裙、短裤、短薄外套、T恤等夏季服装。"}},"humidity":"20%","lastUpdateTime":"2017-09-19 11:39:20","pm25":"13","temp":29,"tempRange":"14℃~30℃","weather":"晴","weatherType":0,"wind":"西北风3-4级","windLevel":1},{"city":"北京","date":"2017-09-20","dateLong":1505836800,"lastUpdateTime":"2017-09-19 11:39:20","tempRange":"14℃~27℃","weather":"晴","weatherType":0,"wind":"南风微风","windLevel":0},{"city":"北京","date":"2017-09-21","dateLong":1505923200,"lastUpdateTime":"2017-09-19 11:39:20","tempRange":"17℃~28℃","weather":"多云","weatherType":1,"wind":"南风微风","windLevel":0},{"city":"北京","date":"2017-09-22","dateLong":1506009600,"lastUpdateTime":"2017-09-19 11:39:20","tempRange":"15℃~28℃","weather":"晴","weatherType":0,"wind":"西北风微风","windLevel":0},{"city":"北京","date":"2017-09-23","dateLong":1506096000,"lastUpdateTime":"2017-09-19 11:39:20","tempRange":"18℃~29℃","weather":"晴转多云","weatherType":0,"wind":"南风微风","windLevel":0},{"city":"北京","date":"2017-09-24","dateLong":1506182400,"lastUpdateTime":"2017-09-19 11:39:20","tempRange":"19℃~28℃","weather":"阴","weatherType":2,"wind":"东风微风","windLevel":0},{"city":"北京","date":"2017-09-25","dateLong":1506268800,"lastUpdateTime":"2017-09-19 11:39:20","tempRange":"19℃~28℃","weather":"多云转阴","weatherType":1,"wind":"东南风微风","windLevel":0}]},"rc":0,"semantic":[{"intent":"QUERY","slots":[{"name":"location.city","value":"CURRENT_CITY","normValue":"CURRENT_CITY"},{"name":"location.poi","value":"CURRENT_POI","normValue":"CURRENT_POI"},{"name":"location.type","value":"LOC_POI","normValue":"LOC_POI"},{"name":"queryType","value":"内容"},{"name":"subfocus","value":"天气状态"}]}],"service":"weather","text":"天气","uuid":"atn00913a37@ch46b50d1c09d46f2a01","used_state":{"state_key":"fg::weather::default::default","state":"default"},"answer":{"text":"\"北京\"今天\"晴\",\"14℃~30℃\",\"西北风3-4级\""},"dialog_stat":"DataValid","sid":"cid6f1c2494@ch00270d1c09d2010010"}}}}

返回格式

参照开放技能“天气”等json数据返回,把结果放在data或者intent的answer里,其它字段还是用post请求发过来的数据。“天气”语义理解之后的数据如下:

{
  "data": {
    "result": [
      {
        "airData": 44,
        "airQuality": "优",
        "city": "北京",
        "date": "2017-09-20",
        "dateLong": 1505836800,
        "exp": {
          "ct": {
            "expName": "穿衣指数",
            "level": "热",
            "prompt": "天气热,建议着短裙、短裤、短薄外套、T恤等夏季服装。"
          }
        },
        "humidity": "25%",
        "lastUpdateTime": "2017-09-20 11:07:03",
        "pm25": "10",
        "temp": 24,
        "tempRange": "14℃~27℃",
        "weather": "晴",
        "weatherType": 0,
        "wind": "北风微风",
        "windLevel": 0
      },
      {
        "city": "北京",
        "date": "2017-09-21",
        "dateLong": 1505923200,
        "lastUpdateTime": "2017-09-20 11:07:03",
        "tempRange": "17℃~29℃",
        "weather": "多云",
        "weatherType": 1,
        "wind": "南风微风",
        "windLevel": 0
      },
      {
        "city": "北京",
        "date": "2017-09-22",
        "dateLong": 1506009600,
        "lastUpdateTime": "2017-09-20 11:07:03",
        "tempRange": "13℃~27℃",
        "weather": "晴",
        "weatherType": 0,
        "wind": "西北风微风",
        "windLevel": 0
      },
      {
        "city": "北京",
        "date": "2017-09-23",
        "dateLong": 1506096000,
        "lastUpdateTime": "2017-09-20 11:07:03",
        "tempRange": "18℃~29℃",
        "weather": "晴转多云",
        "weatherType": 0,
        "wind": "南风微风",
        "windLevel": 0
      },
      {
        "city": "北京",
        "date": "2017-09-24",
        "dateLong": 1506182400,
        "lastUpdateTime": "2017-09-20 11:07:03",
        "tempRange": "19℃~28℃",
        "weather": "阴",
        "weatherType": 2,
        "wind": "东风微风",
        "windLevel": 0
      },
      {
        "city": "北京",
        "date": "2017-09-25",
        "dateLong": 1506268800,
        "lastUpdateTime": "2017-09-20 11:07:03",
        "tempRange": "19℃~28℃",
        "weather": "多云转阴",
        "weatherType": 1,
        "wind": "东南风微风",
        "windLevel": 0
      },
      {
        "city": "北京",
        "date": "2017-09-26",
        "dateLong": 1506355200,
        "lastUpdateTime": "2017-09-20 11:07:03",
        "tempRange": "13℃~25℃",
        "weather": "晴",
        "weatherType": 0,
        "wind": "西北风3-4级",
        "windLevel": 1
      }
    ]
  },
  "rc": 0,
  "semantic": [
    {
      "intent": "QUERY",
      "slots": [
        {
          "name": "location.city",
          "value": "CURRENT_CITY",
          "normValue": "CURRENT_CITY"
        },
        {
          "name": "location.poi",
          "value": "CURRENT_POI",
          "normValue": "CURRENT_POI"
        },
        {
          "name": "location.type",
          "value": "LOC_POI",
          "normValue": "LOC_POI"
        },
        {
          "name": "queryType",
          "value": "内容"
        },
        {
          "name": "subfocus",
          "value": "天气状态"
        }
      ]
    }
  ],
  "service": "weather",
  "text": "天气",
  "uuid": "atn00018593@ch60f10d1d8a556f2601",
  "used_state": {
    "state_key": "fg::weather::default::default",
    "state": "default"
  },
  "answer": {
    "text": "\"北京\"今天\"晴\",\"14℃~27℃\",\"北风微风\""
  },
  "dialog_stat": "DataValid",
  "sid": "atn00018593@ch60f10d1d8a556f2601"
}

DEMO

Demo地址,Demo包括后处理服务端和Android App

后处理服务端

nodejs实现

  • get请求处理方法中,主要是实现了aiui后处理服务器验证
  • post请求处理方法中,实现了一个非常简单的状态机,使用aiui发来的语义结果结合一个code变量,来控制返回什么样的数据;返回数据格式参照开放技能“天气”

Android App

基于官方demo完成(在aiui上注册android应用之后,该应用的设置界面可下载工程代码,遗憾的是这货居然是个eclipse工程o(╯□╰)o)

  • 在语义理解demo中基于语音合成功能,加入了语音播报结果功能
  • 说“我尚”,返回“欢迎您使用...请说出自己的名字”,然后说“张三”,返回“您的名字是张三,请说出您的年龄”;然后说“28”,返回“您的年龄是28,谢谢使用,再见”。

此demo在AIUI上的配置

应用配置
自定义技能 init
自定义技能 input_name
自定义实体
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,615评论 4 59
  • 今早早早起床给俩宝做早饭,用胡萝卜、芋头、地瓜、芝麻做的小饼,本以为用心做的早饭,能让大宝高兴,可恰恰相反,...
    轩萌妈阅读 170评论 0 0
  • 我从崖边跌落 落入星空辽阔 银河不清不浊 不知何以摆脱 我从崖边跌落 ...
    酥浅珞暖阅读 282评论 0 1
  • 雨下过,洗去了灰尘 雪飘过,盖住了世界 风刮过,吹倒了老树 雷响过,掩住了抽泣 冬雷震震,掩不住此间悲伤 秋风呼啸...
    小黄日记阅读 318评论 0 2