2時間でAlexaスキルを作ってみたけどできなかった話 その2

はじめに

前回の続きで、「面接練習」スキルを作ってみる。

やってみたこと

方向性を考えてみる

  • 次に具体的にやりたいのは、「回答内容の録音」である
  • 回答内容の録音をする機能があるかどうかはまだ不明
  • あっても、必要な長さで録音できるかどうか不明(1分で切れちゃうとか)

まずは、ドキュメントをみてみることにする

道場に再入門する

  • やりたいことを段階ワケしてみると、次のようになった
    • 発話した内容を受け取る
    • 受け取った内容を処理する(テキストにして、リストに入れるなど)
  • 発話した内容を受け取るには、「スロット」の利用が必要そうだった
    • ググってみると、今回やりたいことに違いことについて書いてあるブログが見つかった
      • Alexaスキルでおうむ返し – Qiita https://qiita.com/yuppejp/items/6375c0babc11897ff1b4
    • そのブログでは「スロット」が使われていた
  • 我々はまだ、Alexa道場の「Season 3 スロットを使いこなそう」のセクションを学んでいなかったので、そもそもスロットという概念についてよく知らない

まずAlexa道場の「Season 3 スロットを使いこなそう」のセクションを学ぶことにした。

Alexa道場での学び – スロットについて

  • 「スロット」を利用して、ユーザから情報を受け取ることができる
  • ユーザから受け取るすべてのパターンをインテントで網羅できれば、スロットを使わなくてもよいが、無駄が多くなる場合がある
    • 例えばコーヒーショップスキルに置いて、次のようなリクエストを処理する場合である
      • 「カフェラテを2つ注文して」
      • 「カフェモカを3つ注文して」
      • 「エスプレッソを4つ注文して」
    • スロットを使わない場合には
      • 「カフェラテを2つ注文して」→OrderCoffeLatteIntent
      • 「カフェモカを3つ注文して」→OrderCoffeMochaIntent
      • 「エスプレッソを4つ注文して」→OrderEspressoIntent
      • のようになる。
    • スロットを使う場合には
      • {menu}を{amount}つ注文して、というスロットタイプをOrderIntentにつなげる?だけで済むため、メニューが増減したり、変更してもメンテナンスしやすいし、コード量も最小限で無駄がな
  • スロットに入るデータを定義するには、スロットタイプの指定が必要
    • 例えば、「{menu}を{amount}つ注文して」であれば、menuとamountのスロットタイプをそれぞれ定義が必要となる
    • amountは、ビルトインスロットタイプが使用できる(数字、日付、場所、人の名前、などAmazon側で初めから用意されているタイプ)
    • menuはビルトインスロットタイプが使用できないので、カスタムスロットタイプの使用が必要である

Alexa道場での学び – 設定例(with コーヒーショップスキル)

これまでSeason2で作ってきたコーヒーショップスキルをベースに、「{menu}を{amount}つ注文して」のようなスロットをセットする場合の設定方法は次の通り

  1. {menu}に対応するカスタムスロットタイプを作成
  2. OrderIntentのサンプル発話を修正
  3. コードでスロットを処理するようにする

{menu}に対応するカスタムスロットタイプを作成する方法:
  • スロットタイプを追加
OrderIntentのサンプル発話を修正する方法
  • サンプル発話を修正する
  • 上記設定後に、モデルを保存して、ビルドを実行する
  • モデルを評価する
コードでスロットを処理するようにする
  • OrderIntentを次のように修正
const OrderIntentHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
            && Alexa.getIntentName(handlerInput.requestEnvelope) === 'OrderIntent';
    },
    handle(handlerInput) {
        
        let menu = handlerInput.requestEnvelope.request.intent.slots.menu.value;
        let amount = handlerInput.requestEnvelope.request.intent.slots.amount.value;
        
        const speakOutput = `${menu}を${amount}つですね。ありがとうございます。`;

        return handlerInput.responseBuilder
            .speak(speakOutput)
            .getResponse();
    }
};
  • テストしてみる

ためしに面接練習スキルで、オウム返しするスキルを作ってみる

この記事を参考にすると、スロットタイプを「AMAZON.CITY」などにすると、任意のテキストを受け取れるようだ。そのため、受け取ったテキストをそのまま返すようにすれば、オウム返しするスキルを実装可能そう

Alexa-hostedスキルを使って 最速でオウム返しスキルを作る – Speaker Deck https://speakerdeck.com/toranoana/alexa-hostedsukiruwoshi-tute-zui-su-deoumufan-sisukiruwozuo-ru?slide=20

実際に試してみた。

スロットタイプをAMAZON.CITYにしてみたところ、ある長さを超えると入力内容が取得できないようだった。

以下、やってみたこと。

  • インテントを修正
  • コードエディタでHelloWorldIntentHandlerを修正
const HelloWorldIntentHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
            && Alexa.getIntentName(handlerInput.requestEnvelope) === 'HelloWorldIntent';
    },
    handle(handlerInput) {
        
        let text = handlerInput.requestEnvelope.request.intent.slots.text.value;
        const speakOutput = `あなたはこう言いました。${text}`;

        return handlerInput.responseBuilder
            .speak(speakOutput)
            //.reprompt('add a reprompt if you want to keep the session open for the user to respond')
            .getResponse();
    }
};

  • テストしてみる

最後に

面接練習スキルを作るためには、十分に自己紹介を行うだけの長さで入力できるようにしたいが、難しいかもしれない。

あるいは、「以上です」をいうまで何回も聞き取って、リストに追加してくれるとか、「発話内容をそのまま録音」して返すようなことができればよいのかも。ただ、発話内容をそのまま取れるのかは要調査。

引き続き調べてみる。

とりあえず、言った言葉をつなげて、リストに保存してくれるものを一旦作ってみる。

それか、全部三行で説明されるようにするとか。

リストに保存する機能の使い方については要調査。

参考

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です