1. 始める前に
この Codelab では、会話型 UI を構築するための会話型 AI プラットフォーム(CAIP)である Dialogflow CX を使用して、小売業向けの chatbot を構築する方法を学びます。Dialogflow CX は、chatbot、音声ボット、電話ゲートウェイなどの仮想エージェントを実装でき、50 以上の言語で複数のチャネルをサポートできます。
この Codelab では、小売業向けのウェブサイト チャットボットを構築する方法について説明します。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 Identity / 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 を使用していないため、「No, I am not using them」と答えます。
- [完了] をクリックします

新しい Dialogflow CX エージェントを作成する
新しい Dialogflow CX エージェントを作成するには、まず Dialogflow CX コンソールを開きます。
- 以前に作成した Google Cloud プロジェクトを選択します。
- [Create Agent(エージェントを作成)] をクリックします。
基本的なエージェント設定に関するフォームに入力します。
- 任意の表示名を選択できます。
- ロケーションとして [us-central1] を選択する
- 使用するタイムゾーンを選択します。
- デフォルトの言語として [en - English] を選択する
[作成] をクリックします。

これで準備完了です。これで、仮想エージェントのモデリングを開始できます。
3. フロー
多くの場合、複雑なダイアログでは複数の会話トピックが関与します。G-Records 向けに構築する chatbot の場合、バンドグッズの販売に関する商品カタログ、支払い、注文ステータス、カスタマー ケアに関する質問のダイアログが考えられます。これらの会話トピックをフローに分割できます。

フローを使用すると、チームは個々の会話パスで作業できます。フローを簡素化して、画面に収まりやすく、モジュール化しやすくすることをおすすめします。
フローは Dialogflow CX の新しいコンセプトです。Dialogflow Essentials には、フローと似たメガ エージェントというコンセプトがあります。ただし、フローははるかに頻繁に使用します。
このラボの後半では、フローを終了できる状態ハンドラを使用します(次のフローまたは前のフローに戻ります)。また、エージェント セッション全体を終了することもできます。
フローを作成してみましょう。
フローの作成
- Dialogflow CX で、+ アイコン > [フローを作成] をクリックします。
- 名前「
Catalog」を指定して、Enter キーを押します。

最初のフロー Catalog が作成されました。次に、他のフローを作成します。
Order ProcessMy OrderCustomer Care

このラボの後半でページ状態ハンドラを設定します。これにより、最終的に可視化は次のようになります。

シミュレータ
Dialogflow CX コンソールの右側にある組み込みのシミュレータを使用して、仮想エージェントをテストできます。会話の最初から、または特定のフローから会話をテストできます。
- 画面右上にある [エージェントをテストする] ボタンをクリックします。
- [talk to agent] フィールドに「
Hello」と入力します。仮想エージェントは、デフォルトのウェルカム テキスト「Greetings!

このデフォルトのウェルカム テキストを変更してみましょう。
デフォルトの開始フロー
まず、仮想エージェントに挨拶したときにトリガーされるインテント ルートを作成します。
- 左側の [Build] > [Flows] サイドバーで、[Default Start Flow] をクリックし、[Start] ツリーノードを選択します。
[スタート] ページが開きます。[ビルド > ページ] サイドバー セクションで、[スタートページ] が自動的に選択されています。
- [Start] > [Routes] で、[Default Welcome Intent] をクリックします。
インテントは、1 回の会話ターンにおけるエンドユーザーの意図を分類します。Dialogflow CX では、インテントは次のアクティブなページまたはフルフィルメントをルーティングする状態ハンドラの一部にできます
- 「Agent says」のエントリをすべて削除し、次の新しいテキストを追加します。
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?
会話を効率化するために、クイック返信ボタン / 候補ワードも必要になります。
- [Add dialogue option > Custom payload] をクリックし、以下のコード スニペットを使用します。
- 以下のコード スニペットをカスタム ペイロードとして使用し、[保存] をクリックします。
カスタム ペイロードの詳細については、ドキュメントをご覧ください。
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "Which artists?"
},
{
"text": "Which products?"
},
{
"text": "About my order..."
}
]
}
]
]
}

- シミュレータでウェルカム インテントをテストしてみましょう。
リッチ コンテンツが表示されない理由についてご説明します。これは、候補チップなどのリッチ コンテンツが統合に依存しているためです。次の手順では請求先アカウントが必要ですが、お持ちでない場合はスキップできます。
- 左側のサイドバーで、[管理] > [インテグレーション] をクリックします。
- [Dialogflow Messenger] を選択し、[接続] をクリックします。
- ポップアップで [有効にする] をクリックします。

別のポップアップが表示されます。今回は、ウェブサイトに貼り付けて Dialogflow Messenger コンポーネントをウェブサイトに統合できる統合 JavaScript コードが表示されます。ウェブサイトはまだないため、ツールで仮想エージェントを直接テストします。

- [今すぐ試す] リンクをクリックします。
- 右下のチャットボット アイコンをクリックして、チャット ウィンドウを開きます。会話を開始するには、
Helloと入力します。

現時点では、提案チップをクリックしても、仮想エージェントは意味を理解しません。これは、仮想エージェントがまだ状態を切り替えていないためです。Dialogflow CX では、ページを使用してこれを行うことができます。ラボを続行します。まず、エンティティとインテントを作成します。
4. エンティティ タイプ
エンティティ タイプを使用して、エンドユーザー入力からデータを抽出する方法を制御します。Dialogflow CX エンティティ タイプは、Dialogflow ES エンティティ タイプと非常によく似ています。Dialogflow には、多数の一般的なデータタイプに対応する事前に定義されたシステム エンティティが用意されています。たとえば、日付、時刻、色、メールアドレスなどをマッチングするためのシステム エンティティがあります。カスタムデータに対応する独自のカスタム エンティティを作成することもできます。
フローのページを設計する前に、まずすべてのカスタム エンティティを準備しましょう。次のエンティティを作成します。

エンティティの作成
アーティスト エンティティを作成しましょう。
- [Manage] > [Entity Types] をクリックします。
- [+ Create] をクリックする
- 表示名:
Artist - エンティティ:
The Google Dolls(類義語:Google Dolls)The Goo Fighters(類義語:Goo Fighters)G's N' Roses(類義語:Gs and Roses)Alice Googler- [詳細オプション] をクリックし、[ファジー一致] をオンにします。(バンド名のスペルが間違っていても、正しいエンティティと一致することがあります)。
- [詳細オプション] で [ログで編集] もオンにします。(バンド名を間違って入力すると、ログ内の名前が修正されます)。
- [保存] をクリックします。
また、Merch アイテムのエンティティも必要です。
- [Manage] > [Entity Types] をクリックします。
- [+ Create] をクリックする
- 表示名:
Merch - エンティティ:
T-shirtLongsleeve(類義語:Longsleeve shirt)Tour MovieDigital Album(同義語:MP3 Album、MP3)CD(同義語Disc、Physical CDを含む)
- [保存] をクリックします。
アルバムのエンティティも必要です。
- [Manage] > [Entity Types] をクリックします。
- [+ Create] をクリックする
- 表示名:
Album - エンティティ:
LiveGreatest Hits(類義語:Hits)
- [保存] をクリックします。
衣料品のサイズのエンティティも必要になります。
- [Manage] > [Entity Types] をクリックします。
- [+ Create] をクリックする
- 表示名:
ShirtSize - エンティティ:
XS(類義語:Extra Small)S(類義語:Small)M(類義語:Medium)L(類義語:Large)XL(類義語:Extra Large)2XL(類義語:Extra Extra Large)3XL
- [保存] をクリックします。
通常は 4 桁の英数字と 3 桁の数字で構成される注文番号のエンティティ。(ABCD123 など)
- [Manage] > [Entity Types] をクリックします。
- [+ Create] をクリックする
- 表示名:
OrderNumber - 正規表現エンティティ
- エンティティ: [A-Z]{4}[0-9]{3}
- [保存] をクリックします。
エンティティ構成は次のようになります。
@Artist: 
@Merch: 
@Album: 
@ShirtSize: 
@OrderNumber: 
カスタム エンティティの準備ができたら、インテントを準備できます。ラボを続行しましょう。
5. インテント
インテントは、1 回の会話ターンにおけるエンドユーザーの意図を分類します。Dialogflow CX では大幅に簡素化され、会話制御の構成要素ではなくなりました。Dialogflow CX は、ユーザーの発言内容を照合するためにインテントのみを使用します。Dialogflow ES では、すべてのもの(パラメータ、イベント、フルフィルメントなど)をインテントに関連付ける必要がありました。Dialogflow CX のインテントにはトレーニング フレーズのみが含まれているため、再利用できます。会話を制御しなくなります。インテントの作成プロセスは次のようになります。
インテントのトレーニング フレーズでは、エンティティを使用して「変数」入力を抽出できます。そのため、エンティティ タイプを事前に作成しておくことをおすすめします。これは、ラボの手順の前のページで行ったことです。
インテントの作成
フローのページを設計する前に、すべてのインテントを準備することから始めましょう。
- [管理] > [インテント] をクリックします。
- [+ 作成] をクリックします。
次の詳細を使用します。
- 表示名
redirect.artists.overview - 説明文
Artists overview: The bands supported by the label

下にスクロールして、次のトレーニング フレーズを作成します。
Which bands are signed?Which bandsWhich artistsWhich artists are part of the record labelWho is part of the labelFrom which bands can I buy merchandiseBand merchandiseWhich music do you have?I would like to know who are signed to the labelWho are supported by the labelFrom who can I buy shirtsWhat music can I orderCan 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 の場合、インテント ルートを作成し、静的エントリ フルフィルメント レスポンスを提供します。このレスポンスは、ページが有効になるとすぐにユーザーに表示されます。後で、条件ルートを使用してパラメータを作成し、グッズの注文に必要な情報を収集します。
ページ インテント ルート
[Default Start Flow] でページを作成する
デフォルトの開始フローのフローチャートを次に示します。

一緒にクリックしてみましょう。
- [ビルド > デフォルトの開始フロー] をクリックします。
- [Start Page] をクリックします。
- [ルート] の横にある [+] アイコンをクリックします。
- redirect.artists.overview を追加
- [移行] まで下にスクロールし、カタログ フローに移行します。
- [保存] をクリックします。
redirect.product.overviewと、このテーブルの他の 11 行について、上記の手順を繰り返します。
ページ(フロー内) | [ルート] > [インテント] | [Routes] > [Transition To] |
開始 |
| - |
開始 |
| フロー: カタログ |
開始 |
| フロー: カタログ |
開始 |
| フロー: カタログ |
開始 |
| フロー: カタログ |
開始 |
| フロー: カタログ |
開始 |
| フロー: カタログ |
開始 |
| フロー: カスタマーケア |
開始 |
| フロー: カスタマーケア |
開始 |
| フロー: カスタマーケア |
開始 |
| フロー: My Order(注文) |
開始 |
| フロー: My Order(注文) |
開始 |
| フロー: My Order(注文) |
開始 |
| ページ: セッションを終了 |

Default Start Flow は、コールセンターに電話をかけたときに表示されるオプション メニューのように機能します。ただし、この仮想エージェントは自然言語でトレーニングされ、インテントにトレーニング フレーズが含まれています。そのため、インタラクションは 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?
カタログ フロー内のすべてのページのフローチャートは次のとおりです。

このフローの複雑さに注目してください。
- 「どのアーティストのグッズが購入できますか?」という質問を飛ばして、すぐに「どのグッズが購入できますか?」と尋ねることもできます。
- デフォルトの開始フローから、「Google Dolls の T シャツを買いたい」や「何か買いたい」と尋ねることができます。つまり、仮想エージェントは、これらの必須パラメータのスロットを埋めるために、フォローアップの質問をします。商品ページに直接移動します。
- Price ダイアログは、再利用される Price ページから取得されます。
- ツアー動画のダイアログは最もシンプルなダイアログに見えますが、実際には特別な処理を行います。このダイアログの一部は再利用されるため、エンドユーザーはすべての情報を一度に指定する場合、他のプロダクトのいずれかに直接入力することもできます。
> "I want The Goo Fighters longsleeve size S."
"The longsleeve of The Goo Fighters size S costs $30. Shall I continue to order?"
まず、ページを接続することから始めましょう。
- [ビルド] > [カタログ] をクリックします。
- [Start Page] をクリックします。
- [ルート] の横にある [+] アイコンをクリックします。
- redirect.artists.overview を追加
- [トランジション] まで下にスクロールし、[ページ] を選択して、[+ 新しいページ] を選択します。
- ページ名に「
Artist Overview」と入力して [保存] をクリックします。
フローの残りの部分を完成させましょう。
- 次のページ、インテント、フルフィルメントを使用して、上記の手順を繰り返すことができます。このテーブルを引き継ぎます。[Page] はフローで選択するページです。[Routes > Transition To] は、作成して移行する新しいフローまたはページです。
ページ(フロー内) | [ルート] > [インテント] | [Routes] > [Transition To] |
カタログの開始 |
| アーティストの概要 |
カタログの開始 |
| プロダクト |
カタログの開始 |
| プロダクトの概要 |
カタログの開始 |
| プロダクトの概要 |
カタログの開始 |
| シャツ |
カタログの開始 |
| 音楽 |
カタログの開始 |
| セッションを終了 |
カタログの開始 |
| フローを終了 |
アーティストの概要 |
| プロダクトの概要 |
次に、静的なフルフィルメントを追加しましょう。
- カタログ フローで、[アーティストの概要] ページをクリックします。
- [Entry fulfillment] セクションで [Edit fulfillment] をクリックします。
- 次の静的フルフィルメントを使用します(エージェントの発言)。
The following bands are signed with G-Records: Alice Googler, G's N' Roses, The Goo Fighters and The Google Dolls.
- [保存] をクリックします。
- カタログ フローで、[商品の概要] ページをクリックします。
- [Entry fulfillment] セクションで [Edit fulfillment] をクリックします。
- 次の静的フルフィルメントを使用します(エージェントの応答)。
We sell shirts, music or the tour movie.
- [保存] をクリックします
ページ パラメータ
パラメータは、セッション中にエンドユーザーが指定した値を取得して参照するために使用されます。各パラメータには名前とエンティティ タイプがあります。@Artist と @Merch は、グッズの注文を行うために収集する必要がある最低限のパラメータです。T シャツや長袖の場合は @ShirtSize も収集し、音楽を注文する場合は @Carrier と @Album の名前も必要になります。
これらのパラメータは「必須」とマークする必要があります。また、これらのパラメータを収集するために、エンドユーザーを記憶し、正しい回答を提供するためのカスタム プロンプトを提供する必要があります。Dialogflow CX には、この目的で使用できるメカニズムがいくつかあります。
たとえば、[パラメータ] セクションでカスタムの静的フルフィルメント メッセージを指定できます。パラメータが必須の場合、これらのパラメータのフルフィルメントが表示されます。これらのレスポンス メッセージはレスポンス キューに追加されます。エージェントのターンの間に、複数のフルフィルメントを呼び出して、それぞれがレスポンス メッセージを生成することが可能です(生成が必要な場合もあります)。Dialogflow は、こうしたレスポンスをレスポンス キューに保持します。ページのライフサイクルと、これらのフルフィルメントがレスポンス キューに追加される順序の詳細については、Dialogflow CX ページのドキュメントをご覧ください。
アーティストの概要ページでパラメータを作成する
ページ パラメータを定義してみましょう。
- [カタログ] フローで、[アーティストの概要] ページをクリックします。
- [パラメータ] ブロックの [+] をクリックします。artist パラメータを追加します。
- 表示名:
artist - エンティティ タイプ:
@Artist - 必須: チェック
- ログ内での秘匿化: 確認
- 次に、カスタム パラメータのフルフィルメント メッセージを追加します。アーティスト パラメータが仮想エージェントによってまだ収集されていない場合、エンドユーザーはレスポンス キューに追加された次のエージェント レスポンスを受け取ります。
From which of these artists would you like to order merchandise?
- リッチな候補ワードを提供する 2 つ目のダイアログ オプションを追加します。[Add dialogue option] をクリックし、次のコード(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 つ] を選択します。
- 次に、次の条件を満たす式を記述します。
- パラメータ:
$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"
}
]
}
]
]
}
- [Event Handler] >
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"
}
]
}
]
]
}
- [Event Handler] >
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] ページ:
- [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 - [Parameter] > [Event Handler] > [
No-match default] - [Parameter] > [Event Handler Fulfillment]:
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"
}
]
}
]
]
}
- [Parameter] > [Event Handler] > [
No-input default] - [Parameter] > [Event Handler Fulfillment]:
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"
}
]
}
]
]
}
- エントリ フルフィルメントをクリックして [パラメータ プリセット] までスクロールします。シャツのページがアクティブになるたびに、カテゴリ パラメータが shirts に設定されます。
パラメータ | 値 |
|
|
- 条件付きルートを追加します。
- 1 つのルールに一致(または)
- 式:
$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"
}
]
}
]
]
}
- インテント ルートを作成します。
redirect.priceでPriceページに遷移します。 - 次のパラメータを作成します。
- パラメータ:
shirtsize- エンティティ タイプ:@ShirtSize-Required、Redact In Log - [Parameter] > [Event Handler] > [
No-match default] - [Parameter] > [Event Handler Fulfillment]:
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"
}
]
}
]
]
}
- [Parameter] > [Event Handler] > [
No-input default] - [Parameter] > [Event Handler Fulfillment]:
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?"
}
]
}
]
]
}
- インテント ルートを作成します。
redirect.priceページへの遷移:Price。 - 次のパラメータを作成します。
- パラメータ:
album- エンティティ タイプ:@Album-Required、Redact In Log - [Parameter] > [Event Handler] > [
No-match default] - [Parameter] > [Event Handler Fulfillment]:
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"
}
]
}
]
]
}
- [Parameter] > [Event Handler] > [
No-input default] - [Parameter] > [Event Handler Fulfillment]:
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 - [Parameter] > [Event Handler] > [
No-match default] - [Parameter] > [Event Handler Fulfillment]:
Do you want a physical CD or the digital album? - [Parameter] > [Event Handler Fulfillment]: [Custom payload]:
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "CD"
},
{
"text": "Digital Album"
}
]
}
]
]
}
- [Parameter] > [Event Handler] > [
No-input default] - [Parameter] > [Event Handler Fulfillment]:
I couldn't understand if you mean CD or MP3. Which one do you want? - [Parameter] > [Event Handler Fulfillment]: [Custom payload]:
{
"richContent": [
[
{
"type": "chips",
"options": [
{
"text": "CD"
},
{
"text": "MP3"
}
]
}
]
]
}
- 条件付きルートを追加します。
- すべてのルールに一致(AND)
- 式:
$page.params.merch != "null" - ページへの切り替え:
Product
商品ページ:
- 次のパラメータを作成します。
パラメータの表示名 | パラメータ エンティティ タイプ | チェック |
|
| 必須、ログ内での秘匿化 |
|
| 必須、ログ内での秘匿化 |
- アーティスト パラメータには、アーティストが不明な場合に表示される次の初期プロンプト フルフィルメントが必要です。
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"
}
]
]
}
- また、フルフィルメントを含む
No-input defaultイベント ハンドラI couldn't understand what you just said. Ask me which artists are signed.も追加します。 - フルフィルメントを含む
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
- [condition] の例:
$session.params.user-age >= 21。ルートの条件と同様の形式を使用します。 - [response] は静的なテキスト レスポンスを取得します。
- 条件付きレスポンスは常に
ifで始まります elifブロックとelseブロックは省略可能です。
Dialogflow CX は、組み込みのシステム関数を利用することもできます。たとえば、日付や時刻の形式を設定したり、現在時刻($sys.func.NOW())を表示したりする場合
確認ページと価格ページを修正して、カタログ フローを完成させましょう。
確認ページ:
次に、確認ページを作成します。これには次の要件があります。
- グッズが CD またはデジタル アルバムの場合。確認画面には、アーティスト、グッズ、アルバム、価格の各フィールドが表示されます。
- グッズが T シャツまたは長袖の場合。確認画面には、artist、merch、size、price の各フィールドが表示されます。
- それ以外の場合(つまり、merch が Tour Movie の場合)。確認画面には、アーティスト、グッズ、価格の各フィールドが表示されます。
- [Confirmation] ページをクリックします。
- [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.ordertransitions to:Order ProcessFlow.decline.proceed.ordertransitions 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.endintent. 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.endintent. Create the following fulfillment:Thank you for contacting G-Records! Have a nice day! - Select the Start Page and click on the
redirect.homeintent. 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 GooglerI am not a fan of G's N' RosesI 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-defaultevent 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-defaultevent 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。 - [Add Dialogue Option] > [Text]:
Have a good day! - 切り替え:
End Session
- [Start] ページを選択し、
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] > [Transition To] |
Customer Care Start |
| 配送 |
Customer Care Start |
| 払い戻し |
Customer Care Start |
| スワップ |
Customer Care Start |
| フローを終了 |
Customer Care Start |
| セッションを終了 |

- [配送] ページに次のエントリ フルフィルメントを作成します。
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! - [Start] ページを選択し、
redirect.homeインテントをクリックします。次のパラメータ プリセットを作成します。restart = true
テストケースを作成する
- 画面の右側にある [エージェントをテストする] ボタンをクリックします。
シミュレータを初めて開いた場合は、エージェント環境とアクティブなフローを選択する必要があります。ほとんどの場合、下書き環境とデフォルトの開始フローを使用する必要があります。
- タイプ:
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
- [保存] をクリックします。
テストケースをさらに作成しましょう。
- まず、リセット(ゴミ箱)アイコンをクリックして、現在のダイアログをクリアします。
- 次のテストケースを作成します。
Alice Googler T シャツを購入する:
>"Buy the Alice Googler t-shirt."
>"XL"
- テストケース名:
Buy the Alice Googler t-shirt - タグ:
#catalog, #shirts, #t-shirt, #AliceGoogler
M サイズの T シャツを購入する:(アーティスト名は言及されていませんが、バンドの概要、商品の概要、シャツ、シャツのサイズに関するページはスキップしたい場合)
>"Buy a t-shirt size M"
>"The Google Fighters"
- テストケース名:
Buy a t-shirt size M - タグ:
#catalog, #shirts, #t-shirt, #TheGoogleFighters - 説明:(アーティスト名は言及されていませんが、バンドの概要、商品の概要、シャツとシャツのサイズのページはスキップしたいとします)
Guns 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として保存します。 - [Manage] > [Test Cases] パネルに移動し、グリッドの右上にある [Run] ボタンを押して、
Shippingテストケースのみを実行します。
このテストは合格するはずです。
- カスタマー ケア フローに戻り、[開始] ページを選択して、[ルート] ヘッダーをクリックします。
すべてのルートを示すグリッドが表示されます。
redirect.shipping.info routeを削除する- [Manage] > [Test Cases] パネルに移動し、グリッドの右上にある [Run] ボタンを押して、
Shippingテストケースのみを実行します。
このテストは失敗するはずです。
- 失敗したテストをクリックすると、失敗の詳細が表示されます。
この場合、テストは次のエラー メッセージで失敗しました。
Page: Page mismatch:
Expected: Shipping
Actual: Start Page
これは、ページがフローに存在しなくなったためです。Shipping ページに移動するはずでしたが、Start ページから移動しませんでした。(または、エンドユーザーにフォールバック メッセージが送信されます)。
つまり、これはリクエストの欠落、つまり偽陰性のテスト結果です。テストが失敗しました。[Shipping] ページが表示されるはずなのに、何も起こらないか、フォールバック メッセージが表示された。
- カスタマーケア フローに戻り、
redirect.shipping.infoをインテント ルートとして [開始] ページに追加します。[配送] ページに移動して [保存] をクリックしてください。 - シミュレータでテストケース
I want to swap my itemを記録し、このテストケースをSwapping#swappingとして保存します。 - [Manage] > [Intents] > [redirect.refund.info] を開き、次のトレーニング フレーズを追加します。
I want to swap this item for a refund
このトレーニング フレーズがないと、お客様が払い戻しのためにアイテムの変更をリクエストしたときに redirect.swapping.info インテントがヒットしますが、アイテムの変更に関する情報ではなく、払い戻しに関する情報を提供する必要があります。
- シミュレータで次のゴールデン テストケース
I want to swap this item for a refundを作成し、このテストケースをSwap for Refund#refundとして保存します。 - [Manage] > [Intents] > [redirect.refund.info] インテントに戻り、
I want to swap this item for a refund行を削除します。 - [Manage] > [Test Cases] に戻り、[Swap for Refund](払い戻し用の交換)テストケースを選択して [Run](実行)します。
最新のテストが失敗しました。エラー メッセージは次のとおりです。
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] をクリックします。
- [トランジション] タブをクリックします。
これにより、すべてのページ遷移のテスト カバレッジが表示されます。

- [インテント] タブをクリックします。
これにより、すべてのインテントのテスト カバレッジが表示されます。

おめでとうございます。これで、小売業者のボットの完全な実例を構築してテストしました。次のラボページに進んで、結論を読み、便利なリファレンスを見つけましょう。
10. まとめ
Dialogflow CX は、チャットボットや音声 bot などの仮想エージェントを作成するための会話型 AI プラットフォーム(CAIP)です。Dialogflow CX を使用すると、ビジュアル bot ビルダー、再利用可能なインテント、複数ターンの会話に対応する機能により、エンタープライズ レベルの会話エクスペリエンスの作成を迅速化できます。
この Codelab では、実際の小売業の仮想エージェントを構築する方法を学びました。次のコンセプトについて説明しました。
- フロー
- パラメータ、カスタム エンティティ、システム エンティティ
- ページ
- インテント ルートや条件ルートなどの状態ハンドラ
- 静的フルフィルメント メッセージと条件付きレスポンス
- フォールバック インテント
- シミュレータ、テストケース、カバレッジ

参照
Dialogflow CX の詳細については、以下のブログとドキュメントをご覧ください。