From 4a699901dfa1911606a39be746fb1bcf3e3edfe2 Mon Sep 17 00:00:00 2001 From: Antoni Solarski Date: Sat, 25 May 2024 12:52:38 +0200 Subject: [PATCH] DST and DP --- book.jsgf | 23 +++--- dialog_model.py | 214 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 170 insertions(+), 67 deletions(-) diff --git a/book.jsgf b/book.jsgf index 6665e47..4acf61c 100644 --- a/book.jsgf +++ b/book.jsgf @@ -2,23 +2,27 @@ grammar book; -public = interesuja mnie dania kuchni woskiej oraz meksykanskiej | jaka jest gramatura waszego burrito i czy mozna wybrac do niego mieso | przyjmujecie patnosc karta | a od ktorej do ktorej jest otwarta | super w takim razie czy mogbym dokonac rezerwacji na godzine 21 | przy oknie poprosze | jakie alergeny zawiera stek z grillowanymi warzywami i jakie piwa importowane macie dokadnie | czy akceptujecie bitcoina | a w jakiej cenie jest ta pizza | karta | koreanskie bibimbap z woowina brzmi dobrze ile kosztuje | nie nie chce nic zmieniac prosze o przekazanie dania do realizacji | zaplace gotowka przy odbiorze | lasagne brzmi super moge do tego wypic cole i zamowic jakis deser | wszystko jest okej dziekuje | chciabym dostac 2 rozne warianty mozesz mi zaproponowac alternatywe dla drugiej osoby zamiast ryby i rosou | podaj menu bez potraw na zimno | a piwo 0 | a czy mozna blikiem | jakie dania oferujecie | czy oferujecie rozne poziomy wysmazenia wolowiny | ile kosztuje to danie gowne | tak zoz zamowienie na adres xyz | a cos innego nie lubie kurczaka | oki | czy macie moze w ofercie zrazy woowe | jaka macie karte napojow | czy oferujecie dowoz | jaki jest koszt steka z poledwicy woowej caprese i wody gazowanej | poprosze o dostawe na adres rubiez 12j na godzine 16 | dziekuje czy moge zamowic posiki na godzine 15 | a co oferujecie z dan miesnych | czy do tego serwowane sa jeszcze ziemniaki | dziekuje bardzo w takim razie chciabym to zamowic | jaka sa ceny deserow | jak duza jest porcja pierogow ruskich | to poprosze do tego sok owocowy soki z jakich owocow sa dostepne czy sa one swiezo wyciskane | to poprosze dodac to do zamowienia oraz podsumowac cae zamowienie | na wynos | 00120 watykan | a czy macie jakies dania azjatyckie | w takim razie dodaj ja do zamowienia czy mogbys zaproponowac cos na przystawke i na deser | poprosze wode i cole | potwierdzam | nie dziekuje do widzzenia | chciabym zjesc tatara zupe grzybowa stek i tiramisu czy moge zjesc tatara bez cebuli | za drogo jednak nie zjem tatara z dowozem na adres biedronkowa 4 | w takim razie na przystawke bedzie tatar a co do zupy mam pytanie z jakich grzybow ona sie skada | w takim razie cae moje zamowienie to bedzie tatar krem z dyni stek z poledwicy woowej i obedzie sie bez deseru pytanie jeszcze czy mozna pacic karta | w takim razie chetnie zostane i na ten moment bedzie dla mnie wszystko | tak ale jeszcze to nie koniec; +public = interesuja mnie dania kuchni wloskiej oraz meksykanskiej | jaka jest gramatura waszego burrito i czy mozna wybrac do niego mieso | przyjmujecie patnosc karta | a od ktorej do ktorej jest otwarta | super w takim razie czy mogbym dokonac rezerwacji na godzine 21 | przy oknie poprosze | jakie alergeny zawiera stek z grillowanymi warzywami i jakie piwa importowane macie dokadnie | czy akceptujecie bitcoina | a w jakiej cenie jest ta pizza | koreanskie bibimbap z woowina brzmi dobrze ile kosztuje | nie nie chce nic zmieniac prosze o przekazanie dania do realizacji | zaplace gotowka przy odbiorze | lasagne brzmi super moge do tego wypic cole i zamowic jakis deser | wszystko jest okej dziekuje | chciabym dostac 2 rozne warianty mozesz mi zaproponowac alternatywe dla drugiej osoby zamiast ryby i rosou | podaj menu bez potraw na zimno | a piwo 0 | a czy mozna blikiem | jakie dania oferujecie | czy oferujecie rozne poziomy wysmazenia wolowiny | ile kosztuje to danie gowne | tak zoz zamowienie na adres xyz | a cos innego nie lubie kurczaka | czy macie moze w ofercie zrazy woowe | jaka macie karte napojow | czy oferujecie dowoz | jaki jest koszt steka z poledwicy woowej caprese i wody gazowanej | poprosze o dostawe na adres rubiez 12j na godzine 16 | dziekuje czy moge zamowic posiki na godzine 15 | a co oferujecie z dan miesnych | czy do tego serwowane sa jeszcze ziemniaki | dziekuje bardzo w takim razie chciabym to zamowic | jaka sa ceny deserow | jak duza jest porcja pierogow ruskich | to poprosze do tego sok owocowy soki z jakich owocow sa dostepne czy sa one swiezo wyciskane | to poprosze dodac to do zamowienia oraz podsumowac cae zamowienie | na wynos | 00120 watykan | a czy macie jakies dania azjatyckie | w takim razie dodaj ja do zamowienia czy mogbys zaproponowac cos na przystawke i na deser | poprosze wode i cole | nie dziekuje do widzzenia | chciabym zjesc tatara zupe grzybowa stek i tiramisu czy moge zjesc tatara bez cebuli | za drogo jednak nie zjem tatara z dowozem na adres biedronkowa 4 | w takim razie na przystawke bedzie tatar a co do zupy mam pytanie z jakich grzybow ona sie skada | w takim razie cae moje zamowienie to bedzie tatar krem z dyni stek z poledwicy woowej i obedzie sie bez deseru pytanie jeszcze czy mozna pacic karta | w takim razie chetnie zostane i na ten moment bedzie dla mnie wszystko | tak ale jeszcze to nie koniec; -public = poprosze {portion_size} porcje | [] {dish} | no dobrze | []
{address} | czy moglibyscie przygotowac porcji na okreslona godzine na wynos; -
= uniwersytetu poznanskiego 61614 poznan | poziomkowa poznan; + = poprosze na | poprosze do | poprosze | do | na ; -public = dziekuje to wszystko | jakie aperitify sa u was dostepne | poprosze w takim razie carpaccio z buraka tiramisu i jakies dwa napoje | dobrze nie moge sie juz doczekac | troche drogo nie ma znizki dla studentow; + = chcialbym zjesc | poprosze | chcialbym | chcialabym | chcialabym zjesc | chce | chce zjesc | dla mnie bedzie | wezme ; + +
= uniwersytetu poznanskiego 61614 poznan | poziomkowa poznan | poznan | uam poznan | wydzial matematyki | poznanska ; + +public = dziekuje to wszystko | jakie aperitify sa u was dostepne | poprosze w takim razie carpaccio z buraka tiramisu i jakies dwa napoje | troche drogo nie ma znizki dla studentow; public = | witam system | dzien dobry | czesc | witam ; public = czesc jestem agentem dialogowym przyjmujacym zamowienia w restauracji moge doradzic ci w wyborze odpowiedniej pozycji z menu w czym moge ci pomoc ; -public = potwierdzam | tak | tak potwierdzam | tak to wszystko | to poprosze | super to zatem wszystko | oki | to odbiore | wszystko jest ok dziekuje; +public = potwierdzam | tak | tak potwierdzam | tak to wszystko | to poprosze | super to zatem wszystko | oki | to odbiore | wszystko jest ok dziekuje | dobrze nie moge sie juz doczekac; public = chetnie wezme ziemniaki pieczone | to prosze dodac to do moje zamowienia czy macie jakies napoje | patnosc moze byc karta ale w 3 porcjach | super to zatem wszystko | pasuje czy mozesz powiedziec jakie skadniki sa w saatce moge miec uczulenia na niektore skadniki | a mozliwosc jest z szarlotki z lodami | dostawy i patnosci | a na miejscu moge zapacic | wezme cole ile wynosi cakowity koszt zamowienia | okej w takim razie dziekuje za pomoc pojde do innej restauracji; -public = w takim razie niech zostanie poczatkowa opcja mozemy przejsc do kwestii dostawy | platnosc gotowka ulica sezamkowa pacanowo | okej to wziabym | okej to wziabym to a co do {dish} proponujesz | okej to wezme do tego cole zero ile wynosi koszt caego zamowienia | chciabym bez saatki jednak a w miejscu tego kiszonke czy maci kiszonki w restauracji | tak | dobrze a czy po takich potrawach nie bedzie mi smierdziao z buzi na randce | czemu nie podaes tego wczesniej piwo to tez napoj | kuflowe mocne | a czy mozecie zapakowac dania na wynoc | dobrze to poprosze jednak 4pak kuflowego i prosze zapakowac na wynos | to poprosze | dobrze w takim razie zaproponuj cos innego; +public = w takim razie niech zostanie poczatkowa opcja mozemy przejsc do kwestii dostawy | platnosc gotowka ulica sezamkowa pacanowo | okej to wziabym | [okej to wziabym] [to] a co do {dish} proponujesz | okej to wezme do tego cole zero ile wynosi koszt caego zamowienia | chciabym bez saatki jednak a w miejscu tego kiszonke czy maci kiszonki w restauracji | tak | dobrze a czy po takich potrawach nie bedzie mi smierdziao z buzi na randce | czemu nie podaes tego wczesniej piwo to tez napoj | kuflowe mocne | a czy mozecie zapakowac dania na wynoc | dobrze to poprosze jednak 4pak kuflowego i prosze zapakowac na wynos | to poprosze | dobrze w takim razie zaproponuj cos innego; = hej | siema | czesc | witam ; @@ -54,11 +58,10 @@ public = (dobrze nie moge sie juz doczekac | do widzenia | dziekuje milego public = [pokaz] {help_with}; - = menu | (jakie posilki moge zjesc z tego menu) | (A jaka to ) | (Chciabym zjesc ); + = menu | (jakie posilki moge zjesc z tego menu) | (A jaka to ) ; - = tatara | tatar | poledwica | poledwice | pizza | makaron | picia | zupa | danie_glowne | deser | napoj | ryba | rybe; + = tatara | tatar | poledwica | poledwice | pizza | pizze | tiramisu | zrazy [wolowe] | pyzy | placki | makaron | picia | zupa | danie_glowne | deser | napoj | ryba | rybe; public = Dziekuje | tak; -public = poprosze w takim razie ta pizze razy oraz litra coli | chciabym zamowic na adres
| wybornie czy z kuchni woskiej znajdzie sie lasagne oraz czy w winach znajda sie ciekawsze pozycje takie jak amarena | jestem wysoce niepocieszony z powodu braku trunkow siarczystych ale jakos przebrne przez to czy na deser jest mozliwosc tiramisu | dziekuje | na 15 dzisiaj mozna zarezerowac stoli z podanym obiadem | na na pojutrze | no dobrze przekonales mnie zoze u was zamowienie czy przyjmujecie patnosc karta | pamietajcie zeby byo cieple ; - +public = poprosze w takim razie ta pizze razy oraz litra coli | chciabym zamowic na adres
| wybornie czy z kuchni woskiej znajdzie sie lasagne oraz czy w winach znajda sie ciekawsze pozycje takie jak amarena | jestem wysoce niepocieszony z powodu braku trunkow siarczystych ale jakos przebrne przez to czy na deser jest mozliwosc tiramisu | dziekuje | na 15 dzisiaj mozna zarezerowac stoli z podanym obiadem | na na pojutrze | no dobrze przekonales mnie zoze u was zamowienie czy przyjmujecie patnosc karta | pamietajcie zeby byo cieple ; \ No newline at end of file diff --git a/dialog_model.py b/dialog_model.py index 40569e6..887b5e3 100644 --- a/dialog_model.py +++ b/dialog_model.py @@ -1,29 +1,50 @@ +import string from typing import Any + import jsgf from unidecode import unidecode -import string -import argparse + +from convlab.dst import dst -class Model(): +def default_state(): + return dict( + user_action=[], + system_action=[], + belief_state={ + 'address': '', + 'payment_method': '', + 'dish': [], + 'time': '' + }, + booked={}, + request_state=[], + terminated=False, + history=[] + ) + + +class Model: def __init__(self): - pass + self.state = default_state() + self.nlu = NLU() + self.dst = DST(self.state) + self.dp = DP(self.state) + self.nlg = NLG(self.state) def __call__(self, prompt) -> Any: - nlu = NLU() - dst = DST() - dp = DP() - nlg = NLG() - + print(prompt) msg = prompt.lower() - rama_nlu = nlu(msg) - print(rama_nlu) - rama_dst = dst(rama_nlu) - rama_dp = dp(rama_dst) - text = nlg(rama_dp) + r = self.nlu(msg) + print(r) + r = self.dst(r) + print(r) + r = self.dp() + print(r) + # r = self.nlg(r) - return text + return r class NLU(): @@ -61,29 +82,85 @@ class NLU(): return {'act': 'null', 'slots': []} -class DST(): - def __init__(self): - self.msgs = [] +class DST(dst.DST): - def __call__(self, msg) -> Any: - self.msgs.append(msg) - return msg + def __init__(self, state): + dst.DST.__init__(self) + self.state = state + + def __call__(self, user_act) -> Any: + if len(user_act['slots']) == 0: + user_act = [(user_act['act'], None, None)] + else: + user_act = [(user_act['act'], k, v) for k, v in user_act['slots'] if v is not None] + + self.state['request_state'] = {} + for act, slot, value in user_act: + self.state['user_action'].append(act) + + if act == "platnosc": + self.state['belief_state']['payment_method'] = value + self.state['request_state'] = ['payment_method'] + + elif act == "offer": + self.state['request_state'] = ['menu'] + + elif act == 'select': + if slot == 'dish': + self.state['belief_state']['dish'].append(value) + else: + self.state['belief_state'][slot] = value + self.state['request_state'] = [slot] + + elif act == 'inform': + pass + + elif act == 'request': + pass + + return self.state class DP(): - def __init__(self): - pass + def __init__(self, state): + self.state = state + + def __call__(self) -> Any: + system_action = None + + if self.state['user_action'][-1] == 'hello': + system_action = 'welcomemsg' + # przywitaj uzytkownika (i pokaz menu) + + elif self.state['user_action'][-1] == 'select': + system_action = 'inform' + # poinformuj o wybranych slotach z "request_state" + + elif (self.state['user_action'][-1] == 'help' + or self.state['user_action'][-1] == 'offer' + or self.state['user_action'][-1] == 'reqmore' + or (self.state['user_action'][-1] == 'request' and len(self.state['request_state']) == 0) + ): + system_action = 'offer' + # zaoferuj cale menu + + elif self.state['user_action'][-1] == 'ack': + system_action = 'bye' + self.state['terminated'] = True + # potwierdz i zakoncz, podsumuj zamowienie - def __call__(self, msg) -> Any: - if "imie" in msg: - return "imieMSG" else: - return None + system_action = 'inform' + # poinformuj o wybranych slotach z "request_state" + # lub o wszystkich jezeli nic nie ma w request state + + self.state['system_action'].append(system_action) + return system_action class NLG(): - def __init__(self): - pass + def __init__(self, state): + self.state = state def __call__(self, msg) -> Any: if msg == "imieMSG": @@ -94,32 +171,55 @@ class NLG(): if __name__ == "__main__": model = Model() - # parser = argparse.ArgumentParser() - # parser.add_argument("--msg") - # args = parser.parse_args() - # print(model(prompt="chcialbym zarezerwowac stolik na jutro na dziesiata dla trzech osob")) - # print(model(prompt="Cześć")) - # print(model(prompt="Hej, jakim botem jesteś?")) - # print(model(prompt="Hej, w czym mi możesz pomóc?")) - # print(model(prompt="Siema, w czym możesz mi pomóc?")) - # print(model(prompt="Witam")) - # print(model(prompt="Witam system")) - # print(model(prompt="Hej, czym się zajmujesz?")) - # print(model(prompt="Czesc, jestem agentem dialogowym przyjmujacym zamowienia w restauracji. Moge doradzic ci w wyborze odpowiedniej pozycji z menu. W czym moge ci pomoc?")) - # print(model(prompt="oki")) - # print(model(prompt="Potwierdzam!")) - # print(model(prompt="Tak!")) - # print(model(prompt="Tak to wszystko!")) - print(model(prompt="Interesuja mnie dania kuchni woskiej oraz meksykanskiej")) - print(model(prompt="okej to wziabym to a co do picia proponujesz")) - print(model(prompt="Poproszę ryba")) - print(model(prompt="Poproszę tatara")) - print(model(prompt="Poproszę 2 porcje")) - print(model(prompt="Zaplacę kartą przy odbiorze")) - print(model(prompt="Dobrze, nie mogę sie już doczekać")) - print(model(prompt="uniwersytetu poznanskiego 4 61-614 poznan")) - print(model(prompt="dziekuje to wszystko")) - print(model(prompt="pokaz menu")) - print(model(prompt="poprosze blikiem z gory")) - print(model(prompt="menu")) + # jezeli sie przywita to przywitaj uzytkownika (i pokaz menu) + # response = model("Cześć") + # response = model("Witam") + # response = model("Witam system") + # response = model("Hej, jakim botem jesteś?") + # response = model("Hej, czym się zajmujesz?") + # response = model("Hej, w czym mi możesz pomóc?") + response = model("Siema, w czym możesz mi pomóc?") + assert response == "welcomemsg" + + print() + + # jezeli prosi o pomoc lub po prostu o menu to zaoferuj cale menu + # response = model("Pokaz menu") + # response = model("A co do picia proponujesz?") + # response = model("Jakie inne desery oferujesz?") + response = model("Interesują mnie dania kuchni włoskiej oraz meksykanskiej.") + assert response == "offer" + + print() + + # jezeli wybierze danie to zapisz wybor i poinformuj o nim + # response = model("Wezmę rybe") + # response = model("Poproszę tatara") + response = model("Chciałbym zjesc tatara") + assert response == "inform" + + print() + + # jezeli poda adres to zapisze wybor i poinformuj o nim + # response = model('Poproszę na poznańską 2') + response = model("uniwersytetu poznanskiego 4 61-614 poznan") + assert response == "inform" + + # jezeli wybierze rodzaj platnosci to zapisz wybor i poinformuj o nim + # response = model("karta") + # response = model("Poproszę blikiem z góry") + response = model("Zapłacę kartą przy odbiorze") + assert response == "inform" + + print() + + # jezeli potwiedzi zamowienie to zakoncz zamawianie sukcesem i wypisz calosc + # response = model("Potwierdzam!") + # response = model("Tak!") + # response = model("Tak to wszystko!") + # response = model("Super, to zatem wszystko!") + response = model("Dobrze, nie mogę się już doczekać.") + assert response == "bye" + + print()