メニュー
Amazon Lex
開発者ガイド

情報フローの詳細

この演習では、Amazon Lex コンソールで提供されているテストウィンドウクライアントを使用して、Amazon Lex の BookTrip ボットと会話しました。このセクションでは次の項目について説明します。

  • クライアントと Amazon Lex の間のデータフロー。

     

    このセクションでは、クライアントが PostText ランタイム API を使用して Amazon Lex にリクエストを送信することを前提としていて、それに応じてリクエストとレスポンスの詳細を示しています。PostText ランタイム API の詳細については、「PostText」を参照してください。

    注記

    クライアントが PostContent API を使用する場合の、クライアントと Amazon Lex の間の情報フローの例については、「ステップ 2a (オプション): 音声による情報フローの詳細を確認する (コンソール) 」を参照してください。

     

  • Amazon Lex と Lambda 関数の間のデータフロー。詳細については、「Lambda 関数の入力イベントとレスポンスの形式」を参照してください。

データフロー: BookHotel インテント

このセクションでは、各ユーザー入力の後に何が起こるかを説明します。

  1. ユーザー: 「ホテルの予約」

    1. クライアント (コンソール) は以下の PostText リクエストを Amazon Lex に送信します。

      Copy
      POST /bot/BookTrip/alias/$LATEST/user/wch89kjqcpkds8seny7dly5x3otq68j3/text "Content-Type":"application/json" "Content-Encoding":"amz-1.0" { "inputText":"book a hotel", "sessionAttributes":{} }

      リクエストの URI と本文の両方で Amazon Lex に情報が提供されています。

      • リクエスト URI – ボット名 (BookTrip)、ボットのエイリアス ($LATEST)、およびユーザー名が提供されています。末尾の text では、これが PostText API リクエストである (PostContent ではない) ことが示されています。

      • リクエスト本文 – ユーザー入力 (inputText) と空の sessionAttributes が含まれています。これは最初は空のオブジェクトであり、Lambda 関数によって最初にセッション属性が設定されます。

    2. Amazon Lex は inputText からインテント (BookHotel) を検出します。このインテントには、ユーザーデータの初期化/検証を行うためのコードフックとして Lambda 関数が設定されています。したがって、Amazon Lex は以下の情報をイベントパラメータ (「入力イベントの形式」を参照) として渡して Lambda 関数を呼び出します。

      Copy
      { "messageVersion":"1.0", "invocationSource":"DialogCodeHook", "userId":"wch89kjqcpkds8seny7dly5x3otq68j3", "sessionAttributes":{ }, "bot":{ "name":"BookTrip", "alias":null, "version":"$LATEST" }, "outputDialogMode":"Text", "currentIntent":{ "name":"BookHotel", "slots":{ "RoomType":null, "CheckInDate":null, "Nights":null, "Location":null }, "confirmationStatus":"None" } }

      クライアントによって送信された情報に加えて、Amazon Lex は以下の追加データも含めます。

      • messageVersion – 現在 Amazon Lex でサポートしているのは 1.0 バージョンだけです。

      • invocationSource – Lambda 関数呼び出しの目的を示しています。この場合は、ユーザーデータの初期化および検証を実行することが目的です (この時点で、Amazon Lex はインテントを達成するためのスロットデータの一部をユーザーが指定していないことを知っています)。

      • currentIntent – すべてのスロット値は null に設定されています。

    3. この時点では、すべてのスロット値は null です。Lambda 関数が検証する対象はありません。Lambda 関数は以下のレスポンスを Amazon Lex に返します。レスポンスの形式については、「レスポンスの形式」を参照してください。

      Copy
      { "sessionAttributes":{ "currentReservation":"{\"ReservationType\":\"Hotel\",\"Location\":null,\"RoomType\":null,\"CheckInDate\":null,\"Nights\":null}" }, "dialogAction":{ "type":"Delegate", "slots":{ "RoomType":null, "CheckInDate":null, "Nights":null, "Location":null } } }

      注記

      • currentReservation – Lambda 関数はこのセッション属性を含めます。この値は、現在のスロット情報と予約タイプのコピーです。

        これらのセッション属性を更新できるのは Lambda 関数とクライアントだけであり、Amazon Lex はこれらの値を渡すだけです。

      • dialogAction.type – この値を Delegate に設定すると、Lambda 関数は次の一連のアクションの責任を Amazon Lex に委任します。

        Lambda 関数は、ユーザーデータの検証で何かを検出すると、次に何をするかを Amazon Lex に指示します。

    4. Amazon Lex は dialogAction.type に従って次の一連のアクションを判断します。つまり、ユーザーから Location スロットに対するデータを引き出します。Amazon Lex は、インテント設定に応じて、このスロットに対するプロンプトメッセージの 1 つ (「どの都市に滞在されますか?」) を選択し、以下のレスポンスをユーザーに送信します。

      セッション属性がクライアントに渡されます。

      クライアントはレスポンスを読み取り、そのメッセージ (「どの都市に滞在されますか?」) を表示します。

  2. ユーザー: 「モスクワ」

    1. クライアントは以下の PostText リクエスト (読みやすいように改行が追加されています) を Amazon Lex に送信します。

      Copy
      POST /bot/BookTrip/alias/$LATEST/user/wch89kjqcpkds8seny7dly5x3otq68j3/text "Content-Type":"application/json" "Content-Encoding":"amz-1.0" { "inputText":"Moscow", "sessionAttributes":{ "currentReservation":"{\"ReservationType\":\"Hotel\", \"Location\":null, \"RoomType\":null, \"CheckInDate\":null, \"Nights\":null}" } }

      クライアントは、inputText に加えて、受信したのと同じ currentReservation セッション属性を含めます。

    2. Amazon Lex はまず、現在のインテントのコンテキストの inputText を解釈します (このサービスでは Location スロットに関する情報を特定のユーザーに求めていたことが記憶されています)。Amazon Lex は現在のインテントのスロット値を更新し、以下のイベントを使用して Lambda 関数を呼び出します。

      Copy
      { "messageVersion": "1.0", "invocationSource": "DialogCodeHook", "userId": "wch89kjqcpkds8seny7dly5x3otq68j3", "sessionAttributes": { "currentReservation": "{\"ReservationType\":\"Hotel\",\"Location\":null,\"RoomType\":null,\"CheckInDate\":null,\"Nights\":null}" }, "bot": { "name": "BookTrip", "alias": null, "version": "$LATEST" }, "outputDialogMode": "Text", "currentIntent": { "name": "BookHotel", "slots": { "RoomType": null, "CheckInDate": null, "Nights": null, "Location": "Moscow" }, "confirmationStatus": "None" } }

      注記

      • invocationSourceDialogCodeHook のままです。このステップではユーザーデータを検証しているだけです。

      • Amazon Lex はセッション属性を Lambda 関数に渡すだけです。

      • currentIntent.slots については、Amazon Lex は Location スロットを Moscow に更新しています。

    3. Lambda 関数は、ユーザーデータの検証を実行し、Moscow は無効な場所であると判断します。

      注記

      この演習の Lambda 関数には、有効な都市の単純なリストがあり、Moscow はそのリストに存在しません。本稼働アプリケーションでは、この情報の取得にバックエンドデータベースを使用できます。

      Lambda 関数は、スロット値を null にリセットし、以下のレスポンスを送信して、ユーザーに別の場所を指定し直すように求めることを Amazon Lex に指示します。

      Copy
      { "sessionAttributes": { "currentReservation": "{\"ReservationType\":\"Hotel\",\"Location\":\"Moscow\",\"RoomType\":null,\"CheckInDate\":null,\"Nights\":null}" }, "dialogAction": { "type": "ElicitSlot", "intentName": "BookHotel", "slots": { "RoomType": null, "CheckInDate": null, "Nights": null, "Location": null }, "slotToElicit": "Location", "message": { "contentType": "PlainText", "content": "We currently do not support Moscow as a valid destination. Can you try a different city?" } } }

      注記

      • currentIntent.slots.Location は null にリセットされています。

      • dialogAction.typeElicitSlot に設定されています。これにより、以下を指定してユーザーに再入力を求めるように Amazon Lex に指示しています。

        • dialogAction.slotToElicit – ユーザーからデータを引き出すスロット。

        • dialogAction.message – ユーザーに伝えるメッセージ (message)。

    4. Amazon Lex は dialogAction.type に気づき、以下のレスポンスでその情報をクライアントに渡します。

      クライアントは、「当社では現在、モスクワは有効な目的地ではありません。別の都市を指定いただけますか?」というメッセージを表示するだけです。

  3. ユーザー: 「シカゴ」

    1. クライアントは以下の PostText リクエストを Amazon Lex に送信します。

      Copy
      POST /bot/BookTrip/alias/$LATEST/user/wch89kjqcpkds8seny7dly5x3otq68j3/text "Content-Type":"application/json" "Content-Encoding":"amz-1.0" { "inputText":"Chicago", "sessionAttributes":{ "currentReservation":"{\"ReservationType\":\"Hotel\", \"Location\":\"Moscow\", \"RoomType\":null, \"CheckInDate\":null, \"Nights\":null}" } }
    2. Amazon Lex は、これが Location スロットに対して引き出されているデータであるというコンテキストを知っています。このコンテキストでは、Amazon Lex は inputTextLocation スロットに対する値であることを知っています。Amazon Lex は以下のイベントを送信することで Lambda 関数を呼び出します。

      Copy
      { "messageVersion": "1.0", "invocationSource": "DialogCodeHook", "userId": "wch89kjqcpkds8seny7dly5x3otq68j3", "sessionAttributes": { "currentReservation": "{\"ReservationType\":\"Hotel\",\"Location\":Moscow,\"RoomType\":null,\"CheckInDate\":null,\"Nights\":null}" }, "bot": { "name": "BookTrip", "alias": null, "version": "$LATEST" }, "outputDialogMode": "Text", "currentIntent": { "name": "BookHotel", "slots": { "RoomType": null, "CheckInDate": null, "Nights": null, "Location": "Chicago" }, "confirmationStatus": "None" } }

      Amazon Lex は Location スロットを Chicago に設定して、currentIntent.slots を更新します。

    3. DialogCodeHookinvocationSource の値に従って、Lambda 関数はユーザーデータの検証を実行します。Lambda 関数は、Chicago を有効なスロット値として認識し、それに応じてセッション属性を更新して、以下のレスポンスを Amazon Lex に返します。

      Copy
      { "sessionAttributes": { "currentReservation": "{\"ReservationType\":\"Hotel\",\"Location\":\"Chicago\",\"RoomType\":null,\"CheckInDate\":null,\"Nights\":null}" }, "dialogAction": { "type": "Delegate", "slots": { "RoomType": null, "CheckInDate": null, "Nights": null, "Location": "Chicago" } } }

      注記

      • currentReservation – Lambda 関数は LocationChicago に設定して、このセッション属性を更新します。

      • dialogAction.typeDelegate に設定されています。ユーザーデータは有効であり、Lambda 関数は、次の一連のアクションを選択するように Amazon Lex に指示します。

       

    4. Amazon Lex は dialogAction.type に従って次の一連のアクションを選択します。Amazon Lex は、より多くのスロットデータが必要であることを知っているため、インテント設定に従って最も優先度が高い次の未指定スロット (CheckInDate) を選択します。Amazon Lex はプロンプトメッセージの 1 つ (「何日にチェックインされますか?」) を選択します。以下のレスポンスをクライアントに送信します。

      クライアントは「何日にチェックインされますか?」のメッセージを表示します。

  4. ユーザーの操作が続行され、ユーザーがデータを提供し、Lambda 関数がデータを検証して次の一連のアクションを Amazon Lex に委任します。最終的に、ユーザーはすべてのスロットデータを提供し、Lambda 関数はすべてのユーザー入力を検証し、Amazon Lex はすべてのスロットデータがそろっていることを認識します。

    注記

    この演習では、ユーザーがすべてのスロットデータを提供すると、Lambda 関数はホテル予約の価格を計算し、それを別のセッション属性 (currentReservationPrice) として返します。

    この時点で、このインテントが達成される準備ができていますが、BookHotel インテントでは、Amazon Lex がインテントを達成する前にユーザーの確認を必要とする確認プロンプトが設定されています。したがって、Amazon Lex は、ホテルを予約する前に確認をリクエストする以下のメッセージをクライアントに送信します。

    クライアントは「かしこまりました。シカゴでの 2016 年 12 月 18 日から 5 泊の滞在を承りました」のメッセージを表示します。この内容で予約いたしましょうか?」

  5. ユーザー: 「はい」

    1. クライアントは以下の PostText リクエストを Amazon Lex に送信します。

      Copy
      POST /bot/BookTrip/alias/$LATEST/user/wch89kjqcpkds8seny7dly5x3otq68j3/text "Content-Type":"application/json" "Content-Encoding":"amz-1.0" { "inputText":"Yes", "sessionAttributes":{ "currentReservation":"{\"ReservationType\":\"Hotel\", \"Location\":\"Chicago\", \"RoomType\":\"queen\", \"CheckInDate\":\"2016-12-18\", \"Nights\":\"5\"}", "currentReservationPrice":"1195" } }
    2. Amazon Lex は現在のインテントの確認のコンテキストで inputText を解釈します。Amazon Lex はユーザーが予約を進めることを望んでいることを理解しています。Amazon Lex は今回は、以下のイベントを送信して Lambda 関数を呼び出し、インテントを達成します。このイベントで invocationSourceFulfillmentCodeHook に設定することで、Amazon Lex は Lambda 関数に送信します。また、Amazon Lex は confirmationStatusConfirmed に設定しています。

      Copy
      { "messageVersion": "1.0", "invocationSource": "FulfillmentCodeHook", "userId": "wch89kjqcpkds8seny7dly5x3otq68j3", "sessionAttributes": { "currentReservation": "{\"ReservationType\":\"Hotel\",\"Location\":\"Chicago\",\"RoomType\":\"queen\",\"CheckInDate\":\"2016-12-18\",\"Nights\":\"4\"}", "currentReservationPrice": "956" }, "bot": { "name": "BookTrip", "alias": null, "version": "$LATEST" }, "outputDialogMode": "Text", "currentIntent": { "name": "BookHotel", "slots": { "RoomType": "queen", "CheckInDate": "2016-12-18", "Nights": "4", "Location": "Chicago" }, "confirmationStatus": "Confirmed" } }

      注記

      • invocationSource – Amazon Lex は今回はこの値を FulfillmentCodeHook に設定して、インテントを達成するように Lambda 関数に指示しています。

      • confirmationStatusConfirmed に設定されています。

    3. Lambda 関数は今回は BookHotel インテントを達成し、Amazon Lex は予約を完了して、次のレスポンスを返します。

      Copy
      { "sessionAttributes": { "lastConfirmedReservation": "{\"ReservationType\":\"Hotel\",\"Location\":\"Chicago\",\"RoomType\":\"queen\",\"CheckInDate\":\"2016-12-18\",\"Nights\":\"4\"}" }, "dialogAction": { "type": "Close", "fulfillmentState": "Fulfilled", "message": { "contentType": "PlainText", "content": "Thanks, I have placed your reservation. Please let me know if you would like to book a car rental, or another hotel." } } }

      注記

      • lastConfirmedReservation – Lambda 関数が追加した新しいセッション属性です (currentReservationcurrentReservationPrice ではない)。

      • dialogAction.type – Lambda 関数はこの値を Close に設定して、ユーザーの応答を期待しないことを Amazon Lex に示しています。

      • dialogAction.fulfillmentStateFulfilled に設定されていて、ユーザーに伝える適切なメッセージ (message) が含まれています。

    4. Amazon Lex は fulfillmentState を確認し、以下のレスポンスをクライアントに送信します。

      注記

      • dialogState – Amazon Lex はこの値を Fulfilledに設定しています。

      • message – Lambda 関数が提供したのと同じメッセージです。

      クライアントはそのメッセージを表示します。

データフロー: BookCar インテント

この演習の BookTrip ボットでは 2 つのインテント (BookHotel と BookCar) がサポートされています。ホテルを予約した後に、ユーザーは会話を続行して車を予約できます。セッションがタイムアウトしない限り、それ以降の各リクエストで、クライアントはセッション属性 (この例では、lastConfirmedReservation) を送信し続けます。Lambda 関数はこの情報を使用して BookCar インテントのスロットデータを初期化できます。この例では、クロスインテント情報共有でのセッション属性の使用方法を示しています。

具体的には、ユーザーが BookCar インテントを選択すると、Lambda 関数ではセッション属性にある関連情報を使用して、BookCar インテントのスロットデータ (PickUpDate、ReturnDate、および PickUpCity) が事前に設定されます。

注記

Amazon Lex コンソールでは、[Clear] リンクを使用して以前のセッション属性をクリアできます。

この手順の以下のステップに従って会話を続行します。

  1. ユーザー: 「車も予約します」

    1. クライアントは以下の PostText リクエストを Amazon Lex に送信します。

      Copy
      POST /bot/BookTrip/alias/$LATEST/user/wch89kjqcpkds8seny7dly5x3otq68j3/text "Content-Type":"application/json" "Content-Encoding":"amz-1.0" { "inputText":"also book a car", "sessionAttributes":{ "lastConfirmedReservation":""{\"ReservationType\":\"Hotel\", \"Location\":\"Chicago\", \"RoomType\":\"queen\", \"CheckInDate\":\"2016-12-18\", \"Nights\":\"5\"}" } }

      クライアントは lastConfirmedReservation セッション属性を含めます。

    2. Amazon Lex は inputText からインテント (BookCar) を検出します。このインテントも、Lambda 関数を呼び出して、初期化とユーザーデータの検証を実行するように設定されています。Amazon Lex は以下のイベントを使用して Lambda 関数を呼び出します。

      Copy
      { "messageVersion": "1.0", "invocationSource": "DialogCodeHook", "userId": "wch89kjqcpkds8seny7dly5x3otq68j3", "sessionAttributes": { "lastConfirmedReservation": "{\"ReservationType\":\"Hotel\",\"Location\":\"Chicago\",\"RoomType\":\"queen\",\"CheckInDate\":\"2016-12-18\",\"Nights\":\"4\"}" }, "bot": { "name": "BookTrip", "alias": null, "version": "$LATEST" }, "outputDialogMode": "Text", "currentIntent": { "name": "BookCar", "slots": { "PickUpDate": null, "ReturnDate": null, "DriverAge": null, "CarType": null, "PickUpCity": null }, "confirmationStatus": "None" } }

      注記

      • messageVersion – 現在 Amazon Lex でサポートされているのは 1.0 バージョンだけです。

      • invocationSource – 呼び出しの目的が初期化とユーザーデータの検証の実行であることを示しています。

      • currentIntent – インテント名とスロットが含まれています。この時点では、すべてのスロット値は null です。

    3. Lambda 関数は、すべてのスロット値が null であり、検証する対象がないことに気づきます。ただし、Lambda 関数は、セッション属性を使用して一部のスロットデータ (PickUpDateReturnDate、および PickUpCity) を初期化し、以下のレスポンスを返します。

      Copy
      { "sessionAttributes": { "lastConfirmedReservation": "{\"ReservationType\":\"Hotel\",\"Location\":\"Chicago\",\"RoomType\":\"queen\",\"CheckInDate\":\"2016-12-18\",\"Nights\":\"4\"}", "currentReservation": "{\"ReservationType\":\"Car\",\"PickUpCity\":null,\"PickUpDate\":null,\"ReturnDate\":null,\"CarType\":null}", "confirmationContext": "AutoPopulate" }, "dialogAction": { "type": "ConfirmIntent", "intentName": "BookCar", "slots": { "PickUpCity": "Chicago", "PickUpDate": "2016-12-18", "ReturnDate": "2016-12-22", "CarType": null, "DriverAge": null }, "message": { "contentType": "PlainText", "content": "Is this car rental for your 4 night stay in Chicago on 2016-12-18?" } } }

      注記

      • Lambda 関数は、lastConfirmedReservation に加えて、より多くのセッション属性 (currentReservation および confirmationContext) を含めています。

      • ユーザーから「はい/いいえ」の応答が期待されていることを Amazon Lex に通知するために、dialogAction.typeConfirmIntent に設定されています。confirmationContext が AutoPopulate に設定されているため、「はい/いいえ」のユーザー応答が、Lambda 関数で実行された初期化 (自動入力されたスロットデータ) に対するユーザーの確認を得るためであることを Lambda 関数はわかっています。

         

        また、Lambda 関数は、Amazon Lex がクライアントに返す dialogAction.message の情報メッセージをレスポンスに含めています。

        注記

        ConfirmIntent (dialogAction.type の値) という用語は、ボットのインテントとは関係ありません。この例では、ユーザーから「はい/いいえ」の応答を得るように Amazon Lex に指示するために、Lambda 関数でこの用語が使用されています。

    4. dialogAction.type に従って、Amazon Lex は以下のレスポンスをクライアントに返します。

      クライアントは「このレンタカーはシカゴでの 2016 年 12 月 18 日から 5 泊の滞在で使用されますか?」のメッセージを表示します。

  2. ユーザー: 「はい」

    1. クライアントは以下の PostText リクエストを Amazon Lex に送信します。

      Copy
      POST /bot/BookTrip/alias/$LATEST/user/wch89kjqcpkds8seny7dly5x3otq68j3/text "Content-Type":"application/json" "Content-Encoding":"amz-1.0" { "inputText":"yes", "sessionAttributes":{ "confirmationContext":"AutoPopulate", "currentReservation":"{\"ReservationType\":\"Car\", \"PickUpCity\":null, \"PickUpDate\":null, \"ReturnDate\":null, \"CarType\":null}", "lastConfirmedReservation":"{\"ReservationType\":\"Hotel\", \"Location\":\"Chicago\", \"RoomType\":\"queen\", \"CheckInDate\":\"2016-12-18\", \"Nights\":\"5\"}" } }
    2. Amazon Lex は inputText を読み取り、そのコンテキスト (自動入力の確認をユーザーに求めた) を知っています。Amazon Lex は以下のイベントを送信して Lambda 関数を呼び出します。

      Copy
      { "messageVersion": "1.0", "invocationSource": "DialogCodeHook", "userId": "wch89kjqcpkds8seny7dly5x3otq68j3", "sessionAttributes": { "confirmationContext": "AutoPopulate", "currentReservation": "{\"ReservationType\":\"Car\",\"PickUpCity\":null,\"PickUpDate\":null,\"ReturnDate\":null,\"CarType\":null}", "lastConfirmedReservation": "{\"ReservationType\":\"Hotel\",\"Location\":\"Chicago\",\"RoomType\":\"queen\",\"CheckInDate\":\"2016-12-18\",\"Nights\":\"4\"}" }, "bot": { "name": "BookTrip", "alias": null, "version": "$LATEST" }, "outputDialogMode": "Text", "currentIntent": { "name": "BookCar", "slots": { "PickUpDate": "2016-12-18", "ReturnDate": "2016-12-22", "DriverAge": null, "CarType": null, "PickUpCity": "Chicago" }, "confirmationStatus": "Confirmed" } }

      ユーザーが「はい」と応答しているため、Amazon Lex は confirmationStatusConfirmed に設定します。

    3. confirmationStatus によって、Lambda 関数は事前入力されていた値が正しいことを知っています。Lambda 関数は以下を実行します。

      • currentReservation セッション属性を、事前入力されていたスロット値に更新します。

      • dialogAction.typeElicitSlot に設定します。

      • slotToElicit の値を DriverAge に設定します。

      以下の応答が送信されます。

      Copy
      { "sessionAttributes": { "currentReservation": "{\"ReservationType\":\"Car\",\"PickUpCity\":\"Chicago\",\"PickUpDate\":\"2016-12-18\",\"ReturnDate\":\"2016-12-22\",\"CarType\":null}", "lastConfirmedReservation": "{\"ReservationType\":\"Hotel\",\"Location\":\"Chicago\",\"RoomType\":\"queen\",\"CheckInDate\":\"2016-12-18\",\"Nights\":\"4\"}" }, "dialogAction": { "type": "ElicitSlot", "intentName": "BookCar", "slots": { "PickUpDate": "2016-12-18", "ReturnDate": "2016-12-22", "DriverAge": null, "CarType": null, "PickUpCity": "Chicago" }, "slotToElicit": "DriverAge", "message": { "contentType": "PlainText", "content": "How old is the driver of this car rental?" } } }
    4. Amazon Lex は以下のレスポンスを返します。

      クライアントは「このレンタカーを運転される方の年齢を教えていただけますか?」のメッセージを表示します。会話が続行されます。