SPRAWOZDANIE Z ĆWICZENIA
LABORATORYJNEGO NR 5
Przedmiot: Systemy dialogowe
Prowadzący: dr inż. Andrzej Wiśniewski
Wykonał: Wojciech Węgrecki
Grupa: I9G2S1
1. Sporządzić schemat strukturalny (elementy i powiązania - rysunek) oraz
opisać działanie portalu głosowego.
Użytkownik po wybraniu numeru telefonu łączy się z serwisem, a dokładniej z
serwerem VXML (interpreter VXML) i otrzymuje wiadomość powitalną.
Następnie serwer z kodu VXML pobiera informację co ma dalej zrobić i odtwarza
opcję jaką chcemy zaproponować użytkownikowi. Użytkownik wypowiada opcję i
dalej sprawdzany jest kod. Jest to realizowane do zakończenia rozmowy lub
zakończenia programu. Aby serwer rozpoznał plik VXML musi być podany Tag
<vxml></vxml>. Dokumenty VXML i inne związane z nimi pliki mogą być
przechowywane na hoście udostępnianym przez portal głosowy lub na innym
zewnętrznym serwerze.
Interpreter może wykonywać następujące zadania:
1) wysyłanie do użytkownika podpowiedzi głosowych, wiadomości lub innych
materiałów audio (jak muzyka i efekty dźwiękowe);
2) przyjmowanie wejść numerycznych, które wprowadza użytkownik za
pomocą sygnałów DTMF (telefon tonowy);
3) przyjmowanie wejść głosowych i rozpoznawanie słów;
4) przyjmowanie i nagrywanie wejść głosowych (bez rozpoznawania słów);
5) przesyłanie informacji użytkownika na strony sieciowe lub inne serwery
internetowe;
6) otrzymywanie informacji z Internetu i przekazywanie jej do użytkownika.
Dodatkowo w VXML można wykonywać operacje arytmetyczne, logiczne oraz
operacje na tekście. Rozmowa użytkownika z programem nie musi przebiegać za
każdym razem tak samo, stosuje się do tego np. dyrektywy if-then-else. Testowanie
aplikacji odbywa się przez połączenie z odpowiednim numerem telefonicznym i
interakcję z nią.
rys. 1 Schemat portalu głosowego
2. Zaprojektować prostą aplikację głosową (temat aplikacji wybiera student):
a) identyfikacja aplikacji (przykładowe dialogi);
b) opracowanie modelu (scenariusza) dialogu w postaci schematu
blokowego;
c) opis dostępu użytkownika do aplikacji.
Wybraną przeze mnie aplikacją jest obsługa pizzerii.
a) identyfikacja aplikacji (przykładowe dialogi);
Przykładowy Dialog 1:
Aplikacja: Welcome in pizzeria Ghost. Choose your pizza. Bacon, ham, salami,
vegetarian or end.
Użytkownik: Bacon
A: your choice is bacon. Would you like any drink? Say yes or no.
U: yes
A: What drink do you prefer? Cola, fanta, sprite?
U: fanta.
A: Would you like any sauce? Say yes or no.
U: no
A: Would you like eat in our local or home? Say home or local.
U: local.
A: Thank you for order and we invite to Wall Street 25. Good bye.
Przykładowy Dialog 2:
A: Welcome in pizzeria Ghost. Choose your pizza. Bacon, ham, salami, vegetarian
or end.
U: Ham
A: Your choice is ham. Would you like any drink? Say yes or no.
U: Yes
A: What drink do you prefer? Cola, fanta, sprite?
U: Sprite.
A: Would you like any sauce? Say yes or no.
U: Yes
A: What sauce do you prefer? Tomato or garlic?
U: Garlic
A: Would you like eat in our local or home? Say home or local.
U: Home.
A: Where deliver the order? Wall Street, Ghost Street, Police Street or School
Street?
U: Wall Street.
A: You chose Wall Street. We'll send order. Please wait. Thank you and invite
again. Goodbye.
b) opracowanie modelu (scenariusza) dialogu w postaci schematu blokowego;
Prompt ‘Welcome in pizzeria Ghost. Choose your pizza. Bacon, ham, salami, vegetarian or end.’
bacon
ham
salami
vegetarian
end
Prompt ’your
choice is bacon’
Prompt ‘your
choice is ham’
Prompt ‘your
choice is salami’
Prompt ‘your
choice is
vegetarian’
Prompt ’your
choice is End.
Thank you and
invite again.
Goodbye’
Prompt ‘Would you like any drink? Say yes or
no.’
yes
no
Prompt ‘What drink do you prefer? Cola, fanta,
sprite?’
cola
fanta
sprite
Prompt ‘Thank you for order
and we invite to Wall Street
25. Good bye.’
You chose Wall Street.
We'll send order.
Please wait. Thank you
and invite again.
Goodbye.
You chose Ghost
Street. We'll send
order. Please wait.
Thank you and invite
again. Goodbye.
You chose Police
Street. We'll send
order. Please wait.
Thank you and invite
again. Goodbye.
You chose School
Street. We'll send
order. Please wait.
Thank you and invite
again. Goodbye.
Prompt ‘Would you like any sauce? Say yes or no.’
no
yes
Prompt ‘What sauce do you prefer? Tomato or
garlic?’
tomato
garlic
Prompt ‘Would you like eat in our local or home? Say home or local.’
home
local
Prompt ‘Where deliver the order? Wall Street, Ghost Street, Police Street or School Street?’
Wall Street
Ghost Street
Police Street
School Street
c)
opis dostępu użytkownika do aplikacji
Użytkownik może w wieloraki sposób skorzystać z aplikacji. Portal voxeo
umożliwia połączenie z aplikacją z różnych krańców świata generując numery
telefonów poszczególnych krajów oraz dodatkowym atutem jest dostępność
bezpłatnego (dla użytkowników) numeru skype. Poniżej przedstawiam zrzut ekranu
przedstawiający numery telefonów, dzięki którym można połączyć się z moją
aplikacją.
3. Utworzenie aplikacji w postaci dokumentu VXML:
a) opatrzyć komentarzem wszystkie jej znaczniki.
b) testowanie (iteracyjne) w celu udoskonalenia interfejsu.
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.1"> <!-- -->
Na początku programu deklaruje sobie jak będzie się on zachowywał jeśli nie
zrozumie danego słowa lub jeśli użytkownik go nie poda.
<!--Kwestia wypowiadana jeśli program błędnie dopasował wypowiedziane słowo-->
<nomatch>
<!--Brak dopasowania-->
Please repeat, i did't understand.
<reprompt
/><!--Wypowiedzenie ponowne po ponownej wizycie-->
</nomatch>
<!--Kwestia wypowiadana jeśli program nie wykrył wypowiedzianego słowa-->
<noinput>
<!--brak wypowiedzi-->
Please repeat, i didn't hear.
<reprompt/>
</noinput>
Kolejnym krokiem było przejście już do sedna naszego programu, czyli kwestii
wypowiadanych przez aplikację oraz możliwe odpowiedzi klienta naszej pizzerii.
Na początku klient mógł wybrać pizzę z czterech podanych w podpowiedzi lub
zakończyć program.
<!--Deklaracja formularza odpowiadającego za wybór pizzy-->
<form id="pizzeria">
<!--prezentacja dialogu do wydobycia informacji od użytkownika.
atrybuty: id(nazwa) scope(zasięg)-->
<property name="input" value="voice"/>
<field name="Menu">
<!--definiowanie pola. atrybuty: name(nazwa),
expr(wypowiedz), cond(warunek), type(typ), slot(nazwa gramatyki), modal-->
<!--Wiadomość powitalna-->
<prompt>
<!--wypowiadanie kwestii-->
Welcome in pizzeria Ghost. Choose your pizza. Bacon, ham, salami,
vegetarian or end.
</prompt>
Użytkownik dokonuje wyboru w oparciu o następującą gramatykę.
<!--Definiowanie słów jakie mogą zostać wypowiedziane przez użytkownika-->
<grammar mode="voice" root="Choice">
<!--specyfikacja rozpoznawania
mowy. atrybuty: mode, root, version, xml:lang, tag-format, xml:base -->
<rule id="Choice" scope="public">
<!--definicja zasad. atrybuty:
id(nazwa), scope(zasięg)-->
<one-of>
<!-- jeden z-->
<item>bacon</item>
<item>ham</item>
<item>salami</item>
<item>vegetarian</item>
<item>end</item>
</one-of>
</rule>
</grammar>
Następnie sprawdzane jest jakie słowo zostało wypowiedziane i co w danym
przypadku zrobić. W moim przypadku wypowiadany jest wybór pizzy i
przechodzenie do menu pytającego o chęć zamówienia napoju. W przypadku
wybrania „end ” użytkownik otrzymuje komunikat i program kończy działanie.
<!-- Deklarowanie co będzie wykonywane po rozpoznaniu danego słowa -->
<filled namelist="Menu">
<!--akcja wykonywana kiedy pola są
wypełnione. atrybuty: mode, namelist(nazwa)-->
<if cond="Menu == 'bacon'">
<!--warunek-->
<prompt>your choice is bacon </prompt>
<goto next="#czy_chcesz_napoj"/>
<!-- miejsce następnego
kroku w naszym przypadku formularz czy_chcesz_napoj,
atrybuty: expr(wypowiedź)-->
<elseif cond="Menu == 'ham'"/>
<prompt>your choice is ham.</prompt>
<goto next="#czy_chcesz_napoj"/>
<elseif cond="Menu == 'salami'"/>
<prompt>your choice is salami.</prompt>
<goto next="#czy_chcesz_napoj"/>
<elseif cond="Menu == 'vegetarian'"/>
<prompt>your choice is vegetarian</prompt>
<goto next="#czy_chcesz_napoj"/>
<elseif cond="Menu == 'end'"/>
<prompt>your choice is End. Thank you and invite again.
Goodbye.</prompt>
</if>
</filled>
</field>
</form>
Kolejne kroki to po prostu następne pytania, jakie zadaje aplikacja. Wykonane jest
to analogicznie do pierwszego formularza. Co wykonuje dany formularz napisałem
w komentarzach przed każdym z nich.
<!-- Formularz sprawdzajacy, czy klient chce napoj -->
<form id ="czy_chcesz_napoj">
<field name="Menu_drink">
<prompt>
Would you like any drink? Say yes or no.
</prompt>
<grammar mode="voice" root="drink">
<rule id="drink" scope="public">
<one-of>
<item>yes</item>
<item>no</item>
</one-of>
</rule>
</grammar>
<filled namelist="Menu_drink">
<if cond="Menu_drink == 'yes'">
<goto next="#wybor_napoju"/>
<elseif cond="Menu_drink == 'no'"/>
<goto next="#czy_chcesz_sos"/>
</if>
</filled>
</field>
</form>
<!-- Formularz sprawdzajacy jaki klient chce napoj -->
<form id ="wybor_napoju">
<field name="Choice_drink">
<prompt>
What drink do you prefer? Cola, fanta, sprite?
</prompt>
<grammar mode="voice" root="drink_choice">
<rule id="drink_choice" scope="public">
<one-of>
<item>cola</item>
<item>fanta</item>
<item>sprite</item>
</one-of>
</rule>
</grammar>
<filled namelist="Choice_drink">
<if cond="Choice_drink == 'cola'">
<prompt>You chose cola.</prompt>
<goto next="#czy_chcesz_sos"/>
<elseif cond="Choice_drink == 'fanta'"/>
<prompt>You chose fanta</prompt>.
<goto next="#czy_chcesz_sos"/>
<elseif cond="Choice_drink == 'sprite'"/>
<prompt>You chose sprite</prompt>.
<goto next="#czy_chcesz_sos"/>
</if>
</filled>
</field>
</form>
<!-- Formularz sprawdzajacy, czy klient chce sos -->
<form id ="czy_chcesz_sos">
<field name="Menu_sauce">
<prompt>
Would you like any sauce? Say yes or no.
</prompt>
<grammar mode="voice" root="sauce">
<rule id="sauce" scope="public">
<one-of>
<item>yes</item>
<item>no</item>
</one-of>
</rule>
</grammar>
<filled namelist="Menu_sauce">
<if cond="Menu_sauce == 'yes'">
<goto next="#wybor_sosu"/>
<elseif cond="Menu_sauce == 'no'"/>
<goto next="#czy_dostawa"/>
</if>
</filled>
</field>
</form>
<!-- Formularz sprawdzajacy jaki klient chce sos -->
<form id ="wybor_sosu">
<field name="Choice_sauce">
<prompt>
What sauce do you prefer? Tomato or garlic?
</prompt>
<grammar mode="voice" root="sauce_choice">
<rule id="sauce_choice" scope="public">
<one-of>
<item>tomato</item>
<item>garlic</item>
</one-of>
</rule>
</grammar>
<filled namelist="Choice_sauce">
<if cond="Choice_sauce == 'tomato'">
<prompt>You chose tomato.</prompt>
<goto next="#czy_dostawa"/>
<elseif cond="Choice_sauce == 'garlic'"/>
<prompt>You chose garlic</prompt>.
<goto next="#czy_dostawa"/>
</if>
</filled>
</field>
</form>
<!-- Formularz sprawdzajacy, czy klient chce zjesc w lokalu, czy w domu -->
<form id ="czy_dostawa">
<field name="Menu_czy_dostawa">
<prompt>
Would you like eat in our local or home? Say home or local.
</prompt>
<grammar mode="voice" root="dostawa">
<rule id="dostawa" scope="public">
<one-of>
<item>home</item>
<item>local</item>
</one-of>
</rule>
</grammar>
<filled namelist="Menu_czy_dostawa">
<if cond="Menu_czy_dostawa == 'home'">
<goto next="#gdzie_dostawa"/>
<elseif cond="Menu_czy_dostawa == 'local'"/>
<prompt>Thank you for order. We invite to Wall Street 25.
Good bye.</prompt>
</if>
</filled>
</field>
</form>
<!-- Formularz sprawdzajacy gdzie klient chce otrzymac dostawe -->
<form id ="gdzie_dostawa">
<field name="Choice_dostawa">
<prompt>
Where deliver the order? Wall Street, Ghost Street, Police Street or School
Street?
</prompt>
<grammar mode="voice" root="dostawa_choice">
<rule id="dostawa_choice" scope="public">
<one-of>
<item>Wall Street</item>
<item>Ghost Street</item>
<item>Police Street</item>
<item>School Street</item>
</one-of>
</rule>
</grammar>
<filled namelist="Choice_dostawa">
<if cond="Choice_dostawa == 'Wall Street'">
<prompt>You chose Wall Street. We'll send order. Please
wait. Thank you and invite again. Goodbye.</prompt>
<elseif cond="Choice_dostawa == 'Ghost Street'"/>
<prompt>You chose Ghost Street. We'll send order. Please
wait. Thank you and invite again. Goodbye.</prompt>
<elseif cond="Choice_dostawa == 'Police Street'"/>
<prompt>You chose Police Street. We'll send order. Please
wait. Thank you and invite again. Goodbye.</prompt>
<elseif cond="Choice_dostawa == 'School Street'"/>
<prompt>You chose School Street. We'll send order. Please
wait. Thank you and invite again. Goodbye.</prompt>
</if>
</filled>
</field>
</form>
</vxml>
Wydaje mi się, że mój program po kilku poprawkach i rozbudowaniu go mógłby
być w pełni funkcjonalną aplikacją dla pizzerii. Na pewno usprawniłoby to
funkcjonowanie takiej placówki i mogłoby zmniejszyć koszty utrzymania, gdyż nie
byłaby potrzebna osoba do odbierania zamówień. W moim programie nie ma
dodatkowych podpowiedzi gdy użytkownik błędnie wypowie zdanie. Po prostu w
każdej dyrektywie „prompt” podaje użytkownikowi konkretnie co ma powiedzieć i
od razu nakierowuje go na odpowiedź jaka jest rozpoznawalna przez program.
Mimo niezbyt skomplikowanego rozwiązania wydaje mi się, że jest to
funkcjonalne i nie powinno przysparzać klientowi zbyt dużo kłopotów, gdyż
wypowiadałby bardzo krótkie frazy. Po kilkukrotnym przetestowaniu programu
mogę stwierdzić, ze nie trzeba bardzo wyraźnie wypowiadać słów, żeby zostały
one poprawnie rozpoznane, co jest dodatkowym atutem. Główną wadą mojego
rozwiązania jest to, że wykonana jest w języku angielskim, jednak istnieją portale
(w tym także voxeo), które obsługują język polski i przy większej ilości czasu to
też nie stanowiłoby problemu. Podsumowując, uważam że wykonanie takiego
portalu głosowego było ciekawym doświadczeniem i w dzisiejszych czasach, w
których dużą uwagę skupia się na zautomatyzowaniu wszelkich działań będzie to
bardzo przydatna umiejętność.