Come si scrivono i flussi di finestre di dialogo in OBotML?
OBotML utilizza una sintassi semplice per impostare le variabili e definire gli stati. Poiché si tratta di una variante di YAML, tenere presenti le convenzioni di spaziatura YAML quando si definisce il flusso della finestra di dialogo. Non è necessario iniziare da zero. È invece possibile utilizzare la definizione del flusso della finestra di dialogo predefinita come modello di base.
context
e states
, pertanto è sufficiente eliminare il testo standard esistente e aggiungere il proprio contenuto. Per creare definizioni di stato sintatticamente valide, utilizzare i modelli di componente nel menu + Componente. Per suggerimenti sull'impostazione delle variabili e sulla definizione degli stati, vedere Sintassi del flusso di dialogo.
Suggerimento
Fare clic su Convalida durante la scrittura del flusso della finestra di dialogo per cercare gli errori di sintassi e applicare le procedure ottimali.Sintassi flusso finestra di dialogo
Come | Usare questo |
---|---|
Impostare le variabili che rendono persistente il contesto nell'intero flusso della finestra di dialogo? |
Nel nodo
context , utilizzare la sintassi seguente: variablename: "variableType" Ad esempio:
È possibile definire le variabili come entità (ad esempio |
Definire un handler di errori per lo skill? |
Definire il nodo
defaultTransitions che punta a uno stato che gestisce gli errori. In genere si aggiunge questo stato alla fine della definizione del flusso della finestra di dialogo. Ad esempio:
Vedere Configurare il flusso di finestre di dialogo per le azioni impreviste. |
Definire una variabile che contenga il valore per l'intento risolto? |
Nel nodo
context definire una variabile che denomini l'entità nlpresult . Come suggerisce il nome ("nlp" sta per Natural Language Processing), questa entità estrae l'intento risolto dal motore degli intenti. Quasi tutti i bot di riferimento dichiarano variabili nlpresult . Ad esempio:
|
Controllare il flusso della finestra di dialogo in base all'input dell'utente? |
In genere, anche se non sempre, si definisce una proprietà Come descritto in La struttura del flusso della finestra di dialogo in modalità YAML, è possibile dichiarare una variabile |
Dotare la mia abilità di gestire gli intenti non risolti? |
Definire uno stato per l'azione Ad esempio:
|
Abilitare i componenti per accedere ai valori delle variabili? |
Utilizzare la proprietà
.value nelle espressioni (${crust.value} ). Per sostituire un valore predefinito, utilizzare ${variable.value!\"default value\"} . Ad esempio, thick è il valore predefinito in ${crust.value!\"thick\"} . Ad esempio:
Utilizzare l'operatore predefinito FreeMarker di Apache ( |
Salvare i valori utente per le visite di ritorno? |
All'interno di una definizione di stato, aggiungere una definizione di variabile con un prefisso
user. . Vedere Componenti YAML incorporati per l'impostazione dei valori utente. Ad esempio:
Per ulteriori informazioni sulle variabili utente, vedere il flusso della finestra di dialogo per il bot di riferimento PizzaBotWithMemory. |
Uscire da un flusso di finestre di dialogo e terminare la sessione utente. |
Utilizzare una transizione Ad esempio:
|
Navigazione e transizioni del flusso
È possibile impostare il motore della finestra di dialogo su un percorso specifico all'interno del flusso della finestra di dialogo impostando la proprietà Transitions per uno stato. Le transizioni descrivono la modalità di fork della finestra di dialogo quando i valori delle variabili sono impostati o non impostati. Permettono di tracciare il percorso tipico attraverso la conversazione (il flusso "felice") e impostare percorsi alternativi che soddisfano i valori mancanti o il comportamento imprevedibile dell'utente.
Questa operazione... | ... Usa questa transizione |
---|---|
Specificare lo stato successivo da eseguire. | Impostare una transizione next (next: "statename" ) per indicare al motore della finestra di dialogo di passare allo stato indicato dal tasto next . Come indicato nella transizione successiva, è possibile aggiungere una transtione next a qualsiasi stato ad eccezione di quelli con una transizione return .
|
Reimposta la conversazione. | Utilizzare una transizione return per cancellare i valori impostati per le variabili di contesto e reimpostare il flusso della finestra di dialogo. È possibile assegnare a questa transizione qualsiasi valore di stringa. La definizione di una transizione return: "done" termina la sessione utente e posiziona il motore di dialogo all'inizio del flusso.
|
Attiva azioni condizionali. | Definire i tasti actions per attivare la navigazione per uno stato specifico. Quando un componente completa la sua elaborazione, restituisce una stringa di azione che indica al motore della finestra di dialogo dove procedere. Se non si definiscono chiavi di azione, il motore di dialogo si basa sulla transizione predefinita o su una transizione next (se esistente). È possibile definire tutte le azioni necessarie. Alcuni componenti integrati prevedono azioni specifiche. Ad esempio, un componente come System.MatchEntity che valuta un'espressione FreeMarker di Apache utilizza le azioni match e nomatch . System.OAuthAccountLink dispone di azioni textReceived , pass e fail e i componenti dell'interfaccia utente utilizzano azioni proprie (descritte in Transitions for Common Response Components). Utilizzare i modelli di componente come guida. È possibile definire una transizione actions su qualsiasi stato ad eccezione di quelli con una transizione return .
|
Gestire gli errori. | I componenti a volte generano errori. Ciò si verifica spesso a causa di un problema o di un errore correlato al sistema (password non valide, nomi host non validi o errori di comunicazione). L'impostazione di una transizione error con il nome di uno stato di gestione degli errori consente di gestire in modo corretto i problemi: Se non si imposta una transizione error , la competenza restituirà il prompt di errore imprevisto (Oops! Sto riscontrando un problema) e termina la sessione. È possibile definire una transizione error all'interno di qualsiasi stato, ad eccezione di quelli con una transizione return .
Alcuni componenti hanno un errore definito come azione. Queste transizioni di errore integrate gestiscono gli errori specifici del componente:
|
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"
Sebbene sia possibile definire più transizioni, la transizione
return
rappresenta un'eccezione: non è possibile combinare una transizione return
con le transizioni error
, next
o actions
.
transizione successiva
La transizione next
viene utilizzata per specificare lo stato successivo predefinito. Quando uno stato combina le transizioni error
, actions
e next
, la transizione next
viene attivata solo quando il componente non può restituire una stringa che soddisfa una delle transizioni error
o actions
.
next
ogni volta che non è possibile eseguire errori o azioni, definire un'azione next
all'interno del nodo 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"
Configurare il flusso di finestre di dialogo per le azioni impreviste
Scenario | Soluzione |
---|---|
Invece di toccare i pulsanti, l'utente risponde in modo inappropriato immettendo del testo. | Per consentire al bot di gestire questa operazione in modo normale, eseguire l'instradamento a uno stato in cui il componente System.Intent può risolvere l'input di testo, ad esempio textReceived: Intent nello snippet seguente da CrcPizzaBot:
|
Gli utenti scorrono fino a un messaggio precedente e toccano le relative opzioni, anche se dovrebbero toccare i pulsanti nella risposta corrente. |
Per impostazione predefinita, Digital Assistant gestisce i messaggi non ordinati, ma è possibile eseguire l'override o la personalizzazione di questo funzionamento, come descritto nella sezione Modalità di rilevamento delle azioni non in ordine.
Ad esempio, l'aggiunta di una transizione
system.outofOrderMessage predefinita indica al motore di dialogo di passare a un singolo stato che gestisce tutti i messaggi non in ordine, ad esempio lo stato HandleUnexpectedAction nello snippet OBotML sopra riportato. È possibile utilizzare approcci diversi per creare questo stato:
|
Richiama una competenza da un'altra competenza da un flusso di dialogo YAML
Ci possono essere momenti in cui si desidera fornire agli utenti un'opzione esplicita per lasciare temporaneamente l'abilità con cui sono impegnati per fare qualcosa in una seconda abilità all'interno dello stesso assistente digitale. Ad esempio, se si trovano in un'abilità di acquisto e hanno effettuato alcune selezioni, è possibile visualizzare un pulsante che consente loro di passare a un'abilità bancaria (per assicurarsi di avere abbastanza denaro per l'acquisto) e quindi tornare alla capacità di acquisto per completare il loro ordine.
Per risolvere questo problema in un flusso di dialogo YAML, è possibile configurare un'azione in uno skill per avviare l'interazione con uno skill diverso nello stesso assistente digitale e quindi tornare al flusso originale.
Funzionamento:
-
Il componente
System.CommonResponse
consente di presentare all'utente un pulsante per eseguire operazioni in un'altra skill.Il pulsante si basa su un'azione di postback, in cui si configura il payload per fornire un'espressione diretta verso lo skill di destinazione. Idealmente, quell'espressione dovrebbe contenere il nome di invocazione dell'abilità di destinazione (cioè essere un'invocazione esplicita) al fine di massimizzare la probabilità che si verifichi l'instradamento a tale abilità. In questo modo, è essenzialmente difficile codificare un enunciato per innescare l'intento desiderato.
Ecco il formato di quel codice:
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" ...
Utilizzando un'azione
system.textReceived
e specificando il testo nella variabilesystem.text
, si garantisce che il postback venga considerato come un messaggio utente che può essere instradato correttamente dall'assistente digitale.Nota
Quando si utilizzasystem.textReceived
in questo modo,system.text
è l'unica variabile che è possibile definire nel payload di postback. Tutte le altre variabili nel payload vengono ignorate. - La transizione
textReceived
viene impostata sullo stato che contiene il componenteSystem.Intent
.transitions: actions: .... textReceived: "Name of the state for the System.Intent component"
Ciò è necessario per garantire che l'assistente digitale fornisca una risposta di fallback appropriata se l'assistente digitale non contiene la competenza di destinazione.
A tale scopo, è necessario che la proprietà
daIntercept
del componenteSystem.Intent
dello skill sia impostata su"always"
(impostazione predefinita).
Se lo skill di destinazione si trova nell'assistente digitale, l'assistente digitale riconosce il richiamo esplicito, assume il controllo della richiesta (che normalmente verrebbe gestita dal componente) e instrada la richiesta al componente System.Intent
dello skill di destinazione. Al termine del flusso nello skill di destinazione, l'utente viene riportato allo skill chiamante.
Se lo skill di destinazione non si trova nell'assistente digitale (o lo skill chiamante viene esposto senza un assistente digitale), viene richiamato il componente System.Intent
dello skill chiamante e l'intento deve essere risolto in unresolvedIntent
.
Suggerimento
Per gestire il caso in cui il nome del richiamo dello skill di destinazione viene modificato quando viene aggiunto a un assistente digitale, è possibile utilizzare un parametro personalizzato per passare il nome del richiamo dello skill nella variabile system.text
.
Ad esempio, è possibile creare un parametro denominato da.CrcPizzaCashBankInvocationName
nell'abilità pizza e assegnargli il valore predefinito CashBank
. Potresti quindi fare riferimento al parametro in questo modo:
system.text: "ask ${system.config.daCrcPizzaFinSkillInvocationName}, what is my balance"
Se il nome del richiamo dello skill viene modificato, è sufficiente modificare il valore del parametro personalizzato in modo che corrisponda al nuovo nome del richiamo.
Vedere Parametri personalizzati.
Quando si utilizza un richiamo esplicito nella variabile
system.text
, è possibile che l'utente visualizzi il messaggio con il pulsante due volte:
- Quando viene visualizzato il pulsante per passare all'altra abilità.
- Quando completano il flusso nell'altra abilità.
system.text
anziché un richiamo esplicito. Un'invocazione implicita è un'espressione che corrisponde bene a una determinata abilità senza utilizzare il nome dell'invocazione dell'abilità (o una variante del nome dell'invocazione con spaziatura o maiuscole diverse).
Esempio: chiamare una competenza da un'altra competenza
Ad esempio, ecco un intento per ordinare la pizza (OrderPizza
) che offre all'utente la possibilità di controllare il saldo del proprio conto bancario prima di completare l'ordine. Il saldo del conto è fornito da una competenza diversa (CashBank
). Se l'utente seleziona l'opzione Check Balance
, il testo "chiedi a CashBank, qual è il mio saldo" viene inviato all'assistente digitale e l'utente viene indirizzato all'intento appropriato all'interno della competenza 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
...
Supponendo che l'abilità pizza si trovi nello stesso assistente digitale dell'abilità Cash Bank, ecco come dovrebbe apparire se si apre l'assistente digitale nel tester, si accede all'abilità pizza e quindi si fa clic su Verifica il saldo del conto bancario.

Descrizione dell'immagine skill-to-skill.png
Nella scheda Instradamento del tester è possibile vedere che il richiamo esplicito è stato riconosciuto e viene data la preferenza:
Più in basso, è possibile vedere che l'intento Saldo assegno dello skill Cash Bank è abbinato:
Flussi di dialogo Variabili con ambito utente in YAML
Al termine della conversazione, i valori delle variabili impostati dall'input utente vengono eliminati. Con questi valori andati, gli utenti delle tue abilità devono ricorrere a ripercorrere i loro passi ogni volta che tornano alla tua abilità. È possibile risparmiare agli utenti questo sforzo definendo le variabili di ambito utente nel flusso della finestra di dialogo. La tua abilità può utilizzare queste variabili, che memorizzano l'input dell'utente dalle sessioni precedenti, per guidare rapidamente gli utenti attraverso la conversazione.
context
, sono precedute dal prefisso user.
Lo stato checklastorder
nel seguente estratto del flusso della finestra di dialogo PizzaBotWithMemory include la variabile user.lastsize
che conserva la dimensione della pizza dalla sessione utente precedente. La variabile user.
persiste nell'ID utente. Tale ID è specifico del canale, pertanto, mentre è possibile tornare a una conversazione o saltare un ordine utilizzando le voci precedenti sulle competenze eseguite sullo stesso canale, non è possibile eseguire questa operazione su canali diversi.
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:
...
Componenti YAML integrati per l'impostazione dei valori utente
Definire la proprietà value
dei seguenti componenti con espressioni quali “${user.age.value}”
per impostare i valori utente memorizzati.
Componente | Usi |
---|---|
System.SetVariable | Imposta il valore utente memorizzato. |
System.ResetVariables | Reimposta un valore utente memorizzato. |
System.CopyVariables | Copia nel valore utente memorizzato. |
System.Output | Restituisce il valore utente memorizzato come testo. |
System.ConditionExists | Verifica se la variabile con ambito utente è già nel contesto. |
System.ConditionEquals | Verifica la variabile definita dall'utente. |
System.Switch | Utilizza il valore memorizzato per passare da uno stato all'altro. |
Numerazione automatica per i canali di solo testo nei flussi di finestre di dialogo YAML
La struttura di numerazione automatica consente al bot skill di essere eseguito su canali di solo testo poiché antepone i numeri ai pulsanti e alle opzioni elenco. Quando gli utenti non possono utilizzare i gesti dei tocchi, possono comunque attivare le azioni di postback del pulsante immettendo un numero. Ad esempio, quando CrcPizzaBot viene eseguito in un canale che supporta i pulsanti, vengono visualizzati Pizze e Paste.
Ma quando viene eseguito su un canale di solo testo, visualizza le opzioni Pizza e Pasta come testo e le precede con numeri sequenziali (1). Pizza 2. Pasta).
La numerazione automatica non è limitata ai canali di solo testo; l'abilitazione dei pulsanti in cui sono supportati consente agli utenti di immettere le proprie scelte in un altro modo. Per esempio, gli utenti possono toccare Pizza o immettere 1.
Imposta numerazione automatica per flussi finestra di dialogo YAML
Per i flussi di dialogo YAML, è possibile impostare la funzione di numerazione automatica su una scala globale (ovvero che influisce su tutti i componenti denominati nella definizione del flusso della finestra di dialogo) o a livello di componente per i componenti che attivano le azioni di postback, ovvero i componenti System.List
, System.CommonResponse
, System.ResolveEntities
, System.QnA
, System.Webview
, System.OAuthAccountLinkComponent
e System.OAuth2AccountLinkComponent
.
-
Nel nodo di contesto aggiungere
autoNumberPostbackActions: "boolean"
. Questa, cometextOnly
eautoTranslate
, è una variabile comune che può essere utilizzata in tutti i bot.context: variables: pizzaSize: "PizzaSize" pizzaType: "PizzaType" pizzaCrust: "PizzaCrust" pizzaCheese: "CheeseType" autoNumberPostbackActions: "boolean" iResult: "nlpresult"
-
Impostare la proprietà
autoNumberPostbackActions
sutrue
: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: ...
Se è necessario eseguire l'override della numerazione automatica per un determinato componente (un componente di sistema o un componente personalizzato), impostare la proprietàautoNumberPostbackActions
sufalse
. Per eseguire l'override della numerazione automatica per un'azione di postback specifica in System.CommonResponse, aggiungere una proprietàskipAutoNumber
e assegnare un nome all'azione.Nota
Poiché la numerazione automatica viene applicata tramite l'elaborazione lato server, funziona solo sulle azioni di postback e non sulle azioni URL lato client. Di conseguenza, i componenti che visualizzano due azioni pulsante, un'azione URL e un'azione di postback determinano un'esperienza utente non ottimale a causa della numerazione incoerente dei vari elementi dell'interfaccia utente. Per i componenti OAuth che visualizzano sia un'azione URL di login che un'azione Annulla postback, solo l'azione Annulla viene preceduta da un numero. Per mantenere la coerenza in casi come questo, impostare la proprietàautoNumberPostbackActions
sufalse
. -
È possibile abilitare la numerazione automatica in modo condizionale impostando la variabile
autoNumberPostbackActions
con il canale corrente. Ad esempio:
Dopo aver impostato la variabilesetAutoNumbering: component: "System.SetVariable" properties: variable: "autoNumberPostbackActions" value: "${(system.channelType=='facebook')?then('true','false')}"
autoNumberPostbackActions
, è possibile fare riferimento alla variabile per modificare il testoprompt
:
Allo stesso modo, è possibile condizionare il testo del piè di pagina: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>
Esegui rendering del contenuto per i canali di solo testo nei flussi della finestra di dialogo YAML
textOnly
nei componenti di diramazione del flusso della finestra di dialogo, ad esempio System.ConditionEquals o System.Switch. Prima di poter suddividere il flusso in base a messaggi di solo testo, è necessario dichiarare textOnly
come variabile di contesto e quindi impostarne il valore. Di seguito sono riportati i passi di base.
-
Aggiungere la variabile
textOnly: "boolean"
al nodocontext
.context: variables: autoNumberingPostbackActions: "boolean" textOnly: "boolean"
-
Fare riferimento a
textOnly
nei componenti di impostazione delle variabili, ad esempio System.SetVariable e System.Switch. -
Utilizzare la proprietà
system.message
per esporre il messaggio utente completo. Il seguente snipppet mostra come impostare un valore booleano all'interno dell'espressionesystem.channelType
che indica se un canale di solo testo (in questo caso Twilio) è in uso o meno.setTextOnly: component: "System.SetVariable" properties: variable: "textOnly" value: "${(system.channelType=='twilio')?then('true','false')}"
È possibile abilitare la numerazione automatica in modo condizionale facendo riferimento al canale dei messaggi utente. Ad esempio:setAutoNumbering: component: "System.SetVariable" properties variable: autoNumeringPostbackActions value: "${(system.channelType=='twilio')?then('true','false')}"