GitHub - terrenjpetersoncaloriecounter AWS Lex Chatbot, який обчислює калорії на основі

Лічильник калорій Чат-бот

Це чат-бот на базі Lex, який буде обчислювати калорії, зроблені поїздками в різні ресторани швидкого харчування. Він увімкнений через чат-бот FB Messenger, до якого можна отримати доступ зі сторінки Facebook або через додаток Messenger на телефоні.

Зміст

Використання моделей NLU

Цей бот використовує AWS Lex - послугу, яка містить інтелектуальну інформацію для розшифровки запитів користувачів та ініціювання намірів на основі даних, представлених у моделях. Потім наміри викликають лямбда-функції, які містять бізнес-логіку, специфічну для наміру.

калорії

В даний час існує багато різних намірів, на які сортується процес NLU. Ось "основні функції" бота.

  • FoodTypeOptions (Зразок висловлювання - Які мої варіанти харчування?)
  • GetCalories (Зразок висловлювання - Скільки калорій у Big Mac?)
  • GetMexicanFoodCalories (Зразок висловлювання - Скільки калорій у курячому буріто?)
  • GetNuggetsCalories (Зразок висловлювання - Скільки калорій у 20 курячих нагетсах?)
  • GetPizzaCalories (Зразок висловлювання - Скільки калорій у 2 скибочках піци Пеппероні в Papa Johns?)
  • GetChineseCalories (Зразок висловлювання - Скільки калорій у курячому кунг-пао?)
  • GetChickenCalories (Зразок висловлювання - Скільки калорій у шматочку оригінальної курячої рецептури?)

Є також наміри, які доповнюють основні функції.

  • MoreDetails (Зразок висловлювання - Більше деталей. Примітка: це можна викликати лише після того, як попередні запити зроблені в розмові, оскільки це зчитування даних із сеансу).
  • DailyIntakeAnalysis (Зразок висловлювання - проаналізуйте мою їжу. Подібно до більш детальної інформації, тут використовуються дані сеансу, тому потрібно слідувати одному з попередніх запитів.
  • WhatPizzaTypes (Зразок висловлювання - Які типи піци існують?)
  • WhichRestaurants (Зразок виступу - Список ресторанів.)
  • CalculateBMR (Зразок висловлювання - Яке моє щоденне рекомендоване споживання калорій?)
  • GetCarbs (Зразок висловлювання - Скільки вуглеводів у цьому?)

Потім є наміри, які формують «особистість» бота. Вони були створені на основі реального користувацького використання та запобігають використанню загального повідомлення про помилку для реагування.

  • EndConversation (Вбудований намір - використовуються зразки висловлень AWS, такі як - Зупинити)
  • Вступ (Зразки висловлювань - Привіт, розпочати роботу, надіслати повідомлення)
  • Дякую (Зразки висловлювань - Дякую, до побачення, до побачення)
  • Доповнення (зразки висловлювань - я люблю тебе)
  • Критик (зразки висловлювань - U смоктати)
  • Шок (зразки висловлювань - нічого собі)
  • MyName (Зразки висловлювань - як вас звати)
  • HelpRequest (Вбудований намір - використовуються зразки висловлювань AWS, наприклад - Довідка)
  • NewRestaurant (Зразок висловлювання - Новий ресторан. Це очищає сесію.)

У межах кожного з намірів передбачено вибіркові висловлювання, які будують потенційні висловлювання, які може надати користувач. Значення слота (тобто Large Fry) передається функції лямбда як унікальний атрибут.

Ви можете отримати зведену інформацію з AWS CLI, виконавши наступну команду.

Це поєднання вибіркових висловлювань та слотів, які визначають, який намір будуть викликати моделі NLU. Вони підтримуються в Lex і використовуються для навчання моделей.

На даний момент, ось власні слоти, які використовуються за намірами.

Елемент не потрібно вказувати в слоті для NLU, щоб розмістити в ньому значення. Однак, якщо дані розріджені, це може погіршити спосіб інтерпретації запитів користувача NLU.

Кілька слотів в одному намірі

Юзабіліті чат-бота вимагає природного взаємодії з користувачем. Однією з ключових концепцій є те, як включити кілька слотів в один намір. Наприклад, користувач може запитати "Скільки калорій у Big Mac, фрі та кока-колі?" Це три різні елементи, кожна з яких повинна бути проаналізована. У цьому чат-боті основна обробка має безліч різних слотів, які відображаються за намірами. Наприклад, ось слоти, які відповідають наміру GetCalories.

У цьому є кілька пунктів, на які слід звернути увагу.

У наведеному вище прикладі запити моделі NLU аналізуватимуть дані висловлювання на три різні слоти (Їжа, Екстра та Напої).

Порядок слотів не має значення для синтаксичного аналізу, але він визначає, якою буде наступна відповідь (слот 1 - у якому ресторані ви перебуваєте?)

У цьому намірі немає двох слотів - кетчуп та PacketsKetchup. Ця додаткова інформація запитується, якщо картопля фрі просить як допоміжний продукт. Це зумовлено кодом у функції Лямбда, який викликається у гачку коду перевірки.

Правила логіки в лямбда

Вся логіка при формулюванні відповідей на різні наміри обробляється в серії лямбда-функцій. Якою лямбда-функцією викликати керує Lex і встановлює на рівні наміру. Це дозволяє вбудувати модульність у програму, зберігаючи функції легкими.

У Lex є два різних місця, які можуть викликати лямбда-функцію. Перший - через базову перевірку, а ім’я атрибута, яке його ідентифікує, називається invocationSource. Для цього є два потенційні значення - DialogCodeHook та FulfillmentCodeHook. Ось де ці функції лямбда вказані в Lex Bot.

Першим випадаючим списком є ​​перевірка і викликає лямбда-функцію кожного разу, коли викликається бот. Атрибут, який він передає, називається DialogCodeHook. Другим випадаючим списком є ​​Виконання, і викликається лише після того, як обов'язкові слоти будуть завершені, і перевірка з початкового виклику завершена. Це дозволяє різні функції, що забезпечує кращу масштабованість у побудові бота.

Ось огляд кожної написаної функції.

lambda.js - основна функція, яка обробляє базову перевірку для запитів, джерелом якої є лише режим DialogCodeHook.

calcu.js - обчислення відповіді на фактичні калорії в їжі обробляється цим функціонуванням, а джерело отримує FulfillmentCodeHook.

pizza.js - обробляє наміри щодо обчислення калорій у піці, включаючи цілі - WhatPizzaTypes.

misc.js - обробляє такі прості наміри, як допомога, вступ та більше деталей навколо їжі.

chinese.js - обробляє наміри навколо китайської їжі та з’єднує різні слоти, утворюючи їжу.

Таблиці пошуку даних

Основна функціональність цього бота - це можливість відповідати на запити про те, скільки калорій міститься в різних стравах. Хоча слоти, які використовує Lex, корисні для навчання моделям NLU, вони не мають можливості служити файлами пошуку. Саме там надходять об’єкти json, які зберігаються в папці/src/data /.

Ось зразок формату.

Ламбда-функції посилаються на ці об'єкти для відповіді на різні запити та для розрахунку споживання калорій для користувача.

Кожен харчовий продукт може бути продубльований для різних орфограм і фраз, що використовуються для отримання. Наприклад.

Також є таблиці підстановки навколо соусів, заправок та коригування окремих предметів. Наприклад.

Враховуючи, що моделі NLU не виправляють написання, надане користувачем, функція Лямбда повинна обробляти цю частину логіки.

Великі нестандартні слоти

Управління великими спеціальними слотами може бути складним, особливо якщо дані динамічні. Основний пошук продуктів має кілька сотень унікальних цінностей і зростає на основі користувальницького використання. Процес створення цього слоту автоматизований, а дані для користувацького слоту беруться з об'єкта даних foods.json. Це робиться за допомогою AWS CLI, який може завантажувати їх безпосередньо з командного рядка. Всі файли містяться в каталозі [slots> (https://github.com/terrenjpeterson/caloriecounter/tree/master/src/slots) для довідки. Ось кроки, використані для створення.

  1. Об'єкт даних foods.json передається лямбда-функції, яка називається convertFoodsObjForSlot.
  2. Функція сортує дані, усуває дублікати, потім дані відформатовуються у простий масив із лише іменами елемента.
  3. Масив повертається, а потім передається в AWS CLI за допомогою команди put-slot-type.
  4. Потім модель вручну відновлюється через консоль і розгортається, як і будь-яка інша навчальна діяльність.

Синтаксис виглядає так.

Крім того, значення контрольної суми належить до попереднього розгортання спеціального слоту. Ви можете знайти поточну контрольну суму для слота за допомогою команди get-slot-type.

Обмін даними сесії між намірами

Ключ до ефективних тривалих розмов між користувачем та ботом полягає в управлінні контекстом розмови. Наприклад, діалогове вікно може тривати кілька хвилин і викликати багато намірів.

Частиною сприяння цьому є створення потоку розмови. Повідомлення про помилки не повинні бути занадто різкими і повинні привести користувача до альтернативного запиту. Наміри також повинні передавати дані між собою. Цього можна досягти, зберігаючи дані сеансу під час завершення наміру. Це дозволяє наступному наміру отримати інформацію та не вимагати від користувача повторювати її з кожним запитом.

У наведеному вище прикладі розмова починається з того, що користувач вказує, в якому ресторані вони їдять. Це зберігається у сеансі за наміром FoodTypeOptions. Діалогове вікно переходить до деталей їжі, але назва ресторану зберігається. Крім того, початкова реакція на кількість калорій коротка, але пропонує більш детальне пояснення, якщо користувач каже "більше деталей". Дані знову зберігаються у даних сеансу та передаються назад як частина структури Lex. Ось приклад одного з об’єктів.

Ламбда-функції в цьому боті повністю не мають стану, тому будь-які дані з попередніх викликів повинні надходити через об'єкт запиту.

Створення кнопок в інтерфейсі користувача

Однією з особливостей основних інтерфейсів чат-ботів (Messenger, Slack тощо) є кнопки. Вони зменшують зусилля користувача, надаючи ряд таких опцій.

Кожна платформа обміну повідомленнями має власну реалізацію цього шаблону, і ось що використовує Messenger. Lex обробляє переклад, щоб отримати кнопки у правильному форматі, і в рамках Lex атрибут responseCard повинен бути наданий з деталями кнопки.

Модифікація Lex здійснюється повністю через консоль. Ламбда-функції, які обслуговують бізнес-логіку, розміщуються в лямбда-режимі AWS і розгортаються з хоста EC2.

Повний сценарій розгортання /src/build.sh, але короткий огляд можна знайти в наступних інструкціях.

  1. Створіть zip-файл на хості, який виконує роль сервера збірки. Це з сервера збірки, де маніпулюють як вихідним кодом, так і файлами даних. Потім файли даних читаються локально, і коли вони змінюються, створюється нове розгортання.
  2. Завантажте zip-файл у відро s3, використовуючи відповідні команди AWS CLI.
  3. Оновіть існуючу лямбда-функцію новим пакетом і за допомогою команди AWS CLI вкажіть розташування zip-файлу, що містить пакет збірки.
  4. Виконайте тест лямбда-функції безпосередньо з дійсними зразковими даними. Об'єкт відповіді повертається і записується на консоль, а також у локальний файл.

Цей процес повторюється для кожної з лямбда-функцій, які викликає Лекс. Сюди входить наявність принаймні однієї умови тесту для кожної лямбда-функції для забезпечення правильного розгортання.

Додайте особистості до бота

Однією з тем в дизайні ботів є навколо наявності особистості. Щось, що слід враховувати при розробці намірів, це те, що є всі можливі запитання, які може задати користувач. Сюди повинні входити питання, не пов’язані з темою, наприклад, „як вас звати“ або емоційні відповіді на зразок „о-ні“ чи „ви смоктати“. Вони легко кодуються - зазвичай це просто простий відповідь на запит без залучення слотів, і вони, як правило, роблять діалоги більш природними.

Для прикладу, ось коротка відповідь, закодована у функції misc.js, яка відповідає, якщо хтось запитує, як називається бот. У моделях вислів "як тебе звати" вирішує цей намір.

Веб-сайт триває

Як частина початкових зусиль, я намагався опублікувати цього чат-бота в магазині слайків. В рамках цього мені потрібно було створити веб-сайт для громадської підтримки програми. Це незавершене виробництво, яке називається калорійним роботом.com. Його розміщує s3, а джерело знаходиться в папці/website.

Про

Чат-бот на базі AWS Lex, який розраховує калорії на основі різних ресторанів швидкого харчування. Це стаття для завдання кодування на DevPost і активно використовується у Facebook Messenger. Список питань активно управляється тим, які дефекти чи вдосконалення виявляються в реальному світі.