コンポジット・バッグ・エンティティの構成

コンポジット・バッグ・エンティティは、「エンティティの解決」または「共通レスポンス」の1つのコンポーネントのみを使用して解決できるため、このエンティティによって、はるかに短く、簡潔なダイアログ・フロー定義を作成できます。

ビジネス・トランザクションの実行に必要なユーザー入力すべてを取得するためのスイッチや変数の設定などのコンポーネントが不要になるため、このアプローチを使用することをお薦めします。かわりに、1つのコンポーネントで、バッグ内の各アイテムの値を指定するようユーザーに求めることができます。プロンプト自体は、各バッグ・アイテムの個別の構成に基づくため、条件固有です。コンポジット・バッグ・エンティティ、エンティティ・イベント・ハンドラまたはApache FreeMarker、およびCommon ResponseコンポーネントまたはResolve Entitiesコンポーネントを使用して、スキルは次のことを実行できます:
  • STRING、ATTACHMENTおよびLOCATIONアイテムにより、すべてのフリー・テキストを取得し、ファイルのアップロードを許可し、ユーザーの現在のロケーションを収集します。

  • バッグ内の各メンバー・エンティティについて個別の動作を実行します。コンポジット・バッグ(カスタム・エンティティ、システム・エンティティ、およびSTRING、ATTACHMENTおよびLOCATIONアイテムを含む)内の個々のエンティティについて、値固有のプロンプトやエラー・メッセージを追加できます。また、ユーザー入力と一致するようにする(または一致しないようにする)エンティティを制御することもできます。プロンプト・シーケンスを作成できるため、スキルは、ユーザーの試行ごとに異なるプロンプトを出力できます。

  • 複数選択ピック・リストを提示します。

  • 検証ルールに基づいて値の一致を検証します。

  • アンハッピー・フローをサポートします。ユーザーは、以前のエントリを修正できます。

  • 一時的な、一致ベースの遷移を実行します。エンティティが一致したときに、別の状態でRESTコールなどの補助機能を実行できるように、ダイアログ・フローは一時的にコンポーネントから抜けることができます。機能が完了すると、値の照合を続行できるように、ダイアログ・フローは遷移してコンポーネントに戻ります。例:
    • ユーザーが領収書をアップロードしたら、領収書自体をスキャンして、バッグ内の他のエンティティのために経費日付、金額、経費タイプなどの値をそこから抽出できるようにする必要があります。これにより、コンポーネントは、ユーザー入力からではなく、領収書から残りの値を書き込むことができるようになります。

    • スキルは、バッグ内のエンティティの一致セットの間に「もう少しです。質問はあと数問です」のようなメッセージを出力します。

    • ユーザー入力は、バックエンドRESTコールを介して検証する必要があります。どのバッグ・アイテムでさらにユーザー入力を求める必要があるかを検証によって決定するため、検証がすぐに必要になる場合があります。または、ポリシー違反の警告など、ユーザーと共有する必要がある情報がコールによって返される場合もあります。

  • 値のあいまい性を解消します。エンティティ固有のプロンプトおよびコンポーネント・プロパティによって、ユーザー入力から値を分離できます。これには、以前の入力の修正(アンハッピー・フロー)および特定の組込みエンティティ・プロパティに関するユーザー入力の要求のサポートが含まれます。

コンポジット・バッグ・エンティティの作成

  1. サイド・ナビゲーション・バーで「エンティティ」これは「エンティティ」アイコンのイメージです。をクリックします。

  2. 「エンティティの追加」をクリックします。

  3. エンティティ・タイプとして「コンポジット・バッグ」を選択します。

  4. 名前と説明を入力します。
  5. エンティティ・イベント・ハンドラを使用してコンポジット・バッグのプロンプトおよびロジックをプログラムで実行する場合は、「+イベント・ハンドラ」をクリックします。
  6. 「+バッグ・アイテム」をクリックして、「バッグ・アイテムの追加」ダイアログを開きます。組込みエンティティまたは既存のカスタム・エンティティを追加する場合は、それにバッグ固有の名前を作成し、コンポジット・バッグのコンテキスト内でのその役割の説明を追加できます。

  7. バッグには、カスタム・エンティティ、組込みエンティティおよび次のものを含めることができます:
    • STRING—ユーザーからのフリー・テキストを取得します。

    • LOCATION—ユーザーのロケーションを取得します。

    • ATTACHMENT—ユーザーによってアップロードされたファイル、オーディオ・ファイル、ビデオまたはイメージ・ファイルを受け入れます。コンポジット・バッグ・エンティティには、アタッチメントがホストされているURLが格納されます。

    ノート

    DATE_TIMEエンティティを追加すると、サブタイプの入力を求められます。
    項目は、追加した順に変換されます。ただし、コンポジット・バッグの個々のメンバーを構成する方法に応じて、順序に影響が生じることがあります。
  8. 「閉じる」をクリックすると、「エンティティ」ページに戻りますが、先にバッグ固有の他の機能をアイテムに追加できます(または、「エンティティ」ページでこれは「編集」アイコンのイメージです。をクリックして後で更新することもできます)。

  9. 次のステップ:
    • バッグ・アイテムについて個別のエラー・メッセージ、あいまい性解消のプロンプトまたは条件付きプロンプトを追加します。
      ノート

      これらは、エンティティをコンポジット・バッグに追加すると上書きされます。
    • エンティティをインテントに追加します。インテントへのエンティティの追加を参照してください。

    • コンポジット・バッグ・エンティティを使用するようにダイアログ・フローを構成します。

拡張スロット充填

「設定」「構成」「拡張スロット充填の使用」をオンにして拡張スロット充填を有効にする場合:
  • 現在解決中のアイテムのみが更新されます。一致が複数のバッグ・アイテムに適用されると、現在解決されているバッグ・アイテムが他のアイテムより優先されます。拡張スロット充填をオフにすると、すべてのアイテムが同じ値で更新されます。
  • 現在の解決アイテムがSTRINGバッグ・アイテムである場合、他のバッグ・アイテムは更新されません。
  • エンティティの一致が複数の(解決されていない)バッグ・アイテムに適用される場合、曖昧さ回避ダイアログが表示され、ユーザーはすべてのバッグ・アイテムを更新するのではなく、どのアイテムを更新するかを選択できます。
  • エンティティの「あいまい化の要求」スイッチは無視されます。エンティティ・イベント・ハンドラを使用して、カスタムの明確化を実装することをお薦めします。
ノート

プラットフォームのバージョン22.08を使用して作成されたスキルの場合、「拡張スロット・フィリングの使用」トグルはデフォルトでオンに切り替えられます。このバージョンにアップグレードされたスキルの場合はオフに切り替えられます。

プロンプトの追加

1つのプロンプトを追加することも、ユーザーが無効な値を入力するたびにそれぞれのプロンプトで次第に詳細な情報を提供していく一連のプロンプトを作成することもできます。デフォルトではプロンプトは有効です。このようなプロンプトを追加するには:
  1. プロンプトを有効にする場合は、「値のプロンプト」フィールドを空白(デフォルトの状態)のままにします。「値のプロンプト」フィールドにfalseと入力すると、プロンプトは表示されません。条件値の入力を要求するには、true (プロンプト)またはfalseに評価されるFreeMarkerブール式を追加します。

    ヒント:

    「値のプロンプト」falseに設定しても、「順不同の抽出」を有効にすると、入力を要求されている別のアイテムの一部としてアイテムを解決できます。
  2. 「プロンプトの追加」をクリックして、プロンプト・シーケンスを作成します。ドラッグ・アンド・ドロップ・ジェスチャを使用してフィールドをシャッフルするか、番号を付けなおすことによって、プロンプトの順序を変更できます。2つ以上のプロンプトに同じ番号を付けると、プロンプトの出力をランダム化できます。
    ノート

    組込みエンティティのプロンプトは、それらをコンポジット・バッグに追加する場合にのみ追加できます。
    プロンプトは、リソース・バンドル(たとえば、${rb.askCheese})に格納することも、テキストとFreeMarker式の組合せとして記述することもできます。

Apache FreeMarker式を使用したスロット済値の更新

「更新可能」フィールドに、コンポジット・バッグ・アイテムのスロットされた値を更新できるように、trueと評価されるApache FreeMarker式を入力します。

順不同の抽出の有効化

順不同抽出では、コンポジット・バッグがユーザーに値の入力を促したかどうかに関係なく、会話の任意の時点でコンポジット・バッグ・アイテムの値のスロッティングおよび更新が可能になります。次のルールを使用して、任意のアイテムまたはアイテム・サブタイプ(DATE_TIMEサブタイプなど)の会話の任意の時点で値をスロットまたは変更する方法、いつ、またはいつ、どのように設定するかを設定できます。
  • 常時– デフォルトのオプション。アイテムに対してこのオプションを選択すると、プロンプトを表示せずにその値をスロットに入れることができます。たとえば、顧客が「ピザの「大」がほしい」と入力したときに、PizzaSizeエンティティが解決されたとします。このオプションでは、「更新可能」プロパティの式がfalseに評価されない場合、項目値をいつでも変更できます。たとえば、コンポジット・バッグがPizzaTypeエンティティの入力を求めたときに、顧客は「野菜をお願いします。でも、「中」にしてください」と応答します。バッグのPizzaSizeおよびPizzaTypeアイテムに対して「常に」が有効になっているため、スキルは、会話を再開することなくPizzaSizeエンティティの値を「中」に更新できます。
    ノート

    このオプションはデフォルトの動作ですが、必ずしもSTRINGアイテムに適しているとはかぎりません。たとえば、STRINGアイテムに対してこのオプションを選択した場合、最初のユーザー・メッセージは、目的のエンティティによって照合されるのではなく、STRINGアイテムによって格納されます(これは、解決するバッグ内の最初のアイテムとして指定される場合があります)。
  • なし– このオプションを選択すると、アイテムは、他のユーザー・メッセージに有効な値が含まれている場合でも、入力を求められた後にのみスロットされます。不注意一致を防止するには、「なし」を選択します。
  • インテント発話を解決する場合のみ– 順不同値のスロットを、コンポジット・バッグ・エンティティに関連付けられているインテントに解決された最初のユーザー発話に制限します。
次に、PizzaToppingsコンポジット・バッグ・アイテムに適用される順序外抽出ルールの例を示します。
故障した抽出ルール 初期ユーザー発話 スロット値 ノート
常時 マグロでピザを注文 マグロ PizzaToppingsアイテムの値のスロッティングは、ユーザー・メッセージに正しい値(かわりにMushrooms!)が含まれるたびに照合できます。プロンプトを表示せずに、会話の任意の時点でスロッティングまたは更新できます。
使用しない マグロでピザを注文 なし PizzaToppingアイテムの値は、順不同のスロットまたはアド・ホックの更新はできません。照合できるのは、入力を求められた場合のみです。
インテント発話を解決する場合のみ マグロでピザを注文 マグロただし、ユーザーが「Order large pizza」と入力した場合、コンポジット・バッグはPizzaTopping値の入力を要求する必要があります。 PizzaToppingアイテムは、インテントに解決される最初のユーザー発話の値が一致する場合にのみ、順不同でスロットできます。そうでない場合は、この値の入力を求められる必要があります。コンポジット・バッグでは、このアイテムのアドホック更新またはスロッティングは許可されません。

「次を使用して抽出」の有効化

「次を使用して抽出」オプションを使用すると、スキルは、バッグ・アイテムを解決する際にバッグ内の別のアイテムについて入力された入力を使用できます。このオプションにより、関連する値をスキルが処理できるようになるため、ユーザー入力の柔軟性が高まります。たとえば、ユーザーは、完全な住所のかわりに「自宅」と入力できます。方法は次のとおりです:
  • このコンポジット・バッグには、住所に関連する2つのエンティティがあります: 自宅やオフィスなどの値を持つリスト値エンティティであるNamedAddressと、ADDRESSエンティティであるDeliveryAddressです。
  • DeliveryAddressエンティティのプロンプトは、「配達先はどこにしますか。」です
  • NamedAddressエンティティでは、入力は要求されません(「値のプロンプト」フィールドにfalseが入力されています)。
  • NamedAddressエンティティは、DeliveryAddressを使用して抽出できます(「次を使用して抽出」メニューから「DeliveryAddress」が選択されています)。

コンポジット・バッグは、DeliveryAddressエンティティの値の入力を要求した際に、物理的な住所、またはNamedAddressリスト値(自宅またはオフィス)のいずれかを使用して、このエンティティを解決できます。

検証ルールの追加

バッグ内の各アイテムに独自の検証ルールを設定できます。検証ルールを追加するには、まず「+検証ルール」をクリックし、次にFreeMarker式とテキスト・プロンプトを追加します。式は、次のパターンを使用してアイテム値を参照します。varNameは、ダイアログ・フロー定義で変数として宣言されているコンポジット・バッグ・エンティティの名前です:
${varName.value.itemName}
この式がfalseに評価された場合、ユーザー入力は無効です。
次に示す検証式の例は、Amountというアイテムのものです。これは、組込みエンティティであるCURRENCYです。比較に使用する数値の金額を返すために、この式ではCURRENCYエンティティのamountプロパティが追加されています:
${expense.value.Amount.amount > 4}
対応する検証メッセージにも、FreeMarker式を介してユーザー入力を反映させることができます。たとえば、次のメッセージでは、ユーザーの入力から抽出された通貨のタイプが検証メッセージの一部として使用されています:
Amounts below 5 ${expense.value.Amount.currency} cannot be expensed. Enter a higher amount or type 'cancel'.
その他のCURRENCYプロパティ(およびその他の組込みエンティティ・プロパティ)の詳細は、組込みエンティティとそのプロパティを参照してください。

コンポジット・バッグ・エンティティのYAMLダイアログ・フローの構成

スキルがYAMLダイアログ・モードで開発されている場合は、コンポジット・バッグ・エンティティのダイアログ・フローを構成するために必要な操作を次に示します:

  1. contextノードで、コンポジット・バッグ・エンティティを変数として宣言します:
    ...
    metadata:
      platformVersion: "1.1"
    main: true
    name: "ExpenseBot"
    context:
      variables:
        expense: "Expense"
        iResult: "nlpresult"
  2. System.ResolveEntitiesまたはSystem.CommonResponseを使用できます。これらのどちらのコンポーネントでもコンポジット・バッグ・エンティティを利用でき、どちらにも独自の利点があります。この2つの中では、プロパティの数が少ないSystem.ResolveEntitiesのほうが単純です。System.ResolveEntitiesコンポーネントとは異なり、System.CommonResponseでは、バッグ内のエンティティの解決に使用されるUIをより細かく制御できます。たとえば、プロンプトおよび値関連のグローバル・アクションを決定するための条件ロジックを追加できます。

    ヒント:

    コンポジット・バッグ・エンティティを使用すると、System.CommonResponseコンポーネントのメタデータが非常に複雑になる可能性があるため、かわりにSystem.ResolveEntitiesコンポーネントを使用し、UIのカスタマイズにはエンティティ・イベント・ハンドラを使用することをお薦めします。
  3. コンポーネントのvariableプロパティでコンポジット・バッグ・エンティティのコンテキスト変数を参照し、必要に応じて他のプロパティを定義します。System.ResolveEntitiesおよびコンポーネントのプロパティでは、それらのプロパティについて説明するとともに、詳細な例を提供しています。

    System.ResolveEntitiesコンポーネントの例を次に示します:
    createExpense:
        component: "System.ResolveEntities"
        properties:
          variable: "expense"
          useFullEntityMatches: true
          nlpResultVariable: "iResult"
          cancelPolicy: "immediate"
        transitions:
          actions:
            cancel: "cancelExpense"
          return: "done"          

system.entityToResolve変数

system.entityToResolve変数は、エンティティの解決コンポーネントおよび共通レスポンス・コンポーネントによって実行されるエンティティ解決プロセスの現在のステータスに関する情報を提供します。メッセージをカスタマイズする場合は、通常、共通レスポンス・コンポーネントのメタデータでこの変数値のプロパティを参照します。これを使用して、エンティティのエラー・メッセージのロジックや、エンティティの解決および共通レスポンス・コンポーネントに属する様々なプロパティのロジックを定義できます。現在のエンティティ値を返すには、次のプロパティを追加します:
  • userInput
  • prompt
  • promptCount
  • updatedEntities
  • outOfOrderMatches
  • disambiguationValues
  • enumValues
  • needShowMoreButton
  • rangeStartVar
  • nextRangeStart
FreeMarker式のプロパティは、prompterrorMessage、検証ルールなどのバッグ・アイテム・プロパティを使用することもできます。
この変数を使用してエンティティのエラー・メッセージで現在のユーザー入力を返す例を次に示します:
Sorry,'${system.entityToResolve.value.userInput!'this'}' is not a valid pizza size.
様々なsystem.entityToResolve定義の使用例を次に示します。その中に、textプロパティに対して定義されたメッセージがあります。これは、Apache FreeMarkerのlistディレクティブおよびupdatedEntitiesプロパティを使用して、以前に設定したエンティティ値に対する更新を確認します。
    metadata:
      responseItems:        
      - type: "text" 
        text: "<#list system.entityToResolve.value.updatedEntities>I have updated <#items as ent>${ent.description}<#sep> and </#items>. </#list><#list system.entityToResolve.value.outOfOrderMatches>I got <#items as ent>${ent.description}<#sep> and </#items>. </#list>"
      - type: "text" 
        text: "${system.entityToResolve.value.prompt}"
        actions:
        - label: "${enumValue}"
          type: "postback"
          iteratorVariable: "system.entityToResolve.value.enumValues"
グローバル・アクションの場合、この変数でneedShowMoreButtonrangeStartVarおよびnextRangeStartプロパティを使用して「さらに表示」グローバル・アクションが制御されます:
        globalActions: 
        - label: "Show More"
          type: "postback" 
          visible:
            expression: "${system.entityToResolve.value.needShowMoreButton}"
          payload:
            action: "system.showMore"
            variables: 
              ${system.entityToResolve.value.rangeStartVar}: ${system.entityToResolve.value.nextRangeStart} 
        - label: "Cancel"
          type: "postback" 
          visible:
            onInvalidUserInput: true
          payload:
            action: "cancel"
「さらに表示」ラベルには、system.showMore (action: "system.showMore")が含まれている必要があります。そうしないと、機能しません。

entityToResolve式

説明
${system.entityToResolve.value.resolvingField} バッグ・アイテムの名前を返します。
${system.entityToResolve.value.allMatches[0].entityName} バッグ・アイテムで参照されているエンティティ名を返します。allMatches配列には、ユーザーのメッセージによって値が更新される可能性があるすべてのエンティティが含まれます。
${<variable>1.value[system.entityToResolve.value.resolvingField]} ユーザーが入力または選択したバッグ・アイテム値を返します。
${system.entityToResolve.value.userInput} ユーザーが入力したテキストを返します。この式を使用して、たとえばユーザーが無効な値を入力したときに、ユーザー入力をログに記録したり、チャットに表示できます。
${system.entityToResolve.value.outOfOrderMatches[n].entityName} 順不同で抽出されたエンティティの名前を返します。ユーザーは、「エンティティの解決」または「共通レスポンス」コンポーネントで求められる値とともに、順不同値の抽出およびコンポジット・バッグ内の他のエンティティへの更新をトリガーする追加の値を提供できます。
${system.entityToResolve.value.outOfOrderMatches[n].name} コンポジット・バッグ・アイテムの名前を返します。
${system.entityToResolve.value.outOfOrderMatches? has_content?then(…,…)} 順不同で照合されたエンティティの値を返します。順不同で照合されたエンティティがない可能性があるため、この式ではhas_content演算子が使用されます。

エンティティ・イベント・ハンドラ

エンティティ・イベント・ハンドラを使用して、コンポジット・バッグ・エンティティ項目の検証、プロンプトおよび明確化をプログラムで実行できます。エンティティ・イベント・ハンドラ(EEH)は、コンポジット・バッグ・エンティティ用に作成され、カスタム・コード・サービスとしてデプロイされるJavaScript (またはTypeScript)実装です。
ノート

EEHにデプロイされたサービスは、「コンポーネント」ページこれは左側のナビゲーション・バーの「コンポーネント」アイコンのイメージです。から管理できます。
bots-node-sdkで提供されるイベント・ハンドラ関数を定義することで、個々のバッグ・アイテムとエンティティ自体の解決動作を制御できます。たとえば、次のスニペットは、ユーザーが経費精算書を提出するときに将来の日付を入力できないExpenseDateというバッグ・アイテムに対するvalidateイベントの定義を示しています。
ExpenseDate: {

        validate: async (event, context) => {
          if (new Date(event.newValue.date) > new Date()) {
            context.addValidationError("ExpenseDate",context.translate('ExpenseDate.text'));
            return false;
          }          
        }
bots-node-sdkエンティティ・イベント・ハンドラの記述ドキュメントでは、イベント・ハンドラ・コードの全体的な構造、アイテム・レベルとエンティティ・レベルのイベント、および前述のスニペットのaddValidationErrortranslateなどのEntityResolutionContextメソッドについて説明します。

エンティティ・イベント・ハンドラはJavaScriptで記述されるため、バッグ・アイテムの編集ページおよびダイアログ・フローで検証、エラーおよびプロンプトを定義するために使用できるFreeMarker式を使用して、簡単に実現できない、または実行可能な高度なロジックを使用できます。デバッグも簡単です。しかしながら、FreeMarker式ではなくエンティティ・イベント・ハンドラを選択する必要はありません。2つを組み合せることができます。たとえば、単純な検証およびプロンプトにFreeMarker式を使用し、すべてのバッグ・アイテムが解決された場合にREST APIをコールするなど、より複雑な関数に対してEEHを予約できます。

イベント・ハンドラ・コード・エディタを使用したエンティティ・イベント・ハンドラの作成

EEHは、コンポジット・バッグのプロパティ・ページからアクセスするイベント・ハンドラ・コード・エディタまたは任意のIDEを使用して構築できます。イベント・ハンドラ・コード・エディタにはサード・パーティ・ツールよりもいくつかの利点がありますが、タスクのサイズや必要なライブラリに応じて、サード・パーティ製のIDEで代替することもできます。長所と短所の重み付けについては、「使用するIDE」を参照してください。

イベント ハンドラ コード エディタにアクセスするには、次の手順に従います。
  1. 「+イベント・ハンドラ」をクリックします。
  2. サービス名とハンドラ名を追加して、「イベント・ハンドラの作成」ダイアログに入力します。

ハンドラを作成したら、これは「編集」アイコンのイメージです。をクリックしてエディタを開くことができます。

エディタには、初期コードが移入されています。そのhandlersオブジェクトには、entityitemsおよびcustomオブジェクトが含まれます。これらのオブジェクト内で、コンポジット・バッグ全体に対してトリガーされるイベント・レベルのイベント、個々のバッグ・アイテムの解決を制御するアイテム・レベルのイベント、およびポストバック・アクションで起動されるカスタム・イベントを定義します。デフォルトでは、handlerオブジェクトにはentityオブジェクトが定義されています。itemsおよびcustomオブジェクトは、アイテム・レベルまたはカスタム・テンプレートを追加すると移入されます。
eeh-default-template.pngの説明が続きます
図eeh-default-template.pngの説明

イベント自体は、次の2つの引数をとる非同期JavaScript関数です。
  • event: イベント固有のプロパティのJSONオブジェクト。
  • context: EntityResolutionContextクラスの参照。そのメソッド(次のスニペットのaddValidationErrorなど)がイベント・ハンドラ・ロジックを提供します。
items: {
  Amount: { 
    validate: async (event, context) => {
      let amount = event.newValue.amount;
      if (amount < 5) {
        context.addValidationError("Amount",`Amounts below 5 ${event.newValue.currency} cannot be expensed. Enter a higher amount or type 'cancel'.`);
      }
    }
  }
テンプレートにアクセスするには、「+イベントの追加」をクリックします。
ノート

EEHスタータ・コード、アイテム・レベルおよびエンティティ・レベルのイベント、EntityResolutionContextおよびコード・サンプルの詳細は、bots-node-sdkエンティティ・イベント・ハンドラの作成のドキュメントを参照してください。
イベントの追加
「+イベントの追加」をクリックすると、イベント、アイテムおよびカスタム・イベントのテンプレートを追加できます。

たとえば、validateイベント・テンプレートを追加すると、次のコードがエディタに移入されます:
validate: async (event, context) => {
        
      },
その後、このテンプレートを独自のコードで更新できます:
validate: async (event, context) => {
     if (event.newValue.value === 'PEPPERONI')
       context.addValdiationError('Type', "Sorry, no pepperoni pizzas today!");     
      },
「検証」をクリックするとコードの設計時の問題がチェックされるため、このオプションを定期的にクリックする必要があります。コードが無効な場合はイベントを追加できません。また、無効なコードは保存できません。コードの保存はコードのデプロイも意味するため、無効なコードはデプロイすることもできません。

コードが有効な場合、「保存」をクリックすると自動的にデプロイされ、TGZファイルにパッケージ化されます。「コンポーネント」ページで、デプロイメントのステータスをモニターし、他のスキルで再利用するためにTGZファイルをダウンロードできます。

ヒント:

ランタイム・エラーを確認するには、「コンポーネント・ロギングの有効化」をオンにし、ログ(「診断」→「ログの表示」をクリックしてアクセス)を確認して、イベントを起動したパラメータを見つけます。
サービスをデプロイすると、コンポジット・バッグのページで、「準備完了」ステータスこれは「準備完了」ステータス・アイコンのイメージです。が表示され、コードを修正するための「編集」アイコン編集アイコンが使用できるようになります。

エンティティ・レベル・イベント・ハンドラの追加
エンティティ・レベルのイベントの場合、validatepublishMessagemaxPromptsReachedresolved attachmentReceivedおよびlocationReceivedエンティティ・レベルのイベントのテンプレートを更新できます。

イベント 説明
validate 少なくとも1つのバッグ・アイテムの値が変更されたときにコールされるエンティティ・レベルの検証のハンドラ。
publishMessage バッグ・アイテムにプロンプト・メッセージまたは曖昧さ回避処理がない場合にコールされる汎用フォールバック・ハンドラ。
maxPromptsReached 最大プロンプト数に達するためのアイテム固有のハンドラが指定されていない場合の汎用フォールバック・ハンドラ。
resolved この関数は、コンポジット・バッグ・エンティティが解決されるとコールされます。通常、resolvedイベントを追加して、コンポジット・バッグ・エンティティによって収集された値に関連するトランザクションを完了するバックエンドAPIをコールします。コンポジット・バッグによって収集された値の一部が有効でないためにAPIコールでエラーが返された場合は、これらの値をクリアできます。
attachmentReceived このハンドラは、ユーザーが添付ファイルを送信したときに呼び出されます。
locationReceived このハンドラは、ユーザーが場所を送信したときにコールされます。
デフォルトでは、テンプレートにはエンティティ・レベルのイベントpublishMessageが移入されます。このイベントでは、updatedItemMessage関数およびoutOfOrderItemsMessage関数(デフォルト・テンプレートでも定義されています)を使用して、以前に解決されたバッグ・アイテム値が更新されたこと、またはエンティティが現在プロンプトしているバッグ・アイテム以外のバッグ・アイテムに対して有効な入力を受け入れたこと(順不同入力)を確認するメッセージをスキルが出力できます。

このイベントはオプションです。削除したり、そのままにしたり、機能を追加できます。たとえば、ユーザーが有効な値の入力がプロンプトの最大数を超えた場合に、取消ボタンを追加できます。
publishMessage: async (event, context) => {
        updatedItemsMessage(context);
        outOfOrderItemsMessage(context);
        //Add Cancel button for invalid values entered by users
        let message = context.getCandidateMessageList()[0];
      }
…
message.addGlobalAction(context.getMessageFactory().createPostbackAction('Cancel', {action:'cancel'}));
        context.addMessage(message);      }
}
アイテム・レベル・ハンドラの追加
ダイアログにリストされているバッグ・アイテムに対して、アイテム・レベル・イベントのテンプレート(shouldPromptvalidatepublishPromptMessagepublishDisambiguateMessageおよびMaxPromptsReached)を追加できます。

イベント 説明
shouldPrompt バッグ内の他のアイテムの値に基づいてアイテムのプロンプトを表示します。このハンドラは、「値のプロンプト」フィールドで構成されたプロンプトよりも優先されます。
validate このハンドラがコールされるのは、バッグ・アイテムに値が設定されている場合のみです。値の有効性が他のバッグ・アイテムに依存する場合は、かわりにエンティティ・レベルのvalidateイベントを実装する必要があります。
publishPromptMessage この機能を使用して、共通レスポンスおよびエンティティの解決コンポーネントによって生成されたメッセージを置換または拡張し、アイテムの入力を求めます。
publishDisambiguateMessage この関数を使用して、共通レスポンス・コンポーネントおよびエンティティの解決コンポーネントによって生成された曖昧化解除プロンプト・メッセージを置換または拡張します。
maxPromptsReached この関数がコールされるのは、このアイテムのプロンプトの最大数(コンポジット・バッグ・アイテム画面の「ユーザー入力の最大試行回数」で指定された)に達したときです。

アイテム・レベルのイベントを追加すると、itemsオブジェクトが生成されます。
eeh-items-block.pngの説明が続きます
図eeh-items-block.pngの説明

カスタム・イベントの追加
カスタム・イベント・テンプレートを使用して、ポストバック・アクション(ボタンまたはリスト・アイテム)からコールされるカスタム・イベントを作成できます。

カスタム・テンプレートを追加すると、基本イベント・コードを含むcustomオブジェクトが追加されます。カスタム・イベントの実装例は、bots-node-sdkエンティティ・イベント・ハンドラの記述のドキュメントを参照してください。
someCustomEvent: async (event, context) => {
  
}

エンティティ・イベント・ハンドラの置換または削除

EEHを置換または削除する必要がある場合:
  1. 「イベント・ハンドラ」メニューから空の行を選択して、「+」「イベント・ハンドラ」ボタンを再アクティブ化します。

  2. 「コンポーネント」ページこれは左側のナビゲーション・バーの「コンポーネント」アイコンのイメージです。を開きます。「サービス有効」をオフにするか、サービスを削除します。
    ノート

    EEHがまだコンポジット・バッグ・エンティティに関連付けられている場合は、サービスを削除または無効にできません。
  3. 必要に応じて、新しいEEHをコンポジット・バッグに追加するか、新しいEEHを選択しない場合は、FreeMarker式を使用して解決ロジックを追加できます。

ヒント:

コンポジット・バッグ・エンティティを削除すると、EEHにデプロイされているサービスも削除されます。

使用するIDE

選択したIDEを使用してEEHを作成し、bots-node-sdk packによって手動でパッケージ化したTGZファイルを使用してコードをデプロイします。または、提供されているイベント・ハンドラ・コード・エディタを使用できます。エディタを使用する場合、開発環境を設定したり、コードをパッケージ化してデプロイしたりする必要はありません。コードを保存すると自動的にデプロイされます。コードを再デプロイせずに直接修正することもできます。これは、独自のIDEで作成されたハンドラをパッケージ化してデプロイする場合には実行できません。イベント ハンドラ コード エディタを使用してNPMパッケージを追加することはできません。別のIDEが必要になります。たとえば、Moment.jsを使用して日付を操作する場合は、TGZをダウンロードし、選択したIDEを使用してライブラリを追加してから、TGZを再パッケージ化してデプロイする必要があります。その後、イベント・ハンドラ・コード・エディタを使用して続けることができます。

ヒント:

イベント・ハンドラ・コード・エディタは、どちらかといえば小規模な変更に適したオプションです。より大きな変更を加える必要がある場合、またはNPMパッケージを追加する必要がある場合は、「コンポーネント」ページからTGZをダウンロードして解凍し、任意のエディタを使用してコードを変更してから再パッケージ化してデプロイできます。

エンティティ・イベント・ハンドラを使用したダイアログ・フローの簡略化

エンティティ・イベント・ハンドラは、コンポジット・バッグ・エンティティであるダイアログ短縮ベスト・プラクティスで使用されるため、ダイアログ・フロー定義を簡略化できます。バックエンド・サービスの場合は、ダイアログ・フロー定義をコールするカスタム・コンポーネントに個別の状態を記述する必要がないため、その定義はより複雑になります。

イベント・ハンドラでは、ダイアログ・フロー定義がもう1つの方法で簡素化されます。つまり、エンティティの解決コンポーネントによって生成されるメッセージを変更できます。たとえば、Common Responseコンポーネントのmetadataプロパティの複雑な構造を使用せずに、カード・メッセージのカルーセルを作成できます。かわりに、単純なコードを使用してカルセルを追加できます。つまり、エンティティの解決コンポーネントにカード・レスポンスを追加することもできます。たとえば、次のコードを使用すると、「エンティティの解決」コンポーネントで、横向きにスクロールするピザ・タイプのカードのカルーセルを出力できます。各カードに取消ボタンがある:
Type: {

        publishPromptMessage: async (event, context) => {
          let candidateMessage = context.getCandidateMessageList()[0];
          const mf = context.getMessageFactory();
          const message = mf.createCardMessage()
            .setLayout(horizontal)
            .setCards(context.getEnumValues().map(p => {
                      mf.createCard(p.value)
                        .setDescription(pizzaInfo[p.value].description)
                        .setImageUrl(pizzaInfo[p.value].image)
                        .addAction(mf.createPostbackAction('Order',{variables: {pizza: p.value}}));
                      })
            .setGlobalActions(candidateMessage.getGlobalActions());
          context.addMessage(message);
        }

エンティティ・イベント・ハンドラのチュートリアル

このチュートリアルに従って、エディタを使用してエンティティ・イベント・ハンドラを作成することで、エンティティ・イベント・ハンドラを理解します。次に、この高度なチュートリアルを確認し、外部IDEおよびbots-node-sdkを使用するエンティティ・イベント・ハンドラを作成します。

ネストされたバッグ・アイテムおよびサブタイプの明確化

コンポジット・バッグは常に、ネストされたバッグ・アイテムの階層構造によって決定されるアイテム順序ごとに値の入力を求められます。複数のアイテムの値を盲目的にスロットすることはできません。かわりに、ユーザー・メッセージの値と、現在プロンプトが表示されているアイテムとの照合のみが試行されます。ユーザー入力が現在のアイテムと一致しない場合、またはINTERVALサブタイプstartTimeおよびendTimeの場合のように複数のアイテムと一致する可能性がある場合、リクエストされた入力を明確にするためにLabelプロパティに定義された値をユーザーに提示します。

ヒント:

すべての文字列と同様に、「ラベル」の値をリソース・バンドルとして定義することをお薦めします。

コンポジット・バッグへのDATE_TIMEエンティティの追加

会議のスケジュールや繰返しイベントの設定など、複数のユーザー・プロンプトを必要とする複雑なシナリオをスキルで処理できるようにするには、DATE_TIMEコンポジット・バッグ・アイテムを作成し、「間隔」、「繰返し」および「日時」サブタイプの属性と、それぞれのネストされたバッグ・アイテムを構成する必要があります。
ノート

日付、時間および期間はスタンドアロン・エンティティとして使用できますが、コンポジット・バッグ・エンティティ内で使用することをお薦めします。
  1. DATE_TIMEバッグ・アイテムを作成する前に、ユース・ケースに適した日付と時間のあいまいさ解決ルールを構成します。たとえば、経費精算書スキルを作成する場合は、「過去」を選択します。スキルが会議スケジューラの場合は、「将来」を選択します。
  2. コンポジット・バッグ・エンティティ内で、「アイテムの追加」をクリックします。
  3. 「タイプ」メニューから「エンティティ」を選択します。
  4. 「エンティティ名」メニューからDATE_TIMEを選択します。
  5. 「サブタイプ」メニューからDATE_TIMEサブタイプを選択します。

    「バッグ・アイテムの追加」ページの構成オプションは、選択したサブタイプに応じて変わります。たとえば、「繰返し」サブタイプを選択した場合、繰返しイベントの設定に固有のネストされたバッグ・アイテムの構成オプション(初期開始日時の「日時」オブジェクト、イベント頻度の設定用の「期間」オブジェクトなど)にアクセスできます。

  6. 「繰返し」または「間隔」サブタイプを選択した場合:
    • コンポジット・バッグが「プロンプト対象」メニューからプロンプトするサブタイプ値を設定します。
    • 会議は通常同じ日に開始および終了するため、startDateサブタイプの「デフォルトの終了日から開始日」をオンにします。これにより、ユーザー メッセージに終了日が指定されていない(または終了日が順不同で抽出されない)場合、終了日は開始日と同じに設定されます。
      これは、「デフォルトの開始日から終了日までの切替え」のイメージです。

  7. オプションで、ユーザー入力が複数のサブタイプと一致できる場合は、曖昧さ回避ラベルを追加します。

    ヒント:

    拡張スロット充填、Apache FreeMarkerによるスロッティング値の更新、カスタム・プロンプト、エラー・メッセージなど、DATE_TIME固有ではないプロパティを構成することもできます。
  8. サブタイプ・レベルの構成にアクセスするには、サブタイプをクリックします。横断を使用して、品目レベルの構成に戻ります。
    これは、「バッグ・アイテムの編集」トラバーサルのイメージです。

  9. 次のステップ:
    • コンポジット・バッグ・エンティティをインテントに関連付けます。
    • ダイアログ・フローでエンティティの変数を宣言します。
    • ダイアログ・フローで、「コンポジット・バッグの解決」状態を使用して、DATE_TIME項目を含むコンポジット・バッグ・エンティティを参照します。
    • DATE_TIME値は、ISO 8601として表されます。わかりやすい出力には、Apache FreeMarker .xs built-inを使用します。次のスニペットでは、Timeサブタイプの値は.value?time.xs?string['hh:mm a']を使用して書式設定されます。
      Your pizza will be delivered at ${pizza.value.deliveryTime.value?time.xs?string['hh:mm a']}.
      
      DATE_TIMEアイテムを文字列として参照するかわりに、次の例のDeliveryMessageなど、リソース・バンドルでアイテムを参照するベスト・プラクティスに従うことができます。
      ${rb('DeliveryMessage','time',pizza.value.deliveryTime.value?time.xs?string['hh:mm a'])}
      
      DeliveryMessageリソース・バンドル・メッセージの場合、値は{time}パラメータを介してレンダリングされます。
      Your pizza will be delivered at {time}.
      

チュートリアル: コンポジット・バッグ・エンティティを使用した実際のエンティティ抽出

コンポジット・バッグ・エンティティを使用した実際のエンティティ抽出の有効化のチュートリアルを使用すると、コンポジット・バッグの作成を実践形式で確認できます。