Dave Raggett   Débuter en VoiceXML 2.0

Dave Raggett, revu le 14 novembre 2001.

[Le document original Getting started with VoiceXML 2.0 a été traduit par Patrick Blanchenay le 23 octobre 2004.]

Cet article est une courte introduction au VoiceXML. Il doit beaucoup aux diapositives de Scott McGlashan de Pipebeach. Scott co-préside le groupe de travail du W3C sur les navigateurs vocaux et dirige le sous-groupe dédié au VoiceXML.

Plan

Vue d'ensemble du VoiceXML

Téléphone, interpréteur VoiceXML et site Web

Le VoiceXML, qu'est-ce que c'est ? C'est un langage XML qui permet de créer des pages Web avec lesquelles on intéragit en écoutant des annonces et jingles, et que l'on contrôle par la voix. Le VoiceXML met le Web aux portes du téléphone. Si vous voulez un aperçu de ce que cela peut donner, il existe un nombre croissant de portails vocaux auxquels vous pouvez téléphoner et essayer par vous-mêmes. Par ailleurs, de nombreux sites proposent un hébergement VoiceXML gratuit. La FAQ sur la page Overview proposent des liens vers ces sites.

Le VoiceXML n'est pas du HTML. Le HTML a été conçu pour des pages Web visuelles et n'offre pas le contrôle sur l'interaction utilisateur/application que nécessite une interface vocale. Par la voix, on ne peut entendre qu'une chose à la fois (c'est comme lire un journal avec une loupe 10x). VoiceXML a été conçu avec soin, dans le but de donner aux auteurs un contrôle total sur le dialogue parlé entre l'utilisateur et l'application. L'application et l'utilisateur parlent à tour de rôle : l'application demande un renseignement à l'utilisateur (une "invite"), lequel à son tour répond.

Les documents XML décrivent :

Le VoiceXML permet de créer rapidement de nouvelles applications et épargnent aux développeurs les détails de premier niveau et de mises en place. Il sépare l'interaction utilisateur de la logique du service. La spécification VoiceXML 2.0 du W3C est la référence d'autorité du VoiceXML. Vous trouverez des travaux similaires sur la page voice browser overview page du W3C.

Concepts fondamentaux

Une session commence lorsque l'utilisateur commence d'interagir avec l'interpréteur VoiceXML et se poursuit pendant que les documents VoiceXML sont chargés et déchargés. La session se termine à la demande de l'utilisateur, du document VoiceXML ou du contexte de l'interpréteur. La plateforme définit le comportement par défaut de la session, bien que cela puisse être en partie changé par le VoiceXML.

Les documents VoiceXML définissent des applications comme un ensemble d'états de dialogue identifiés. L'utilisateur se trouve à tout moment dans l'un des états de dialogue. Chaque dialogue précise grâce à un URL le prochain dialogue vers lequel s'acheminer.

Les dialogues VoiceXML incluent : des formulaires et des menus. Un menu propose à l'utilisateur plusieurs options et indique les transitions vers d'autres états de dialogue selon le choix de l'utilisateur. Un formulaire définit une interaction qui recueille les valeurs pour chacun des champs du formulaire. Chaque champ peut indiquer une invite, la réponse attendue et les règles d'évaluation. Le formulaire peut être soumis à un serveur d'une manière très similaire à celle du HTML.

Une application est un ensemble de documents VoiceXML partageant le même document racine. Le document racine est automatiquement chargé quand l'un des documents de l'application est chargé, et reste chargé tant qu'une transition vers une autre application existe ou lorsque l'appel est interrompu. L'information contenue dans le document racine est utilisable dans tous les documents de l'application.

Plusieurs documents VoiceXML peuvent partager le même document racine d'application

Chaque état de dialogue possède une ou plusieurs grammaires associées, qui servent à décrire la réponse attendue par l'utilisateur, soit vocale soit en pressant une touche à tonalité (DMTF). Dans le cas le plus simple, seul les grammaires du dialogue sont actives dans ce dialogue. Dans des cas plus complexes, d'autres grammaires peuvent être actives :

Un sous-dialogue ressemble à un appel de fonction : il permet d'insérer un nouveau dialogue et de revenir au dialogue de départ, en retenant l'information de l'état local de ce dialogue. Les sous-dialogues peuvent servir à gérer les demandes de confirmation ou à créer une bibliothèque de dialogues réutilisables pour les tâches communes.

Modèle d'héritage pour la saisie d'évènements
Le VoiceXML permet de définir des variables nommées, qui peuvent contenir des données. Ces variables peuvent être définies à n'importe quel niveau et leur portée suit un modèle d'héritage. Vous pouvez effectuer des tests sur les valeurs des variables pour déterminer à quel état de dialogue la prochaine transition doit mener. Des expressions variables peuvent également être utilisées pour des invites et grammaires conditionnelles etc.

Des évènements sont lancés lorsque l'utilisateur ne répond pas à une invite ou lorsque sa réponse ne peut être interprétée. VoiceXML permet de gérer les évènements ; cette gestion suit un modèle d'héritage, et les évènements peuvent être gérés à un niveau supérieur s'il n'existe pas de gestion définie au niveau du dialogue.

Le VoiceXML vous permet d'utiliser des scripts (ECMAScript) pour vous offrir une meilleure maîtrise de l'application. Il fonctionne un peu comme un formulaire : vous pouvez définir une grammaire complexe, destinée à recueillir les valeurs de plusieurs champs dans un même temps. Les champs non-remplis peuvent être gérés par des sous-dialogues spécifiques au sein de chaque dialogue.

Des exemples de VoiceXML

Voici une application VoiceXML très simple. Elle dit "Cher voyageur, bienvenue !", lance un petit message publicitaire audio et quitte :

<?xml version="1.0" encoding="ISO-8859-1"?>
<vxml version="2.0" lang="fr">
<form>
<block>
<prompt bargein="false">Cher voyageur, bienvenue !
<audio src="http://www.adline.com/mobile?code=12s4"/>
</prompt>
</block>
</form>
</vxml>

L'exemple suivant propose un menu offrant trois choix : sport, météo ou nouvelles.

<?xml version="1.0"?>
<vxml version="2.0">
<menu>
<prompt>
Choisissez un canal : <enumerate />
</prompt>
<choice next="http://www.sport.exemple/debut.vxml">
Sport
</choice>
<choice next="http://www.meteo.exemple/intro.vxml">
Météo
</choice>
<choice next="http://www.nouvelles.exemple/nouvelles.vxml">
Nouvelles
</choice>
<noinput>Merci de choisir un canal : <enumerate/></noinput>
</menu>
</vxml>

Voici comment peut se dérouler le dialogue :

Serveur : Choisissez un canal : sports ; météo ; nouvelles.
Utilisateur : Horoscope.
Serveur : Je n'ai pas compris votre réponse.
(un message propre à la plateforme)
Serveur : Merci de choisir un canal : sports ; météo ; nouvelles.
Utilisateur : Sport.
Serveur : (se rend à l'adresse http://www.sports.example/start.vxml)

Voici un autre exemple utilisant cette fois un formulaire, pour que l'utilisateur choisisse une ville et le nombre de voyageurs. Une fois cette information recueillie, elle est envoyée à un serveur Web :

<?xml version="1.0" encoding="ISO-8859-1"?>
<vxml version="2.0" lang="fr">
<form>

<field name="ville">
<prompt>Quelle est votre destination?</prompt>
<option>Edimbourg</option>
<option>New-York</option>
<option>Londres</option>
<option>Paris</option>
<option>Stockholm</option>
</field>

<field name="voyageurs" type="number">
<prompt>Combien de voyageurs se rendent à <value expr="ville" />?</prompt>
</field>

<block>
<submit next="http://localhost/handler" namelist="ville voyageurs" />
</block>

</form>
</vxml>

Le VoiceXML permet de lancer des invites de plus en plus détaillées lorsque l'utilisateur peine à répondre. Ce mécanisme repose sur un compteur qui s'incrément à chaque boucle. L'exemple suivant en montre le fonctionnement pour un champ qui recueille le nombre de voyageurs. On demande d'abord à l'utilisateur : "Combien de voyageurs se rendent à Sydney ?". Si la réponse ne convient pas, on demande à l'utilisateur : "Merci d'indiquer le nombre de voyageurs". L'élément nomatch permet de lancer une invite si l'utilisateur répond autrement que par un nombre :

<field name="voyageurs" type="number">

<prompt count="1">
Combien de voyages se rendent à <value expr="ville" />?
</prompt>

<prompt count="2">
Merci d'indiquer le nombre de voyageurs.
</prompt>

<prompt count="3">
Pour réserver un vol, vous devez indiquer combien
de personnes se rendent à <value expr="ville" />.
</prompt>

<nomatch>
<prompt>Merci de répondre par un nombre.</prompt>
<reprompt />
</nomatch>

</field>

Voici un exemple qui teste la valeur d'un champ après l'avoir recueillie. Ce mécanisme peut être utilisé pour lancer un message d'alerte lorsque le nombre de voyageurs dans un groupe est supérieur à douze :

<field name="voyageurs" type="number">
<prompt>Combien de voyageurs se rendent à <value expr="ville" />?</prompt>

<filled>
<var name="nb_voyageurs" expr="voyageurs + 0" />
<if cond="nb_voyageurs > 12">
<prompt>
Désolé, nous ne gérons pas les groupes de plus de douze personnes.
</prompt>
<clear namelist="voyageurs" />
</if>
</filled>

</field>

Le VoiceXML permet de définir des sous-dialogues réutilisables pour les tâches habituelles. Les sous-dialogues sont très similaires aux sous-routines utilisées dans les langages de programmation. Voici l'exemple d'un sous-dialogue de confirmation dans lequel on demande une confirmation pour savoir si l'on garde l'entrée précédente ou non :

<form id="ynconfirm">
<var name="user_input"/>

<field name="yn" type="boolean">

<prompt>Avez-vous dit <value expr="user_input"/> ?</prompt>

<filled>
<var name="result" expr="'false'"/>
<if cond="yn">
<assign name="result" expr="'true'"/>
</if>
<return namelist="result"/>
</filled>

</field>

</form>

Si la reconnaissance vocale indique que la réponse de l'utilisateur n'est pas clairement identifiable, le VoiceXML vous permet de construire le dialogue selon vos besoins. Dans l'exemple suivant, on demande à l'utilisateur de confirmer sa réponse si le score de confiance du nom de la ville est inférieur à 0,7 mais s'il est inférieur à 0,3 on demande à l'utilisateur de redire le nom de la ville :

<field name="ville">
<prompt>Quelle ville ?</prompt>
...
<filled>
<if cond="ville$.confidence < 0. 3">
<prompt>Désolé, je n'ai pas compris votre réponse.</prompt>
<clear namelist="ville" />
<elseif cond="ville$.confidence < 0.7" />
<assign name="utterance" expr="city$.utterance" />
<goto nextitem="confirmerville" />
</if>
</filled>
</field>

<subdialog name="confirmerville" src="#ynconfirm" cond="false">
<param name="user_input" expr="utterance" />
<filled>
<if cond="confirmerville.result=='false'">
<clear namelist="ville" />
</if>
</filled>
</subdialog>

Si la confiance est inférieure à 0,3 l'utilisateur entend : "Désolé, je n'ai pas compris votre réponse." Si la confiance est inférieure à 0,7 le sous-dialogue générique de confirmation est appelé. Le sous-dialogue agit exactement comme un appel de sous-routine. On se sert de l'élément param pour passer des données au sous-dialogue.

Vous pouvez également utiliser des grammaires dans des fichiers séparés. L'exemple suivant utilise des grammaires du fichier "trade.xml" :

<form name="bourse">

<field name="societe">
<prompt>Sur quelle société voulez-vous échanger ?</prompt>
<grammar src="trade.xml#societe" type="application/grammar+xml" />
</field>

<field name="action">
<prompt>
Voulez-vous acheter ou vendre des actions de
<value expr="company" />?
</prompt>
<grammar src="trade.xml#action" type="application/grammar+xml" />
</field>

</form>

Vous pouvez utiliser l'élément import pour importer des règles de grammaire pour y faire référence dans des grammaires locales. Dans l'exemple suivant, on suppose que dans "politeness.xml" sont définies les règles "startPolite" (ex : "S'il-vous-plaît'') and "endPolite" (ex : "merci") :

<grammar xml:lang="fr">

<import uri="http://please.com/politeness.xml" name="polite" />

<rule name="command" scope="public">
<ruleref import="polite#startPolite"/>
<ruleref uri="#action"/>
<ruleref uri="#object"/>
<ruleref import="polite#endPolite"/>
</rule>

<rule name="action" scope="public">
<choice>
<item tag="acheter"> acheter </item>
<item tag="vendre"> vendre </item>
</choice>
</rule>

<rule name="societe" scope="public">
<choice>
<item tag="ericsson"> ericsson </item>
<item tag="nokia"> nokia </item>
</choice>
</rule>
</grammar>

Dans l'exemple suivant pour une application de bourse, l'utilisateur peut répondre avec une phrase courte comme "acheter Ericsson" qui définit à la fois la société et le type d'opération. La grammaire pour ce procédé est définie dans le fichier "trade.xml". Si l'utilisateur ne répond pas correctement, l'application tente une approche plus simple, en demandant d'abord le nom de la société, puis le type d'opération à effectuer. Les éléments field sont sautés si les valeurs correspondantes ont déjà été remplies.

<form name="bourse"> 

<grammar src="trade.xml#command" type= "application/grammar+xml"/>

<initial name="debut">
<prompt>Quel opération voulez-vous effectuer ?</prompt>
<nomatch count="1">
<prompt>Merci de donner une instruction du type : 'acheter Ericsson'.</prompt>
<reprompt/>
</nomatch>
<nomatch count="2">
Désolé, je n'ai pas compris votre demande. Nous allons procéder plus simplement.
<assign name="debut" expr="true"/>
</nomatch>
</initial>

<field name="societe"> ... </field>
<field name="action"> ... </field>
</form>

L'application peut donner à l'utilisateur l'occasion de passer à une tâche différente en donnant l'ordre vocal approprié. La grammaire de ce mécanisme peut être précisée au niveau du document ou au document racine de l'application. Voici un exemple d'un menu de commande au niveau du document :

<?xml version="1.0" encoding="ISO-8859-1"?>
<vxml version="2.0" lang="fr">

<form name="bourse">
...
</form>

<menu name="portail-commandes" scope="document">
<choice expr="http://www.wl.com?action=car">Location de voiture</choice>
<choice expr="http://www.wl.com?action=hotel">Réservation d'hôtel</choice>
<choice expr="http://www.wl.com?action=nouvelles">Nouvelles</choice>
</menu>

...
</vxml>

Pour faire référence au document racine de l'application, on utilise l'attribut application de l'élément vxml :

<?xml version="1.0" encoding="ISO-8859-1"?>
<vxml version="2.0" lang="fr"
application="http://buster/portal?sessionID=12d4rf65hg4" >

...
</vxml>

Voici l'exemple d'un document racine qui crée une commande permettant de retourner à la page d'accueil du portail. Cet exemple inclut aussi un gestionnaire permettant de saisir les évènement "noinput", au cas où ils ne l'auraient pas été par des gestionnaires de niveu inférieur, par exemple à chaque dialogue :

<form name="commandes-portail" scope="document"> 
<field name="action">
<grammar src="http://buster/portal/commands.xml"
type="application/grammar+xml"/>
</field>
<block>
<submit next="http://www.wl.com"/>
</block>
</form>
<var name="portail-aide" expr=
"Pour retourner à la page d'accueil, dîtes 'accueil' ou appuyez sur 0."/>

<catch event="noinput">
Désolé, je n'ai rien entendu.
</catch>

Pour plus d'information

La spécification VoiceXML 2.0 du W3C est la spécification faisant autorité pour le VoiceXML. Pour plus d'informations sur le W3C Speech Interface Framework et les spécifications relatives, allez voir le W3C Voice Browser Activity. Les membres du W3C peuvent avoir accès aux dernières spécifications en cours de développement par le Voice Browser working group. Sur le site du VoiceXML Forum, vous trouverez d'autres tutoriels et de nombreux de liens utiles .

Je prévois d'ajouter des sections supplémentaires sur les grammaires vocales et la synthèse vocale, ainsi que des commentaires à propos du travail du W3C sur le multimodal et d'autres sujets.

Bonne chance et à vos plumes !

Dave Raggett <dsr@w3.org>


Droit de copie ©2002-2003 W3C ® ( MIT, ERCIM, Keio), Tous droits réservés. Les règles de responsabilité, de marque déposée, d'utilisation du document et de licence sur les logiciels du W3C s'appliquent. Votre interaction avec ce site est en accord avec notre politique sur la vie privée, pour le public et pour les membres.

[Le document original Getting started with VoiceXML 2.0 a été traduit par Patrick Blanchenay le 23 octobre 2004.]