1. 始める前に
この Codelab では、会話型 UI を構築するための会話型 AI プラットフォーム(CAIP)である Dialogflow CX を使用して、小売チャットボットを構築する方法を学習します。Dialogflow CX は、chatbot、音声 bot、Phone Gateway などの仮想エージェントを実装でき、50 以上の言語で複数のチャネルをサポートできます。
この Codelab では、小売業向けのウェブサイト用 chatbot を構築する方法を説明します。chatbot を構築する架空のビジネスは G-Records という名前です。G-Records は、カリフォルニアを拠点とするロック レコードレーベルです。このレーベルには、Alice Googler、G's N' Roses、The Goo Fighters、The Google Dolls の 4 つのロックバンドが所属しています。G-Records は、すべてのロック ファンにバンドのグッズを販売しています。
この Codelab の終わりには、chatbot を使用してシャツや音楽を注文したり、注文について問い合わせたりできるようになります。
学習内容
実践を通して、Dialogflow ES と比較した Dialogflow CX のメリットを学びます。次のコンセプトが含まれます。
- Google Cloud 内で Dialogflow CX 仮想エージェントを作成する方法
- フローの作成方法の詳細
- エンティティを作成する方法
- インテントの作成方法
- 状態ハンドラを使用してページを作成し、ページを遷移する方法
- インテント ルートを使用してページを遷移する方法
- パラメータと条件ルートを使用してページを遷移する方法
- システム関数を使用して条件付きレスポンスを返す方法を学習する
- フォールバック メッセージの作成方法
- シミュレータの使い方を学ぶ
- テストケースとテストカバレッジを作成する方法を学習する
最終的な Dialogflow CX エージェントの設計は次のようになります。
必要なもの
- Dialogflow CX エージェントを作成するには、Google ID または Gmail のメールアドレスが必要です。
- Google Cloud へのアクセス。
2. 環境設定
Google Cloud プロジェクトを作成する
Dialogflow CX は Google Cloud で実行されるため、Google Cloud プロジェクトを作成する必要があります。プロジェクトを使用して、すべての Google Cloud のリソースがまとめられます。プロジェクトは、共同編集者、有効化された API などのリソース、モニタリング ツール、お支払い情報、認証とアクセス制御で構成されます。
新しいプロジェクトを作成するときに、プロジェクト名を入力する必要があります。既存の請求先アカウントと組織にリンクする必要があります。
請求先アカウントは、特定のリソースセットに対する支払いをだれが行うかの定義に使用され、1 つ以上のプロジェクトにリンクできます。プロジェクトの利用料金は、リンクされた請求先アカウントに請求されます。ほとんどの場合、プロジェクトの作成時に請求情報を構成します。詳細については、お支払いとご請求に関するドキュメントをご覧ください。Cloud プロジェクトで課金が有効になっていることを確認します。
Dialogflow API を有効にする
Dialogflow を使用するには、プロジェクトで Dialogflow API を有効にする必要があります。
- API を有効にするプロジェクトを選択し、[続行] をクリックします。
- [API とサービス] のメニューを閉じて、[認証情報を作成] をクリックします。
- [アプリケーション データ] をクリックします。
- Kubernetes Engine、App Engine、Cloud Functions を現在使用していないため、いいえ、使用していませんと伝えます。
- [完了] をクリックします
新しい Dialogflow CX エージェントを作成する
新しい Dialogflow CX エージェントを作成するには、まず Dialogflow CX コンソールを開きます。
- 前に作成した Google Cloud プロジェクトを選択します。
- [Create Agent(エージェントを作成)] をクリックします。
基本的なエージェント設定に関するフォームに入力します。
- 任意の表示名を選択できます。
- ロケーションとして選択: us-central1
- 使用するタイムゾーンを選択します。
- デフォルトの言語として [en - 英語] を選択します。
[作成] をクリックします。
これで準備が整いました。いよいよ仮想エージェントのモデル化に取り掛かります。
3. フロー
多くの場合、複雑なダイアログには複数の会話トピックが含まれます。G-Records 用に構築している chatbot の場合、バンドのグッズを販売するために、商品カタログ、支払い、注文ステータス、カスタマーケアの質問に関するダイアログを表示します。これらの会話トピックをフローに分割できます。
フローを使用すると、チームは個々の会話パスで作業できます。フローを簡素化して、画面に簡単に収まり、モジュラー化を進めることをおすすめします。
フローは Dialogflow CX の新しいコンセプトです。Dialogflow Essentials には、フローと同様の概念であるメガ エージェントがあります。ただし、フローの方がはるかに頻繁に使用されます。
このラボの後半では、フローを終了できる状態ハンドラを使用します(これにより、次のフローまたは前のフローにジャンプします)。また、エージェント セッション全体を終了することもできます。
では、フローを作ってみましょう。
フローの作成
- Dialogflow CX で、+ アイコン > [Create flow] をクリックします。
- 名前として
Catalog
を指定して、Enter キーを押します。
最初のフロー カタログが作成されました。次に、他のフローを作成します。
Order Process
My Order
Customer Care
このラボで後ほどページ状態ハンドラを設定します。これにより、最終的に次のように可視化されます。
シミュレータ
Dialogflow CX コンソールの右側にある組み込みのシミュレータを使用して、仮想エージェントをテストできます。会話の最初から、または特定のフローから会話をテストできます。
- 画面右上にある [エージェントをテストする] ボタンをクリックします。
- [エージェントと話す] フィールドに「
Hello
」と入力します。仮想エージェントはデフォルトのウェルカム テキストで応答します: 「Greetings!
このデフォルトのウェルカム テキストを変更してみましょう。
デフォルトの開始フロー
まず、仮想エージェントに挨拶したときにトリガーされるインテント ルートを作成します。
- 左側の [Build] > [Flows] サイドバーで、[Default Start Flow] をクリックし、[Start] ツリーノードを選択します。
[開始] ページが開きます。サイドバーの [Build > Pages] セクションで、自動的に [Start page] が選択されました。
- [Start > Routes](開始 > ルート)で、[Default Welcome Intent](デフォルトのウェルカム インテント)をクリックします。
インテントは、1 回の会話ターンにおけるエンドユーザーの意図を分類します。Dialogflow CX では、インテントを状態ハンドラの一部として、次のアクティブなページまたはフルフィルメントに転送できます。
- [エージェントが言う] のエントリをすべて削除し、次の新しいテキストを追加します。
Welcome, I am the virtual agent of G-Records, a fictional rock label. You can order artists merchandise, ask questions about your order or shipping, and I can tell you more which artists are currently signed with us. How can I help?
会話を効率化するために、クイック返信ボタンや候補チップも必要になります。
- [ダイアログ オプションを追加] > [カスタム ペイロード] をクリックし、以下のコード スニペットを使用します。
- 以下のコード スニペットをカスタム ペイロードとして使用し、[保存] をクリックします。
カスタム ペイロードの詳細については、こちらのドキュメントをご覧ください。
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "Which artists?"
},
{
"text": "Which products?"
},
{
"text": "About my order..."
}
]
}
]
]
}
- シミュレータでウェルカム インテントをテストしましょう。
リッチ コンテンツが表示されない理由について、ご不明な点があると思います。これは、候補チップなどのリッチ コンテンツが統合に依存しているためです。次の手順では請求先アカウントが必要ですが、請求先アカウントがない場合はスキップできます。
- 左側のサイドバーで、[管理] > [統合] をクリックします。
- [Dialogflow Messenger] を選択して [接続] をクリックします。
- ポップアップで [有効にする] をクリックします。
別のポップアップが表示されます。今回は、ウェブサイトに貼り付けて Dialogflow Messenger コンポーネントをウェブサイトに統合できる統合 JavaScript コードが表示されます。まだウェブサイトがないため、ツールで直接仮想エージェントをテストします。
- [今すぐ試す] リンクをクリックします。
- 右下の chatbot アイコンをクリックして、チャット ウィンドウを開きます。
Hello
と入力して会話を開始します。
現時点では、候補チップをクリックしても、仮想エージェントはユーザーの意図を理解できません。これは、仮想エージェントがまだ状態を切り替えていないためです。Dialogflow CX では、ページを使用してこれを実現できます。ラボを続行します。まず、エンティティとインテントを作成します。
4. エンティティ タイプ
エンティティ タイプを使用して、エンドユーザー入力からデータを抽出する方法を制御します。Dialogflow CX のエンティティ タイプは Dialogflow ES のエンティティ タイプとよく似ています。Dialogflow には、多数の一般的なデータタイプに対応する事前に定義されたシステム エンティティが用意されています。たとえば、日付、時刻、色、メールアドレスなどをマッチングするためのシステム エンティティがあります。カスタムデータに対応する独自のカスタム エンティティを作成することもできます。
フローでページを設計する前に、すべてのカスタム エンティティを準備することから始めましょう。次のエンティティを作成します。
エンティティの作成
アーティスト エンティティを作成しましょう。
- [管理] > [エンティティ タイプ] をクリックします。
- [+ 作成] をクリックします。
- 表示名:
Artist
- エンティティ:
The Google Dolls
(類義語:Google Dolls
)The Goo Fighters
(類義語:Goo Fighters
)G's N' Roses
(類義語:Gs and Roses
)Alice Googler
- [詳細オプション] をクリックし、[ファジー一致] をオンにします。(バンド名のスペルが間違っていても、正しいエンティティと一致することがあります)。
- [詳細オプション] で [ログで削除] もオンにします。(バンド名のスペルが間違っている場合は、ログ内の名前が修正されます)。
- [保存] をクリックします。
また、グッズ アイテムのエンティティも必要です。
- [管理] > [エンティティ タイプ] をクリックします。
- [+ 作成] をクリックします。
- 表示名:
Merch
- エンティティ:
T-shirt
Longsleeve
(類義語:Longsleeve shirt
)Tour Movie
Digital Album
(類義語:MP3 Album
、MP3
)CD
(類義語Disc
、Physical CD
)
- [保存] をクリックします。
また、アルバムのエンティティも必要です。
- [Manage] > [Entity Types] をクリックします。
- [+ 作成] をクリックします。
- 表示名:
Album
- エンティティ:
Live
Greatest Hits
(類義語:Hits
)
- [保存] をクリックします。
また、衣料品のサイズのエンティティも必要です。
- [Manage] > [Entity Types] をクリックします。
- [+ 作成] をクリックします。
- 表示名:
ShirtSize
- エンティティ:
XS
(類義語:Extra Small
)S
(同義語:Small
)M
(類義語:Medium
)L
(類義語:Large
)XL
(類義語:Extra Large
)2XL
(類義語:Extra Extra Large
)3XL
- [保存] をクリックします。
注文番号のエンティティは、通常は 4 つの英数字と 3 つの数字です。(ABCD123 など)
- [管理] > [エンティティ タイプ] をクリックします。
- [+ 作成] をクリックします。
- 表示名:
OrderNumber
- 正規表現エンティティ
- エンティティ: [A-Z]{4}[0-9]{3}
- [保存] をクリックします。
エンティティの構成は次のようになります。
@アーティスト:
@商品:
@アルバム:
@ShirtSize:
@OrderNumber:
カスタム エンティティが準備できたら、インテントを準備します。ラボを続けましょう。
5. インテント
インテントは、1 回の会話ターンにおけるエンドユーザーの意図を分類します。Dialogflow CX では劇的に簡素化されました。会話制御の構成要素ではなくなりました。Dialogflow CX は、ユーザーの発言を照合するためにインテントのみを使用します。Dialogflow ES では、パラメータ、イベント、フルフィルメントなど、すべてをインテントに合わせる必要がありました。Dialogflow CX のインテントにはトレーニング フレーズのみが含まれるため、再利用できます。会話の制御は行われなくなります。そのため、インテントを作成するプロセスは簡単です。
インテントのトレーニング フレーズでは、エンティティを使用して「変数」入力を抽出できます。そのため、事前にエンティティ タイプを作成することをおすすめします。これは、ラボの手順の前のページで行ったことです。
インテントの作成
フローのページを設計する前に、すべてのインテントを準備することから始めましょう。
- [管理] > [Intents] をクリックします。
- [+ 作成] をクリックします。
次の情報を使用します。
- 表示名
redirect.artists.overview
- 説明文
Artists overview: The bands supported by the label
下にスクロールして、次のトレーニング フレーズを作成します。
Which bands are signed?
Which bands
Which artists
Which artists are part of the record label
Who is part of the label
From which bands can I buy merchandise
Band merchandise
Which music do you have?
I would like to know who are signed to the label
Who are supported by the label
From who can I buy shirts
What music can I order
Can I get an overview of all the artists
- [保存] をクリックします。
- 次に、他のすべてのインテントを作成します。独自の想像力を使って、トレーニング フレーズをさらに作成します。ベスト プラクティスとしては、ユーザーがそのインテントをトリガーするさまざまな方法に対応できるように、インテントごとに 10 個以上のトレーニング フレーズを用意することをおすすめします。このラボでは、それより少ない数でも問題ありません。
以下の点をご確認ください。
- トレーニング フレーズを入力すると、Dialogflow CX によってエンティティに自動的にアノテーションが付けられます。存在しない場合は、(類義語を追加して)エンティティを更新するか、トレーニング フレーズに手動でアノテーションを付ける必要があります。
- 短いトレーニング フレーズ: Dialogflow の NLU システムは短いトレーニング フレーズにも対応します。ここでは、いくつかの例を紹介します。
- 過剰トレーニング: インテントに対してトレーニング フレーズが多すぎると、過剰トレーニングが発生し、望ましくない結果になる可能性があります。ベスト プラクティスとして、反復テストと増分テストを使用し、インテント マッチがない場合はトレーニング フレーズを追加することをおすすめします。
表示名 | トレーニング フレーズ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
再利用可能な要素(フロー、エンティティ、インテント)が準備できたので、ページと状態ハンドラを作成して、これらをまとめることができます。
6. ページと状態ハンドラ
Dialogflow CX の会話(セッション)は、有限状態マシンとして記述し、可視化できます。自動販売機を例にとると、有限ステートマシンとしてモデル化できます。ステータスは、"Waiting for Coins]、[Select Candy]、[Give Candy] です。一連の入力を与えられると、これらの状態間を移動します。たとえば、コインを挿入すると、自動販売機は [コインを待機中] から [キャンディを選択] に移動します。ページでは、Dialogflow CX 仮想エージェントのこれらの状態をモデル化できます。
エンドユーザーが会話で Dialogflow CX を操作すると、会話はページ間で移動します。そのため、どの時点でも、正確に 1 つのページが現在のページであり、現在のページがアクティブとみなされ、そのページに関連付けられたフローがアクティブとみなされます。
フローごとに多数のページを定義します。結合されたページでは、フローが設計されたトピックに関する完全な会話を処理できます。すべてのフローには特別なスタートページがあります。フローが最初にアクティブになると、スタートページが現在のページになります。会話の各ターンでは、現在のページがそのまま表示されるか、別のページに遷移します。このコンセプトを使用すると、多くのページと複数の会話ターンを持つ大規模なエージェントを作成できます。
ページには、フルフィルメント(静的エントリ ダイアログや Webhook)、パラメータ、状態ハンドラが含まれます。会話の制御は状態ハンドラによって行われます。これにより、さまざまな遷移ルートを作成して別の Dialogflow CX ページに遷移できます。条件付き(会話の分岐用)にすることもできます。
会話の状態は、次の 3 種類のルートを使用してページ間の遷移を処理することで制御されます。
- インテント ルート: インテントが一致するタイミング(エンドユーザーの発言に基づいてページを変更するなど)。(図中の青い線)。
- 条件ルート: 条件を確認する必要がある場合(セッションに保存されている特定のパラメータに基づいてページを変更する場合など)(ビジュアル ダイアグラムの橙色の線)。
- イベント ハンドラ: 特定のフォールバック イベントを処理する必要がある場合(例: 入力なし、一致なしを処理して、エンドユーザーがインテント ルートまたは条件ルートのどちらに該当するかを明確にするため)(図の緑色の線)。
会話の発話(つまり、コンテンツまたはユーザーへの応答)はフルフィルメントによって定義されます。フルフィルメントは静的または動的です。
- 静的フルフィルメント: 静的フルフィルメント レスポンスが提供された場合
- 動的フルフィルメント: 動的レスポンスのためにフルフィルメント Webhook が呼び出されたとき
小売 bot では、インテント ルートを作成して静的エントリ フルフィルメントレスポンスを提供します。このレスポンスは、ページが有効になるとすぐにユーザーに表示されます。後で、条件ルートを使用してパラメータを作成し、商品注文に必要な情報を収集します。
ページ インテント ルート
デフォルトの開始フローでページを作成する
デフォルトの開始フローのフローチャートを以下に示します。
一緒にクリックしましょう。
- [Build] > [Default Start Flow] をクリックします。
- [Start Page] をクリックします。
- [Routes] の横にある + アイコンをクリックします。
- redirect.artists.overview を追加
- [Transition] まで下にスクロールし、[Catalog] フローへ移行します。
- [保存] をクリックします。
redirect.product.overview
と、このテーブルの他の 11 行に対して上記の手順を繰り返します。
ページ(フロー内) | [Routes] > [Intent] | [ルート] > [移行先] |
開始 |
| - |
開始 |
| フロー: カタログ |
開始 |
| フロー: カタログ |
開始 |
| フロー: カタログ |
開始 |
| フロー: カタログ |
開始 |
| フロー: カタログ |
開始 |
| フロー: カタログ |
開始 |
| フロー: カスタマーケア |
開始 |
| フロー: カスタマーケア |
開始 |
| フロー: カスタマーケア |
開始 |
| フロー: My Order |
開始 |
| フロー: My Order |
開始 |
| フロー: My Order |
開始 |
| ページ: セッションを終了 |
デフォルトの開始フローは、コールセンターに電話をかけたときのオプション メニューのように機能します。ただし、この仮想エージェントは、インテントのトレーニング フレーズを使用して自然言語でトレーニングされます。したがって、やり取りは DTMF オプションではなく会話によって行われるので、より自然で人間らしいやり取りになります。
カタログフローでページを作成する
次のチャット トランスクリプトはカタログ フローに属しています。
> "Hi"
"Welcome, I am the virtual agent of G-Records, a fictional rock label.
You can order artists merchandise, ask questions about your order or shipping,
and I can tell you more which artists are currently signed with us. How can I help?"
> "Which bands are signed with this record label?"
"The following bands are signed with G-Records:
Alice Googler, G's N' Roses, The Goo Fighters and The Google Dolls.
From which of these artists would you like to order merchandise?"
> "Alice Googler"
"You want to rock with Alice Googler merchandise. Awesome!
We sell shirts, music or the tour movie.
Which merchandise item do you want?"
"(Suggestion chips: [Shirts] [Music] [Tour Movie])"
> "I would like to buy a Shirt"
"Do you want a longsleeve or a t-shirt?"
"(Suggestion chips: [T-shirt, Longsleeve, Price?])"
> "What's the price difference?"
"A t-shirt costs $25 and a longsleeve costs $30.
Do you want a longsleeve or a t-shirt?"
> "A t-shirt",
"What shirt size do you want?"
"(Suggestion chips: [XS, S, M, L, XL, 2XL, 3XL])"
> "M"
"A T-shirt of Alice Googler size: M costs $25. Shall I continue to order?"
[音楽] または [ツアームービー] を選択した場合、ダイアログは異なります。音楽の場合、ダイアログは次のようになります。
> "Music"
"We have a Greatest Hits Album or the Live Album. Which one do you want?"
"(Suggestion chips: [Greatest Hits, Live, Price?])"
> "The Live Album"
"Do you want this album on CD or MP3?"
"(Suggestion chips: [CD, MP3])"
> "What's the price difference?"
"A CD costs $15. The digital album on MP3 costs $10.
Do you want this album on CD or MP3?"
> "Digital Album",
"The Digital Album: Alice Googler - Live costs $10. Shall I continue to order?"
ツアームービーの場合、ダイアログは次のようになります。
> "Tour Movie"
"The Tour Movie of G's N' Roses costs $25. Shall I continue to order?
次のフローチャートは、カタログフロー内のすべてのページのフローチャートです。
このフローの複雑さに注目してください。
- どのアーティストですか?の質問をスキップして、すぐに「どのグッズが購入できますか」と尋ねることができます。
- デフォルトの開始フローから、「The Google Dolls の T シャツを買いたい」や「何か買いたい」と尋ねることができます。つまり、仮想エージェントは、これらの必須パラメータのスロットを埋めるために、フォローアップの質問をします。商品ページに直接移動します。
- 価格ダイアログは、再使用される価格ページから取得されます。
- ツアー動画の台詞は最もシンプルな台詞のように見えますが、実際には特別な処理を行います。この部分はダイアログで再利用されるため、エンドユーザーは、すべての情報を一度に指定する場合、他のいずれかのプロダクトに直接入力することもできます。
> "I want The Goo Fighters longsleeve size S."
"The longsleeve of The Goo Fighters size S costs $30. Shall I continue to order?"
まず、ページを接続しましょう。
- [Build] > [Catalog] をクリックします。
- [Start Page] をクリックします。
- [Routes] の横にある + アイコンをクリックします。
- redirect.artists.overview を追加します。
- [Transition] までスクロールし、[Page] を選択して、[+ new Page] を選択します。
- ページ名
Artist Overview
を使用して [保存] をクリックします。
残りのフローを完成させましょう。
- 上記の手順は、次のページ、インテント、フルフィルメントで繰り返すことができます。このテーブルを引き継ぎます。[ページ] は、フロー内で選択するページです。[ルート > 遷移先] は、作成して遷移先とする新しいフローまたはページです。
ページ(フロー内) | [Routes] > [Intent] | [ルート] > [移行先] |
カタログの開始 |
| アーティストの概要 |
カタログの開始 |
| プロダクト |
カタログの開始 |
| プロダクトの概要 |
カタログの開始 |
| プロダクトの概要 |
カタログの開始 |
| シャツ |
カタログの開始 |
| 音楽 |
カタログの開始 |
| セッションを終了 |
カタログ開始 |
| フローを終了する |
アーティストの概要 |
| プロダクトの概要 |
次に、静的フルフィルメントをさらに追加します。
- カタログのフローで、[アーティストの概要] をクリックします。
- [エントリのフルフィルメント] セクションで [フルフィルメントを編集] をクリックします。
- 次の静的フルフィルメント(エージェントが伝える)を使用します。
The following bands are signed with G-Records: Alice Googler, G's N' Roses, The Goo Fighters and The Google Dolls.
- [保存] をクリックします。
- カタログ フローで、[商品の概要] ページをクリックします。
- [エントリのフルフィルメント] セクションで [フルフィルメントを編集] をクリックします。
- 次の静的フルフィルメントを使用します(エージェントが伝える):
We sell shirts, music or the tour movie.
- [保存] をクリックします
ページ パラメータ
パラメータは、セッション中にエンドユーザーが指定した値を取得して参照するために使用されます。各パラメータには名前とエンティティ タイプがあります。@Artist
と @Merch
は、グッズを注文するために収集する必要がある最小限のパラメータです。T シャツや長袖の場合は、@ShirtSize
も収集する必要があります。音楽を注文する場合は、@Carrier
と @Album
の名前も必要になります。
これらのパラメータは必須としてマークする必要があります。必要な場合は、エンドユーザーを記憶し、正しい回答を提供してこれらのパラメータを収集できるように、カスタム プロンプトを用意する必要があります。Dialogflow CX には、この目的で使用できるメカニズムがいくつかあります。
たとえば、[パラメータ] セクションでカスタムの静的フルフィルメント メッセージを指定できます。パラメータが必須の場合、これらのパラメータのフルフィルメントが表示されます。これらのレスポンス メッセージはレスポンス キューに追加されます。エージェントのターンの間に、複数のフルフィルメントを呼び出して、それぞれがレスポンス メッセージを生成することが可能です(生成が必要な場合もあります)。Dialogflow は、こうしたレスポンスをレスポンス キューに保持します。ページのライフサイクルと、これらのフルフィルメントがレスポンス キューに追加される順序について詳しくは、Dialogflow CX ページのドキュメントをご覧ください。
アーティストの概要ページでパラメータを作成する
ページ パラメータを定義しましょう。
- [カタログ] フローから、[アーティストの概要] ページをクリックします。
- [Parameters] ブロックの [+] をクリックします。artist パラメータを追加します。
- 表示名:
artist
- 事業体タイプ:
@Artist
- 必須: チェック
- ログ内での秘匿化: チェック
- 次に、カスタム パラメータのフルフィルメント メッセージを追加します。artist パラメータが仮想エージェントによってまだ収集されていない場合、エンドユーザーには、レスポンス キューに追加された次のエージェント レスポンスが届きます。
From which of these artists would you like to order merchandise?
- 豊富な候補ワードを提供する 2 つ目のダイアログ オプションを追加します。[ダイアログのオプションを追加] をクリックして、次のコードを(JSON で)使用します。
{
"richContent": [
[
{
"options": [
{
"text": "The Google Dolls"
},
{
"text": "The Goo Fighters"
},
{
"text": "Alice Googler"
},
{
"text": "G's N' Roses"
}
],
"type": "chips"
}
]
]
}
エンドユーザーが回答しようとした回数に応じて、さまざまなフォールバック フルフィルメント プロンプトを処理できます。これは、パラメータ イベント ハンドラを使用して行います。無効なパラメータ、発話が長すぎる、入力なし、1 回目の試行で入力なし、2 回目の試行、一致なしなど、さまざまな組み込みイベント ハンドラから選択できます。入力なしと一致なしの違いは、入力なしの場合、ユーザーが回答を提供しなかったことに対し、一致なしの場合、ユーザーは回答を提供したものの、Dialogflow CX がページとインテントを一致させることができなかったことです。
- [リプロンプト イベント ハンドラ] セクションまでスクロールします。
- [イベント ハンドラを追加] をクリックし、イベント
No-match default
を選択します。 - 次のイベントの静的テキスト フルフィルメントを使用します。
I missed that. Please, specify the artist. You can choose between: Alice Googler, G's N' Roses, The Google Dolls or The Goo Fighters. Which artist do you want to buy merchandise from?
- [保存] をクリックします。
- [イベント ハンドラを追加] をクリックし、イベント「
No-input default
」を選択します。 - 次のイベントの静的テキスト フルフィルメントを使用します。
I am sorry, I could understand the artist's name. You can choose between Alice Googler, G's N' Roses, The Google Dolls or The Goo Fighters. Which artist do you want to buy merchandise from?
- [保存] をクリックします。
ページ条件のルート
パラメータは、ページ条件ルートと組み合わせると非常に強力です。条件が true と評価されると、関連するページルートが呼び出されます。条件には、パラメータが特定の値に等しい、パラメータが欠落している、フォームが完了しているなどがあります。パラメータと条件の詳細については、Dialogflow CX のドキュメントをご覧ください。
小売のバーチャル エージェントでは、一連のパラメータを収集する必要があります。そのため、「フォーム」が完了したかどうかを確認する条件を作成する必要があります。フォームは、ページのエンドユーザーから収集するパラメータのリストです。仮想エージェントは、必要なフォーム パラメータ(ページ パラメータとも呼ばれます)をすべて収集するまで、複数の会話ターンでエンドユーザーとやり取りします。
Dialogflow CX では、フォームの入力中にエンドユーザーから提供されたパラメータ値が自動的に設定されます。現在のページのすべてのフォームが入力されているかどうかを確認するには、次の条件を使用します。$page.params.status = "FINAL"
アーティストの概要ページで条件付きルートを作成する
アーティストが判明したら次のページに遷移する条件付きルートを作成しましょう。
- [アーティストの概要] ページの [ルート] セクションで、+ アイコンをクリックします。
- [状態] セクションまで下にスクロールします。
- [1 つ以上](OR)を選択します。
- 次に、次の式を記述します。
- パラメータ:
$page.params.status
- 演算子:
=
- 値:
"FINAL"
- 次に、エンドユーザーの選択を確認する、ルート上の特定の静的フルフィルメント メッセージを作成します。[Fulfillment] ブロックまでスクロールして、次のフルフィルメント メッセージを記述します。
$session.params.artist, great choice! Rock on!
You want to rock with $session.params.artist merchandise. Awesome!
- 条件が true の場合は、[Product Overview] ページに移動します。[移行] セクションまで下にスクロールし、次のページを使用します。
Product Overview
- [保存] をクリックします
[プロダクトの概要] ページでルートを作成する
パラメータと条件付きルートの作成方法を理解したので、次のページのパラメータを作成しましょう。
プロダクトの概要
- [商品の概要] ページで
artist
パラメータを作成します。
- 表示名:
artist
- 事業体タイプ:
@Artist
- 必須: チェック
- ログ内での秘匿化: チェック
- 初期のプロンプト フルフィルメント:
From which of these artists would you like to order merchandise?
{
"richContent": [
[
{
"options": [
{
"text": "The Google Dolls"
},
{
"text": "The Goo Fighters"
},
{
"text": "Alice Googler"
},
{
"text": "G's N' Roses"
}
],
"type": "chips"
}
]
]
}
- イベント ハンドラ >
No-match default
:To buy merchandise you can choose between the following artists: Alice Googler, G's N' Roses, The Google Dolls or The Goo Fighters. Which artist do you want to buy merchandise from?
- カスタム ペイロード:
{
"richContent": [
[
{
"options": [
{
"text": "The Google Dolls"
},
{
"text": "The Goo Fighters"
},
{
"text": "Alice Googler"
},
{
"text": "G's N' Roses"
}
],
"type": "chips"
}
]
]
}
- イベント ハンドラ >
No-input default
:To buy merchandise you can choose between the following artists: Alice Googler, G's N' Roses, The Google Dolls or The Goo Fighters. Which artist were you trying to mention?
- カスタム ペイロード:
{
"richContent": [
[
{
"options": [
{
"text": "The Google Dolls"
},
{
"text": "The Goo Fighters"
},
{
"text": "Alice Googler"
},
{
"text": "G's N' Roses"
}
],
"type": "chips"
}
]
]
}
merch
パラメータを作成します。
- 表示名:
merch
- 事業体タイプ:
@Merch
- 必須: ご確認ください
- ログ内での秘匿化: チェック
- フルフィルメント:
Which merchandise item do you want?
- [Add dialogue option] > [Custom payload] をクリックします。
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "Shirts"
},
{
"text": "Music"
},
{
"text": "Tour movie"
}
]
}
]
]
}
- イベント ハンドラ >
No-match default
- イベント ハンドラの実行:
We sell Shirts, Music or the Tour movie. Which of these items do you want?
- カスタム ペイロード:
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "Shirts"
},
{
"text": "Music"
},
{
"text": "Tour movie"
}
]
}
]
]
}
- イベント ハンドラ >
No-input default
- イベント ハンドラの実行:
I couldn't understand which merchandise item you wanted to buy. You can choose between: Shirts, Music or the Tour movie. Which item do you want?
- カスタム ペイロード:
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "Shirts"
},
{
"text": "Music"
},
{
"text": "Tour movie"
}
]
}
]
]
}
artist
が提供され、merch
アイテムが提供された場合に [商品] ページに遷移するルートを作成します。
- 条件:
- すべてのルールに一致(AND)
- 式:
$session.params.artist != null
- 式:
$session.params.merch != null
- フルフィルメント:
Alright! $session.params.merch of $session.params.artist, let's go!
- 切り替え: ページ:
Product
- ユーザーが「シャツ」と言ったときのルートを作成する
- インテント: redirect.shirts
- 切り替え: ページ:
Shirts
- ユーザーが「音楽」と言った場合のルートを作成する
- インテント: redirect.music
- 切り替え: ページ:
Music
- ユーザーが料金情報を尋ねてきた場合のルートを作成する
- インテント: redirect.price
- 遷移: 新しいページを作成:
Price
上記の設定を行うと、次の画像のような可視化が表示されます。図では、インテントのルートは青色、条件ルートはオレンジ色になっています。イベント ハンドラは緑色で、複数のルートタイプがページに遷移する場合は、線がグレーになります。
ここまで、パラメータに基づくインテント ルートや条件付きルートなどの状態ハンドラを使用して、フロー、エンティティ、インテント、ページを作成する方法を学びました。このラボの後半では、フルフィルメントで条件付き分岐を使用して、入力に基づいて異なるダイアログを提供します。
次の構成を使用して、仮想エージェントを完成させることができます。
シャツのページ:
- [Shirts] ページで、次の構成を作成します。
- エントリのフルフィルメント:
Do you want a longsleeve or a t-shirt?
- エントリのフルフィルメント カスタム ペイロード:
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "T-shirt"
},
{
"text": "Longsleeve"
},
{
"text": "Price?"
}
]
}
]
]
}
- インテント ルート
redirect.price
を作成して、Price
ページに遷移します。 - 次のパラメータを作成します。
- パラメータ:
merch
- エンティティ タイプ:@Merch
、Required
、Redact in log
- パラメータ > イベント ハンドラ >
No-match default
- パラメータ > イベント ハンドラのフルフィルメント:
You can choose between a t-shirt or a longsleeve. Which of these do you want?
- [Parameter] > [Event Handler Fulfillment Custom payload](パラメータ > イベント ハンドラのフルフィルメント カスタム ペイロード):
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "T-shirt"
},
{
"text": "Longsleeve"
}
]
}
]
]
}
- パラメータ > イベント ハンドラ >
No-input default
- パラメータ > イベント ハンドラの実行:
I couldn't understand if you want the t-shirt or the longsleeve. Which of these do you want?
- [Parameter] > [Event Handler Fulfillment Custom payload](パラメータ > イベント ハンドラのフルフィルメント カスタム ペイロード):
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "T-shirt"
},
{
"text": "Longsleeve"
}
]
}
]
]
}
- エントリのフルフィルメントをクリックし、[パラメータのプリセット] までスクロールします。[シャツ] ページがアクティブになるたびに、カテゴリ パラメータが [シャツ] に設定されます。
パラメータ | 値 |
|
|
- 条件付きルートを追加します。
- 少なくとも 1 つのルールに一致(OR)
- 式:
$session.params.merch = "T-shirt"
- 式:
$session.params.merch = "Longsleeve"
- 新しいページへの遷移:
Shirt Size
料金ページ:
価格のメッセージは選択した商品やカテゴリ(音楽やシャツ)によって異なるため、この部分はラボで後ほど修正します。今のところは、プレースホルダを入力するだけで十分です。
- [料金] ページで、次の構成を作成します。
- エントリのフルフィルメント:
PRICE TODO
会話のさまざまな場所で価格をリクエストできるため、常に答えが得られ、会話の前の部分に戻って注文が続行されるはずです。ダイアログ ツリーには、料金情報を取得するために分岐できる場所が 5 か所あります。(シャツ、シャツのサイズ、音楽、携帯通信会社、インテント ルート経由の直接アクセス)があるため、戻るには条件付きルートが必要です。
- 条件付きルートを追加します。
- すべてのルールに一致(AND)
- 式:
$session.params.category = "shirts"
- 式:
$session.params.merch = "null"
- 新しいページへの遷移:
Shirts
- 条件付きルートを追加します。
- すべてのルールに一致(AND)
- 式:
$session.params.category = "shirts"
- 式:
$session.params.size = "null"
- 新しいページへの遷移:
Shirt Size
- 条件付きルートを追加します。
- すべてのルールに一致(AND)
- 式:
$session.params.category = "music"
- 式:
$session.params.album = "null"
- 新しいページへの遷移:
Music
- 条件付きルートを追加します。
- すべてのルールに一致(AND)
- 式:
$session.params.category = "music"
- 式:
$session.params.merch = "null"
- 新しいページへの遷移:
Carrier
- 条件付きルートの追加:
- すべてのルールに一致(AND)
- 式:
$session.params.category = "null"
- 新しいページへの遷移:
Product Overview
シャツのサイズのページ:
- [Shirt Size] ページで、次の構成を作成します。
- エントリのフルフィルメント:
What shirt size do you want?
- エントリ フルフィルメントのカスタム ペイロード:
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "XS"
},
{
"text": "S"
},
{
"text": "M"
},
{
"text": "L"
},
{
"text": "XL"
},
{
"text": "2XL"
},
{
"text": "3XL"
}
]
}
]
]
}
Price
ページへの遷移を含むインテント ルートredirect.price
を作成します。- 次のパラメータを作成します。
- パラメータ:
shirtsize
- エンティティ タイプ:@ShirtSize
-Required
、Redact In Log
- パラメータ > イベント ハンドラ >
No-match default
- パラメータ > イベント ハンドラのフルフィルメント:
Please tell me the shirt size, such as XL.
- [Parameter] > [Event Handler Fulfillment Custom payload](パラメータ > イベント ハンドラのフルフィルメント カスタム ペイロード):
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "XS"
},
{
"text": "S"
},
{
"text": "M"
},
{
"text": "L"
},
{
"text": "XL"
},
{
"text": "2XL"
},
{
"text": "3XL"
}
]
}
]
]
}
- パラメータ > イベント ハンドラ >
No-input default
- パラメータ > イベント ハンドラの実行:
I couldn't understand the shirt size. What size do you want?
- [Parameter] > [Event Handler Fulfillment Custom payload](パラメータ > イベント ハンドラのフルフィルメント カスタム ペイロード):
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "XS"
},
{
"text": "S"
},
{
"text": "M"
},
{
"text": "L"
},
{
"text": "XL"
},
{
"text": "2XL"
},
{
"text": "3XL"
}
]
}
]
]
}
- 条件付きルートを追加します。
- すべてのルールに一致(AND)
- 式:
$page.params.shirtsize != "null"
- ページへの遷移:
Product
音楽ページ:
- [音楽] ページで、次の構成を作成します。
- エントリのフルフィルメント:
We have a Greatest Hits Album or the Live Album. Which one do you want?
- エントリのフルフィルメント カスタム ペイロード:
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "Greatest Hits"
},
{
"text": "Live"
},
{
"text": "Price?"
}
]
}
]
]
}
- ページ:
Price
への遷移を含むインテント ルート:redirect.price
を作成します。 - 次のパラメータを作成します。
- パラメータ:
album
- エンティティ タイプ:@Album
-Required
、Redact In Log
- パラメータ > イベント ハンドラ >
No-match default
- パラメータ > イベント ハンドラのフルフィルメント:
You can choose between Greatest Hits and Live Album. Which of these do you want?
- [Parameter] > [Event Handler Fulfillment Custom payload](パラメータ > イベント ハンドラのフルフィルメント カスタム ペイロード):
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "Greatest Hits"
},
{
"text": "Live"
}
]
}
]
]
}
- パラメータ > イベント ハンドラ >
No-input default
- パラメータ > イベント ハンドラのフルフィルメント:
I couldn't understand if you want the album: Greatest Hit or Live. Which of these do you want?
- [Parameter] > [Event Handler Fulfillment Custom payload](パラメータ > イベント ハンドラのフルフィルメント カスタム ペイロード):
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "Greatest Hits"
},
{
"text": "Live"
}
]
}
]
]
}
- エントリのフルフィルメントをクリックし、[パラメータ プリセット] までスクロールします。音楽ページが有効になるたびに、カテゴリ パラメータが music に設定されます。
パラメータ | 値 |
|
|
- 条件付きルートを追加します。
- すべてのルールに一致(AND)
- 式:
$page.params.album != "null"
- ページへの遷移:
Carrier
携帯通信会社ページ:
- [Carrier] ページで、次の構成を作成します。
- エントリのフルフィルメント:
Do you want this album on CD or MP3?
- エントリのフルフィルメント カスタム ペイロード:
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "CD"
},
{
"text": "MP3"
},
{
"text": "Price?"
}
]
}
]
]
}
- インテント ルート
redirect.price
を作成します。このルートは、Price
ページに遷移します。 - 次のパラメータを作成します。
- パラメータ:
merch
- エンティティ タイプ:@Merch
-Required
、Redact In Log
- パラメータ > イベント ハンドラ >
No-match default
- パラメータ > イベント ハンドラのフルフィルメント:
Do you want a physical CD or the digital album?
- [パラメータ] > [イベント ハンドラのフルフィルメント: カスタム ペイロード] に移動します。
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "CD"
},
{
"text": "Digital Album"
}
]
}
]
]
}
- パラメータ > イベント ハンドラ >
No-input default
- パラメータ > イベント ハンドラのフルフィルメント:
I couldn't understand if you mean CD or MP3. Which one do you want?
- [パラメータ] > [イベント ハンドラのフルフィルメント: カスタム ペイロード] に移動します。
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "CD"
},
{
"text": "MP3"
}
]
}
]
]
}
- 条件付きルートを追加します。
- すべてのルールに一致(AND)
- 式:
$page.params.merch != "null"
- ページへの遷移:
Product
商品ページ:
- 次のパラメータを作成します。
パラメータの表示名 | パラメータ エンティティ タイプ | チェック |
|
| 必須、ログ内での秘匿化 |
|
| 必須、ログ内での秘匿化 |
- artist パラメータには、アーティストが不明な場合に表示される次の初期プロンプト フルフィルメントが必要です。
You didn't mention which artist you are interested in. You can ask me to buy the $session.params.merch of the artist you like or ask which artists we signed. How can I help?
{
"richContent": [
[
{
"options": [
{
"text": "Which artists?"
}
],
"type": "chips"
}
]
]
}
- また、フルフィルメント
I couldn't understand what you just said. Ask me which artists are signed.
を持つNo-input default
イベント ハンドラを追加します。 - フルフィルメントを含む
No-match default
イベント ハンドラ:I missed that. Please ask me which artists are signed.
- merch パラメータには、リプロンプト イベント ハンドラも必要です。
- フルフィルメント:
I couldn't understand what you just said. Which merchandise item do you want?
のNo-input default
イベント ハンドラを追加します。 - フルフィルメントを含む
No-match default
イベント ハンドラ:I missed that. Which merchandise item do you want?
アーティストがわかっていて、ユーザーが「ツアームービー」を選択すると、次のルートが確認ページに移動します。
- 条件付きルートを追加します。
- すべてのルールに一致(AND)
- 式:
$session.params.artist != null
- 式:
$session.params.merch = "Tour Movie"
- パラメータ プリセット [パラメータを追加] >
price = 25
- 新しいページへの遷移:
Confirmation
次のルートは、アーティストが判明し、ユーザーが [T シャツ] を選択し、シャツのサイズを選択すると、確認ページに遷移します。
- 条件付きルートを追加します。
- カスタム式:
$session.params.artist != null AND $session.params.merch = "T-shirt" AND $session.params.shirtsize != null
- パラメータ プリセット [パラメータを追加] >
price = 25
- ページへの遷移:
Confirmation
次のルートは、アーティストが判明し、ユーザーが [長袖] を選択し、シャツのサイズを選択すると、確認ページに移動します。
- 条件付きルートの追加:
- カスタム式:
$session.params.artist != null AND $session.params.merch = "Longsleeve" AND $session.params.shirtsize != null
- パラメータ プリセット [パラメータを追加] >
price = 30
- ページへの遷移:
Confirmation
次のルートは、アーティストが判明し、ユーザーが [CD] を選択してアルバム名を選択すると、確認ページに移行します。
- 条件付きルートを追加します。
- カスタム式:
$session.params.artist != null AND $session.params.merch = "CD" AND $session.params.album != null
- パラメータ プリセット [パラメータを追加] >
price = 15
- 次のページに移動:
Confirmation
次のルートは、アーティストが判明し、ユーザーが [デジタル アルバム] を選択し、アルバム名を選択すると、確認ページに移行します。
- 条件付きルートの追加:
- カスタム式:
$session.params.artist != null AND $session.params.merch = "Digital Album" AND $session.params.album != null
- パラメータ プリセット [パラメータを追加] >
price = 10
- ページへの遷移:
Confirmation
次に、不足している情報を検出するプロンプトを使用して、高度な条件を作成します。次のルートでは、アーティストがわかっていて、ユーザーが「CD」または「デジタル アルバム」を選択したものの、アルバム名が選択されなかった場合、音楽ページに戻ります。
- 条件付きルートを追加します。
- カスタム式:
$session.params.artist != null AND ($session.params.merch = "CD" OR $session.params.merch = "Digital Album") AND $session.params.album = null
- フルフィルメント:
I would also need to know which album you would like to buy!
- ページへの遷移:
Music
最後のルートは、アーティストが判明し、ユーザーが「T シャツ」または「長袖」を選択したが、T シャツのサイズを選択しなかった場合に、確認ページに遷移します。
- 条件付きルートを追加します。
- カスタム式:
$session.params.artist != null AND ($session.params.merch = "T-shirt" OR $session.params.merch = "Longsleeve") AND $session.params.shirtsize = null
- フルフィルメント:
I would also need to know which shirt size you need!
- 次のページに移動:
Shirt Size
ラボの次のパートでは、条件付きフルフィルメントを使用して、入力に応じて異なるフルフィルメント メッセージを返します。
7. 条件付きレスポンス
一部のレスポンスは、入力に基づいて異なるダイアログを返します。ダイアログは分岐します。これを条件付きレスポンスと呼びます。これは、Webhook フルフィルメントを使用しておらず、条件付きレスポンスがバックエンドで決定されている場合に役立ちます。例を次に示します。
if [condition]
[response]
elif [condition]
[response]
elif [condition]
[response]
else
[response]
endif
- [条件] の例は
$session.params.user-age >= 21
のようになります。ルートの条件と同様の形式を使用します。 - [response] は静的テキスト レスポンスを受け取ります
- 条件付きレスポンスは常に
if
で始まる elif
ブロックとelse
ブロックは省略可能です。
Dialogflow CX では、組み込みのシステム関数も使用できます。たとえば、日付や時刻の形式設定、現在の時刻の表示($sys.func.NOW()
)
カタログ フローを完成させるため、[確認] ページと [価格] ページを修正しましょう。
確認ページ:
次に、確認ページを作成します。次の要件があります。
- merch が CD または Digital Album の場合。確認画面には、artist、merch、Album、price の各フィールドが表示されます。
- [グッズ] が [T シャツ] または [長袖] の場合。確認画面には、[アーティスト]、[グッズ]、[サイズ]、[価格] の各フィールドが表示されます。
- それ以外の場合(merch が Tour Movie の場合)。確認画面には、artist、merch、price の各フィールドが表示されます。
- [確認] ページをクリックします。
- [Edit Fulfillment] > [Agent Responses] > [Add dialogue] オプション > [Conditional Response] をクリックします。
if ($session.params.merch = "CD" OR $session.params.merch = "Digital Album")
The $session.params.merch: $session.params.artist - $session.params.album costs $$session.params.price. Shall I continue to order?
elif ($session.params.merch = "T-shirt" OR $session.params.merch = "Longsleeve")
A $session.params.merch of $session.params.artist size: $session.params.shirtsize costs $$session.params.price. Shall I continue to order?
elif $session.params.merch = "Tour Movie"
The $session.params.merch of $session.params.artist costs $$session.params.price. Shall I continue to order?
else
It looks like something went wrong with your order. You can say "Reset", to restart the order process.
endif
- Create the following Custom payload:
- Custom payload:
{
"richContent": [
[
{
"options": [
{
"text": "Yes, confirm"
}
],
"type": "chips"
}
]
]
}
Next, create two intent routes:
confirm.proceed.order
transitions to:Order Process
Flow.decline.proceed.order
transitions toEnd Flow
When the user declines the order, and does not want to proceed the order process, we will have to transition back to the welcome page, but all the parameters have to be cleared. We can do this by specifically setting null to all the possible parameters. You can do this with Parameter presets.
- In the decline.proceed.order intent route, scroll down to Parameter presets and add the following parameters:
Parameter | Value |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Notice that we have created an additional parameter called restart
. If this parameter is present, the Default Start Flow, should know to continue the conversation by showing a customized message.
- Click on the Default Start Flow, Start Page, and create another Conditional Route:
$session.params.restart = "true"
- Fulfillment:
"Welcome back, as the virtual agent of G-Records, I can help you order artists merchandise, you can ask questions about your order or shipping, and I can tell you more which artists are currently signed with us. How can I help?"
- Custom payload:
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "Which artists?"
},
{
"text": "Which products?"
},
{
"text": "About my order..."
}
]
}
]
]
}
- Select the Start Page and click on the
redirect.end
intent. Create the following fulfillment:Thank you for contacting G-Records! Have a nice day!
Price Page:
Let's also fix the Price TODOs. The price information will be static for now. Click on the Price Page in the Catalog Flow, and use the following entry fulfillment:
- Delete the Agent Says entry fulfillment.
- Create a new Conditional Response:
if $session.params.category = "shirts"
A t-shirt costs $25 and a longsleeve costs $30.
elif $session.params.category = "music"
A CD costs $15. The digital album on MP3 costs $10.
else
A t-shirt costs $25 and a longsleeve costs $30. A CD costs $15 and a digital album on MP3 $10. In case you are interested in the Tour Movie, that one is $25.
endif
Well done, by now you completed the Catalog flow. Your flow should look similar to this diagram:
8. Wrapping up the agent
We are almost at the end of this lab. Let's configure the last flows together, and take in practice all the new things that we have learned.
Creating the My Order Flow
- Go to the My Order Flow, and create the following intent transitions:
Page (In Flow) | Routes > Intent | Routes > Transition To |
My Order Start |
| My Order |
My Order Start |
| My Order Status |
My Order Start |
| My Order Cancellation |
My Order Start |
| End Session |
My Order Start |
| End Flow |
My Order |
| My Order Status |
My Order |
| My Order Cancellation |
Default Start Flow |
| Flow: My Order |
Default Start Flow |
| Flow: My Order |
- Let's create the following entry fulfillment for the My Order Page:
- Entry fulfillment:
I can look up the status of your order, or I can cancel an order.
- In the My Order Page create the following parameter:
- Displayname:
ordernumber
- Entity Type:
@OrderNumber
- Required: checked
- Initial prompt fulfillment:
What's the order number? For example ABCD123.
- Event Handler:
No-match default
:To proceed with your order I will need an order number. Order numbers start with 4 characters and end with 3 numbers, such as ABCD123. Which order number may I use?
- Event Handler:
No-input default
:I missed that. To proceed with your order I will need an order number. Order numbers start with 4 characters and end with 3 numbers, such as ABCD123. Which order number may I use?
- Create the following conditional route:
- Customize Expression:
$page.params.status = "FINAL"
- Fulfillment:
And do you want to Cancel your order, or should I look up the status?
- Click on Add state handler > Event Handlers and create the Event Handler:
No-input default
- Fulfillment:
I'm sorry, what was that? Would you like me to cancel an order or look up the status?
- Custom payload:
{
"richContent": [
[
{
"options": [
{
"text": "Status"
},
{
"text": "Cancel"
}
],
"type": "chips"
}
]
]
}
- Create the Event Handler:
No-match default
- Fulfillment:
Would you like me to cancel an order or lookup the status?
- Custom payload:
{
"richContent": [
[
{
"options": [
{
"text": "Status"
},
{
"text": "Cancel"
}
],
"type": "chips"
}
]
]
}
- In the My Order Status Page create the following parameter:
- Displayname:
ordernumber
- Entity Type:
@OrderNumber
- Required checked
- Initial prompt fulfillment:
What's the order number? For example ABCD123.
- Event Handler:
No-match default
:To proceed with your order I will need an order number. Order numbers start with 4 characters and end with 3 numbers, such as ABCD123. Which order number may I use?
- Event Handler:
No-input default
:I missed that. To proceed with your order I will need an order number. Order numbers start with 4 characters and end with 3 numbers, such as ABCD123. Which order number may I use?
- In the My Order Status Page create the following conditional route:
- Customize Expression:
$session.params.ordernumber != null
- Fulfillment:
Your order $session.params.ordernumber has been shipped, it can take up to approx 2 weeks before you will receive your items.
- Add dialogue option > Text:
Is there anything else I can help you with?
- In the My Order Cancelation Page create the following parameter:
- Displayname:
ordernumber
- Entity Type:
@OrderNumber
- Required checked
- Initial prompt fulfillment:
What's the order number? For example ABCD123.
- Event Handler:
No-match default
:To proceed with your order I will need an order number. Order numbers start with 4 characters and end with 3 numbers, such as ABCD123. Which order number may I use?
- Event Handler:
No-input default
:I missed that. To proceed with your order I will need an order number. Order numbers start with 4 characters and end with 3 numbers, such as ABCD123. Which order number may I use?
- In the My Order Cancelation Page create the following conditional route:
- Customize Expression:
$session.params.ordernumber != null
- Fulfillment:
Your order $session.params.ordernumber has been canceled.
- Add dialogue option > Text:
Is there anything else I can help you with?
- Test the flow and create the following two test scenarios:
>"About my order"
>"ABCD123"
>"Status"
And:
>"What's the status of order DEFG222"
- Select the Start Page and click on the
redirect.end
intent. Create the following fulfillment:Thank you for contacting G-Records! Have a nice day!
- Select the Start Page and click on the
redirect.home
intent. Create the following parameter preset:restart = true
Default Negative intents (Fallback)
When you create a virtual agent, a default negative intent is created for you. You can add training phrases to this intent that act as negative examples that will trigger a No-match event. There may be cases where end-user input has a slight resemblance to training phrases in normal intents, but you do not want these inputs to match any normal intents.
- Try in the simulator:
I don't like Alice Googler
.
You will see that the virtual agent answers with the Product Overview Page, to continue ordering Alice Googler merchandise. However, your end user does not like that artist. Let's use the Default Negative Intent for this.
- Go to Manage > Intents and select the Default Negative Intent.
- Add the following training phrases that will trigger the No-match event.
I don't like Alice Googler
I am not a fan of G's N' Roses
I can't stand the music of the Google Dolls
- Hit Save and test the following sentence in the simulator:
I am really not a fan of the Goo Fighters
This time the No-match
event was triggered, you stayed on the Start Page.
Default Fallback Messages
- Click the Default Start Flow, select the
sys.no-input-default
event handler.
The No-input fallback basically means: No text or speech answers were detected. Likely no answers were given, or the system couldn't hear it. Therefore, let's make the fallback messages more specific. Use the tab key, to create alternative dialogues:
- Remove all answers, and add these text dialogues:
I'm sorry, I didn't receive an answer. Can you say it again?
I missed your answer, can you say it again?
Sorry, I didn't hear anything. Can you say it again?
I couldn't hear what you were saying, what was that?
I'm sorry, I missed your answer. What were you trying to say?
Don't forget to click Save.
- Click the Default Start Flow, select the
sys.no-match-default
event handler.
The No Match fallback basically means: Text or speech answers were detected but nothing in Dialogflow CX got matched.
- Remove all answers, and add these text dialogues:
Sorry, I didn't get that. Can you please rephrase?
I'm sorry, I don't understand. Can you please rephrase?
I don't understand, please rephrase.
Sorry, I didn't get that. What was that?
I didn't get that, can you please rephrase?
Don't forget to click Save.
- It's advised to repeat these steps for the Catalog, My Order, Order Process and Customer Care flows.
Here's a tip: when creating fallback messages, make them more explicit, by rephrasing the previous question or by mentioning an example. You could create these type of No-match and No-input events on Page level when creating parameters. In our labs, we have already done this.
Creating the Order Process Flow
- Go to the Order Process Flow, and create the following intent transitions:
Page (In Flow) | Routes > Intent | Routes > Transition To |
Order Process Start |
| End Session |
Order Process Start |
| End Flow |
Order Process Start |
| New Page: Shipping Details |
- Let's create the following entry fulfillment for the Shipping Details Page:
- Entry fulfillment:
To complete your order I will first need to collect your shipping details.
- Create the following parameters:
These parameters will make use of built-in system entities. System entity support differs for each language. See the docs for more information.
Parameter Display name | Entity | Required? | Initial prompt fulfillment | No-match default | No-input default |
| @sys.person | Required |
|
|
|
| @sys.person | Required |
|
|
|
| @sys.address | Required |
|
|
|
| @sys.any | Required |
|
|
|
| @sys.geo-city | Required |
|
|
|
| @sys.geo-country | Required |
|
|
|
| @sys.email | Required |
|
|
|
- Create the following conditional route:
- Customize Expression:
$page.params.status = "FINAL"
- Transition to new Page:
Payment Details
- Create the following entry fulfillment.
Let's fake it that this virtual agent makes use of Google Pay. Don't worry this tutorial won't make real transactions. Create the following entry dialogues:
- Agent Says:
Alright $session.params.firstname! We will make use of Google Pay, that's connected to your email account: $session.params.email.
- Conditional Response
if $session.params.merch != "Digital Album"
Shipping costs an additional 5 dollars. This will make the total price $$sys.func.TO_TEXT($sys.func.ADD($session.params.price, 5)).
Your merchandise will be shipped to:
$session.params.firstname $session.params.lastname
$session.params.address
$session.params.zipcode $session.params.city
$session.params.country
To continue the order process please explicitly say "I confirm". Do you want to confirm your $session.params.artist $session.params.merch order?
else
The total costs will be: $$session.params.price.
After purchasing the digital album, you will receive an email with the download link.
To continue the order process please explicitly say "I confirm".
Do you want to confirm your $session.params.artist $session.params.merch order?
endif
- 次のインテント ルートを作成します。
- インテント:
confirm.proceed.order
- エージェントの発話:
Thank you for your order! Your merchandise will be shipped today!
- [Add Dialogue Option] > [Text] に
Here's the order number: ABCD123
を入力します。 - 会話オプションを追加 > テキスト:
Have a good day!
- 切り替え:
End Session
- [スタート] ページを選択し、
redirect.end
インテントをクリックします。次のフルフィルメントを作成します。Thank you for contacting G-Records! Have a nice day!
- [Start] ページを選択し、
redirect.home
インテントをタップします。次のパラメータ プリセットを作成します。restart = true
問題ないようです。これで、実店舗の小売店の chatbot が完全に機能するようになりました。次のラボでは、仮想エージェントの性能をテストします。
9. 仮想エージェントをテストする
組み込みのシミュレータを使用して、仮想エージェントの会話をテストできます。シミュレータでフローをテストする利点は、フロー、ページ、パラメータ、(DTMF)イベントの概要を、シミュレータがフロー実行中に収集した内容に基づいて確認できることです。このような情報はエンドユーザーには表示されないため、統合で直接テストするよりもテストが容易になります。テストケースを作成して保存し、再利用することもできます。これは、フローを長期間維持または編集する際に、変更によって以前の作業が破損しないようにしたい場合に非常に便利です。
作成したテストケースを Google Cloud Storage またはローカルに保存することで、エクスポートとインポートを行うこともできます。テストをエクスポートすると、Blob ファイルがダウンロードされます。シミュレータとテストケースの詳細については、シミュレータとテストケースのドキュメントをご覧ください。
テストケースを作成する前に、まず仮想エージェントの残りの部分を完成させましょう。
カスタマーケア フローの作成
- [カスタマーケア] フローを開き、次のインテントの遷移を作成します。
ページ(フロー内) | [Routes] > [Intent] | [ルート] > [移行先] |
カスタマーケアの開始 |
| 送料 |
カスタマーケアの開始 |
| 払い戻し |
カスタマーケアの開始 |
| スワップ |
カスタマーケアの開始 |
| フローを終了する |
カスタマーケアの開始 |
| セッションを終了 |
- [配送] ページに次のエントリ フルフィルメントを作成します。
Shipping physical merchandise items can take up to 2 weeks.
Is there anything else I can help you with?
- [Refund] ページに次のエントリ フルフィルメントを作成します。
We offer free returns and refunds. We provide one free return label for each order. You can use it within 30 days from receiving your order. If your refund is accepted, we will refund the price you paid for your item back to your original payment method.
Is there anything else I can help you with?
- [Swapping] ページに次のエントリ フルフィルメントを作成します。
If you would like to change your item for a different one, please return your unwanted item and place a new order. If your refund is accepted, we will refund the price you paid for your item back to your original payment method.
Is there anything else I can help you with?
- [Start] ページを選択し、
redirect.end
インテントをタップします。フルフィルメントThank you for contacting G-Records! Have a nice day!
を作成します。 - [スタート] ページを選択し、
redirect.home
インテントをクリックします。次のパラメータ プリセットを作成します。restart = true
テストケースを作成する
- 画面の右側にある [Test Agent] ボタンをクリックします。
シミュレータを初めて開くときは、エージェント環境とアクティブなフローを選択する必要があります。ほとんどの場合、下書き環境とデフォルトの開始フローを使用する必要があります。
- タイプ:
Hi
- 質問:
Which artists are signed with your label?
- 「
The Google Dolls
」と言ってください - 「
I am interested in buying a shirt
」と言ってください - 「
A t-shirt
」と言ってください - 「
Medium
」と言ってください - テストケースの保存ボタンをクリックします。シミュレータの上部(やり直し矢印とリセット ゴミ箱のアイコンの横)にあります。
- 次の情報を指定します。
- テストケース名:
Buy Google Dolls t-shirt size M
- タグ: #catalog, #shirts, #T-shirt, #TheGoogleDolls
- [保存] をクリックします。
テストケースをさらに作成しましょう。
- まず、リセット(ゴミ箱)アイコンをクリックして現在のダイアログを消去します。
- 次のテストケースを作成します。
Google 社員の T シャツ(アリス)を購入:
>"Buy the Alice Googler t-shirt."
>"XL"
- テストケース名:
Buy the Alice Googler t-shirt
- タグ:
#catalog, #shirts, #t-shirt, #AliceGoogler
T シャツを購入する(M サイズ): (アーティスト名は言及していませんが、バンドの概要、商品の概要、シャツ、シャツのサイズに関するページはスキップできます)
>"Buy a t-shirt size M"
>"The Google Fighters"
- テストケース名:
Buy a t-shirt size M
- タグ:
#catalog, #shirts, #t-shirt, #TheGoogleFighters
- 説明:(アーティスト名は言及されていないが、バンドの概要、商品の概要、シャツとシャツのサイズのページはスキップする)
G's N' Roses の音楽を購入する(バンドの概要と商品の概要ページはスキップされます)
>"Purchase music of G's N' Roses"
>"Live"
>"CD"
- テストケース名:
Purchase music of G's N' Roses
- タグ:
#catalog, #music, #CD, #GsNRoses, #live
- 説明: (これにより、バンドの概要ページとプロダクトの概要ページはスキップされます)
料金情報を確認する:
>"Which products"
>"Shirts"
>"What's the price difference?"
>"Longsleeve"
>"What does it cost?"
>"M"
>"The Google Dolls"
>"No"
>"Which bands"
>"The Gooo Fighters"
>"Music"
>"How much does it cost?"
>"Greatest Hits"
>"What's the price difference?"
>"Mp3"
>"No"
>"I want to buy the tour movie"
>"Alice Googler"
>"Yes"
- テストケース名:
Price info
- タグ:
#catalog, #music, #tourmovie, #shirts
- 説明: 会話のさまざまなポイントで価格情報をテストする
事前録画されたテストケースをテストする
- 左側の Dialogflow メインメニューで、[管理] > [テストケース] を選択します。
- すべてのテストケースを選択し、表の上にある [実行] ボタンをクリックします。
Dialogflow CX は、選択したすべてのテストケースを「ゴールデン テストケース」として保存された録音に対して実行します。結果が保存した内容と同じであれば、テストは合格です。- フロー内で何かが変更された場合(ページが正しく設定されていない、またはインテントによって間違ったページに誘導されたなど)、テストは失敗します。
- シミュレータで次の質問をします。
How long will shipping take?
- 結果を確認し、テストケースを
#shipping
タグを付けてShipping
として保存します。 - [管理] > [テストケース] パネルに移動し、グリッドの右上にある [実行] ボタンを押して、
Shipping
テストケースのみを実行します。
このテストは合格するはずです。
- カスタマーケア フローに移動し、[開始] ページを選択して、[ルート] ヘッダーをクリックします。
すべてのルートが表示されたグリッドの画面が表示されます。
redirect.shipping.info route
を削除する- [Manage] > [Test Cases] パネルに移動し、グリッドの右上にある [Run] ボタンを押して、
Shipping
テストケースのみを実行します。
このテストは失敗します。
- 失敗したテストをクリックすると、失敗の詳細を確認できます。
この場合、テストは失敗し、次のエラー メッセージが表示されます。
Page: Page mismatch:
Expected: Shipping
Actual: Start Page
これは、そのページがフロー内に存在しなくなったためです。Shipping
ページが表示されるはずが、Start
ページから移動しなかった。(またはエンドユーザーに代替メッセージが送信されます)。
つまり、これは検出できなかったリクエストであり、偽陰性のテスト結果です。テストは失敗しました。[配送] ページが表示されるはずが、何も起こらない、またはフォールバック メッセージが表示される。
- カスタマーケア フローに移動し、[開始] ページに
redirect.shipping.info
をインテント ルートとして追加します。忘れずに [Shipping] ページに移行し、[Save] をクリックします。 - シミュレータで次のテストケース
I want to swap my item
を記録し、このテストケースをSwapping
#swapping
として保存します。 - [管理] > [Intents] > [redirect.refund.info] を開き、次のトレーニング フレーズを追加します。
I want to swap this item for a refund
このトレーニング フレーズがないと、ユーザーが払い戻しのために商品の変更をリクエストすると、redirect.swapping.info インテントにヒットします。しかし、Google は商品の変更に関する情報ではなく、払い戻しに関する情報を提供したいのです。
- シミュレータでゴールデン テストケース
I want to swap this item for a refund
を作成し、このテストケースをSwap for Refund
#refund
として保存します。 - [管理] > [インテント] > [redirect.refund.info] インテントに戻り、
I want to swap this item for a refund
行を削除します。 - [管理] > [テストケース] に戻り、[Swap for Refund] テストケースを選択して実行します。
最新のテストが失敗し、次のエラー メッセージが表示されました。
If you would like to change your item for a different one, please return your unwanted item and place a new order. If your refund is accepted, we will refund the price you paid for your item back to your original payment method.`
Is there anything else I can help you with?
Page: Page mismatch:
Expected: Refund
Actual: Swapping
つまり、これはリクエストが誤って認識された偽陽性のテスト結果です。テストは失敗しました。[払い戻し] ページが表示されるはずが、[交換] ページが表示された。
対象範囲
Dialogflow CX では、テストのカバレッジは、特定のテストスイートを実行するときに仮想エージェントのダイアログ(ページとインテント)が実行される程度を示す指標です。テストカバレッジ(割合)が高いバーチャル エージェントは、テスト中に実行されたダイアログが多いため、テストカバレッジが低いバーチャル エージェントと比較して、検出されていないバグ(理解されていないリクエストの見落としなど)が含まれている可能性が低くなります。
- すべてのテストケースのテスト カバレッジ レポートを表示するには、[Coverage] をクリックします。
- [切り替え] タブをクリックします。
すべてのページ遷移のテスト カバレッジが表示されます。
- [Intents] タブをクリックします。
すべてのインテントのテストカバレッジが表示されます。
これで、小売店ボットの完全な実例を構築してテストできました。次のラボのページに進んで、結論を読み、役立つ参考資料をいくつかご紹介します。
10. まとめ
Dialogflow CX は、チャットボットや音声ボットなどの仮想エージェントを作成するための会話型 AI プラットフォーム(CAIP)です。Dialogflow CX を使用すると、ビジュアル bot ビルダー、再利用可能なインテント、マルチターンの会話に対応する機能により、エンタープライズ レベルの会話エクスペリエンスの構築を加速できます。
この Codelab では、実際の小売店のバーチャル エージェントを構築する方法を学びました。ここで取り上げたコンセプトは次のとおりです。
- フロー
- パラメータ、カスタム エンティティ、システム エンティティ
- ページ
- インテント ルートや条件ルートなどの状態ハンドラ
- 静的フルフィルメント メッセージと条件付きレスポンス
- フォールバック インテント
- シミュレータ、テストケース、カバレッジ
参照
Dialogflow CX について詳しくは、以下のブログとドキュメントをご覧ください。