Comment écrire des flux de dialogue dans OBotML?
OBotML utilise une syntaxe simple pour définir les variables et les états. Comme il s'agit d'une variante de YAML, conservez les conventions d'espacement YAML lorsque vous définissez le flux de dialogue. Il n'est pas nécessaire de commencer à zéro. Vous pouvez utiliser la définition de flux de dialogue par défaut comme modèle de base.
context
et states
. Il vous suffit de supprimer le texte passe-partout existant et d'ajouter votre propre contenu. Pour vous aider à créer des définitions d'état saines sur le plan syntaxique, utilisez les modèles de composant du menu + Component (+ Composant). Voir Syntaxe de flux de dialogue pour obtenir des conseils sur la définition des variables et des états.
Conseil :
Cliquez sur Validate (Valider) pendant que vous rédigez votre flux de dialogue pour rechercher les erreurs de syntaxe et appliquer les meilleures pratiques.Syntaxe de flux de dialogue
Procédures? | Utiliser |
---|---|
Définir des variables qui conservent le contexte dans l'ensemble du flux de dialogue |
Dans le noeud
context , utilisez la syntaxe suivante : variablename: "variableType" Par exemple :
Vous pouvez définir des variables en tant qu'entités (comme |
Définir un programme de traitement d'erreurs pour votre compétence? |
Définissez le noeud
defaultTransitions qui pointe vers un état qui gère les erreurs. En général, vous ajoutez cet état à la fin de la définition du flux de dialogue. Par exemple :
Voir Configurer le flux de dialogue pour des actions inattendues. |
Définir une variable contenant la valeur de l'intention résolue |
Dans le noeud
context , définissez une variable qui nomme l'entité nlpresult . Comme son nom l'indique ("nlp" signifie traitement du langage naturel), cette entité extrait l'intention résolue par le moteur d'intention. Presque tous les robots de référence déclarent des variables nlpresult . Par exemple :
|
Contrôler le flux de dialogue en fonction de l'entrée de l'utilisateur |
Généralement (mais pas toujours), vous définissez une propriété Comme décrit dans Structure du flux de dialogue en mode YAML, vous pouvez déclarer une variable |
Définir ma compétence pour qu'elle gère les intentions non résolues? |
Définissez un état pour l'action Exemple :
|
Permettre aux composants d'accéder aux valeurs de variable |
Utilisez la propriété
.value dans vos expressions (${crust.value} ). Pour remplacer une valeur par défaut, utilisez ${variable.value!\"default value\"} . Par exemple, thick est la valeur par défaut dans ${crust.value!\"thick\"} . Par exemple :
Utilisez l'opérateur par défaut d'Apache FreeMarker ( |
Enregistrer les valeurs de l'utilisateur pour les prochaines visites |
Dans une définition d'état, ajoutez une définition de variable avec le préfixe
user. . Voir Composants YAML intégrés pour la définition de valeurs utilisateur. Par exemple :
Pour en savoir plus sur les variables d'utilisateur, voir le flux de dialogue pour le robot de référence PizzaBotWithMemory. |
Quitter un flux de dialogue et terminer la session utilisateur. |
Utilisez une transition Exemple :
|
Navigation et transitions de flux
Vous pouvez diriger le moteur de dialogue sur un chemin spécifique dans le flux de dialogue en définissant la propriété "transitions" pour un état. Les transitions décrivent les branchements possibles dans le dialogue selon les valeurs de variable. Elles vous permettent de définir le cheminement type de la conversation (cas nominal) et de définir d'autres chemins prenant en compte les valeurs manquantes ou un comportement imprévisible de l'utilisateur.
Pour ce faire... | ... Utiliser cette transition |
---|---|
Spécifier l'état suivant à exécuter. | Définissez une transition next (next: "statename" ) pour indiquer au moteur de dialogue de passer à l'état nommé par la clé next . Comme indiqué dans la rubrique Transition suivante, vous pouvez ajouter une transition next à tout état, à l'exception de ceux qui comportent la transition return .
|
Réinitialiser la conversation. | Utilisez une transition return pour effacer tout jeu de valeurs pour les variables de contexte et réinitialiser le flux de dialogue. Vous pouvez donner à cette transition n'importe quelle valeur de chaîne. La définition d'une transition return: "done" met fin à la session utilisateur et positionne le moteur de dialogue au début du flux.
|
déclencher des actions conditionnelles; | Définissez des clés actions pour déclencher la navigation à un état spécifique. Lorsqu'un composant termine un traitement, il retourne une chaîne d'action indiquant au moteur de dialogue où se diriger. Si vous ne définissez aucune clé d'action, le moteur de dialogue utilise la transition par défaut ou la transition next (s'il en existe une). Vous pouvez définir autant d'actions que nécessaire. Certains composants intégrés comportent des actions spécifiques. Par exemple, un composant comme System.MatchEntity qui évalue une expression Apache FreeMarker utilise les actions match et nomatch . System.OAuthAccountLink comporte les actions textReceived , pass et fail , et les composants de l'interface utilisateur utilisent leurs propres actions (décrites dans Transitions for Common Response Components ). Utilisez les modèles de composant comme guide. Vous pouvez définir une transition actions pour n'importe quel état, sauf ceux qui comportent une transition return .
|
Traiter les erreurs. | Les composants génèrent parfois des erreurs. Cela se produit généralement en raison d'un problème ou d'un échec lié au système (mot de passe ou nom d'hôte non valide, ou erreur de communication). La définition d'une transition error qui nomme un état de traitement d'erreur permet à votre compétence de traiter correctement les problèmes : Si vous ne définissez pas de transition error , la compétence affiche l'invite d'erreur inattendue ( Oops! I'm encountering a spot of trouble) (Désolé, une erreur est survenue) et termine la session. Vous pouvez définir une transition error dans n'importe quel état, sauf pour ceux qui comportent une transition return .
Certains composants incluent une erreur définie comme action. Ces transitions d'erreur intégrées permettent de traiter les erreurs propres au composant :
|
next
:state_name:
component: "component name"
properties:
component_property: "value"
component_proprety: "value"
transitions:
next: "go_to_state"
error: "go_to_error_handler"
actions:
action_string1: "go_to_state1"
action_string2: "go_to_state2"
Vous pouvez définir plusieurs transitions, mais la transition
return
est une exception : vous ne pouvez pas combiner une transition return
avec les transitions error
, next
ou actions
.
Transition suivante
Vous utilisez la transition next
pour spécifier l'état suivant par défaut. Lorsqu'un état combine des transitions error
, actions
et next
, la transition next
n'est déclenchée que lorsque le composant ne peut pas retourner de chaîne satisfaisant les transitions error
ou actions
.
next
est déclenchée lorsque des erreurs ou des actions ne peuvent pas l'être, définissez une action next
dans le noeud defaultTransition
.
context:
variables:
name: "string"
defaultTransitions:
next: "nextRules"
states:
getName:
component: "System.Text"
properties:
prompt: "What's your name please?"
variable: "name"
transitions:
next: "printName"
printName:
component: "System.Output"
properties:
text: "Hello ${name.value}."
transitions:
return: "done"
nextRules:
component: "System.Output"
properties:
text: "Hello ${name.value}. I told you! Next transitions rule the game!"
transitions:
return: "done"
Configurer le flux de dialogue pour des actions inattendues
scénario; | Solution |
---|---|
Au lieu de toucher des boutons, l'utilisateur répond de manière inappropriée en entrant du texte. | Pour permettre à votre robot de réagir correctement, dirigez le flux vers un état où le composant System.Intent peut résoudre l'entrée de texte, par exemple textReceived: Intent dans l'extrait de code suivant de CrcPizzaBot :
|
Les utilisateurs remontent jusqu'à un message antérieur et touchent ses options, alors qu'ils devraient se servir des boutons de la réponse courante. |
Par défaut, Digital Assistant gère les messages dans le ordre, mais vous pouvez remplacer ou personnaliser ce comportement, comme indiqué dans la rubrique sur la détection des actions dans le désordre.
Par exemple, l'ajout d'une transition
system.outofOrderMessage par défaut indique au moteur de dialogue de passer à un état unique qui traite tous les messages dans le désordre, comme l'état HandleUnexpectedAction dans l'extrait de code OBotML ci-dessus. Vous pouvez utiliser différentes approches pour créer cet état :
|
Appeler une compétence à partir d'une autre à partir d'un flux de dialogue YAML
Vous pouvez être amené à fournir aux utilisateurs une option explicite pour quitter temporairement la compétence avec laquelle ils communiquent afin d'effectuer une action dans une deuxième compétence de l'assistant numérique. Par exemple, s'ils sont dans une compétence d'achat et qu'ils ont déjà fait des sélections, vous pouvez afficher un bouton leur permettant de passer à une compétence bancaire (pour s'assurer qu'ils disposent d'assez argent pour l'achat), puis de retourner à la première compétence pour terminer la commande.
Pour ce faire dans un flux de dialogue YAML, vous pouvez configurer une action dans une compétence pour lancer une interaction avec une autre compétence du même assistant numérique, puis retourner au flux initial.
Fonctionnement :
-
Le composant
System.CommonResponse
permet de proposer à l'utilisateur un bouton pour accéder à une autre compétence.Ce bouton est basé sur une action de republication, dans laquelle vous configurez les données utiles afin qu'elles fournissent un énoncé pertinent destinée à la compétence cible. Idéalement, cet énoncé doit contenir le nom d'appel de la compétence cible (pour un appel explicite) afin d'optimiser les chances d'acheminement vers cette compétence. En procédant ainsi, vous codez de façon permanente un énoncé pour déclencher l'intention souhaitée.
Voici le format de ce code :
component: "System.CommonResponse" properties: metadata: ... responseItems: - type: "cards" ... actions: ... - label: "Press me to switch to different skill" type: "postback" payload: action: "system.textReceived" variables: system.text: "utterance with invocation name that you want passed to the digital assistant" ...
En utilisant une action
system.textReceived
et en spécifiant le texte dans la variablesystem.text
, vous assurez que la republication est traitée comme un message utilisateur pouvant être acheminé correctement par l'assistant numérique.Note
Lorsque vous utilisezsystem.textReceived
de cette façon,system.text
est la seule variable que vous pouvez définir dans les données utiles de republication. Toutes les autres variables des données utiles sont ignorées. - Vous réglez la transition
textReceived
à l'état contenant le composantSystem.Intent
.transitions: actions: .... textReceived: "Name of the state for the System.Intent component"
Cela est nécessaire pour assurer que l'assistant numérique fournisse une réponse de secours appropriée si l'assistant numérique ne contient pas la compétence cible.
Pour que cela fonctionne, la propriété
daIntercept
du composantSystem.Intent
de la compétence doit être réglée à"always"
(qui est la valeur par défaut).
Si la compétence cible se trouve dans l'assistant numérique, ce dernier reconnaît l'appel explicite, prend le contrôle de la demande (qui devrait normalement être traitée par le composant) et achemine la demande vers le composant System.Intent
de la compétence cible. Une fois le flux de la compétence cible terminé, l'utilisateur est ramené à la compétence d'appel.
Si la compétence cible n'est pas dans l'assistant numérique (ou si la compétence d'appel est présentée sans assistant numérique), le composant System.Intent
de la compétence d'appel est appelé et l'intention devrait être résolue en unresolvedIntent
.
Conseil :
Pour gérer le cas où le nom d'appel de la compétence cible est modifié lorsqu'il est ajouté à un assistant numérique, vous pouvez utiliser un paramètre personnalisé à transmettre au nom d'appel de la compétence dans la variable system.text
.
Par exemple, vous pouvez créer un paramètre nommé da.CrcPizzaCashBankInvocationName
dans la compétence de commande de pizza et lui donner la valeur par défaut CashBank
. Il est alors possible de référencer le paramètre comme suit :
system.text: "ask ${system.config.daCrcPizzaFinSkillInvocationName}, what is my balance"
Si le nom d'appel de la compétence est modifié, il suffit de modifier la valeur du paramètre personnalisé en fonction du nouveau nom d'appel.
Voir Paramètres personnalisés.
Lorsque vous utilisez un appel explicite dans la variable
system.text
, l'utilisateur peut voir deux fois le message avec ce bouton :
- Lorsque le bouton lui est présenté pour naviguer jusqu'à l'autre compétence.
- Quand il met fin au flux dans l'autre compétence.
system.text
au lieu d'un appel explicite. Un appel implicite est un énoncé qui correspond bien à une compétence donnée sans utiliser le nom d'appel de cette dernière (ou une variante de ce nom avec un espacement ou une capitalisation autre).
Exemple : Appeler une compétence à partir d'une autre
Par exemple, voici une intention de commande de pizza (OrderPizza
) qui donne à l'utilisateur l'option de vérifier le solde de son compte bancaire avant de passer la commande. Le solde du compte est fourni par une autre compétence (CashBank
). Si l'utilisateur sélectionne l'option Check Balance
, le texte "Demander à CashBank quel est mon solde" est publié dans l'assistant numérique et l'utilisateur est dirigé vers l'intention appropriée dans la compétence CashBank
.
OrderPizza:
component: "System.CommonResponse"
properties:
metadata:
...
responseItems:
- type: "cards"
headerText: "Our pizzas:"
cardLayout: "vertical"
name: "PizzaCards"
actions:
- label: "More Pizzas"
...
- label: "Check bank account balance"
type: "postback"
payload:
action: "system.textReceived"
variables:
system.text: "ask CashBank, do I have enough money?"
...
processUserMessage: true
transitions:
actions:
order: "AskPizzaSize"
more: "OrderPizza"
textReceived: "Intent" # where the value of textReceived is the name CashBank's System.Intent state
...
En supposant que votre compétence de commande de pizza se trouve dans le même assistant numérique que la compétence bancaire, voici ce qui se passe si vous ouvrez l'assistant numérique dans le testeur, accédez à la compétence de commande de pizza, puis cliquez sur Check bank account balance (Vérifier le solde du compte bancaire).

Description de l'illustration skill-skill.png
Dans l'onglet Routing (Acheminement) du testeur, vous pouvez voir que l'appel explicite a été reconnu et qu'il passe en priorité :
Plus bas, vous pouvez voir que l'intention de vérification du solde de la compétence Cash Bank est mise en correspondance :
Variables de portée utilisateur dans les flux de dialogue YAML
Lorsque la conversation prend fin, les valeurs de variable définies à partir de l'entrée utilisateur sont supprimées. Une fois ces valeurs disparues, les utilisateurs doivent se souvenir de leurs opérations chaque fois qu'ils retournent dans votre compétence. Vous pouvez leur épargner cet effort en définissant des variables de portée utilisateur dans le flux de dialogue. Votre compétence peut utiliser ces variables, qui stockent l'entrée utilisateur des sessions précédentes, pour diriger les utilisateurs rapidement dans la conversation.
context
, sont préfixées par user.
L'état checklastorder
dans l'extrait suivant du flux de dialogue PizzaBotWithMemory inclut la variable user.lastsize
qui conserve la taille de la pizza de la session d'utilisateur précédente. La variable user.
conserve l'ID utilisateur. Cet ID est propre à un canal. Vous pouvez donc retourner à une conversation ou parcourir rapidement une commande grâce à vos entrées antérieures sur les compétences exécutées sur le même canal, mais vous ne pouvez pas le faire sur d'autres canaux.
main: true
name: "PizzaBot"
parameters:
age: 18
context:
variables:
size: "PizzaSize"
type: "PizzaType"
crust: "PizzaCrust"
iResult: "nlpresult"
sameAsLast: "YesNo"
states:
intent:
component: "System.Intent"
properties:
variable: "iResult"
transitions:
actions:
OrderPizza: "checklastorder"
CancelPizza: "cancelorder"
unresolvedIntent: "unresolved"
checklastorder:
component: "System.ConditionExists"
properties:
variable: "user.lastsize"
transitions:
actions:
exists: "lastorderprompt"
notexists: "resolvesize"
lastorderprompt:
component: "System.List"
properties:
options: "Yes,No"
prompt: "Same pizza as last time?"
variable: "sameAsLast"
transitions:
next: "rememberchoice"
rememberchoice:
component: "System.ConditionEquals"
properties:
variable: "sameAsLast"
value: "No"
transitions:
actions:
equal: "resolvesize"
notequal: "load"
...
load:
component: "System.CopyVariables"
properties:
from: "user.lastsize,user.lasttype,user.lastcrust"
to: "size,type,crust"
transitions:
...
Composants YAML intégrés pour la définition de valeurs utilisateur
Définissez la propriété value
des composants suivants avec des expressions telles que "${user.age.value}"
pour définir les valeurs utilisateur stockées.
Composant | Utilisations |
---|---|
System.SetVariable | Définit la valeur utilisateur stockée. |
System.ResetVariables | Réinitialise la valeur utilisateur stockée. |
System.CopyVariables | Copie dans la valeur utilisateur stockée. |
System.Output | Affiche la valeur utilisateur stockée sous forme de texte. |
System.ConditionExists | Vérifie si la variable de portée utilisateur est déjà en contexte. |
System.ConditionEquals | Recherche la variable de portée utilisateur. |
System.Switch | Utilise la valeur stockée pour passer d'un état à un autre. |
Numérotation automatique pour les canaux textuels dans les flux de dialogue YAML
Le cadre de numérotation automatique permet au robot de compétence d'être exécuté sur des canaux textuels car il ajoute un préfixe numérique aux boutons et aux options de liste. Lorsque les utilisateurs ne peuvent pas effectuer d'action tactile, ils peuvent déclencher les actions de republication en entrant un nombre. Par exemple, lorsque le service CrcPizzaBot est exécuté dans un canal qui prend en charge les boutons, il affiche Pizzas et Pastas.
Toutefois, lorsqu'il est exécuté sur un canal textuel, il affiche les options Pizza et Pasta sous forme de texte et leur ajoute un préfixe numérique séquentiel (1. Pizza 2. Pasta).
La numérotation automatique n'est pas limitée aux canaux textuels. Il est possible de l'activer pour les canaux on où les boutons sont pris en charge afin d'offrir aux utilisateurs une autre manière d'entrer leurs choix. Par exemple, les utilisateurs peuvent toucher Pizza ou entrer 1.
Définir la numérotation automatique pour les flux de dialogue YAML
Pour les flux de dialogue YAML, vous pouvez définir la fonction de numérotation automatique à l'échelle globale (ce qui signifie qu'elle affecte tous les composants nommés dans votre définition de flux de dialogue) ou au niveau du composant pour les composants qui déclenchent des actions de republication, à savoir les composants System.List
, System.CommonResponse
, System.ResolveEntities
, System.QnA
, System.Webview
, System.OAuthAccountLinkComponent
et System.OAuth2AccountLinkComponent
.
-
Dans le noeud de contexte, ajoutez
autoNumberPostbackActions: "boolean"
. CommetextOnly
etautoTranslate
, il s'agit d'une variable commune qui peut être utilisée dans tous vos robots.context: variables: pizzaSize: "PizzaSize" pizzaType: "PizzaType" pizzaCrust: "PizzaCrust" pizzaCheese: "CheeseType" autoNumberPostbackActions: "boolean" iResult: "nlpresult"
-
Réglez la propriété
autoNumberPostbackActions
àtrue
:type: component: "System.List" properties: prompt: "What Type of Pizza do you want?" options: "${pizzaType.type.enumValues}" variable: "pizzType" autoNumberPostbackActions: "true" footerText: "Enter a number or tap your selection." transitions: ...
Si vous devez modifier l'option de numérotation automatique pour un composant particulier (soit un composant système, soit un composant personnalisé), réglez la propriétéautoNumberPostbackActions
àfalse
. Pour modifier la numérotation automatique pour une action de republication particulière dans System.CommonResponse, ajoutez une propriétéskipAutoNumber
et nommez l'action.Note
La numérotation automatique étant appliquée par un traitement côté serveur, elle ne fonctionne que pour les actions de republication et non pour les actions d'URL côté client. Par conséquent, les composants qui présentent deux actions de bouton, une action d'URL et une action de republication produisent une expérience utilisateur imparfaite en raison de la numérotation incohérente des différents éléments d'interface. Pour les composants OAuth qui affichent à la fois une action d'URL de connexion et une action d'annulation de republication, seule l'action d'annulation est numérotée. Pour conserver la cohérence dans des cas comme celui-ci, réglez la propriétéautoNumberPostbackActions
àfalse
. -
Vous pouvez activer conditionnellement la numérotation automatique en réglant la variable
autoNumberPostbackActions
au canal courant. Par exemple :
Une fois la variablesetAutoNumbering: component: "System.SetVariable" properties: variable: "autoNumberPostbackActions" value: "${(system.channelType=='facebook')?then('true','false')}"
autoNumberPostbackActions
définie, vous pouvez la référencer pour modifier le texteprompt
:
Vous pouvez également définir un texte conditionnel pour le pied de page :prompt: "Hello ${profile.firstName}, this is our menu today<#if autoNumberPostbackActions.value>. Make your choice by entering the menu option number</#if>:"
footerText: <#if autoNumberPostbackActions.value>"Make your choice by entering the menu option number."</#if>
Rendre du contenu pour les canaux textuels dans les flux de dialogue YAML
textOnly
dans les composants ramifiés au flux de dialogue, tels que System.ConditionEquals ou System.Switch. Avant de pouvoir diriger votre flux en fonction de messages textuels, vous devez déclarer textOnly
comme variable de contexte, puis définir sa valeur. Voici les étapes de base :
-
Ajoutez la variable
textOnly: "boolean"
au noeudcontext
.context: variables: autoNumberingPostbackActions: "boolean" textOnly: "boolean"
-
Référencez
textOnly
dans les composants de paramétrage de variable, tels que System.SetVariable et System.Switch. -
Utilisez la propriété
system.message
pour présenter le message utilisateur complet. L'extrait de code suivant indique comment définir une valeur booléenne dans l'expressionsystem.channelType
, qui indique si un canal textuel seulement (Twilio, dans ce cas) est utilisé ou non.setTextOnly: component: "System.SetVariable" properties: variable: "textOnly" value: "${(system.channelType=='twilio')?then('true','false')}"
Vous pouvez activer conditionnellement la numérotation automatique en référençant le canal de message utilisateur. Par exemple :setAutoNumbering: component: "System.SetVariable" properties variable: autoNumeringPostbackActions value: "${(system.channelType=='twilio')?then('true','false')}"