Amazon Lex
開発者ガイド

会話コンテキストの管理

会話コンテキストは、インテントを達成するためにユーザー、アプリケーション、または Lambda 関数から Amazon Lex ボットに提供される情報です。会話コンテキストには、ユーザーが提供するスロットデータ、クライアントアプリケーションによって設定されるリクエスト属性、クライアントアプリケーションと Lambda 関数で作成するセッション属性が含まれます。

セッション属性の設定

セッション属性 には、セッション中にボットとクライアントアプリケーションの間でやり取りされるアプリケーション固有の情報が含まれます。Amazon Lex は、ボットに設定されているすべての Lambda 関数にセッション属性を渡します。Lambda 関数でセッション属性が追加または更新されると、Amazon Lex からクライアントアプリケーションに新しい情報が返されます。以下に例を示します。

ボットの初期化、プロンプトやレスポンスカードのカスタマイズには、Lambda 関数のセッション属性を使用します。例:

  • 初期化 — ピザの注文ボットにおいて、PostContent オペレーションまたは PostText オペレーションへの最初の呼び出しで、クライアントアプリケーションはユーザーの場所をセッション属性として渡します。たとえば、"Location": "111 Maple Street" と指定します。Lambda 関数は、この情報に基づいて最寄りのピザ屋を見つけ、注文を行います。

  • プロンプトのカスタマイズ — セッション属性を参照するようにプロンプトとレスポンスカードを設定します。例: 「[FirstName] 様、トッピングは何になさいますか?」 ユーザーの名前をセッション属性 ({"FirstName": "Jo"}) として渡すと、Amazon Lex はプレースホルダをその名前に置き換えます。次に、カスタマイズしたプロンプトをユーザーに送信します: 「Jo 様、トッピングは何になさいますか?」

セッション属性は、セッションの期間にわたって保持されます。 Amazon Lex は、セッションが終わるまで、セッション属性を暗号化されたデータストアに保存します。クライアントは、PostContent オペレーションまたは PostText オペレーションを呼び出し、sessionAttributes フィールドに値を設定することで、リクエストのセッション属性を作成できます。Lambda 関数は、レスポンスのセッション属性を作成できます。クライアントまたは Lambda 関数でセッション属性を作成すると、クライアントアプリケーションで Amazon Lex へのリクエストに sessionAttribute フィールドを指定しない場合に、いつでも保存された属性値が使用されます。

たとえば、2 つのセッション属性 {"x": "1", "y": "2"} があるとします。クライアントが PostContent オペレーションまたは PostText オペレーションを呼び出すときに sessionAttributes フィールドを指定しない場合、Amazon Lex は保存されたセッション属性 ({"x": 1, "y": 2}) を使用して Lambda 関数を呼び出します。Lambda 関数からセッション属性が返されない場合、Amazon Lex は保存されたセッション属性をクライアントアプリケーションに返します。

クライアントアプリケーションまたは Lambda 関数のいずれかがセッション属性を渡すと、Amazon Lex は保存されたセッション属性を更新します。既存の値 {"x": 2} などを渡すと、保存された値が更新されます。新しい一連のセッション属性 ({"z": 3} など)を渡すと、既存の値は削除され、新しい値のみが保持されます。空のマップ {} を渡すと、保存された値が消去されます。

セッション属性を Amazon Lex に送信するには、属性の文字列間マップを作成します。セッション属性のマッピング方法を以下に示します。

{ "attributeName": "attributeValue", "attributeName": "attributeValue" }

PostText オペレーションの場合は、次に示すように、[sessionAttributes] フィールドを使用してリクエストの本文にマップを挿入します。

"sessionAttributes": { "attributeName": "attributeValue", "attributeName": "attributeValue" }

PostContent オペレーションの場合は、マップを base64 エンコードし、それを x-amz-lex-session-attributes ヘッダーとして送信します。

バイナリまたは構造化されたデータをセッション属性で送信する場合は、最初にデータを単純な文字列に変換する必要があります。詳細については、「複雑な属性の設定」を参照してください。

リクエスト属性の設定

リクエスト属性は、リクエスト固有の情報を示し、現在のリクエストにのみ適用されます。クライアントアプリケーションは、この情報を Amazon Lex に送信します。セッション全体を通しては保持する必要がない情報は、リクエスト属性を使用して渡します。リクエスト属性は、独自に作成することも、事前定義されたものを使用することもできます。リクエスト属性を送信するには、PostContentx-amz-lex-request-attributes ヘッダーを使用するか、PostText リクエストのrequestAttributes フィールドを使用します。セッション属性とは異なり、リクエスト属性は複数のリクエストにわたって保持されないため、PostContent レスポンスや PostText レスポンスで返されることはありません。

注記

複数のリクエストにわたって保持される情報を送信するには、セッション属性を使用します。

名前空間 x-amz-lex: は、事前定義されたリクエスト属性用に予約されています。リクエスト属性をプレフィックス x-amz-lex: で作成しないでください。

事前定義されたリクエスト属性の設定

Amazon Lex には、ボットに送信される情報の処理方法を管理するための事前定義されたリクエスト属性があります。事前定義されたリクエスト属性は、セッション全体にわたって保持されないため、リクエストごとに属性を送信する必要があります。すべての事前定義された属性は x-amz-lex: 名前空間にあります。

Amazon Lex には、以下の定義済み属性に加えて、メッセージングプラットフォーム用の定義済み属性が用意されています。これらの属性のリストについては、「メッセージングプラットフォームで Amazon Lex ボットをデプロイする」を参照してください。

レスポンスタイプの設定

異なる機能を持つクライアントアプリケーションが 2 つある場合は、レスポンスのメッセージ形式の制限が必要な場合もあります。たとえば、ウェブクライアントに送信するメッセージをプレーンテキストに制限し、モバイルクライアントではプレーンテキストと音声合成マークアップ言語 (SSML) の両方を使用できるようにしたいといった場合も考えられます。PostContentPostText オペレーションが返すメッセージの形式を設定するには、x-amz-lex:accept-content-types" リクエストの属性を使用します。

次のメッセージタイプを任意に組み合わせて属性を設定することができます。

  • PlainText—メッセージには UTF-8 形式テキストが含まれています。

  • SSML—メッセージには音声出力のテキスト形式が含まれています。

  • CustomPayload—メッセージにはクライアント用に作成したカスタム形式が含まれています。アプリケーションのニーズを満たすようにペイロードを定義することができます。

Amazon Lex はレスポンスの Message フィールドで指定したタイプを使用するメッセージのみを返します。カンマで区切れば複数の値を設定できます。メッセージグループを使用している場合は、各メッセージグループで少なくとも 1 つ指定したタイプのメッセージが含まれている必要があります。それ以外の場合は、NoUsableMessageException エラーが発生します。詳細については、「メッセージグループ」を参照してください。

注記

x-amz-lex:accept-content-types リクエストの属性は、HTML 本文のコンテンツには影響しません。PostText オペレーションのレスポンスの内容は常に UTF-8 形式テキストです。PostContent オペレーションレスポンスの本文には、リクエストの Accept ヘッダーで設定した形式のデータが含まれています。

優先タイムゾーンの設定

ユーザーのタイムゾーンを基準として日付を解決するようにタイムゾーンを設定するには、x-amz-lex:time-zone リクエスト属性を使用します。x-amz-lex:time-zone 属性にタイムゾーンを指定しないと、ボットで使用しているリージョンに応じたデフォルトのタイムゾーンが使用されます。

リージョン デフォルトのタイムゾーン
米国東部(バージニア北部) America/New_York
米国西部 (オレゴン) America/Los_Angeles
欧州 (アイルランド) Europe/Dublin

たとえば、「Which day would you like your package delivered? (何日にパッケージを配達しますか ?)」というプロンプトに対して、ユーザーがレスポンスで tomorrow と回答した場合、パッケージを配達する実際の日付は、ユーザーのタイムゾーンによって異なります。たとえば、ニューヨークの 9 月 16 日 01:00 時は、ロサンゼルスの 9 月 15 日 22:00 時です。ロサンゼルスにいる人物が、デフォルトタイムゾーンを使用してパッケージの配達日を「明日」に指定した場合、パッケージは 16 日ではなく、17 日に配達されます。x-amz-lex:time-zone リクエスト属性を America/Los_Angeles に設定すると、パッケージは 16 日に配達されます。

属性は、IANA (Internet Assigned Number Authority) のタイムゾーン名のいずれかに設定できます。タイムゾーン名のリストについては Wikipedia の「List of tz database time zones」をご覧ください。

ユーザー定義のリクエスト属性の設定

ユーザー定義のリクエスト属性は各リクエストでボットに送信するデータです。この情報を送信するには、PostContent リクエストの amz-lex-request-attributes ヘッダーを使用するか、PostText リクエストの requestAttributes フィールドを使用します。

リクエスト属性を Amazon Lex に送信するには、属性の文字列間マップを作成します。リクエスト属性のマッピング方法を以下に示します。

{ "attributeName": "attributeValue", "attributeName": "attributeValue" }

PostText オペレーションの場合は、次に示すように、[requestAttributes] フィールドを使用してリクエストの本文にマップを挿入します。

"requestAttributes": { "attributeName": "attributeValue", "attributeName": "attributeValue" }

PostContent オペレーションの場合は、マップを base64 エンコードし、それを x-amz-lex-request-attributes ヘッダーとして送信します。

バイナリまたは構造化されたデータをリクエスト属性で送信する場合は、最初にデータを単純な文字列に変換する必要があります。詳細については、「複雑な属性の設定」を参照してください。

セッションタイムアウトの設定

会話セッションが終了するまで、Amazon Lex はコンテキスト情報 (—スロットデータとセッション属性—) を保持します。ボットのセッションの長さを制御するには、セッションタイムアウトを設定します。デフォルトでは、セッションの所要時間は 5 分ですが、0〜1,440 分 (24 時間) の間で任意の所要時間を指定できます。

たとえば、OrderShoesGetOrderStatus などのインテントをサポートする ShoeOrdering ボットを作成したとします。Amazon Lex は、ユーザーのインテントが靴の注文であることを検出すると、スロットデータを求めます。たとえば、靴のサイズ、色、ブランドなどを求めます。ユーザーがスロットデータの一部のみを指定して靴の購入を完了しない場合、Amazon Lex はセッションが終わるまで、すべての指定されたスロットデータとセッション属性を記憶します。ユーザーは、セッションの有効期限が切れる前にセッションに戻った場合、残りのスロットデータを指定して購入を完了できます。

セッションタイムアウトは、ボットの作成時に Amazon Lex コンソールで設定します。AWS コマンドラインインターフェイス (AWS CLI) または API では、PutBot オペレーションを使用してボットを作成または更新するときに、idleSessionTTLInSeconds フィールドを設定してタイムアウトを設定します。

インテント間での情報の共有

Amazon Lex では、インテント間で情報の共有をサポートしています。インテント間で共有するには、セッション属性を使用します。

たとえば、ShoeOrdering ボットのユーザーが靴の注文を開始したとします。ボットは、ユーザーと会話することで靴のサイズ、色、ブランドなどのスロットデータを集めます。ユーザーが注文を行うと、その注文を処理する Lambda 関数では、注文番号を含む orderNumber セッション属性を設定します。注文のステータスを取得するために、ユーザーは GetOrderStatus インテントを使用します。ボットは、ユーザーに発注番号や注文日などのスロットデータを求めます。ボットは、必要な情報を入手すると、注文のステータスを返します。

ユーザーが同じセッション中にインテントを変更すると予想される場合は、最新の注文のステータスを返すようにボットを設計できます。ユーザーに対して注文情報を再度求める代わりに、orderNumber セッション属性を使用してインテント間で情報を共有し、GetOrderStatus インテントを達成できます。ボットでは、そのためにユーザーの最後の注文のステータスを返します。

クロスインテント情報共有の例については、「ボットの例: BookTrip」を参照してください。

複雑な属性の設定

セッション属性およびリクエスト属性は、属性と値の文字列間マップです。多くの場合、文字列マップを使用してクライアントアプリケーションとボットの間で属性値を転送できます。ただし、場合によっては、文字列マップに容易に変換できないバイナリデータや複雑な構造の転送が必要になることもあります。たとえば、次の JSON オブジェクトは米国の最も人口が多い 3 つの都市の配列を示しています。

{ "cities": [ { "city": { "name": "New York", "state": "New York", "pop": "8537673" } }, { "city": { "name": "Los Angeles", "state": "California", "pop": "3976322" } }, { "city": { "name": "Chicago", "state": "Illinois", "pop": "2704958" } } ] }

このデータの配列は、文字列間マップに適切に変換されません。このような場合は、オブジェクトを単純な文字列に変換し、その文字列を PostContent オペレーションと PostText オペレーションを使用してボットに送信できます。

たとえば、JavaScript を使用している場合は、JSON.stringify オペレーションを使用してオブジェクトを JSON に変換し、JSON.parse オペレーションを使用して JSON テキストを JavaScript オブジェクトに変換します。

// To convert an object to a string. var jsonString = JSON.stringify(object, null, 2); // To convert a string to an object. var obj = JSON.parse(JSON string);

セッション属性を PostContent オペレーションで送信するには、次の JavaScript コードに示すように、セッション属性を base64 エンコードしてからリクエストヘッダーに追加する必要があります。

var encodedAttributes = new Buffer(attributeString).toString("base64");

バイナリデータを PostContent オペレーションと PostText オペレーションに送信する場合は、最初にバイナリデータを base64 エンコードされた文字列に変換し、次にその文字列をセッション属性の値として送信します。

"sessionAttributes" : { "binaryData": "base64 encoded data" }