應(yīng)用領(lǐng)域
在智能手機牡辽、手表或 PC 等終端中,AIUI 可以與手機深度結(jié)合為全局的智能語音控制系統(tǒng)越除。在單個應(yīng)用(APP)中节腐,可以幫助用戶用語音完成復(fù)雜的交互,例如導(dǎo)航摘盆、買票铜跑、訂餐等。
接入方式
AIUI 目前支持提供多種集成模式骡澈,包含 SDK、硬件接入掷空、HTTP 協(xié)議的方式肋殴。以及微信公眾號、服務(wù)號托管服務(wù)坦弟。
項目需求
接入科大訊飛語音識別护锤,并創(chuàng)建環(huán)境,用戶在客戶端處理喚醒酿傍,實現(xiàn)用戶無手勢操作烙懦,憑語音實現(xiàn)操作APP進(jìn)行特定頁面跳轉(zhuǎn)。
語音喚醒
AIUI中默認(rèn)不帶語音喚醒功能赤炒,可通過接入MSC庫將喚醒與交互結(jié)合起來氯析。
- 登錄“科大訊飛開放平臺”
- 創(chuàng)建應(yīng)用
- 在我的應(yīng)用中為剛添加的應(yīng)用開通【語音喚醒】服務(wù)和【AIUI平臺】服務(wù)
AIUI平臺服務(wù)
SDK介紹
AIUI移動端SDK為開發(fā)者提供了簡單易用的交互接口亏较。AIUIAgent是和AIUI交互的橋梁,開發(fā)者可以發(fā)送不同的AIUIMessage來控制AIUI的運行掩缓,如發(fā)送CMD_WAKEUP使AIUI進(jìn)入喚醒就緒狀態(tài)雪情,發(fā)送CMD_RESET_WAKEUP使AIUI進(jìn)入休眠狀態(tài)。同時通過AIUIListener監(jiān)聽接收AIUI拋出的AIUIEvent進(jìn)行解析你辣,如通過EVENT_RESULT解析AIUI返回的聽寫和語義結(jié)果巡通,通過EVENT_SLEEP得知AIUI進(jìn)入休眠狀態(tài)。參考官方文檔
集成步驟(參考官方文檔)
參數(shù)配置
SDK中的cfg文件在AIUI初始化時會被讀取舍哄,根據(jù)配置初始化各個內(nèi)部模塊宴凉。參考官方文檔
可動態(tài)配置,配置文件中的情景模式(默認(rèn)情景為main)和后臺應(yīng)用定義的情景模式對應(yīng)表悬,在后臺可以為不同情景模式配置不同語義技能弥锄、問答庫,通過本地的配置文件或者動態(tài)設(shè)置場景可使用不同情景模式下對應(yīng)的業(yè)務(wù)签孔。(目前需求暫不需要使用動態(tài)配置)
消息事件(重點)
AIUI在交互過程中依靠AIUIMessage向SDK傳遞指令叉讥,依靠AIUIEvent從SDK內(nèi)部向外拋出事件回調(diào)。下面將羅列這些AIUIMessage與AIUIEvent的具體取值及含義饥追。參考官方文檔
AIUI交互狀態(tài)(重點)
AIUI在運行過程中图仓,在不同階段處于不同狀態(tài),不同的狀態(tài)能處理的操作也不同但绕。參考官方文檔
語音喚醒服務(wù)
喚醒詞配置
- 喚醒詞最多支持8個救崔,每個為4-6個漢字或不超過2個英文單詞。中英文不可同時配置捏顺。
- 語音喚醒是離線服務(wù)六孵,而且喚醒資源和SDK包捆綁,如果您修改了喚醒詞幅骄,請 前往SDK下載中心 重新下載SDK替換劫窒。
收費標(biāo)準(zhǔn)
- 語音喚醒體驗版提供3個裝機量,60天的免費試用拆座;
- 語音喚醒服務(wù)按照裝機量收費主巍,購買后即獲得相應(yīng)數(shù)量的授權(quán)。啟用一臺新終端挪凑,消耗一個裝機量孕索;
- 在第一次購買成功后,需要重新下載SDK替換原項目中使用的舊版躏碳,避免報錯搞旭;
喚醒SDK集成
iOS集成
- 打開SDK包,進(jìn)入resource/ivw/目錄,將里面的*.jet文件重命名為ivw.jet肄渗,放入工程resource/ivw/下镇眷,進(jìn)入lib目錄將iflyMSC.framework放入工程的framework目錄中
- 語音喚醒iOSSDK集成流程
- 配置喚醒參數(shù)
self.iflyVoiceWakeuper = [IFlyVoiceWakeuper sharedInstance];
self.iflyVoiceWakeuper.delegate = self;
// 設(shè)置keyeword的閾值
// 例如,0:1450; 1:1450
// 0:第一個關(guān)鍵字恳啥,1450:第一個關(guān)鍵字的閾值
// 1:第二個關(guān)鍵字偏灿,1450:第二個關(guān)鍵字的閾值
//關(guān)鍵字的順序必須與資源文件一致
NSString *thresStr = [NSString stringWithFormat:@"0:%d", 1450];
[self.iflyVoiceWakeuper setParameter:thresStr forKey:[IFlySpeechConstant IVW_THRESHOLD]];
// 設(shè)置會話類型
[self.iflyVoiceWakeuper setParameter:@"wakeup" forKey:[IFlySpeechConstant IVW_SST]];
// 設(shè)置資源文件的路徑
NSString *resPath = [[NSBundle mainBundle] resourcePath];
NSString *wordPath = [[NSString alloc] initWithFormat:@"%@/ivw/ivw.jet",resPath];
NSString *ivwResourcePath = [IFlyResourceUtil generateResourcePath:wordPath];
[self.iflyVoiceWakeuper setParameter:ivwResourcePath forKey:@"ivw_res_path"];
// 在服務(wù)成功后設(shè)置會話延續(xù)狀態(tài)。
// 0:一次喚醒后會話結(jié)束; 1:喚醒后會話繼續(xù)
[self.iflyVoiceWakeuper setParameter:@"1" forKey:[IFlySpeechConstant KEEP_ALIVE]];
// 設(shè)置音頻源
[self.iflyVoiceWakeuper setParameter:IFLY_AUDIO_SOURCE_MIC forKey:@"audio_source"];
// 設(shè)置錄像機保存的音頻路徑
[self.iflyVoiceWakeuper setParameter:@"ivw.pcm" forKey:@"ivw_audio_path"];
- 開啟喚醒監(jiān)聽
// 開啟喚醒監(jiān)聽
[self.iflyVoiceWakeuper startListening];
- 喚醒結(jié)果回調(diào)
喚醒成功后钝的,在喚醒結(jié)果回調(diào)中發(fā)送AIUI喚醒消息和開始錄音消息即可進(jìn)行語音交互翁垂。
/**
result callback of voice wakeup
resultDic:語音喚醒結(jié)果
**/
-(void) onResult:(NSMutableDictionary *)resultDic {
// self.aiuiState為AIUI狀態(tài)
// STATE_IDLE:空閑狀態(tài),AIUI服務(wù)未開啟硝桩。
// STATE_READY:就緒狀態(tài)沿猜,已經(jīng)開啟錄音,等待喚醒碗脊。
// STATE_WORKING:工作狀態(tài)啼肩,已經(jīng)喚醒,可以開始人機交互衙伶。
if (self.aiuiState == STATE_READY) {
// 發(fā)送CMD_WAKEUP消息至AIUI祈坠,使AIUI處于喚醒狀態(tài),再發(fā)送開始錄音消息矢劲,使麥克風(fēng)錄入音頻赦拘。
// 發(fā)送喚醒消息
IFlyAIUIMessage *msg = [[IFlyAIUIMessage alloc] init];
msg.msgType = CMD_WAKEUP;
[_aiuiAgent sendMessage:msg];
// 發(fā)送開始錄音消息
IFlyAIUIMessage *msg1 = [[IFlyAIUIMessage alloc] init];
msg1.msgType = CMD_START_RECORD;
[_aiuiAgent sendMessage:msg1];
}
}
Android集成
- 打開SDK包,進(jìn)入res/ivw/目錄芬沉,將里面的*.jet文件重命名為ivw.jet, 放入工程src/main/assets/ivw/下躺同,進(jìn)入libs目錄將Msc.jar放入工程libs/下,libmsc.so放入工程src/main/jniLibs/armeabi下丸逸;
- 修改aiui_phone.cfg配置文件蹋艺,添加喚醒參數(shù)即可。在代碼中創(chuàng)建AIUIAgent后即可開始喚醒黄刚,喚醒成功后可進(jìn)行語音交互捎谨。
// 喚醒參數(shù)
"ivw":{
"res_type":"assets",
"res_path":"ivw/ivw.jet",
"ivw_threshold":"0:2000" //0為喚醒詞編號,2000為喚醒閾值(范圍0~3000)憔维,多個喚醒用分號隔開侍芝,如:"ivw_threshold":"0:2000;1:1500"
},
// 語音業(yè)務(wù)流程控制
"speech":{
"wakeup_mode":"ivw"
}
- 初始化,建議將初始化放在程序入口處(如Application埋同、Activity的onCreate方法),初始化代碼如下,XXXXXX為你的應(yīng)用appid棵红。
SpeechUtility.createUtility(this, String.format("engine_start=ivw,delay_init=0,appid=%s","XXXXXX"));
- 創(chuàng)建AIUIAgent凶赁,發(fā)送CMD_START_RECORD消息,即開始錄音,等待喚醒虱肄。
//創(chuàng)建AIUIAgent
mAIUIAgent = AIUIAgent.createAgent( this, getAIUIParams(), mAIUIListener );
//開始錄音
AIUIMessage msg = new AIUIMessage(AIUIConstant.CMD_START_RECORD, 0 ,0, "data_type=audio,sample_rate=16000", null);
mAIUIAgent.sendMessage(msg);
AIUI自定義技能平臺
技能資源限制
在技能工作室中致板,針對用戶下每種資源的創(chuàng)建,存在數(shù)量上的限制咏窿。詳情查看官方文檔
情景模式
AIUI 應(yīng)用默認(rèn)配置了一個語義情景模式main斟或。目前 AIUI 一個應(yīng)用支持配置最多10個情景模式。情景模式分為語義情景模式和翻譯情景模式集嵌。您可以為每個語義情景模式配置不同的識別萝挤、語義、后處理根欧,也可以選擇新建翻譯專用的情景模式
語義理解
在應(yīng)用配置中開啟語義理解怜珍,可配置關(guān)鍵詞過濾、語義技能
- 用戶表述中可能包含喚醒詞凤粗,此時會影響到語義理解的結(jié)果酥泛,此種情況下可添加關(guān)鍵詞過濾。
- 語義技能包括自定義技能嫌拣、自定義問答柔袁、商店技能。技能優(yōu)先級:自定義技能>自定義問答>商店技能异逐。
自定義技能
進(jìn)入IFlyOS技能工作室構(gòu)建技能捶索,可查看技能工作室官方文檔
創(chuàng)建技能
一個技能的編寫,一定來自于一個具體的產(chǎn)品需求应役。在技能開發(fā)之前情组,你需要定義技能,即確定這個技能能夠滿足用戶的何種需求箩祥。
1.1 技能分為商店技能和私有技能院崇,可查看不同類型技能的區(qū)別。根據(jù)本項目需求袍祖,使用私有技能->AIUI平臺底瓣。
注意:技能類型一經(jīng)創(chuàng)建,不可修改蕉陋,暫不支持刪除技能捐凭,請謹(jǐn)慎操作。-
意圖配置
每個交互模型必須有一個入口意圖凳鬓,作為技能交互入口茁肠。
2.1 語料:用戶的每個意圖在實際中可能有很多種表述方式(以查快遞意圖為例)可能的表述有:- 我要查順豐快遞
- 我要查快遞
- 查一下快遞
- ......
這些表述統(tǒng)稱為語料,一個技能中缩举,每個意圖下可能存在幾十條到幾千條不等的語料垦梆,為了保證技能語義理解的結(jié)果匹颤,我們建議開發(fā)者盡可能完善所有的語料。
2.2 關(guān)于AIUI中實體的理解靜態(tài)實體托猩、動態(tài)實體印蓖、所見即可說、通配實體
2.3 輔助詞:在用戶的表述中會出現(xiàn)的詞匯京腥,但是這些詞匯開發(fā)者并不關(guān)心其具體值赦肃,其存在的意義是保證表述完整,例如常見的輔助詞有:請問公浪、查看他宛、如何等。 技能后處理(暫未使用)
利用技能后處理因悲,您可以通過編寫代碼的方式堕汞,為您的技能配置多輪對話,以及調(diào)用外部信源晃琳,為您的技能組合豐富多彩的回答話術(shù)讯检。后處理云函數(shù),目前AIUI技能后處理使用v2.0協(xié)議卫旱。發(fā)布構(gòu)建技能
4.1 技能修改/構(gòu)建完畢之后需要發(fā)布上線才可以使用人灼。
4.2 發(fā)布之后的私有技能,開發(fā)者可在AIUI應(yīng)用的語義技能處引用該技能顾翼。
4.3 當(dāng)你的AIUI應(yīng)用添加了商店技能時投放,若商店技能更新版本,你的應(yīng)用默認(rèn)會使用舊版本适贸。當(dāng)確認(rèn)新版本不會造成已經(jīng)分發(fā)給用戶的客戶端異常時灸芳,你可以通過移除后再次添加技能的方式,使得商店技能新版本生效拜姿。
AIUI交互事件結(jié)果解析
/*!
* 事件回調(diào)<br>
* SDK所有輸出都通過event拋出烙样。
*
@param event AIUI事件,具體參見IFlyAIUIEvent蕊肥。
*/
- (void) onEvent:(IFlyAIUIEvent *) event ;
AIUI交互結(jié)果事件通過EVENT_RESULT
拋出谒获,詳細(xì)參考官方demo,結(jié)果類型包括:
- 聽寫結(jié)果(iat)
- 語義結(jié)果(nlp)
- 后處理服務(wù)結(jié)果(tpp)
- 云端tts結(jié)果(tts)
- 翻譯結(jié)果(itrans)
AIUI交互結(jié)果事件回調(diào)中IFlyAIUIEvent
對象的info
字段所包含的接送內(nèi)容格式如下:
{
"data": [{
"content": [{
"cnt_id": "0",
"dte": "utf8",
"dtf": "json"
}],
"params": {
"cmd": "iat-kc-tts",
"lrst": "1",
"rstid": "3",
"sub": "nlp",
"tts": "1"
}
}]
}
各字段含義解釋
sub
的值確定對應(yīng)的事件結(jié)果類型壁却;值如果是nlp
批狱,代表是語義結(jié)果,若cnt_id
內(nèi)容id不為空展东,可根據(jù)cnt_id
獲取event.data
中對應(yīng)的語義結(jié)果json串赔硫。
dte
的值確定語義結(jié)果的數(shù)據(jù)編碼;dtf
的值確定語義結(jié)果的數(shù)據(jù)格式盐肃。
其他字段暫未使用爪膊,這里暫時不做介紹
關(guān)于語義結(jié)果json串說明向胡,可以參考AIUI語義協(xié)議
progressive 流式識別(聽寫結(jié)果解析)
progressive 流式識別簡稱 pgs,在關(guān)閉該選項時惊完,云端 VAD 會在用戶說完一句話時返回一次識別結(jié)果。 打開該選項時处硬,云端會在識別一句話的過程中小槐,返回多次識別結(jié)果,并不斷自動修正荷辕,開發(fā)者如果希望在界面上實時展示修正結(jié)果以提高用戶體驗凿跳,可以打開該選項。流失識別官方文檔
JSON字段 | 類型 | 說明 |
---|---|---|
sn | number | 第幾句(當(dāng)前結(jié)果id) |
ls | boolean | 是否為最后一條結(jié)果 |
bg | number | 開始 |
ed | number | 結(jié)束 |
pgs | string | 結(jié)果操作字段疮方,其中apd代表結(jié)果追加控嗜,rpl代表結(jié)果替換 |
rg | array | 替換范圍 |
ws | array | 詞 |
cw | array | 中文分詞 |
sc | number | 分?jǐn)?shù) |
w | string | 單字/詞組 |
技能后處理云函數(shù)編寫示例代碼(幫助理解技能后處理)
AIUI.create("v2", function(aiui, err){
//打印 request 結(jié)構(gòu)體
requestObject = aiui.getRequest().getObject();
console.log(requestObject);
//獲取 response 對象
var response = aiui.getResponse();
// 獲取當(dāng)前意圖名
intentName = requestObject.request.intents[0].name;
console.log("本次意圖來自:"+intentName);
// 獲取填槽對話狀態(tài)
dialogState= requestObject.request.dialogState;
if(dialogState!=null&&dialogState!="COMPLETED"){
// 填槽對話未完成時,托管給系統(tǒng)管理
response.addDelegateDirective();
}else{
// 填槽對話完成時骡显,回復(fù)用戶一句 answer
updatedIntent = aiui.getUpdatedIntent();
// 獲取槽值
companyValue = updatedIntent.getSlotValue("company");
// 獲取槽值
numberValue = updatedIntent.getSlotValue("number");
answer="你的"+"快遞單號是:"+numberValue+"疆栏,已經(jīng)達(dá)到北京市"
// 回答用戶
response.setOutputSpeech(answer);
}
// 提交
aiui.commit();
})