Tutorial: VoiceXML Einführung
Inhalt
1 Allgemeines
1.1 Historie
1.2 Wozu dient VoiceXML ?
1.3 Wie funktioniert VoiceXML ?
2 VoiceXML Grundlagen
2.1 Dialogelemente
2.1.1 <form>
2.1.1.1 Field items
2.1.1.2 Control items
2.1.2 <menu>
2.1.3 <subdialog>
2.2 Datenein- und ausgabe
2.2.1 <prompt>
2.2.2 Grammar
2.2.2.1 Inline Grammar
2.2.2.2 Explizite Grammar
2.2.2.3 Grammar mit Optionslisten: <option>
2.3 Ablaufkontrolle zwischen forms, items & Dokumenten
2.3.1 <goto>
2.3.2 <submit>
2.3.3 <script>
2.4 Bedingte Verzweigungen
2.5 Applikationen mit mehreren Dokumenten
2.5.1 Festlegung eines Root-Dokumentes
2.6 Ereignisbehandlung
2.7 Variablen, Ausdrücke und Scope
2.7.1 <var>
2.7.2 <assign>
2.7.3 Gültigkeitsbereich (scope) von Variablen
2.8 Weitere Elemente
2.8.1 <link>
2.8.2 <meta>
2.8.3 <filled>
2.8.4 <clear>
2.8.5 <reprompt>
2.8.6 <disconnect>, <exit>
1 Allgemeines
1.1 Historie
VoiceXML ist eine Markup-Sprache zur Erstellung von Voice User Interfaces (VUI).
Gegründet wurde das VoiceXML Forum von AT&T, IBM, Lucent und Motorola im März 1999 mit dem Ziel eine neue
Computersprache zu entwickeln, welche Inhalte und Informationen im Internet über Sprache und Telefon zugänglich macht.
Die Gründungsmitglieder erstellten im Jahr 2000 die erste Version des VoiceXML Standards (1.0). Im Oktober 2001 folgte
die Version 2.0; diese wurde vom W3C jedoch erst in 2004 als offizieller Standard festgeschrieben. Derzeit ist die
Version 2.1 veröffentlicht, und es wird bereits an einer Version 3 (genannt V3) gearbeitet, die multimodale Aspekte
stärker berücksichtigt.
1.2 Wozu dient VoiceXML ?
VoiceXML wurde für Telefonanwendungen entwickelt, die auf Sprache basieren und unterstützt daher folgende Features:
- Erkennen von gesprochener Eingabe
- Erkennen von DTMF Eingaben, d.h. Eingaben über die Telefontastatur
- Aufnahme von Sprache
- Ausgabe von Audiodateien
- Ausgabe von synthetischer Sprache, d.h. Umwandlung von Text in Sprache
- Telefoniefeatures wie Verbinden und Trennen (transfer, disconnect)
1.3 Wie funktioniert VoiceXML ?
VoiceXML nutzt vorhandene Webarchitekturen. Anwendungen werden im Voice Browser ausgeführt, der ähnlich wie
Webbrowser die Schnittstelle zwischen Internet und Mensch bilden. Der Voice Browser
sowie die Verbindungen ins Telefon- und IP-Netz werden in der Regel auf einem Voice-Gateway zur Verfügung gestellt,
welchen man mit jedem handelsüblichen Telefon anrufen kann. Man erreicht somit durch VoiceXML weit mehr Nutzer als
durch das datengestützte Internet.
Für die Dateneingabe in einem laufenden VoiceXML Dialog wird Automatische Spracherkennung (ASR) und/oder DTMF-Tastenerkennung verwendet, bei der Ausgabe greift man auf
synthetische Sprache (TTS) bzw. Audiodateien zurück.
Anrufer interagieren mit dem System über einen sog. Voice Browser, der die Sprachkommandos ausgibt bzw. entgegennimmt,
analog zum Web Browser, der die HTML-Webseiten visuell aufbereitet und auf Eingaben/Mausklicks des PC-Nutzers wartet.
Erläuterung zur Farbgebung
Die Erläuterungen in diesem Dokument folgen einem gewissen Farbschema.
<var> |
Grün bezeichnet VoiceXML Tags |
Attribut |
Rot bezeichnet Attribute zu einem best. VoiceXML Tag |
<form>
<block>
</form> |
Blau bezeichnet Beispielcode |
2 VoiceXML Grundlagen
Den gesamten Sprachdialog bezeichnet man als VoiceXML-Applikation. Eine VoiceXML-Applikation besteht aus
einem oder mehreren VoiceXML-Dokumenten (*.vxml)
Ein jedes VoiceXML Dokument besitzt als Toplevel Tag das <vxml> -Tag,
das als Container für die einzelnen Dialoge des Dokumentes fungiert.
VoiceXML-Dokumente können in beliebiger Reihenfolge ausgeführt werden.
Ein VoiceXML-Dokument der Applikation kann als Master (Root-Dokument) definiert werden. Andere VoiceXML-Dokumente
können in ihrem <vxml> Tag auf dieses Root Dokument referenzieren, und somit z.B. globale
Variablen, Einstellungen oder Funktionen nutzen.
2.1 Dialogelemente
Ein VoiceXML Dokument besteht aus einem oder mehreren Dialogen (<form> und/oder <menu> )
2.1.1 <form>
Innerhalb des <vxml> Containers ist das gesamte Dokument unterteilt
in ein oder mehrere Dialogelemente, so genannte Forms.
Das <form>-Element bildet die Schlüsselkomponente in Voice XML Dokumenten.
Jede <form> hat einen spezifischen Namen und führt einen bestimmten
Teil des Gesamtdialogs aus. Zum Beispiel besitzt fast jede Anwendung eine <form> als Hauptmenü, welcher als zentrale Dialogkomponente eine Hauptauswahl der angebotenen Dienste ermöglicht.
Das id-Attribut des <form> -Tags gibt der Form einen innerhalb des
VoiceXML-Dokuments eindeutigen Namen, unter dem es jederzeit referenziert werden kann, z.b.
<form id="start"> .
Direkt unterhalb des <form> -Elements übernehmen Form items verschiedene Aufgaben.
Dabei unterscheidet man zwei Kategorien von Form items: field items und control items.
2.1.1.1 Field items
Field items sammeln Informationen vom Anrufer. Field items beinhalten u.a.:
- Prompts, die den Anrufer anleiten, was er sagen oder drücken kann
- Grammars, die exakt definieren, was gesagt werden darf
- Event handlers
Field items im Überblick:
<field> |
sammelt Eingaben vom Anrufer via Tasten- oder Spracheingabe anhand einer definierten Grammatik
|
<record> |
Aufnahmedialog (z.b. Anrufbeantworter) |
<transfer> |
transferiert den Anrufer zu einer anderen Rufnummer |
<object> |
Aufruf eines plattformspezifischen Objekts; wird sehr selten verwendet, da dabei meist
plattformspezifischer Code verwendet wird |
<subdialog> |
Aufruf eines anderen Dialogs oder Dokumentes, vergleichbar mit einem Funktionsaufruf
(siehe 2.1.3) |
2.1.1.2 Control items
Innerhalb einer Form gibt es zwei verschiedene Arten von Control items.
<block> faßt eine Sequenz von Statements, die zur Ausgabe und
zur Berechnung, aber nicht zur Eingabe benutzt werden, zusammen.
Control items im Überblick:
<block> |
rahmt einen Bereich prozeduraler Logik ein, der keine Eingabe erfordert |
<initial> |
steuert sogenannte "mixed-initiative Dialoge" innerhalb einer
<form> |
2.1.2 <menu>
Als Sonderfall von <form> gibt es eine zweite Art von Dialogelement: <menu>.
Dabei wird ein klassisches Menü abgebildet ("Für A sagen Sie 'A'", Für B sagen Sie 'B'"). Die Dynamik des Dialogs
geht weitestgehend verloren und reduziert sich auf ein 'Eingabe => Gehe zu ...'.
Die mögliche Auswahl wird durch das <choice> Element festgelegt,
indem man ein Fragment einer Sprachgrammatik (z.B. ein bestimmtes Wort) oder einer DTMF Grammatik (z.B.
Zahlenkombination) angibt. Die DTMF Sequenz für die Auswahl gibt man mittels des Attributes
dtmf an. Mit dem next Attribut legt man die URI des
nächsten Dialoges fest, der ausgeführt werden soll, wenn das Fragment der Sprach- oder DTMF Grammatik eingegeben
wurde. Anstelle des next Attributes kann man auch das expr Attribut verwenden,
um einen Ausdruck anzugeben, der bei erfolgter Wahl ausgewertet werden soll, oder man gibt mit dem
event Attribut ein Ereignis an, das ausgelöst werden soll.
Mit dem <enumerate> Element kann man sich eine automatisch erstellte
Beschreibung der Möglichkeiten, die zur Auswahl stehen, ausgeben lassen.
2.1.3 <subdialog>
Das <subdialog> Element dient dem Erstellen von Unterdialogen.
Die Idee der Unterdialoge ist mit der Idee der Funktionen in anderen Programmiersprachen vergleichbar. Der Aufruf
der Unterdialoge erfolgt durch das <subdialog> Element, indem man
durch das src Attribut dessen URI angibt. Des weiteren gibt es noch das
name Attribut, welches angibt unter welchem Namen der Rückgabewert des Unterdialoges
gespeichert werden soll.
Der Aufruf eines Unterdialoges könnte also folgendermaßen aussehen:
<subdialog name="sub1" src="#sub1"> ... <subdialog>
Der Unterdialog selbst ist eine gewöhnliche <form>, muß jedoch ein <return> Element enthalten.
Dieses beendet den Unterdialog und gibt die Kontrolle an den aufrufenden Dialog zurück.
Dabei kann man mittels des event Attributes ein Ereignis hervorrufen und mittel
namelist eine Reihe von Variablen zurückgeben.
Dies kann dann z.B. so aussehen:
<form id="sub1"> ...
<return namelist="Var1 Var2"/>
</form>
2.2 Datenein- und ausgabe
2.2.1 <prompt>
Zur Kontrolle der synthetischen Sprachausgabe und der Kontrolle der Ausgabe von aufgezeichneten Audiodaten steht
dem Benutzer das <prompt> Element zur Verfügung. Mittels des
Attributes bargein kann man festlegen, ob der Benutzer das Recht haben soll, die Ausgabe zu
unterbrechen. Möchte man die Ausgabe an eine bestimmte Bedingung knüpfen, so benutzt man auch hier wieder
cond, und mit count kann man die Ausgabe an die Häufigkeit, mit
der sich der Nutzer wiederholt, anpassen.
Innerhalb des <prompt> Elements stehen einem eine Reihe von
Sprachmarkierungen zur Verfügung, mit denen
man zum Beispiel mittels <break> Sprechpausen einfügen kann. Durch Benutzung des
<audio> Elements kann man die Ausgabe mit einer Audiodatei vermischen und mittels
<value> Variablenreferenzen in die Ausgabe einbetten.
Ein kleines Beispiel:
<prompt cond="language == 'en'"> Please say your city. <audio src="say_your_city.wav"></prompt>
<prompt> <value expr="stadt"/> ist eine schöne Stadt. </prompt>
Guter Programmierstil:
Audioprompts sollten mit alternativem Text versehen werden. Dabei wird, falls das Audiofile nicht auffindbar ist, der zwischen den
<audio> Tags stehende Text per TTS ausgegeben.
Das Ganze ist vergleichbar mit dem alt Attribut des Imagetags in HTML.
<audio src="say_your_city.wav"> Bitte nennen Sie die gewünschte Stadt </audio>
Sollte die Audiodatei 'say_your_city.wav' nicht auffindbar sein, wird per TTS der
Text "Bitte nennen Sie die gewünschte Stadt" ausgegeben.
2.2.2 Grammar
Das <grammar> Element definiert
- eine Auswahl möglicher Äußerungen, die der Anrufer sagen kann, um eine
Aktion auszulösen bzw. eine Information zu geben, und
- liefert im Erfolgsfall eine sog. semantische Interpretation, d.h. ein Ergebnis (meist ein Stringausdruck) zurück.
Grammatiken sind normale Textdaten und werden erst zur Laufzeit in die Sprache des Spracherkenners übersetzt (kompiliert).
Grammatiken können entweder inline oder aber extern angegeben werden. Will man die Grammatik extern angeben, so legt man mit dem
Attribut src die Quelle der Grammatik fest. Des weiteren kann man mit scope
den Wirkungsbereich festlegen (document/ application).
Es folgen einige Beispiele für die Verwendung von Grammatiken innerhalb von VoiceXML.
Eine detaillierte Einführung in VoiceXML Grammatiken und deren Design gibt es hier.
2.2.2.1 Inline Grammar
Eine Inline Grammar ist eine kleine, überschaubare Grammar, die unmittelbar in den VoiceXML Code geschrieben wird.
<grammar type="application/gsl" mode="voice">
[ eins zwei drei ]
</grammar>
Der Anrufer kann sagen:
"eins" oder "zwei" oder "drei"
jedoch z.B. nicht "eins zwei".
2.2.2.2 Explizite Grammar
Die volle Bandbreite der VoiceXML-Grammar entfaltet sich erst bei der Verwendung externer Grammarfiles und entsprechender Tools und
Editoren, mit denen die Grammatiken offline erstellt und getestet werden kann.
Damit lassen sich auch große und hochkomplexe Grammatiken erzeugen.
Als Grammarname kann im src Attribut eine beliebige URL im WWW gewählt werden:
<grammar src="http://www..../grammar/test.grammar" ...>
2.2.2.3 Grammar mit Optionslisten: <option>
Möchte man Standardmenüs anbieten, kann man einerseits auf das <menu> Tag zurückgreifen, oder aber
in einer <form> mit dem <option> Tag arbeiten.
Beim <option> Tag benötigt man keine Grammardefinition, sondern schreibt wie folgt:
<option value="toggle"> umschalten </option>
oder als DTMF Option:
<option dtmf="1" value="wert1"/>
<option dtmf="2" value="wert2"/>
2.3 Ablaufkontrolle zwischen forms, items & Dokumenten
Um zwischen verschiedenen Forms zu wechseln, wird typischerweise das <goto> Tag verwendet.
Der Dialogablauf verlässt umgehend die aktuelle Form und beginnt bei der im next Attribut angegebenen
<form>.
Der Form Interpretation Algorithmus (FIA) beginnt die Ausführung am Beginn der neuen <form>.
Sollte am Ende einer Form kein Sprung zu einer anderen Form festgelegt sein, endet der FIA die Applikation.
2.3.1 <goto>
Das <goto> Element leitet den Nutzer zu einem andern form item, einem anderen Dialog oder einem anderem
Dokument weiter. Eines der Attribute next, expr, nextitem oder expritem muss die Adresse des nächsten Elements bzw. Dokumentes angeben.
Sprung zu einer bestimmten Form innerhalb des vxml-Dokumentes:
<goto next="#Irgendeine_Form_id" />
Sprung zur ersten Form in einem anderen vxml-Dokumentes:
<goto next="http://www.irgendwo.de/irgendein.vxml" />
Sprung zu einer bestimmten Form in einem anderen vxml-Dokumentes:
<goto next="http://www.irgendwo.de/irgendein.vxml#irgendeine_Form_id" />
Sprung zur ersten Form in einem anderen vxml-Dokumentes, dynamisch konstruiert:
<goto expr="'http://www.irgendwo.de/' + var1 + '.vxml'" />
Erzwungener Sprung zu einem bestimmten Form Item innerhalb einer Form:
<goto nextitem="Irgendein_FormItem_Name" />
2.3.2 <submit>
Das <submit> Element ist vergleichbar mit <goto>, jedoch kann man
hier (ähnlich einem Webformular) eine Liste von Variablen durch HTTP GET oder POST an einen Applikationsserver
übermitteln. Die Weiterverarbeitung der Daten erfolgt in einem Applikationsskript, und nicht in einer VoiceXML Datei.
Die HTTP Methode legt man mit dem Attribut method fest und die Adresse des gewünschten Skripts gibt man wie bei
<goto> im src Attribut an.
Die Variablennamen (nicht die Inhalte !) schreibt man in das Attribut namelist.
2.3.3 <script>
Wie in HTML kann man auch in VoiceXML Dokumenten mit dem Element <script> JavaScript Code inline
oder extern (src) einbinden.
2.4 Bedingte Verzweigungen
<if>, <else>, & <elseif> sind drei
Elemente, die innerhalb von VoiceXML für bedingte Verzweigungen verwendet werden. Jedes Element
(außer <else>) muss ein cond attribute enthalten, das einen ECMAScript konformen
Vergleich enthält. Dabei können sowohl direkte Werte, als auch Variablenreferenzen verwendet werden:
<if cond="a == b">
<elseif cond="a == 'test' "/>
<else/>
Hinweis:
Bei <elseif .../> und <else/> ist besonders das schließende
Tag '/>' zu achten (häufige Fehlerquelle) !
2.5 Applikationen mit mehreren Dokumenten
Ein VoiceXML Dokument kann aus mehreren einzelnen Dokumenten bestehen. Dieser Satz von VoiceXML beinhaltet meist genau ein
"root" document. Dieses Root-Dokument definiert globale Variablen und Verhaltensweisen
<var>, <link>, <catch>, <property>,...
Der Vorteil mehrerer VoiceXML-Dokumente liegt auf der Hand:
- zusammengehörige Tasks werden in ein Dokument ausgelagert
- die Dateigröße und die Komplexität des Inhalts bleibt überschaubar
2.5.1 Festlegung eines Root-Dokumentes
Die Festlegung eines Dokumentes als Root-Dokument erfordert die Definition des application Attributs im
<vxml> Tag der Nicht-Root-Dokumente.
<vxml version="2.0" application="./start.vxml">
Das Root-Dokument selbst wird NICHT gesondert gekennzeichnet und bleibt unverändert !
<vxml version="2.0">
2.6 Ereignisbehandlung
Es gibt plattformgenerierte Ereignisse, wenn der Anrufer z.b. nicht oder undeutlich antwortet, Hilfe anfordert usw., oder der
Interpreter kann ein Ereignis erzeugen, wenn es Semantikfehler im VoiceXML Dokument gibt oder dieser nicht unter der angegebenen URL zu finden ist,
oder aber der Interpreter auf ein <throw> Element trifft.
Will man selbst also ein Ereignis erzeugen, so benutzt man dafür das <throw> Element, wobei man mit
dem Attribut event festlegt, wie das erzeugte Ereignis heißt.
Will man ein Ereignis abfangen um auf dieses zu reagieren, so benutzt man das <catch> Element.
Auch hier legt man mittels des event Attributs fest um welches Ereignis es sich handelt.
Das count Attribut zählt die Häufigkeit des Auftretens des Ereignisses mit, so dass man auf
verschiedene Häufigkeiten unterschiedlich reagieren kann, z.B. kurz und knapp oder mit ausführlicher Info.
Außerdem kann man mit cond noch eine Bedingung festlegen, mit der man z.b. ermitteln kann ob man ein
Ereignis wirklich abfangen möchte.
Um die Handhabung der Ereignisbehandlung zu vereinfachen gibt es bereits eine Reihe von Abkürzungen für
<catch> Elemente um bestimmte Ereignisse abzufangen:
<noinput>, <nomatch>, <help> und
<error>.
Eine Erzeugung und Ereignisbehandlung eines Hilferufes könnte folgendermaßen aussehen:
<throw event="help"/>
<catch event="help"> Dies ist die Hilfefunktion. </catch>
2.7 Variablen, Ausdrücke und Scope
2.7.1 <var>
Will man Variablen definieren, so benutzt man das Element <var>. Das Attribut
name gibt dabei den Namen der Variable und expr deren Wert an.
Das expr Attribut ist optional.
<var name="test" />
<var name="test" expr="0" />
2.7.2 <assign>
Möchte man Variablen einen Wert zuweisen, so benutzt man das Element <assign>. Die Variable
muss vorher mit <var> definiert worden sein, sonst wird ein error.semantic ausgelöst.
Auch hier gibt name den Namen der Variable und expr deren Wert an.
<assign name="pi" expr="3.14159"/>
2.7.3 Gültigkeitsbereich (scope) von Variablen
Variablen können fünf unterschiedliche Gültigkeitsbereiche besitzen:
session |
Read only Variablen, die von der Plattform gesetzt werden und während der gesamtten Callsession zur Verfügung stehen.
Sie können innerhalb des VoiceXML-Dokumentes nicht verändert werden.
|
application |
Der Gültigkeitsbereich application tritt bei Variablendefinitionen unmittelbar hinter dem
<vxml> Tag des Rootdokumentes ein. Sie existieren, sobal das Rootdokument geladen wurde und können von jedem Dokument verwendet
werden, welches auf dieses Rootdokument verweist.
|
document |
Der Gültigkeitsbereich ist vergleichbar mit dem applicatiin scope, gilt jedoch nur für ein Nicht-Rootdokument
innerhalb dieses Dokumentes.
|
dialog |
Variablen, die innerhalb von <form> oder <menu> erstellt werden,
besitzen den scope dialog. Eine Verwendung ist nur in diesem Dialogelement möglich.
|
(anonymous) |
Jedes <block>,<filled>,
<catch>* Element definiert einen anonymen scope, in dem Variablen erstellt werden können.
|
2.8 Weitere Elemente
2.8.1 <link>
Ein <link> Element enthält eine oder mehrere Grammatiken. Passt eine dieser Grammatiken zu einer
Eingabe, dann wird der Link ausgeführt. Dies kann einerseits bedeuten, dass der Benutzer zu einem anderen Dialog weitergegeben
wird oder andererseits ein Ereignis erzeugt wird. Mit dem next Attribute wird der Benutzer an die
entsprechende URI weitergegeben und mit dem event Attribut erzeugt man ein Ereignis.
Des weiteren steht dem Programmierer noch das expr Attribut zur Verfügung, das genauso wie das
next Attribut funktioniert, mit dem man aber die URI dynamisch erzeugen kann.
Ein Beispiel für <link>:
<link event="help">
<grammar>
[
(hilfe)
(ich brauche hilfe)
(ich weiss nicht weiter)
(was muss ich tun)
(das habe ich nicht verstanden)
]
<link>
</grammar>
2.8.2 <meta>
Wie in HTML Dokumenten ist es auch in Voice XML Dokumenten möglich mit dem <meta> Element
Metadaten festzulegen.
Es werden diese zwar nicht vom Programmierer gefordert, aber es wird empfohlen Informationen über den Autor (author),
as Copyright (copyright) und den Unterhalter der Seite (maintainer) anzugeben. Außerdem sollte man noch eine Beschreibung
der Seite (description), Schlüsselwörter (keywords) und Anweisungen für Suchroboter (robots) angeben. Das Attribut name
gibt hierbei immer den Namen der Metainformation und das Attribut content den Inhalt dieser an, wobei man anstelle von
name auch http-equiv benutzen kann.
Hier ein Beispiel für eine Metainformation:
<meta name="author" content="Name">
2.8.3 <filled>
Um auf die Eingaben des Nutzers in Felder zu reagieren benutzt man das <filled> Element.
Dieses benutzt man, um Aktionen festzulegen, die eintreten sollen, wenn eine bestimmte Kombination von Feldern vom Nutzer gefüllt
wurden. Das Attribut namelist gibt die Liste der Felder an, auf die sich das <filled> Element bezieht und mode bestimmt an, ob alle (all) oder irgendeines (any) dieser Felder gefüllt sein muß.
Die Attribute finden allerdings nur dann Verwendung, wenn das <filled> Element Kindknoten eines
<form> Elementes ist, denn ist es Kindknoten eines <field> Elements
erübrigen sich diese.
2.8.4 <clear>
Mit dem <clear> Element kann man ein oder mehrere form items, die mit <namelist>
angegeben werden, zurücksetzen, d.h. es werden die entsprechenden Variablen auf undefiniert gesetzt und die Ausgabe und
Ereigniszähler reinitialisiert.
2.8.5 <reprompt>
Durch <reprompt> wird die nächste Ausgabe gewählt und abgespielt und der Ausgabezähler um eins erhöht.
2.8.6 <disconnect>, <exit>
Natürlich gibt es auch die Möglichkeit alle geladenen Dokumente zu beenden. Hierzu stehen dem Programmierer das
<exit> und das <disconnect> Element zur Verfügung.
Der Unterschied zwischen beiden besteht darin, daß <exit> die Kontrolle zum Interpreter zurückgibt und
diesem die Wahl überläßt, was er als nächstes tut, während <disconnect> ein telephone.disconnected.hangup
Ereignis erzeugt und die Trennung des Interpreters vom Nutzer verursacht.
|