Dialogflow CX: создание виртуального агента розничной торговли

1. Прежде чем начать

В этой лабораторной работе вы узнаете, как создать чат-бот для розничной торговли с помощью Dialogflow CX , платформы разговорного ИИ (CAIP) для создания диалоговых пользовательских интерфейсов. Dialogflow CX позволяет реализовывать виртуальных агентов, таких как чат-боты, голосовые боты и телефонные шлюзы, а также поддерживает несколько каналов на более чем 50 языках.

Эта лабораторная работа поможет вам создать чат-бот для сайта розничной торговли. Вымышленная компания, для которой мы создаём чат-бота, называется G-Records . G-Records — это рок-лейбл, расположенный в Калифорнии. С лейблом работают четыре рок-группы: Alice Googler , G's N' Roses , The Goo Fighters и The Google Dolls . G-Records продаёт товары с символикой этих групп всем поклонникам рока.

В конце этой лабораторной работы вы сможете воспользоваться чат-ботом, чтобы заказать футболки или музыку, или задать вопросы о вашем заказе.

Окончательный результат

Чему вы научитесь

Вы узнаете о преимуществах Dialogflow CX по сравнению с Dialogflow ES на практике! В него входят следующие концепции:

  • Как создать виртуальный агент Dialogflow CX в Google Cloud
  • Узнайте, как создавать потоки
  • Узнайте, как создавать сущности
  • Узнайте, как создавать намерения
  • Узнайте, как создавать страницы и страницы перехода с помощью обработчиков состояний.
  • Узнайте, как переходить со страниц на страницы с использованием маршрутов намерений
  • Узнайте, как переходить между страницами с параметрами и условными маршрутами.
  • Узнайте, как возвращать условные ответы с помощью системных функций.
  • Узнайте, как создавать резервные сообщения
  • Узнайте, как пользоваться симулятором
  • Узнайте, как создавать тестовые случаи и тестовое покрытие

Окончательный дизайн агента Dialogflow CX будет выглядеть следующим образом:

Окончательный результат

Что вам понадобится

  • Для создания агента Dialogflow CX вам понадобится идентификатор Google или адрес Gmail.
  • Доступ к Google Cloud.

2. Настройка среды

Создайте проект Google Cloud

Поскольку Dialogflow CX работает в Google Cloud, необходимо создать проект Google Cloud . Проект организует все ваши ресурсы Google Cloud. Он включает в себя набор участников совместной работы, активированные API (и другие ресурсы), инструменты мониторинга, платежную информацию, а также элементы управления аутентификацией и доступом.

При создании нового проекта вам потребуется ввести его название и привязать его к существующему платежному аккаунту и организации.

Платежный аккаунт используется для определения плательщиков за определённый набор ресурсов и может быть связан с одним или несколькими проектами. Плата за использование ресурсов проекта взимается с привязанного платёжного аккаунта. В большинстве случаев выставление счетов настраивается при создании проекта. Подробнее см. в документации по выставлению счетов . Убедитесь, что для вашего облачного проекта включено выставление счетов.

Создать новый проект

Включить API Dialogflow

Чтобы использовать Dialogflow, вам необходимо включить API Dialogflow для вашего проекта.

  1. Выберите проект, для которого вы хотите включить API, и нажмите Продолжить .
  2. Сверните меню API и служб и нажмите «Создать учетные данные».
  3. Нажмите «Данные приложения».
  4. Скажите «Нет, я их не использую», поскольку вы пока не используете Kubernetes Engine, App Engine или Cloud Functions.
  5. Нажмите «Готово».

Настройка учетных данных

Создайте новый агент Dialogflow CX

Чтобы создать новый агент Dialogflow CX, сначала откройте консоль Dialogflow CX:

  1. Выберите ранее созданный проект Google Cloud.
  2. Нажмите Создать агента .

Заполните форму для основных настроек агента:

  • Вы можете выбрать любое отображаемое имя.
  • В качестве местоположения выберите: us-central1
  • Выберите предпочитаемый вами часовой пояс.
  • Выберите en - английский как язык по умолчанию.

Нажмите «Создать» .

Создать агента

Итак, всё готово. Наконец-то можно приступить к моделированию нашего виртуального агента.

3. Потоки

Сложные диалоги часто включают несколько тем для разговора. В случае с чат-ботом, который мы создаём для G-Records, продающего атрибутику музыкальных групп, у нас будут диалоги о каталоге продукции, оплате, статусе заказа и вопросах обслуживания клиентов. Мы могли бы разделить эти темы разговора на потоки.

Розничный поток

Потоки позволяют командам работать над индивидуальными путями обсуждения. Хорошей практикой будет упрощение потока, чтобы он легко помещался на экране и был более модульным.

Потоки — это новая концепция в Dialogflow CX. В Dialogflow Essentials есть концепция мегаагентов, которые в чём-то похожи на потоки. Однако потоки используются гораздо чаще.

Далее в этой лабораторной работе мы будем использовать обработчики состояний , которые могут завершить поток (чтобы он перешел к следующему или предыдущему потоку), или можно завершить весь сеанс агента.

Давайте создадим несколько потоков.

Создание потоков

  1. В Dialogflow CX нажмите значок + > Создать поток .
  2. Укажите название: Catalog и нажмите Enter.

Создать поток

Ваш первый каталог потоков создан. Теперь создайте остальные потоки:

  • Order Process
  • My Order
  • Customer Care

Потоки

Позже в этой лабораторной работе мы настроим обработчики состояния страницы, это позволит гарантировать, что в конечном итоге визуализация будет выглядеть следующим образом:

Потоки

Симулятор

В правой части консоли Dialogflow CX вы можете протестировать виртуального агента с помощью встроенного симулятора. Вы можете протестировать диалог с самого начала или с конкретного потока.

  1. Нажмите кнопку «Тестовый агент» в правом верхнем углу экрана.
  2. В поле «Обращение к агенту» напишите: Hello Виртуальный агент ответит стандартным приветственным текстом: «Приветствую! Чем я могу помочь?»

Симулятор

Давайте изменим этот приветственный текст по умолчанию.

Начальный поток по умолчанию

Давайте начнем с создания маршрута намерений , который будет активирован после приветствия виртуального агента.

  1. На левой боковой панели «Сборка» > «Потоки » нажмите «Начальный поток по умолчанию» и выберите узел дерева «Начало» .

Откроется начальная страница. Она будет автоматически выбрана в разделе «Сборка» > «Страницы» боковой панели.

  1. В меню Пуск > Маршруты нажмите на Добро пожаловать по умолчанию .

Намерение классифицирует намерение конечного пользователя для одного этапа диалога. В Dialogflow CX намерения могут быть частью обработчика состояний для маршрутизации следующей активной страницы или выполнения.

  1. Удалите все записи «Агент говорит» и добавьте этот новый текст:

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?

Чтобы упростить общение, нам также понадобятся кнопки быстрого ответа / фишки с предложениями.

  1. Нажмите «Добавить параметр диалога» > «Пользовательская полезная нагрузка» и используйте приведенный ниже фрагмент кода.
  2. Используйте приведенный ниже фрагмент кода в качестве пользовательской полезной нагрузки и нажмите «Сохранить» .

Более подробную информацию о пользовательских полезных нагрузках можно найти в документации .

{
    "richContent": [
      [
        {
          "type": "chips",
          "options": [
            {
              "text": "Which artists?"
            },
            {
              "text": "Which products?"
            },
            {
              "text": "About my order..."
            }
          ]
        }
      ]
    ]
  }

Приветственное намерение по умолчанию

  1. Продолжайте и протестируйте приветственное намерение в симуляторе.

Вы, вероятно, задаетесь вопросом, почему не отображается расширенный контент. Это связано с тем, что расширенный контент, такой как подсказки, зависит от интеграции. Для выполнения следующих шагов требуется платёжный аккаунт, но вы можете пропустить их, если у вас его нет.

  1. На левой боковой панели нажмите Управление > Интеграции .
  2. Выберите Dialogflow Messenger и нажмите «Подключиться» .
  3. Во всплывающем окне нажмите Включить .

Включить интеграцию

Появится ещё одно всплывающее окно, на этот раз с интеграционным JavaScript-кодом, который вы можете вставить на свой сайт, чтобы интегрировать компонент Dialogflow Messenger. Поскольку у нас пока нет веб-сайта, мы протестируем виртуального агента непосредственно в инструменте.

Попробуйте Dialogflow Messenger сейчас

  1. Нажмите на ссылку «Попробовать сейчас» .
  2. Нажмите на значок чат-бота в правом нижнем углу, чтобы открыть окно чата. Чтобы начать разговор, напишите Hello .

Попробуйте Dialogflow Messenger сейчас

На данный момент, когда вы нажимаете на фишки с предложениями, виртуальный агент не понимает, что вы имеете в виду. Это связано с тем, что наш виртуальный агент пока не переключается между состояниями. Мы можем сделать это в Dialogflow CX с помощью Pages . Продолжим лабораторную работу: сначала создадим несколько сущностей и намерений .

4. Типы сущностей

Типы сущностей используются для управления извлечением данных из данных, вводимых конечным пользователем. Типы сущностей Dialogflow CX очень похожи на типы сущностей Dialogflow ES. Dialogflow предоставляет предопределённые системные сущности, которые могут сопоставлять многие распространённые типы данных. Например, существуют системные сущности для сопоставления дат, времени, цветов, адресов электронной почты и т. д. Вы также можете создавать собственные пользовательские сущности для сопоставления пользовательских данных.

Давайте начнём с подготовки всех пользовательских сущностей, прежде чем мы сможем спроектировать страницы в потоке. Мы создадим следующие сущности:

Сущности Dialogflow

Создание сущностей

Давайте создадим сущность «Художник» .

  1. Нажмите «Управление» > «Типы сущностей».
  2. Нажмите + Создать
  • Отображаемое имя: Artist
  • Сущности:
  • The Google Dolls (с синонимом: Google Dolls )
  • The Goo Fighters (с синонимом: Goo Fighters )
  • G's N' Roses (с синонимом: Gs and Roses )
  • Alice Googler
  • Нажмите «Дополнительные параметры» и выберите «Нечёткое соответствие» . (Если вы неправильно написали название группы, система всё равно может сопоставить его с правильным объектом.)
  • В дополнительных параметрах также установите флажок Исправить в журнале . (Если вы неправильно написали название группы, оно будет исправлено в журнале.)
  1. Нажмите «Сохранить».

Нам также понадобится сущность для предмета Merch :

  1. Нажмите «Управление» > «Типы сущностей».
  2. Нажмите + Создать
  • Отображаемое имя: Merch
  • Сущности:
  • T-shirt
  • Longsleeve (с синонимом: Longsleeve shirt )
  • Tour Movie
  • Digital Album (с синонимами: MP3 Album , MP3 )
  • CD (с синонимами Disc , Physical CD )
  1. Нажмите «Сохранить».

Нам также понадобится сущность для альбома :

  1. Нажмите «Управление» > «Типы сущностей».
  2. Нажмите + Создать
  • Отображаемое имя: Album
  • Сущности:
  • Live
  • Greatest Hits (с синонимом: Hits )
  1. Нажмите «Сохранить».

Нам также понадобится объект для размеров одежды:

  1. Нажмите «Управление» > «Типы сущностей».
  2. Нажмите + Создать
  • Отображаемое имя: ShirtSize
  • Сущности:
  • XS (с синонимом: Extra Small )
  • S (с синонимом: Small )
  • M (с синонимом: Medium )
  • L (с синонимом: Large )
  • XL (с синонимом: Extra Large )
  • 2XL (с синонимом: Extra Extra Large )
  • 3XL
  1. Нажмите «Сохранить».

И объект для номеров заказов , которые обычно состоят из 4 букв, цифр и 3 цифр (например, ABCD123).

  1. Нажмите «Управление» > «Типы сущностей».
  2. Нажмите + Создать
  • Отображаемое имя: OrderNumber
  • Сущности регулярных выражений
  • Сущность: [AZ]{4}[0-9]{3}
  1. Нажмите «Сохранить».

Конфигурация вашей сущности должна выглядеть примерно так:

@Художник: Тип сущности @Artist

@Merch: Тип объекта @Merch

@Альбом: Тип сущности @Album

@ShirtSize: Тип сущности @ShirtSize

@Номер заказа: Тип сущности @OrderNumber

После подготовки пользовательских сущностей мы можем подготовить намерения. Продолжим лабораторную работу.

5. Намерения

Намерение классифицирует намерение конечного пользователя для одного этапа разговора. В Dialogflow CX оно значительно упрощено. Оно больше не является строительным блоком для управления разговором. Dialogflow CX использует намерения только для сопоставления того, что говорят пользователи. В Dialogflow ES приходилось привязывать всё к намерению (параметры, события, выполнение и т. д.). Намерения в Dialogflow CX содержат только обучающие фразы и, следовательно, могут использоваться повторно. Оно больше не управляет разговором. Поэтому процесс создания намерений будет простым:

Обучающие фразы в намерениях могут использовать сущности для извлечения «переменных» входных данных, поэтому рекомендуется заранее создавать типы сущностей, что мы и сделали на предыдущей странице лабораторных работ.

Создание намерений

Давайте начнем с подготовки всех намерений, прежде чем мы сможем проектировать страницы в потоке.

  1. Нажмите Управление > Намерения .
  2. Нажмите «+ Создать»

Используйте следующие данные:

  • Отображаемое имя 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

Учебные фразы

  1. Нажмите «Сохранить ».
  1. Теперь продолжим и создадим все остальные намерения. Дайте волю своему воображению и придумайте больше обучающих фраз. Рекомендуется иметь не менее 10 обучающих фраз на каждое намерение, чтобы охватить различные способы, которыми пользователь может его активировать. Для целей этой лабораторной работы можно использовать и меньшее количество.

Вот на что следует обратить внимание:

  • Обратите внимание, что при вводе обучающей фразы Dialogflow CX автоматически аннотирует ваши сущности. Если этого не происходит, вам может потребоваться обновить сущность (добавив синоним) или вручную аннотировать обучающую фразу.
  • Более короткие обучающие фразы: система NLU Dialogflow также может работать с более короткими обучающими фразами, и мы привели здесь несколько примеров.
  • Переобучение: Слишком большое количество обучающих фраз для намерения может привести к переобучению и нежелательному результату. Рекомендуется использовать итеративное и инкрементальное тестирование и добавлять обучающие фразы в случае отсутствия соответствия намерению.

Отображаемое имя

Учебные фразы

redirect.product.overview

"Which products do you sell?", "What merchandise items do you have?", "What are you selling?", "What are the items?", "Which products?" "What merchandise?", "Please tell me what you have"

confirm.artists.overview

"Yeah, let me buy merchandise", "Yes, I want to purchase something", "Yes, I would like to order merchandise from Alice Googler" (Примечание: Элис Гуглэр должна быть распознана как сущность @Artist!) , "Ok, let's buy stuff."

redirect.price

"How much does a t-shirt cost?", "What's the price for the tour movie?", "The album is how much?", "I want to know the price of a longsleeve shirt", "What's the price difference?", "What does each product costs?", "What does it cost?", "What is the price?"

redirect.product

"Tour movie", "I am interested in a t-shirt", "Can I buy a digital album?", "I want the CD", "I want to buy something", "Can I purchase a record?", "I want to buy a t-shirt size M of The Google Dolls", "Can I purchase the Alice Googler digital album?"

redirect.product.of.artist

"Yeah, let's shop", "Give me merch of Alice Googler", "Shirts of The Google Dolls that would be nice.", "Yes", "I want The Goo Fighters stuff", "Yes, I want to order merchandise", "Yep, give me items of G's N' Roses", "Go for it", "Anything Alice Googler", "I am a G's N' Roses fan!", "Google Dolls", "Yes of The Google Dolls"

redirect.shirts

"Shirts", "I want to buy shirts", "I am interested in shirts", "I want a shirt", "Shirts of G's N' Roses please", "Give me shirts of the Google Dolls", "I want to buy shirts of Alice Googler"

redirect.music

"Music", "I want to buy music", "I am interested in music", "Give me music of the Goo Fighters", "Music of Goo Fighters please", "Interested in buying the Alice Googler album", "Purchase Alice Googler music"

redirect.album

"Hits", "Live Album", "I want the Greatest Hits Digital Album", "Give me the Greatest Hits CD", "Hits on MP3"

redirect.shirt.size

"XS", "I have M", "I want Large", "My size is 3XL", "Extra Large is the size"

redirect.my.order

"About my order", "I have a question about my order", "My order is ABCD123, I have a question about my order."

status

redirect.my.order.status

redirect.my.order.canceled

"I want to cancel my order", "I want to cancel order ABCD123", "Please cancel order ABCD123", "Undo my order", "Stop my order", "Cancel"

redirect.shipping.info

"How long will it take?", "How long is shipping?", "How long does shipping take?", "When will I receive it?"

redirect.refund.info

"I want a refund.", "Can I get a refund", "I want to return the CD", "I want to return my t-shirt"

redirect.swapping.info

"I want to swap my item", "Can I change my t-shirt for a larger size?", "Can I change my product?", "I want to swap the CD"

redirect.order.process

"I want to buy a t-shirt of the Google Dolls, size S", "Let me buy the digital CD of Alice Googler", "Get me the tour movie of G's N' Roses", "Buy a longsleeve shirt of The Goo Fighters", "Purchase the Alice Googler t-shirt", "Please order me the Google Dolls CD"

confirm.proceed.order

"Yes", "Yes, please continue", "Yes order", "I want to order", "Yeah", "Yep", "I confirm", "Agree", "Go ahead", "Order", "Buy it", "Purchase", "Okay"

decline.proceed.order

"No", "I rather not", "I don't want it anymore", "Don't order", "Stop", "Not anymore", "Nope", "Go back", "Reset", "Decline", "I don't need it"

redirect.home

"Go back", "Home", "Help", "What else can I ask", "Restart", "Can you tell me what I can order?", "What questions can I ask", "I need help", "Advice please", "Hi", "Hello", "Good day!"

redirect.end

"No that's it, goodbye", "Bye", "Cheers", "End", "That's it", "No more questions", "Exit", "Have a good day", "End Call", "Close"

Теперь, когда наши повторно используемые элементы (потоки, сущности и намерения) подготовлены, мы можем объединить их, создав страницы и обработчики состояний.

6. Страницы и обработчики состояний

Диалог (сеанс) Dialogflow CX можно описать и визуализировать как конечный автомат . Например, торговый автомат можно смоделировать как конечный автомат. Он имеет следующие состояния: «Ожидание монет», «Выбрать конфету», «Дать конфету». При наличии набора входных данных он переключается между этими состояниями. Например, опускание монеты переводит торговый автомат из состояния «Ожидание монет» в состояние «Выбрать конфету». Страницы — это способ моделирования этих состояний для виртуального агента Dialogflow CX.

Когда конечный пользователь взаимодействует с Dialogflow CX в ходе диалога, диалог перемещается со страницы на страницу, так что в любой момент времени только одна страница является текущей, текущая страница считается активной, а также поток, связанный с этой страницей, считается активным.

Для каждого потока вы определяете множество страниц, где ваши комбинированные страницы могут поддерживать полноценный диалог по темам, для которых он предназначен. У каждого потока есть специальная стартовая страница. Когда поток активируется, стартовая страница становится текущей. Для каждого этапа диалога текущая страница либо остаётся прежней, либо переходит на другую. Эта концепция позволит вам создавать более крупные агенты с большим количеством страниц и несколькими этапами диалога.

Страницы содержат элементы выполнения (статические диалоги ввода и/или веб-перехватчики), параметры и обработчики состояний . Управление диалогом осуществляется через обработчики состояний, что позволяет создавать различные маршруты перехода на другую страницу Dialogflow CX, в том числе условные (для ветвления диалогов).

Состояние беседы контролируется путем обработки переходов между страницами с помощью трех различных типов маршрутов:

  • Маршруты намерений : когда намерение должно быть соблюдено (например, смена страницы в зависимости от слов конечного пользователя). (Синие линии на визуальной диаграмме.)
  • Условные маршруты : когда необходимо проверить условие (например, смена страницы на основе определенных параметров, сохраненных в сеансе) (оранжевые линии на визуальной диаграмме).
  • Обработчики событий : когда необходимо обработать определенное резервное событие (например, обработка отсутствия ввода, отсутствия совпадения, чтобы устранить неоднозначность выбора конечного пользователя по маршруту намерения или условия) (зеленые линии на визуальной диаграмме).

Высказывания в разговоре (т. е. содержание или ответ пользователю) определяются наполнением, которое может быть как статическим, так и динамическим:

  • Статическое выполнение : когда предоставляется ответ о статическом выполнении
  • Динамическое выполнение : когда веб-перехватчик выполнения вызывается для динамических ответов

Для нашего розничного бота мы создадим несколько маршрутов намерений и предоставим несколько статических ответов о выполнении заказа , которые будут отображаться пользователю сразу после активации страницы. Позже мы создадим параметры с маршрутами условий для сбора информации, необходимой для оформления заказа.

Маршруты намерений страниц

Создание страниц в начальном потоке по умолчанию

Вот блок-схема начального потока по умолчанию:

Каталог связанных страниц

Давайте нажмем на это вместе:

  1. Нажмите «Создать» > «Начать поток по умолчанию».
  2. Нажмите «Стартовая страница».
  3. Нажмите значок + рядом с пунктом «Маршруты».
  4. Добавить redirect.artists.overview
  5. Прокрутите вниз до раздела «Переход» и перейдите в раздел «Каталог» .
  6. Нажмите « Сохранить».
  7. Повторите вышеуказанные шаги для redirect.product.overview и остальных 11 строк из этой таблицы:

Страница (в потоке)

Маршруты > Намерение

Маршруты > Переход к

Начинать

Default Welcome Intent

-

Начинать

redirect.artists.overview

Поток: Каталог

Начинать

redirect.product.overview

Поток: Каталог

Начинать

redirect.shirts

Поток: Каталог

Начинать

redirect.music

Поток: Каталог

Начинать

redirect.product

Поток: Каталог

Начинать

redirect.product.of.artist

Поток: Каталог

Начинать

redirect.refund.info

Поток: Обслуживание клиентов

Начинать

redirect.shipping.info

Поток: Обслуживание клиентов

Начинать

redirect.swapping.info

Поток: Обслуживание клиентов

Начинать

redirect.my.order

Поток: Мой заказ

Начинать

redirect.my.order.canceled

Поток: Мой заказ

Начинать

redirect.my.order.status

Поток: Мой заказ

Начинать

redirect.end

Страница: Конец сеанса

Маршруты стартовой страницы по умолчанию

Начальный поток по умолчанию будет работать подобно меню опций при звонке в колл-центр. Однако в этом виртуальном агенте он обучен на естественном языке, а обучающие фразы находятся в намерениях. Поэтому взаимодействие управляется разговором, а не опциями DTMF, и выглядит более естественным и человечным.

Маршруты стартовой страницы по умолчанию

Создание страниц в Catalog Flow

Следующая стенограмма чата относится к потоку Каталога:

> "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» или «Я хочу купить что-то». Это означает, что виртуальный агент задаст уточняющие вопросы, чтобы заполнить ячейки для этих обязательных параметров. Он сразу перейдет на страницу товара.
  • Диалоговое окно «Цена» берется со страницы «Цена» и будет использоваться повторно.
  • Хотя диалог для видеотура выглядит самым простым, мы сделаем с ним нечто особенное. Мы используем эту часть диалога повторно, чтобы конечные пользователи могли ввести её напрямую для одного из других продуктов, если им нужна вся информация сразу:
 > "I want The Goo Fighters longsleeve size S."
"The longsleeve of The Goo Fighters size S costs $30. Shall I continue to order?"

Давайте сначала соединим страницы.

  1. Нажмите «Создать» > «Каталог».
  2. Нажмите «Стартовая страница».
  3. Нажмите значок + рядом с пунктом «Маршруты».
  4. Добавить redirect.artists.overview
  5. Прокрутите вниз до раздела «Переход» , выберите «Страница» и выберите: + новая страница
  6. Используйте название страницы: Artist Overview и нажмите «Сохранить».

Теперь давайте закончим остальную часть потока:

  1. Предыдущие шаги можно повторить со следующими страницами, намерениями и исполнениями. Используйте эту таблицу. «Страница» — это страница, которую вы выберете в потоке, «Маршруты» > «Переход на» — это новый поток или страница, которую вы создадите и на которую перейдете.

Страница (в потоке)

Маршруты > Намерение

Маршруты > Переход к

Начало каталога

redirect.artists.overview

Обзор исполнителей

Начало каталога

redirect.product

Продукт

Начало каталога

redirect.product.overview

Обзор продукта

Начало каталога

redirect.product.of.artist

Обзор продукта

Начало каталога

redirect.shirts

Рубашки

Начало каталога

redirect.music

Музыка

Начало каталога

redirect.end

Конец сеанса

Начало каталога

redirect.home

Конечный поток

Обзор исполнителей

redirect.product.of.artist

Обзор продукта

Теперь давайте продолжим и добавим больше статических исполнений.

  1. В разделе «Каталог» нажмите на страницу «Обзор исполнителей» .
  2. Нажмите кнопку Изменить выполнение в разделе Выполнение записи .
  3. Используйте следующие статические выполнения ( говорит агент ):
  • The following bands are signed with G-Records: Alice Googler, G's N' Roses, The Goo Fighters and The Google Dolls.
  1. Нажмите «Сохранить».
  2. В каталоге нажмите на страницу «Обзор продукта» .
  3. Нажмите кнопку Изменить выполнение в разделе Выполнение записи .
  4. Используйте следующее статическое выполнение ( говорит агент ):
  • We sell shirts, music or the tour movie.
  1. Нажмите « Сохранить ».

Параметры страницы

Параметры используются для сбора и ссылки на значения, предоставленные конечным пользователем во время сеанса. Каждый параметр имеет имя и тип сущности. @Artist и @Merch — это минимальные параметры, которые необходимо собрать для оформления заказа на товар. Для футболок или лонгсливов также необходимо собрать @ShirtSize , а для заказа музыки — @Carrier и @Album .

Эти параметры необходимо отметить как обязательные . После этого вам потребуется настроить специальные подсказки, чтобы ваш конечный пользователь мог запомнить правильные ответы и собрать эти параметры. В Dialogflow CX есть несколько механизмов, которые помогут вам в этом.

Например, вы можете указать пользовательские статические сообщения о выполнении в разделе «Параметры» . Если параметр обязателен, эти сообщения будут отображаться. Эти сообщения-ответы будут добавлены в очередь ответов . Во время хода агента возможно (а иногда и желательно) вызвать несколько сообщений-выполнений, каждое из которых может генерировать сообщение-ответ. Dialogflow хранит эти ответы в очереди ответов . Чтобы узнать больше о жизненном цикле страницы и порядке добавления этих сообщений-выполнений в очередь ответов, ознакомьтесь с документацией по странице Dialogflow CX .

Создание параметров на странице «Обзор исполнителей»

Давайте определим некоторые параметры страницы:

  1. В окне «Каталог » нажмите на страницу «Обзор исполнителей» .
  2. Нажмите на + в блоке «Параметры» . Добавьте параметр «Исполнитель» :
  • Отображаемое имя: artist
  • Тип сущности: @Artist
  • Требуется: Проверить
  • Редактировать в журнале: Проверить
  1. Теперь добавим несколько сообщений о выполнении пользовательских параметров. Если параметр исполнителя ещё не был собран виртуальным агентом, конечный пользователь получит следующий ответ агента, добавленный в очередь ответов:

From which of these artists would you like to order merchandise?

  1. Добавьте второй вариант диалога с подсказками. Нажмите «Добавить вариант диалога» и используйте этот код (в формате JSON ):
{
  "richContent": [
    [
      {
        "options": [
          {
            "text": "The Google Dolls"
          },
          {
            "text": "The Goo Fighters"
          },
          {
            "text": "Alice Googler"
          },
          {
            "text": "G's N' Roses"
          }
        ],
        "type": "chips"
      }
    ]
  ]
}

Можно обрабатывать различные запросы на резервное выполнение в зависимости от количества попыток, предпринятых конечным пользователем. Это можно сделать с помощью обработчиков событий параметров . Существуют различные встроенные обработчики событий, такие как «Недопустимые параметры» , «Слишком длинные высказывания» , «Нет ввода» , «Нет ввода с первой попытки» , «2 попытки» или «Нет соответствия» . Разница между «нет ввода» и «нет соответствия» заключается в том, что при отсутствии ввода пользователь не давал ответа, а при отсутствии соответствия пользователь давал ответ, но Dialogflow CX не мог сопоставить его со страницей.

  1. Прокрутите вниз до раздела Обработчики событий повторного запроса .
  2. Нажмите «Добавить обработчик событий» и выберите событие: No-match default
  3. Используйте следующее статическое наполнение текста события:

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?

  1. Нажмите «Сохранить».
  2. Нажмите «Добавить обработчик событий» и выберите событие: No-input default
  3. Используйте следующее статическое наполнение текста события:

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?

  1. Нажмите «Сохранить».

Маршруты состояния страницы

Параметры очень эффективны в сочетании с условными маршрутами страниц . Если условие истинно, вызывается соответствующий маршрут страницы. Условием может быть: «Параметр равен определённому значению» , «Параметр не может быть пропущен» , «Форма, которая была заполнена » и многие другие. Подробнее о параметрах и условиях можно узнать в документации Dialogflow CX.

Для нашего виртуального агента розничной торговли нам потребуется собрать последовательность параметров, поэтому нам потребуется создать условие для проверки заполнения «формы». Форма — это список параметров, которые необходимо получить от конечного пользователя для страницы. Виртуальный агент взаимодействует с конечным пользователем в течение нескольких этапов диалога, пока не соберёт все необходимые параметры формы, также называемые параметрами страницы.

Dialogflow CX автоматически устанавливает значения параметров, предоставленные конечным пользователем при заполнении формы. Чтобы проверить, заполнена ли форма на текущей странице полностью, используйте следующее условие: $page.params.status = "FINAL"

Создание условных маршрутов на странице «Обзор исполнителей»

Давайте создадим условный маршрут, который перейдет на следующую страницу, как только станет известен исполнитель:

  1. На странице «Обзор исполнителей» нажмите на значок «+» в разделе « Маршруты» .
  2. Прокрутите вниз до раздела «Условие» .
  3. Выберите хотя бы один (ИЛИ)
  4. Далее мы напишем выражение, которое
  • Параметр: $page.params.status
  • Оператор: =
  • Значение: "FINAL"
  1. Теперь создадим специальное статическое сообщение о выполнении заказа на маршруте, подтверждающее выбор конечного пользователя. Прокрутите вниз до блока «Выполнение» и введите следующие сообщения о выполнении заказа:
  • $session.params.artist, great choice! Rock on!
  • You want to rock with $session.params.artist merchandise. Awesome!
  1. Если условие выполнено, необходимо перейти на страницу «Обзор продукта» . Прокрутите вниз до раздела «Переход» и перейдите на следующую страницу: Product Overview .
  2. Нажмите « Сохранить ».

Параметры

Создание маршрутов на странице «Обзор продукта»

Теперь, когда мы знаем, как создавать параметры и условные маршруты, давайте создадим больше параметров для следующих страниц:

Обзор продукта

  1. Создайте параметр 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"
      }
    ]
  ]
}
  1. Создать параметр merch :
  • Отображаемое имя: merch
  • Тип объекта: @Merch
  • Требуется: Проверить
  • Редактировать в журнале: Проверить
  • Выполнение: Which merchandise item do you want?
  • Нажмите: Добавить параметр диалога > Пользовательская полезная нагрузка :
{
    "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"
            }
          ]
        }
      ]
    ]
  }
  1. Создайте маршрут, который будет перенаправлять на страницу продукта при указании artist и предоставлении merch .
  • Состояние:
  • Сопоставьте каждое правило (И)
  • Выражение: $session.params.artist != null
  • Выражение: $session.params.merch != null
  • Выполнение: Alright! $session.params.merch of $session.params.artist, let's go!
  • Переход: Страница: Product
  1. Создайте маршрут для случая, когда пользователь произнесет «Рубашки»
  • Намерение: перенаправление.рубашки
  • Переход: Страница: Shirts
  1. Создайте маршрут для случая, когда пользователь произнесет «Музыка»
  • Намерение: redirect.music
  • Переход: Страница: Music
  1. Создайте маршрут для случая, когда пользователь запрашивает информацию о ценах.
  • Намерение: redirect.price
  • Переход: Создать новую страницу: Price

После настройки указанной выше конфигурации вы увидите визуализацию, похожую на ту, что представлена ​​на рисунке ниже. Обратите внимание, что маршруты намерений обозначены на схеме синим цветом, а маршруты условий — оранжевым. Обработчики событий, хотя они и не изображены, обозначены зелёным цветом, а при переходе на страницу нескольких типов маршрутов линия будет серой.

Начало потока каталога

К настоящему моменту вы научились создавать потоки , сущности , намерения и страницы с обработчиками состояний, такими как маршруты намерений и условные маршруты на основе параметров . Далее в этой лабораторной работе мы будем использовать условное ветвление в процессе выполнения, чтобы создавать различные диалоги в зависимости от входных данных.

Для завершения работы нашего виртуального агента вы можете использовать следующие конфигурации.

Страница рубашек:

  1. Создайте следующие конфигурации на странице «Рубашки» :
  • Выполнение заказа: Do you want a longsleeve or a t-shirt?
  • Выполнение записи Пользовательская полезная нагрузка:
{
    "richContent": [
      [
        {
          "type": "chips",
          "options": [
            {
              "text": "T-shirt"
            },
            {
              "text": "Longsleeve"
            },
            {
              "text": "Price?"
            }
          ]
        }
      ]
    ]
  }
  1. Создайте маршрут намерения : redirect.price с переходом на страницу Price
  2. Создайте следующий параметр:
  • Параметр: 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?
  • Параметр > Выполнение обработчика событий Пользовательская полезная нагрузка:
{
    "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?
  • Параметр > Выполнение обработчика событий Пользовательская полезная нагрузка:
{
    "richContent": [
      [
        {
          "type": "chips",
          "options": [
            {
              "text": "T-shirt"
            },
            {
              "text": "Longsleeve"
            }
          ]
        }
      ]
    ]
  }
  1. Нажмите на запись выполнения и прокрутите вниз до раздела «Предустановки параметров» . Каждый раз, когда страница «Рубашки» становится активной, параметр категории будет установлен на «рубашки» :

Параметр

Ценить

category

shirts

  1. Добавить условный маршрут:
  • Соответствие хотя бы одному правилу (ИЛИ)
  • Выражение: $session.params.merch = "T-shirt"
  • Выражение: $session.params.merch = "Longsleeve"
  • Переход на новую страницу: Shirt Size

Страница с ценами:

Поскольку сообщения о ценах будут зависеть от выбранного товара или категории (музыка или футболки), мы исправим эту часть позже в ходе лабораторной работы. Пока достаточно просто ввести плейсхолдер.

  1. Создайте следующие конфигурации на странице цен :
  • Выполнение записи: PRICE TODO

Поскольку вы можете запросить цену из разных мест диалога, он всегда должен давать ответ и возвращать вас к предыдущей части диалога для продолжения оформления заказа. В дереве диалога есть 5 мест, где можно получить информацию о цене (Рубашка, Размер рубашки, Музыка, Оператор связи, а также напрямую через Маршрут намерения). Поэтому нам понадобятся некоторые условные маршруты для возврата назад:

  1. Добавить условный маршрут:
  • Сопоставьте каждое правило (И)
  • Expression: $session.params.category = "shirts"
  • Expression: $session.params.merch = "null"
  • Transition to new page: Shirts
  1. Add a Conditional Route:
  • Match Every rule (AND)
  • Expression: $session.params.category = "shirts"
  • Expression: $session.params.size = "null"
  • Transition to new page: Shirt Size
  1. Add a Conditional Route:
  • Match Every rule (AND)
  • Expression: $session.params.category = "music"
  • Expression: $session.params.album = "null"
  • Transition to new page: Music
  1. Add a Conditional Route:
  • Match Every rule (AND)
  • Expression: $session.params.category = "music"
  • Expression: $session.params.merch = "null"
  • Transition to new page: Carrier
  1. Add a Conditional Route:
  • Match Every rule (AND)
  • Expression: $session.params.category = "null"
  • Transition to new page: Product Overview

Shirt Size Page:

  1. Create the following configurations in the Shirt Size Page:
  • Entry fulfillment: What shirt size do you want?
  • Entry fulfillment Custom payload:
{
    "richContent": [
      [
        {
          "type": "chips",
          "options": [
            {
              "text": "XS"
            },
            {
              "text": "S"
            },
            {
              "text": "M"
            },
            {
              "text": "L"
            },
            {
              "text": "XL"
            },
            {
              "text": "2XL"
            },
            {
              "text": "3XL"
            }
          ]
        }
      ]
    ]
  }
  1. Create an Intent route : redirect.price with a transition to the Price Page.
  2. Create the following parameter:
  • Parameter: shirtsize - Entity Type: @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"
            }
          ]
        }
      ]
    ]
  }
  1. Add a Conditional Route:
  • Match Every rule (AND)
  • Expression: $page.params.shirtsize != "null"
  • Transition to Page: Product

Music Page:

  1. Create the following configurations in the Music Page:
  • Entry fulfillment: We have a Greatest Hits Album or the Live Album. Which one do you want?
  • Entry fulfillment Custom payload:
{
    "richContent": [
      [
        {
          "type": "chips",
          "options": [
            {
              "text": "Greatest Hits"
            },
            {
              "text": "Live"
            },
            {
              "text": "Price?"
            }
          ]
        }
      ]
    ]
  }
  1. Create an Intent Route : redirect.price with a transition to Page: Price .
  2. Create the following parameter:
  • Parameter: album - Entity Type: @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"
            }
          ]
        }
      ]
    ]
  }
  1. Click on the entry fulfillment and scroll down to Parameter presets , each time when the Music page gets active, the category parameter will be set to music :

Параметр

Ценить

category

music

  1. Add a Conditional Route:
  • Match Every rule (AND)
  • Expression: $page.params.album != "null"
  • Transition to Page: Carrier

Carrier Page:

  1. Create the following configurations in the Carrier Page:
  • Entry fulfillment: Do you want this album on CD or MP3?
  • Entry fulfillment Custom payload:
{
    "richContent": [
      [
        {
          "type": "chips",
          "options": [
            {
              "text": "CD"
            },
            {
              "text": "MP3"
            },
            {
              "text": "Price?"
            }
          ]
        }
      ]
    ]
  }
  1. Create an Intent route : redirect.price which transitions to the Price Page.
  2. Create the following parameter:
  • Parameter: merch - Entity Type: @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"
            }
          ]
        }
      ]
    ]
  }
  1. Add a Conditional Route:
  • Match Every rule (AND)
  • Expression: $page.params.merch != "null"
  • Transition to Page: Product

Страница продукта:

  1. Create the following parameters:

Parameter Displayname

Parameter Entity Type

Проверки

artist

@Artist

Required, Redact in log

merch

@Merch

Required, Redact in log

  1. The artist parameter needs the following initial prompt fulfillment, which will be shown when the artist isn't known. 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"
      }
    ]
  ]
}
  • Also add a No-input default event handler with fulfillment: I couldn't understand what you just said. Ask me which artists are signed.
  • And a No-match default event handler with fulfillment: I missed that. Please ask me which artists are signed.
  1. The merch parameter needs reprompt event handlers as well.
  • Add a No-input default event handler with fulfillment: I couldn't understand what you just said. Which merchandise item do you want?
  • And a No-match default event handler with fulfillment: I missed that. Which merchandise item do you want?

The next route will transition to the confirmation page when the artist is known and the user chooses a "Tour Movie".

  1. Add a Conditional Route:
  • Match Every rule (AND)
  • Expression: $session.params.artist != null
  • Expression: $session.params.merch = "Tour Movie"
  • Parameter Presets Add Parameter > price = 25
  • Transition to new page: Confirmation

The next route will transition to the confirmation page when the artist is known and the user chooses a "T-shirt" and the shirt size is chosen.

  1. Add a Conditional Route:
  • Custom Expression: $session.params.artist != null AND $session.params.merch = "T-shirt" AND $session.params.shirtsize != null
  • Parameter Presets Add Parameter > price = 25
  • Transition to page: Confirmation

The next route will transition to the confirmation page when the artist is known and the user chooses a "Longsleeve" and the shirt size is chosen.

  1. Add a Conditional Route:
  • Custom Expression: $session.params.artist != null AND $session.params.merch = "Longsleeve" AND $session.params.shirtsize != null
  • Parameter Presets Add Parameter > price = 30
  • Transition to page: Confirmation

The next route will transition to the confirmation page when the artist is known and the user chooses a "CD" also the album name is chosen.

  1. Add a Conditional Route:
  • Custom Expression: $session.params.artist != null AND $session.params.merch = "CD" AND $session.params.album != null
  • Parameter Presets Add Parameter > price = 15
  • Transition to page: Confirmation

The next route will transition to the confirmation page when the artist is known and the user chooses a "Digital Album" and the album name is chosen.

  1. Add a Conditional Route:
  • Custom Expression: $session.params.artist != null AND $session.params.merch = "Digital Album" AND $session.params.album != null
  • Parameter Presets Add Parameter > price = 10
  • Transition to page: Confirmation

Next, we will now make some advanced conditionals with prompts that detect missing information. The next route will transition back to the music page when the artist is known and the user chooses a "CD" or a "Digital Album" but the album name was not chosen.

  1. Add a Conditional Route:
  • Custom Expression: $session.params.artist != null AND ($session.params.merch = "CD" OR $session.params.merch = "Digital Album") AND $session.params.album = null
  • Fulfillment: I would also need to know which album you would like to buy!
  • Transition to page: Music

And the last route will transition to the confirmation page when the artist is known and the user choose a "T-shirt" or a "Longsleeve", but when t-shirt size was not chosen.

  1. Add a conditional Route:
  • Custom Expression: $session.params.artist != null AND ($session.params.merch = "T-shirt" OR $session.params.merch = "Longsleeve") AND $session.params.shirtsize = null
  • Fulfillment: I would also need to know which shirt size you need!
  • Transition to page: Shirt Size

In the next part of the lab, we will make use of conditional fulfillments to give different fulfillment messages depending on the input.

7. Conditional Responses

Some responses will return a different dialogue based on the input, The dialogues will branch off, we call this conditional responses . This can become interesting, when you are not making use of webhook fulfillments, where the conditional responses were determined on the back-end. An example could look like:

if [condition]
  [response]
elif [condition]
  [response]
elif [condition]
  [response]
else
  [response]
endif
  • An example of a [condition] could be: $session.params.user-age >= 21 . It uses a similar formatting as the conditions in the routes.
  • An [response] takes the static text response
  • Conditional responses always start with if
  • elif and else blocks are optional

Dialogflow CX can also make use of built-in system functions to make use of. For example to format a date or time, or to display the current time ( $sys.func.NOW() )

Let's finalize the Catalog flow, by fixing the Confirmation and Price Pages.

Confirmation Page:

Now we will build the confirmation page. It has the following requirements:

  • If merch is CD or Digital Album . We will show the following fields in the confirmation: artist , merch , album and price .
  • If merch is T-shirt or Longsleeve . We will show the following fields in the confirmation: artist , merch , size and price .
  • Else (and thus if merch is Tour Movie ). We will show the following fields in the confirmation: artist , merch and price .
  1. Click on the Confirmation Page.
  2. Click Edit Fulfillment > Agent Responses > Add dialogue option > 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
  1. Create the following Custom payload:
  • Custom payload:
{
  "richContent": [
    [
      {
        "options": [
          {
            "text": "Yes, confirm"
          }
        ],
        "type": "chips"
      }
    ]
  ]
}

Next, create two intent routes:

  1. confirm.proceed.order transitions to: Order Process Flow.
  2. decline.proceed.order transitions to End 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.

  1. In the decline.proceed.order intent route, scroll down to Parameter presets and add the following parameters:

Parameter

Value

artist

null

merch

null

shirtsize

null

category

null

album

null

price

null

restart

true

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.

  1. 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..."
            }
          ]
        }
      ]
    ]
  }
  1. 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

Conditional Responses

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

  1. Go to the My Order Flow, and create the following intent transitions:

Page (In Flow)

Routes > Intent

Routes > Transition To

My Order Start

redirect.my.order

My Order

My Order Start

redirect.my.order.status

My Order Status

My Order Start

redirect.my.order.canceled

My Order Cancellation

My Order Start

redirect.end

End Session

My Order Start

redirect.home

End Flow

My Order

redirect.my.order.status

My Order Status

My Order

redirect.my.order.canceled

My Order Cancellation

Default Start Flow

redirect.my.order.canceled

Flow: My Order

Default Start Flow

redirect.my.order.status

Flow: My Order

  1. 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.
  1. 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?
  1. 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?
  1. 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"
      }
    ]
  ]
}
  1. 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"
      }
    ]
  ]
}
  1. 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?
  1. 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?
  1. 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?
  1. 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?
  1. Test the flow and create the following two test scenarios:
>"About my order"
>"ABCD123"
>"Status"

And:

>"What's the status of order DEFG222"
  1. 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!
  2. 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.

  1. 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.

  1. Go to Manage > Intents and select the Default Negative Intent.
  2. 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
  1. 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

  1. 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:

  1. 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.

  1. 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.

  1. 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.

  1. 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

  1. Go to the Order Process Flow, and create the following intent transitions:

Page (In Flow)

Routes > Intent

Routes > Transition To

Order Process Start

redirect.end

End Session

Order Process Start

redirect.home

End Flow

Order Process Start

confirm.proceed.order

New Page: Shipping Details

  1. 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.
  1. 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

firstname

@sys.person

Required

What's your first name?

I'm sorry I missed that. What's the first name?

I'm sorry, I didn't understand. What's the first name?

lastname

@sys.person

Required

What's your last name?

I'm sorry I missed that. What's the last name?

I'm sorry, I didn't understand. What's the last name?

address

@sys.address

Required

What's your address?

I missed that. What's the address?

I'm sorry, I didn't understand. What's the address?

zipcode

@sys.any

Required

What postal code or zipcode do you have?

I'm sorry, what's the zip or postal code? For example: 1234AB or 10001.

I'm sorry, I didn't understand. What's the zip or postal code? For example: 1234AB or 10001.

city

@sys.geo-city

Required

What's the name of the city?

I missed that, what's the name of the city?

I'm sorry, I didn't understand. What's the name of the city?

country

@sys.geo-country

Required

What's the name of the country?

I missed that, what's the name of the country?

I'm sorry, I didn't understand. What's the name of the country?

email

@sys.email

Required

Lastly, what's your email address?

I am sorry. What's the email address? For example name@domain.com.

I am sorry, I didn't understand. What's the email address? For example name@domain.com.

  1. Create the following conditional route:
  • Customize Expression: $page.params.status = "FINAL"
  • Transition to new Page: Payment Details
  1. 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
  1. Create the following Intent Route
  • Intent: confirm.proceed.order
  • Agent Says: 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!
  • Transition: End Session
  1. 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!
  2. Select the Start Page and click on the redirect.home intent. Create the following parameter preset: restart = true

Awesome! By now we have a fully working realworld retailer chatbot! In the next lab, we will test how well the virtual agent performs!

9. Test your virtual agent

You can use the built-in simulator to test the dialogues of your virtual agent. The advantage of testing the flows in the simulator is that you will see a nice overview of flows, pages, parameters, and (DTMF) events that the simulator collected while walking through your flows. This makes testing easier than testing it directly in an integration, as those types of information will be hidden from the end user. It's even possible to create test cases, save and reuse those test cases. This makes a lot of sense, for when you maintain or edit your flows over time, and you want to be sure that none of your changes break your previous work.

It is also possible to export and import previously made test cases, by storing the tests in Google Cloud Storage or local. Exporting a test will download a blob file. To learn more about the simulator and test cases check out the Simulator / Test Cases Docs .

Before creating some test cases, let's first finalize the rest of our virtual agent:

Creating the Customer Care Flow

  1. Go to the Customer Care Flow, and create the following intent transitions:

Page (In Flow)

Routes > Intent

Routes > Transition To

Customer Care Start

redirect.shipping.info

Перевозки

Customer Care Start

redirect.refund.info

Возвращать деньги

Customer Care Start

redirect.swapping.info

Обмен

Customer Care Start

redirect.home

End Flow

Customer Care Start

redirect.end

Конец сеанса

Customer Care Flow

  1. Create the following entry fulfillments for the Shipping Page:
  • Shipping physical merchandise items can take up to 2 weeks.
  • Is there anything else I can help you with?
  1. Create the following entry fulfillments for the Refund Page:
  • 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?
  1. Create the following entry fulfillments for the Swapping Page:
  • 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?
  1. 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!
  2. Select the Start Page and click on the redirect.home intent. Create the following parameter preset: restart = true

Create test cases

  1. Click the Test Agent button on the right side of the screen.

When you first open the simulator, you need to select an agent environment and active flow. In most cases, you should use the draft environment and default start flow.

  1. Type: Hi

Customer Care Flow

  1. Ask: Which artists are signed with your label?
  2. Say: The Google Dolls
  3. Say: I am interested in buying a shirt
  4. Say: A t-shirt
  5. Say: Medium
  6. Now click on the save test case button. Which you can find in the top of the simulator (next to the redo arrow, and reset trash bin icon)

Customer Care Flow

  1. Give it the following details:
  • Test case name: Buy Google Dolls t-shirt size M
  • Tags: #catalog, #shirts, #t-shirt, #TheGoogleDolls
  1. Нажмите «Сохранить».

Let's create more test cases.

  1. First clear the current dialogue, by clicking on the Reset (thrash bin) icon.
  2. Create the following test cases:

Buy the Alice Googler t-shirt:

>"Buy the Alice Googler t-shirt."
>"XL"
  • Test case name: Buy the Alice Googler t-shirt
  • Tags: #catalog, #shirts, #t-shirt, #AliceGoogler

Buy a t-shirt size M: (Note the Artist name hasn't been mentioned, but you do want to skip the bands overview, products overview, shirts and shirt size pages)

>"Buy a t-shirt size M"
>"The Google Fighters"
  • Test case name: Buy a t-shirt size M
  • Tags: #catalog, #shirts, #t-shirt, #TheGoogleFighters
  • Description: (Note the Artist name hasn't been mentioned, but you do want to skip the bands overview, products overview, shirts and shirt size pages)

Purchase Music of G's N' Roses (Note this will skip the bands overview and products overview page)

>"Purchase music of G's N' Roses"
>"Live"
>"CD"
  • Test case name: Purchase music of G's N' Roses
  • Tags: #catalog, #music, #CD, #GsNRoses, #live
  • Description: (Note this will skip the bands overview and products overview page)

Check price information:

>"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"
  • Test case name: Price info
  • Tags: #catalog, #music, #tourmovie, #shirts
  • Description: Test price info on various points in the dialogue

Test pre-recorded test cases

  1. Select Manage > Test Cases in the Dialogflow main menu on the left.
  2. Select all the test cases and press the Run button, above the table.

Dialogflow CX will run all the selected test cases against the recording that was saved as a "Golden Test Case", if the results are the same as how you saved it, then the tests are passed. - Did something change in the flows like Pages that are not correctly configured, or intents that directed you to the wrong pages, then the tests will fail.

Test Cases

  1. In the simulator ask the following question: How long will shipping take?
  2. Note the result, and save the test case as Shipping with the tag: #shipping .
  3. Go to the Manage > Test Cases panel and press the Run button on the top right of the grid, to run only the Shipping test case.

This test should pass.

  1. Go back to the Customer Care Flow, Select the Start Page and click on the Routes header.

This will show a screen with a grid that shows all the routes.

  1. Remove the redirect.shipping.info route
  2. Go to the Manage > Test Cases panel and press the Run button on the top right of the grid, to run only the Shipping test case.

This test should fail.

  1. You can click on the failed test, to see the details of the fail.

In this case the test failed with the below error message:

Page: Page mismatch:
Expected: Shipping
Actual: Start Page

The reason for this is because the page doesn't exist in the flow anymore. We expected the Shipping Page, but instead we never moved away from the Start Page. (or your end-users would receive a fallback message.)

With other words, this is a missed request, a False Negative Test result. The test failed. We expected the Shipping Page, but nothing happens, or a fallback message was shown.

  1. Go back to the Customer Care Flow, and add the redirect.shipping.info as an intent route, to the Start Page. Don't forget to transition to the Shipping Page and hit Save .
  2. In the simulator record the following test case: I want to swap my item , save this test case as Swapping #swapping .
  3. Open Manage >Intents > redirect.refund.info and add the following training phrase: I want to swap this item for a refund

Without that training phrase, when a user would ask to change an item for a refund, it would hit the redirect.swapping.info intent, but we don't want to give information on changing items, we want to give information on refunds.

  1. Create the following golden test case: I want to swap this item for a refund in the simulator, and save this test case as Swap for Refund #refund
  2. Go back to the Manage >Intents > redirect.refund.info intent, and remove the I want to swap this item for a refund line.
  3. Go back to Manage > Test Cases , select the Swap for Refund test case, and Run it.

Your latest test failed, with the below error message:

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

With other words, this is a missed understood request, a False Positive Test result. The test failed. We expected the Refund Page, but Swapping Page became active.

Покрытие

In Dialogflow CX, test coverage is a measure used to describe the degree to which the dialogue of the virtual agent (Pages and Intents) is executed when a particular test suite runs. A virtual agent with high test coverage, measured as a percentage, has had more of its dialogues executed during testing, which suggests it has a lower chance of containing undetected bugs (like missed understood requests) compared to a virtual agent with low test coverage.

  1. To view a test coverage report for all test cases, click Coverage .
  2. Click on the tab Transitions .

This will show you the test coverage for all the page transitions.

Transitions Coverage

  1. Click on the tab Intents .

This will show you the test coverage for all the intents.

Intents Coverage

Congratulations, by now you have built and tested a complete real world example of a retailer bot! Let's go to the next lab page to read the conclusion and find some handy references!

10. Conclusion

Dialogflow CX is a Conversational AI Platform (CAIP) for creating virtual agents like chat or voice bots. Dialogflow CX empowers your team to accelerate creating enterprise-level conversational experiences through visual bot builders, reusable intents, and the ability to address multi-turn conversations.

In this codelab, you have learned how to build a real world retail virtual agent. We addressed the following concepts:

  • Потоки
  • Parameters, Custom & System Entities
  • Страницы
  • State Handlers like Intent Routes and Condition Routes
  • Static Fulfillment Messages and Conditional Responses
  • Fallback intents
  • Simulator, Test Cases and Coverage

Окончательный результат

Ссылки

To learn more about Dialogflow CX have a look into the following blogs and documentation!