Dialogflow fullfillment

Dialogflow i fulfillment – co to właściwie jest? [6]

Zdarza się Wam, że chatbot, oprócz statycznych odpowiedzi, powinien wykonać dodatkowe czynności? Może chcecie odpowiedzi użytkownika zapisać do bazy danych lub wygenerować dynamiczną odpowiedź? W takim momentach na pomoc przychodzi funkcjonalność Fulfillment w Dialogflow. Dzisiejeszy artykuł jest kolejnym poświęconym Dialogflow, a dowiecie się z niego w jaki sposób podpiąć pod chatbota zewnętrzne API. Na potrzeby artykułu i przykładu wykorzystam narzędzie Mockservice.io w celu zasymulowania zewnętrznego serwera.

Problem 

Tak jak mogliście się dowiedzieć ze wcześniejszych artykułów, jestem w trakcie tworzenia chatbot’a, który pomaga w nauce słówek z języka angielskiego. Chatbot będzie umożliwiał dodawanie słówek i ich tłumaczeń, a na ich podstawie wygeneruje testy, quizy oraz fiszki, które pomogą nam w ich nauce. Już z samego tego opisu wynika, że chatbot, poza prowadzeniem konwersacji, wymaga interakcji z zewnętrznymi serwisami (chociażby w celu zapisania słówek do jakiejś bazy danych). W dzisiejszym artykule zaimplementuję opcję dodawania słówek. Podstawowe założenia?

  • Bot pozwoli dodawać słówka i ich tłumaczenia
  • Jeśli potencjalne tłumaczenie zostanie znalezione, bot zasugeruje je użytownikowi

Rozwiązanie będzie wymagało włączenia opcji Fulfillment w Dialogflow oraz implementacji zewnętrznego serwisu. Aby uniknąć tego ostatniego i skupić się na logice biznesowej postanowiłem wykorzystać narzędzie do symulowania zewnętrznego API, aby skrócić czas dostarczenia takiego rozwiązania. Narzędzie to już wcześniej przedstawiłem w TYM miejscu i kolejny raz polecam je, ponieważ jest bardzo przydatne na etapie „prototypowania” bota.

Fulfillment

A co to jest Fulfillment? Fulfilment pomaga połączyć agenta (bota), z zewnętrznym serwisem. Opcja ta jest uruchamiana na poziomie intentu, a nie globalnie. W praktyce oznacza to, że to my decydujemy, który intent potrzebuje dodatkowej integracji z zewnętrznym API. Taka integracja jest niczym innym, jak zapytaniem POST to wskazanego przez nas endpoint’a. Kiedy możemy to zastosować? Gdy użytkownik prosi o informacje na temat dzisiejszej pogody w Zakopanem, możemy odpytać zewnętrzne API o aktualną pogodę i odesłać użytkownikowi odpowiednio sformatowaną odpowiedź.

Jak wygląda krok po kroku uruchomienie Fulfillment:

  • Użytkownik wysyła wiadomość (tekstowo lub głosowo)
  • Dialogflow analizuje wiadomość i przypisuje do jednego ze zdefiniowanych intentów
  • Wysyłany zostaje request do zdefiniowanego endpoint’a. Request zawiera takie informacje jak:
    • intent
    • parametry
    • akcja
    • kontekst
    • itp.
  • Zewnętrzny serwis przetwarza zapytanie (integracja z bazą danych itp.)
  • Serwis odpowiada wiadomością zawierająca odpowiednio sformatowaną odpowiedź dla użytkownika
  • Dialogflow wysyła odpowiedź do użytkownika
  • Użytkownik otrzymuje odpowiedź

Nieco bardziej szczegółowe informacje możecie znaleźć TU i TU.

Dodaj słówko

Przykładem zastosowania opcji fulfillment będzie funkcjonalność dodawania nowego słówka wraz z tłumaczeniem do bazy chatbot’a. Flow jakie sobie wymyśliłem będzie wyglądać mniej więcej tak:

 

Dialogflow fulfillment

Czyli:

  • użytkownik wybiera z menu opcję „Dodaj słówko” lub wpisuje podobną frazę
  • bot pyta się o słówko w języku angielskim
  • użytkownik wpisuje słówko
  • bot odpytuje zewnętrzne API w celu pobrania sugestii tłumaczeń i generuje sugestie/podpowiedzi użytkownikowi
  • użytkownik wybiera jedną z opcji lub wpisuje tłumaczenie
  • bot prosi go o potwierdzenie

Implementacja – intents

Schemat jaki stworzyłem na potrzeby powyższego flow jest następujący:

Intents - dodaj słówko

Użytkownik po wpisaniu frazy, która mówi o tym, że chce dodać słówko do bazy zostaje przekierowany do intent o nazwie add_word i zostaje poproszony o podanie słówka (w języku ang.), które chce dodać. Kolejnym intent’em jest add_word.handle-word. Jest to tzw. follow-up intent, typu fallback, czyli taki który jest procesowany tylko w kontekście rodzica i który odczytuje wszystko co napisze użytkownik. Taki rodzaj intent’u w moim przypadku ma za zadanie zapamiętać słówko wpisane przez użytkownika, odpytać zewnętrzne API o sugestie tłumaczeń i wyświetlić je użytkownikowi. Kolejny intent to add_word.handle-translation. To również jest intent typu follow-up (fallback), który podobnie jak poprzednik czeka na odpowiedź użytkownika, a następnie generuje dynamiczną odpowiedź do użytkownika z prośbą o potwierdzenie zapisania słówka. Użytkownik odpowiadając Tak lub Nie spowoduje, że słówko zostanie zapisanie lub nie, a odpowiedni komunikat zostanie wyświetlony.

Implementacja – fulfillments

Z powyższego opisu wynika, że są 3 intent’y, które wymagają dodatkowej pracy (integracji z bazą, generowania dynamicznej odpowiedzi czy odpytania zewnętrznego API):

  • add_word.handle-word
  • add_word.handle-translation
  • add_word.adding.yes

Aby włączyć fulfillment  w powyższych elementach wchodzimy w każdy z nich po kolei i włączamy Enable webhook call for this intent”.

Dialogflow fulfillment

Kolejnym krokiem będzie stworzenie endpoint’a, serwisu, który będzie przetwarzał nasze zapytania wysyłane z Dialogflow. Tak jak wcześniej wspomniałem, na potrzeby artykułu oraz prototypowania, nie ma sensu tworzenia i hostowania działającego API. Wystarczy stworzyć tzw. mock-up prawdziwego API. Można to zrobić na wiele sposobów, a jednym z nich jest użycie narzędzia Mockservice.io. Opisywane w innym artykule, narzędzie pozwala tworzyć w prosty sposób publiczne endpoint’y, które potrafią symulować prawdziwe serwisy.

Aby stworzyć taki endpoint, logujemy się do narzędzia, tworzymy nowy projekt, endpoint (nazywam go VocabularyTrainer) i ustawiam Http method na POST (taki typ request’u jest wysyłany z Dialogflow). Póki co nie dodaję żadnej odpowiedzi, ale mamy już działający url do własnie stworzonego endpoint’a.

Mockservice - pusty endpoint

Tak stworzony endpoint kopiujemy, wracamy do DIalogflow i przechodzimy od zakładki Fulfillments. W zakładce tej włączamy Webhook i wklejamy w miejscu url, właśnie skopiowany adres do endpoint’a.

 

Fulfilment - właczanie

Tym sposobem uruchomiliśmy opcję fulfillment i dla każdego wybranego intent’u Dialogflow będzie wysyłał zapytanie do naszego endpoint’a, który zdefiniowaliśmy, oczekując przy tym na odpowiedź od niego. W kolejnej sekcji pokażę Wam jak można wygenerować szybko taką odpowiedź, aby bot zaczął odpowiadać poprawnie.

Implementacja – fulfillments – odpowiedź

Pierwszym intent’em jaki chcemy przeprocesować jest add_word.handle-word, którego zadaniem będzie odczytanie słówka w języku angielskim, zasugerowanie tłumaczeń i zapisanie słówka w kontekście rozmowy. Aby zasymulować tego typu odpowiedź przechodzimy do endpoint’a stworzonego w poprzedniej sekcji w Mockservice.io. Jedną z opcji narzędzia jest możliwość generowania dynamicznej odpowiedzi za pomocą Java Script’u na podstawie przychodzącego zapytania. Aby tej opcji użyć przechodzimy do sekcji Body i zmieniamy jego typ na Dynamic.

Mockservice - dynamic

Po włączniu tej opcji możemy wygenerować odpowiedź implementując metodę getBody(requestContext). Obiekt requestContext zawiera informacje o przychodzącym zapytaniu (np. http method, body, headers, itp.). W naszym przypadku ważna jest informacja o tym jaki intent jest w tej chwili przetwarzany, abyśmy mogli wykonać odpowiednie akcje.

Przetwarzanie intent’u add_word.handle-word zrealizowałem w następujący sposób:

Mockservice - dynamic - 1

Kilka słów wyjaśnienia:

  • linia 5 – zamieniam przychodzące body na obiekt js
  • linia 6 – odczytuje z przychodzącej wiadomości aktualny intent (sprawdzam czy intent to add_word.handle-word)
  • linie 7-13 – tworzę payload, który wyświetli na Messengerze podpowiedzi dla użytkownika (quick replies)
  • linie 15-19 – ustawiam kontekst, który przechowywać będzie słówko wpisane przez użytkownika
  • linia 21 – ustawiam jako fulfillmentsMessages wcześniej stworzony payload (taka odpowiedź pokaże się użytkownikowi)
  • linia 22 – przypisuje wcześniej stworzony kontekst do odpowiedzi

Tak zdefiniowany endpoint w odpowiedzi na intent add_word.handle-word wyświetli użytkownikowi sugestie i zapisze informacje o wpisanym słówku do kontekstu. Jak widać słówka i sugestie są tu wpisane „na sztywno”, czyli nie robimy prawdziwych uderzeń do zewnętrznych API, ale tego typu atrapa wystarczy w zupełności do tego, aby stworzyć prototyp działającego bota.

Kolejny intent jaki chcemy obsłużyć to  add_word.handle-translation. Sposób działania jest podobny – musimy dodać do naszego endpoint’a obsługę tego intent’a. Aby to zrobić dodaję następujący kod do sekcji Body:

Mockservice - dynamic - 2

  • linia 1 – sprawdzam, czy przychodzący intent to add_word.handle-transition
  • linie 2-10 – tworzenie dynamicznej odpowiedzi jaka zostanie wysłana użytkownikowi na Messenger’ze
  • linie 12-14 – tworzą kontekst, który zostanie przypisany

W tym przypadku podobnie jak w poprzednim – stworzyliśmy działającą atrapę, która wyśle potwierdzenie dodania słówka do bazy użytkownikowi.

Pozostaje nam obsługa intent’u add_word.adding.yes, którego zadaniem jest zapisanie słówka do bazy danych. W naszym przypadku (z racji tego, że jest to atrapa) nie będziemy realizować zapisu do bazy, więc nie musimy tu nic robić/przetwarzać.

Gotowy kod js, który użyłem do stworzenia endpoint’a znajdziecie TUTAJ.

Tak stworzony endpoint potrafi zasymulować prawdziwe API (jakie kiedyś powstanie) i generuje różne odpowiedzi w zależności od fazy rozmowy użytkownika z botem.

Podsumowanie

Tym sposobem dobrnęliśmy do końca. Dzisiejszym wpis był nieco bardziej techniczny i wymagający minimum wiedzy programistycznej, ale takie artykuły będą się pojawiać coraz częściej. W końcu, z racji mojego doświadczenia, są mi najbliższe. Udało nam się dzisiaj stworzyć fragment rozmowy, mający na celu dodanie słówka oraz jego tłumaczenia do bazy danych. Następnie dowiedzieliśmy się co to jest fulfillment , jak go włączyć i do czego służy. Na koniec stworzyliśmy mock-up zewnętrznego serwisu za pomocą narzędzia  Mockservice.io i sprawiliśmy, że stworzony przez nas endpoint generuje różne odpowiedzi, w zależności w jakiej fazie rozmowy się znajduje. Jeśli macie jakiej pytania – zachęcam do wypisywania ich w  komentarzach.

 

Poprzednie wpisy z tej serii:

Udostępnij: