オートデリゲートを使ってダイアログのスロット値収集をAlexaにお任せする

Alexaのオートデリゲート機能を使うと、会話におけるスロット値の収集を楽ちんにすることができます。
2019.01.31

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

Alexaのスキル開発時に、ダイアログモデルを使ってスロットの値を取得するケースがあります。 例えば、飲み物をオーダーするスキルで、以下のようなシナリオです。

A: ご注文は何になさいますか?
U: コーヒーをお願いします。
A: わかりました。いくつでしょうか?
U: 2つ。
A: コーヒーを2つですね。少々お待ちください。

上記の場合、「飲み物」と「数量」の2つのスロット値を会話の中で収集する必要があります。

Alexaでは、簡単なダイアログであれば会話の組み立てや確認をバックエンドではなく、Alexa側にデリゲート(委譲)することができます。

【公式ドキュメント】ダイアログをAlexaにデリゲートする

このエントリでは、オートデリゲートと呼ばれる機能を使ってダイアログをAlexa側に任せる方法をご紹介します。

スロットの準備とインテントの作成

実際に上記のようなスキルを作成してオートデリゲートを試してみます。 まず、スキル作成後に飲み物のスロットDrinkを準備します。

次に、飲み物を注文するインテントOrderIntentを追加し、インテントスロットには以下のスロット(スロットタイプ)を設定します。

  • drink (Drink)
  • amount (Amazon.NUMBER)

サンプル発話に、飲み物を注文する場合に想定される発話を登録していきます。

ダイアログの設定

次に、各スロットにダイアログの設定を行います。 インテントスロットのdrinkリンクをクリックします。

「このインテントを完了させるために、このスロットは必須ですか?」をONにし、必ずこのスロット値の収集するように設定します。

次に、「Alexaの音声プロンプト」にこのスロット値が収集されなかったときにAlexaが発話する内容を追加します。 今回のケースだと、「OrderIntentと認識されたが発話にdrinkが入っていなかった」という場合です。 なので、何の飲み物を注文するかユーザーに質問する発話を登録します。

(なお、ここでは複数の発話を登録することができますが、実際の会話ではAlexaは候補の中からランダムでどれか一つを発話します)

次に、その質問に対するユーザーのサンプル発話を登録します。 インテントのサンプル発話同様に、想定される発話をできるだけ多く追加しておきます。

次に、「検証」タブを開いてダイアログにおけるスロット値の検証を試してみます。 ここでは、収集されたスロット値について「特定の値だけ許可/拒否する」「定義されたスロット値のみ受け付ける」のようなルールを設定することができます。

今回は、「季節限定のクリームソーダは拒否する」というルールを設定してみます。 検証条件の選択で「値セットのみを拒否する」を選択し、+ボタンをクリック。

「値を追加」項目にクリームソーダを追加し、その下の発話入力欄に、拒否する理由と他の商品の注文を促す発話内容を追加します。

次に、amountインテントスロットも同様にダイアログの設定を行います。

検証では、「1以上の数のみ許可する」というルールを設定してみます。 Amazon.NUMBERスロットでは、以上・未満といった条件を指定することが可能です。

設定後、モデルの保存とビルドを忘れずに実行しておきます。

バックエンドのLambda

次に、バックエンドのLambdaを書いてみます。 今回は、Alexa hostedとしてdeveloper console上のコードエディタで書いています。

OrderIntentハンドラのコード(Node.js 8.10)は下記です。(その他のコードは省略します)

const OrderIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
        && handlerInput.requestEnvelope.request.intent.name === 'OrderIntent';
  },
  handle(handlerInput) {
    const intent = handlerInput.requestEnvelope.request.intent;

    const drink = intent.slots.drink.value;
    const amount = intent.slots.amount.value;

    let speechOutput = drink + "を" + amount + "つですね。少々お待ちください。";

    return handlerInput.responseBuilder
      .speak(speechOutput)
      .withShouldEndSession (true)
      .getResponse();
  }
};

OrderIntentハンドラでは、必要なスロット値が収集された状態(=注文に必要な情報)で入ってくるので、注文の復唱をしてオーダーを完了としています。 このように、Alexa側にスロット値の収集をデリゲートすると、バックエンドのコードは最小限で済ませることができます。

コードエディタで編集後は、SaveとDeployを忘れずに。

スキルのテスト

次に、実際にどのような会話になるかテストしてみます。 テストをしてみると、会話が展開され注文に必要な情報がAlexa側で収集できていることがわかります。

drinkスロットの検証も正しく動作し、クリームソーダが拒否されています。

amountスロットの検証もきちんと動作していますね。

おわりに

Alexaのオートデリゲートの機能を使って、ダイアログにおけるスロット値の収集をAlexa側に任せてしまう方法をご紹介しました。 複雑なダイアログの場合、やはりLambda側で色々と処理する必要がありますが、簡単なダイアログであればAlexa側にデリゲートすることで、最小限のバックエンドコードで済みます。

スロットの検証を活用することで実用的に使えるかと思いますので、オートデリゲートの機能を使って効率的にスキル開発を行っていきましょう。

それでは。