開發小米 AI 上的自定义技能應用

Smart Speaker(智能音箱) 的進步非常快速,例如:Amazon Echo, Google Home, Microsoft Invoke(Harman Kardon) 都正在努力發展,中文的智能音箱就有小米,天貓...等,本篇將介紹怎麽開發在小米 AI 上面的 自定义技能。

如果您研究過目前做語音控制雲端平臺的話,可以發現各家都有 Skills,例如 Alexa, Cortana, Google Assistant 或是 LINE 的 Glova,結構都是:

  • 一個 STT (Speech to ext) 的 Cloud Service 把從音箱收到的聲音轉成文字
  • 一個 NLU (Natural language understanding) Cloud Platform 去理解使用者所説的内容,並分析出句子的意義與關鍵字比率
  • 搭配分析出來的結果找到是否有對應處理的 Skills,將結果交給 Skills 去處理
  • Skill 是其他開發商自己在平臺注冊的服務,再根據收到的分析結果產生對應的任務與處理,最後再回傳給使用者

同樣地,小米目前提供讓第三方開發者加入自己的技能,參考 水滴平台开发者文档 瞭解交易時需要的參數與回傳的内容。

我利用 .NET StandardASP.NET Core 做了資料交易 SDK 與自定義技能的接口: Xiaomi-ai-skill-converter

截取程式碼片段説明:

  1. Skill 收到小米 AI 請求時,可利用 request.type 理解用戶目前是要:喚醒/意圖/結束 的請求;
    收到來自小米 AI 的 request, 内容大致如下:
    {
      "version": "1.0",
      "query": "開啓天氣查詢",
      "session": { // 请求的上下文信息都放这
        "session_id": "xxxxxxxxxxxxx",
        "application": {
          "app_id": "123"
        }
      },
      "request": {
        "type": 1,
        "request_id": "tttttttttt",
        "timestamp": 452453534523,
        "event_type": "leavemsg.finished",
        "event_property": {
            "msg_file_id": "1231312312"
        }
      }
    }
    可以利用下面的程式片段,把 JSON 轉成物件:
    using XiaomiAI.SDK.Models;
    // POST api/values
    [HttpPost]
    public async Task Post([FromBody]string value)
    {
        using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
        {
            string requestJson = await reader.ReadToEndAsync();
    
            var requestContent = JsonConvert.DeserializeObject(requestJson);
    
            switch (requestContent.Request.Type)
            {
                case RequestType.Intent:
                    // 代表用戶説了什麽内容,利用 request.query 抓到用戶講的内容
                    // query 不會有 NLU 的結果,需要搭配其他的 NLU 服務
                    break;
                case RequestType.End:
                    // 代表要結束對話,記得標記 is_session_end = true;
                    break;
                default:
                    // None, Wakeup, 預設用來詢問用戶想要在 Skill 做什麽
                    break;
            }
        }
    }
    
  2. 搭配 Session 在每次的 response 加入參數:

    如果 Skill 是允許多次對話且需要記錄上一次用戶説過的内容或是處理參數,可以搭配 response 中的 session_attributes 來記錄。

    session 會在 request 回傳時再帶回來 session 再送回來。 下

    面是在 response 中加入 session 的内容:

    string displayText = "是的,幫你朗讀現在氣象";
    
    string sessionAttributes = @"{ ""name"": ""pou"", ""age"": ""35"", ""email"": ""poumason@live.com""}";
    
    return new ResponseContent
    {
        IsSessionEnd = false,
        SessionAttributes = sessionAttributes,
        Response = new ResponseData
        {
            // ToSpeak 與 ToDisplay 一定要給,來支援有屏幕跟沒有屏幕的設備
            ToSpeak = new ToSpeakData
            {
                Type = ToSpeakType.TTS,
                Text = displayText
            },
            ToDisplay = new PlainTextToDisplayData
            {
                Text = displayText
            },                                    
            Directives = new List
     {
                new AudioDirectiveData
                {
                    AudioItem = new AudioItemData
                    {
                        Stream = new StreamData
                        {
                            Url = "http://xxxxx.mp3"
                        }
                    }
                },
                new TTSDirectiveData
                {
                    TTSItem = new TTSItemData
                    {
                        Text = displayText
                    }
                }
            }
        }
    };
    

送上面的範例來看是不是非常簡單就可以做完一個 Skill 呢。下面説明幾個開發時遇到且要注意的事項: [注意]

  • to_speak / to_display 是一定要給的。
    to_speak:代表設備要念出的内容,目前只有 TTS;
    to_display:可顯示 text/html/native ui/widgets,其中 native ui / widgets 需要搭配 android 開發
  • 每次交易小米 AI 音箱 <-> Skill 這段時間只有 20 seconds 回應時間,20 seconds 不是代表 Skill 處理時間,而是這個交易時間,所以 Skill 不能太複雜
  • 水滴平臺有提供測試用的 App,盡量使用小米手機測試,因爲其他平臺可能會有一些小問題
  • 建立自定義技能的名稱或是範例句子時,請使用簡體中文,繁體中文會找不到您的技能
  • Skill 必須是 https,它會被利用 POST 觸發,只能 HTTP status code 返回告訴 小米 API 最後 Skill 處理的狀態,例如: 500 是失敗,200 是成功

======

支援中文的智能音箱多數以中國爲主,支援台灣中文發音的廠商也不少,我更期待國際廠能支援中文。

如果您沒有買過小米 AI 也許可以買一臺來玩看看,加入自己的服務會更有感覺。謝謝。

References