Modèle de réponse structurée

S’APPLIQUE À : SDK v4

Les modèles de réponse structurés permettent aux développeurs de définir une structure complexe qui prend en charge les fonctionnalités étendues de génération de langage (LG), telles que la création de modèles et la composition, tout en laissant à l’appelant de la bibliothèque de génération de langage le soin d’interpréter la réponse structurée.

Pour les applications bot, la prise en charge suivante est assurée :

Le modèle d’activité Bot Framework inclut plusieurs champs personnalisables. Les propriétés suivantes sont les plus utilisées et sont configurables via une définition de modèle d’activité :

Propriété Cas d’usage
Texte Afficher le texte utilisé par le canal pour le rendu visuel
Speak Texte parlé utilisé par le canal pour un rendu audible
Documents joints Liste des pièces jointes avec leur type. Utilisées par les canaux pour le rendu sous forme de cartes d’interface utilisateur ou d’autres types de fichiers joints génériques.
SuggestedActions Liste des actions rendues sous forme de suggestions à l’utilisateur.
InputHint Contrôle l’état du flux de capture audio sur les appareils qui prennent en charge la commande vocale. Les valeurs possibles sont accepting, expecting ou ignoring.

Il n’existe aucun comportement de secours par défaut implémenté par le programme de résolution du modèle. Si une propriété n’est pas spécifiée, elle reste non spécifiée. Par exemple, la propriété Speak n’est pas automatiquement affectée à la propriété Text si seule la propriété Text est spécifiée.

Définition

Voici la définition d’un modèle structuré :

# TemplateName
> this is a comment
[Structure-name
    Property1 = <plain text> .or. <plain text with template reference> .or. <expression>
    Property2 = list of values are denoted via '|'. e.g. a | b
> this is a comment about this specific property
    Property3 = Nested structures are achieved through composition
]

Voici un exemple de modèle de texte de base :

# AskForAge.prompt
[Activity
    Text = ${GetAge()}
    Speak = ${GetAge()}
]

# GetAge
- how old are you?
- what is your age?

Voici un exemple de texte avec une action suggérée. Utilisez | pour désigner une liste.

> With '|' you are making attachments a list.
# AskForAge.prompt
[Activity
    Text = ${GetAge()}
    SuggestedActions = 10 | 20 | 30
]

Voici un exemple de définition de carte de bannière :

# HeroCard
[Herocard
    title = Hero Card Example
    subtitle = Microsoft Bot Framework
    text = Build and connect intelligent bots to interact with your users naturally wherever they are, from text/sms to Skype, Slack, Office 365 mail and other popular services.
    images = https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg
    buttons = Option 1| Option 2| Option 3
]

Remarque

LG fournit une certaine variabilité dans la définition des cartes, qui est convertie pour s’aligner sur la définition de carte SDK. Par exemple, les champs image et les champs images sont pris en charge dans toutes les définitions de carte dans LG, même seuls les champs images sont pris en charge dans la définition carte SDK.

Les valeurs définies dans tous les champs image et images d’une carte HeroCard ou miniature sont regroupées et converties en une liste d’images dans la carte générée. Pour les autres types de cartes, la dernière valeur définie dans le modèle est affectée au champ image. Les valeurs que vous affectez au champ image/images peuvent être une chaîne, une expression adaptative ou un tableau au format utilisant |.

Vous trouverez ci-dessous la combinaison des modèles précédents :

# AskForAge.prompt
[Activity
    Text = ${GetAge()}
    Speak = ${GetAge()}
    Attachments = ${HeroCard()}
    SuggestedActions = 10 | 20 | 30
    InputHint = expecting
]

# GetAge
- how old are you?
- what is your age?

# HeroCard
[Herocard
    title = Hero Card Example
    subtitle = Microsoft Bot Framework
    text = Build and connect intelligent bots to interact with your users naturally wherever they are, from text/sms to Skype, Slack, Office 365 mail and other popular services.
    images = https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg
    buttons = Option 1| Option 2| Option 3
]

Par défaut, toute référence de modèle est évaluée une fois, dans le cadre de l’évaluation d’un modèle structuré.

Par exemple, # AskForAge.prompt retourne le même texte de résolution pour les deux propriétés Speak et Text.

# AskForAge.prompt
[Activity
    Text = ${GetAge()}
    Speak = ${GetAge()}
]

# GetAge
- how old are you?
- what is your age?

Vous pouvez utiliser <TemplateName>!() pour demander une nouvelle évaluation sur chaque référence au sein d’un modèle structuré.

Dans l’exemple ci-dessous, Speak et Text peuvent avoir un texte de résolution différent, car GetAge est réévalué sur chaque instance.

[Activity
    Text = ${GetAge()}
    Speak = ${GetAge!()}
]

# GetAge
- how old are you?
- what is your age?

Voici comment afficher un carrousel de cartes :

# AskForAge.prompt
[Activity
> Defaults to carousel layout in case of list of cards
    Attachments = ${foreach($cardValues, item, HeroCard(item)}
]

# AskForAge.prompt_2
[Activity
> Explicitly specify an attachment layout
    Attachments = ${foreach($cardValues, item, HeroCard(item)}
    AttachmentLayout = list
]

# HeroCard (title, subtitle, text)
[Herocard
    title = ${title}
    subtitle = ${subtitle}
    text = ${text}
    images = https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg
    buttons = Option 1| Option 2| Option 3
]

Utilisez \ comme caractère d'échappement.

> You can use '\' as an escape character
> \${GetAge()} would not be evaluated as expression, would be parsed as '${getAge()}' string
# AskForAge.prompt
[Activity
        Text = \${GetAge()}
        SuggestedActions = 10 \| cards | 20 \| cards
]

Composition de modèle structuré

Le comportement de composition suivant est pris en charge avec les modèles structurés :

  • La composition est basée sur le contexte de la structure. Si le modèle cible référencé est également un modèle structuré, le type de structure doit correspondre. Par exemple, il est possible de faire référence à un ActivityTemplate dans un autre ActivityTemplate.
  • Les références à un modèle de réponse simple ou conditionnel peuvent se trouver n’importe où dans un modèle structuré.

Supposez que vous disposiez du modèle suivant :

# T1
[Activity
    Text = ${T2()}
    Speak = foo bar ${T3().speak}
]

# T2
- This is awesome

# T3
[Activity
    Speak = I can also speak!
]

Un appel à evaluateTemplate('T1') aboutirait à la structure interne suivante :

[Activity
    Text = This is awesome
    Speak = I can also speak!
]

Référence complète à un autre modèle structuré

Vous pouvez inclure une référence à un autre modèle structuré en tant que propriété dans un autre modèle structuré, ou en tant que référence dans un autre modèle de réponse simple ou conditionnel

Voici un exemple de référence complète à un autre modèle structuré :

# ST1
[MyStruct
    Text = foo
    ${ST2()}
]
# ST2
[MyStruct
    Speak = bar
]

Avec ce contenu, un appel à evaluateTemplate('ST1') aboutit à la structure interne suivante :

[MyStruct
    Text = foo
    Speak = bar
]

Quand la même propriété existe à la fois dans le modèle appelant et dans le modèle appelé, le contenu de l’appelant remplace tout contenu du modèle appelé.

Voici un exemple :

# ST1
[MyStruct
    Text = foo
    ${ST2()}
]
# ST2
[MyStruct
    Speak = bar
    Text = zoo
]

Avec ce contexte, un appel à evaluateTemplate('ST1') aboutit à la structure interne suivante :

[MyStruct
    Text = foo
    Speak = bar
]

Notez que ce style de composition ne peut exister qu’au niveau de la racine. S’il existe une référence à un autre modèle structuré dans une propriété, la résolution dépend du contexte de cette propriété.

Référence de fichier externe dans une pièce jointe structurée

Deux fonctions prédéfinies sont utilisées pour référencer des fichiers en externe

  1. fromFile(fileAbsoluteOrRelativePath) charge un fichier spécifié. Le contenu retourné par cette fonction prend en charge l’évaluation du contenu. Les références de modèle, les propriétés et les expressions sont évaluées.
  2. ActivityAttachment(content, contentType) définit le contentType s’il n’est pas déjà spécifié dans le contenu.

Ces deux fonctions prédéfinies vous permettent d’extraire tout contenu défini en externe, notamment tous les types de cartes. Utilisez la génération de langage structurée suivante pour composer une activité :

# AdaptiveCard
[Activity
                Attachments = ${ActivityAttachment(json(fromFile('../../card.json')), 'adaptiveCard')}
]

# HeroCard
[Activity
                Attachments = ${ActivityAttachment(json(fromFile('../../card.json')), 'heroCard')}
]

Vous pouvez également utiliser des pièces jointes, comme indiqué ci-dessous :

# AdaptiveCard
[Attachment
    contenttype = adaptivecard
    content = ${json(fromFile('../../card.json'))}
]

# HeroCard
[Attachment
    contenttype = herocard
    content = ${json(fromFile('../../card.json'))}
]

Informations supplémentaires