kun432's blog

Alexaなどスマートスピーカーの話題中心に、Voiceflowの日本語情報を発信してます。たまにAWSやkubernetesなど。

〜スマートスピーカーやVoiceflowの記事は右メニューのカテゴリからどうぞ。〜

日本語に対応したAmazon Lex(V1)を試してみる①

f:id:kun432:20210427220639p:plain

いろいろ忙しくてちょっと久々のエントリ。ついに日本語に対応したAmazon Lexを遅れ馳せながら試してみたいと思います。

目次

Amazon Lexとは?

上記の公式ブログの記載を引用します。

Amazon Lex はチャットボット向けの会話型 AIを提供するサービスで、Alexaと同じテクノロジーを利用した会話インターフェースの構築が可能となります。 音声をテキストに変換するためのディープラーニングを利用した自動音声認識(ASR)と、テキストの意図を認識する自然言語理解(NLU)機能が提供されているため、文字チャットだけではなく、音声入力により、リアルな会話の相互作用を備えたアプリケーションの構築が簡単に行えます。音声には、Amazon Pollyが用いられ、自然な日本語でユーザーに応答し、また発音のカスタマイズ等も可能です。

https://aws.amazon.com/jp/blogs/news/amazon-lex-tokyo/

そして、Lexの画面にある説明を見てみましょう。

f:id:kun432:20210427222318p:plain

Intents/Utterances/Slotsなど、Alexaで見慣れた用語が出て来ていますね。

つまり、Alexaスキル開発を経験したことがあれば、Lexの概要はほとんど理解してるのと同じってことですね。では早速やってみましょう。

余談ですが、"Alexa" から "a"をとると"Lex"になりますね。

はじめる前に

Lexには2つのAPIバージョンがあります。以下の通り、V1とV2ではLambdaのレスポンス形式が異なります。

また、以下のFAQにある通り、V2ではAmazon Connectのコンタクトフローとの統合はできません。

  1. V2 API を使用して作成されたボットを Amazon Connect のコンタクトフローと統合できますか?

いいえ。現在、Amazon Connect のコンタクトフローは既存の V1 API でのみ機能します。V1 コンソールを使用して、ボットを作成し、Amazon Connect と統合することができます。

V2のほうが機能も増えており、将来的にはV2になっていくと思いますが、今回はV1を使ってみたいと思います。

「BookTrip」サンプルを試す

まずは使い方を知るために予め用意されているサンプルの中から「BookTrip」を使ってみたいと思います。

マネジメントコンソールにログインし、Lexの画面を開きます。

f:id:kun432:20210427224000p:plain

初めて使う場合は以下のような画面が表示されるので "Get Started" をクリックします。

f:id:kun432:20210427224108p:plain

ボットの作成画面が表示されます。会話のやり取りが表示されていますね。

f:id:kun432:20210427224320p:plain

デフォルトで"BookTrip"サンプルが選択されていると思うので、ここはそのままで。"TRY A SAMPLE"で"BookTrip"が選択されていること、"Bot Name"に"BookTrip"が指定されているを確認します。

f:id:kun432:20210427224506p:plain

下にスクロールすると、さらに設定があります。まず、言語を「日本語」に変更します。上のやり取りも日本語に変わりますね。

f:id:kun432:20210427225039p:plain

それ以外の項目は以下のとおりとしました。

f:id:kun432:20210427225206p:plain

  • Sentiment analysis
    • Amazaon Comprehendを使って、入力されたテキスト・音声の感情分析の有効・無効を設定します。これはAlexaにはないですね。興味あるので"Yes"にしてみます。
  • COPPA
    • 子供向けサイトの規制に関する法律である「COPPA(Children's Online Privacy Protection Act)」に準拠すべきかどうかを設定します。子供向けのボットを作る場合には有効にする必要があるようで、有効にした場合、制度改善のために入力されたテキストや音声の保存が行われなくなるようです。今回は"No"にしておきましょう。
  • Confidence score threshold
    • インテントの認識に対する信頼度の閾値を設定できるようです。ここは一旦デフォルトのままにしておきます。

IAMロールは自動で作成されるようです。タグも今回は特に指定しません。

設定したら"Create"をクリックします。

ボットが作成されると、以下のような画面が表示されます。

f:id:kun432:20210427230358p:plain

画面の構成を見る前に右上の”Build”がクルクルと回っているのが見えると思います。Alexa開発者コンソールの対話モデルのビルドと同じですね。

f:id:kun432:20210427233546p:plain

ビルドが終わるとメッセージが表示されます。これで対話モデルの構築が完了したということでしょうね。

f:id:kun432:20210427233608p:plain

では画面の構成を見ていきましょう。左のメニューを見てみると、インテントやスロットが並んでるのが見えますね。右に表示されているのは"BookCar_jaJP"インテントのサンプル発話ですね。

f:id:kun432:20210427230716p:plain

もう一つの"BookHotel_jaJP"を見てみると、サンプル発話にスロットが含まれているのがわかりますね。

f:id:kun432:20210427233424p:plain

次にスロットタイプにある"RoomTypeValues_jaJP"を見てみましょう。

f:id:kun432:20210427233931p:plain

スロットの値がいくつか列挙されていますね。つまり、これはAlexaでいう「カスタムスロットタイプ」ということですね。

f:id:kun432:20210427234021p:plain

"Slot Resolution" は "Expand Values" が選択されています。説明を見てみましょう。

f:id:kun432:20210427234225p:plain

「スロット値をトレーニングのデータとして使用し、ユーザからの入力データがスロット値と似ている場合はスロット値として受け取る」とあります。

もう一方の"Restrict to Slot values and Synonyms"の説明も見てみましょう。

f:id:kun432:20210427234507p:plain

こちらは「スロットの値が列挙型として扱われ、ユーザーの値がスロットの値の1つと同じ場合にのみスロットとして受け取る。同義語(シノニム)は、対応するスロット値として解決される。」とありますね。つまり、

  • "Expand Values" の場合は、スロット値と類似した入力データならばスロットに入る。シノニムは使えない。
  • "Restrict to Slot values and Synonyms"の場合は、スロット値は登録されたもののみに限定される。シノニムが使えて、スロット値に変換されてスロットに入る。

ということのようです。このあたり、少しAlexaとは違うようですね。

再度"BookHotel_jaJP"インテントの画面をもう一度見てみましょう。

f:id:kun432:20210427235333p:plain

サンプル発話の下の方に"Slots"というのが見えると思います。

f:id:kun432:20210427235410p:plain

スロットがいくつか並んでいて、スロットタイプにAlexaならおなじみのAMAZON.Cityなどが見えます。これがビルトインスロットタイプなのでしょう。

f:id:kun432:20210427235629p:plain

またこれらのスロットはサンプル発話に含まれていないのですが、"Required"という「必須」を表すチェックボックスと、"Prompt"というそれぞれのスロットを受け取るためのプロンプトが記載されていますね。つまり、これ、ダイアログモデルの設定と同じってことですね。

f:id:kun432:20210427235830p:plain

下に進むと"Confirmation prompt"で確認時の発話とキャンセル時の応答を設定することができます。確認時の発話には受け取ったスロットを含めてありますね。この辺はダイアログモデルとやっていることはほぼ同じですね。

f:id:kun432:20210428000111p:plain

さらに下に進むと"Fulfillment"という項目があり、"Lambda" が選択できることから、ここで受け取ったスロットをバックエンドに渡すのだということがわかります。"Return parameters to client"は多分下にある"Response"のところで固定の応答を返すのではないかなと思いますが、後で見てみましょう。

f:id:kun432:20210428000430p:plain

ボットのテスト

ではテストしてみたいと思います。2つあるインテントのうち、今回は"BookCar_jaJP"のレンタカー予約のほうを使います。右にある"Test Chatbot"をクリックします。

f:id:kun432:20210428000645p:plain

テスト用の画面が開きます。"Chat with your bot"にテキストを入力するか、マイクボタンをクリックして音声入力をすればいいというわけですが、試してみたところマイクでの音声入力がうまくいかないようなので(正しく認識してくれたりしてくれなかったりする)ので、今のところはテキスト入力のほうがベターなようです。

f:id:kun432:20210428000815p:plain

実際にテストしてみた結果はこんな感じです。

f:id:kun432:20210428020137p:plain

最後のところが少しデバッグっぽいですが、ユーザとの対話でスロット値が収集できていることがわかりますね。

また、テストツールの下の方には以下のような状態が表示されます。

  • マッチしたインテント
  • スロット値の収集状況
    • "ElicitSlot" がスロット値の収集途中
    • "ReadyForFullfilment"ですべてのスロット値の収集完了
  • 収集したスロット値

f:id:kun432:20210428023742p:plain

"Detail"をクリックすると、より詳細な情報がJSONで表示され、インテントの信頼度や感情分析の結果なども確認できます。

f:id:kun432:20210428024251p:plain

応答を修正する

応答をLambdaで動的に作ってやりたいところですが、それは次回にして、固定の応答を追加してLex上で完結させるようにしてみます。

"Response" の下にある "Add Message" をクリックします。

f:id:kun432:20210428022738p:plain

応答を設定する入力欄が表示されます。"Message"と"Custom Markup"がありますが、後者はおそらくSSMLで書くのだろうと思います。今回は"Message"で普通に応答内容をテキストで書いてみます。受け取ったスロット値を応答内容に含める場合には {スロット名} みたいに書けばよいです。スロット部分の前後にスペースを入れておいたほうがいいかもですね。こんな感じのテキストを設定してみました。

{PickUpCity} で {CarType} タイプを、{PickUpDate} から {ReturnDate} まで予約しました。ご利用ありがとうございました。

f:id:kun432:20210428022701p:plain

ちなみに、その下にある"Enable response card"はAlexaのカードに似たようなもの、"Wait for user reply" はセッションを終わらせずに次の発話を促すためのプロンプトを設定する箇所のようですが、今回は割愛します。

f:id:kun432:20210428022833p:plain

最後に"Save Intent"をクリックして、インテントを保存します。

f:id:kun432:20210428023324p:plain

そして"Build"をクリックして対話モデルを構築します。

f:id:kun432:20210428023411p:plain

再度テストしてみるとこうなります。

f:id:kun432:20210428024647p:plain

最後の応答が置き換わっているのがわかりますね。かんたんな対話であればLexだけで完結できるということですね。

まとめ

インタフェースもやや異なりますし、多少考え方が違うところもありますが、Alexaスキル開発をやったことがあれば、Lexにはスムーズに入っていけると思います。次回以降でもう少し色々やってみたいと思います。