Modelo de resposta estruturada
APLICA-SE A: SDK v4
Os modelos de resposta estruturada permitem que os desenvolvedores definam uma estrutura complexa que dá suporte à ampla funcionalidade de LG (geração de linguagem), como criação de modelos, composição, deixando a interpretação da resposta estruturada para o chamador da biblioteca LG.
Para aplicativos de bot, o seguinte suporte é fornecido:
O modelo de atividade do Bot Framework inclui vários campos personalizáveis. As propriedades mostradas abaixo são as mais usadas e podem ser configuradas por meio de uma definição de modelo de atividade:
Propriedade | Caso de uso |
---|---|
Texto | Exibir o texto usado pelo canal a ser renderizado visualmente |
Speak | Texto falado usado pelo canal a ser renderizado de maneira audível |
Anexos | Lista de anexos com o respectivo tipo. Usado por canais para serem renderizados como cartões de interface do usuário ou outros tipos de anexo de arquivo genéricos. |
SuggestedActions | Lista de ações renderizadas como sugestões para o usuário. |
InputHint | Controla o estado do fluxo de captura de áudio em dispositivos que dão suporte à entrada falada. Os valores possíveis incluem accepting , expecting ou ignoring . |
Não há nenhum comportamento de fallback padrão implementado pelo resolvedor de modelo. Se uma propriedade não for especificada, ela permanecerá não especificada. Por exemplo, a propriedade Speak
não é atribuída automaticamente para ser a propriedade Text
se apenas a propriedade Text
é especificada.
Definição
Esta é a definição de um modelo estruturado:
# 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
]
Veja um exemplo de um modelo de texto básico:
# AskForAge.prompt
[Activity
Text = ${GetAge()}
Speak = ${GetAge()}
]
# GetAge
- how old are you?
- what is your age?
Este é um exemplo de texto com uma ação sugerida. Use | para indicar uma lista.
> With '|' you are making attachments a list.
# AskForAge.prompt
[Activity
Text = ${GetAge()}
SuggestedActions = 10 | 20 | 30
]
Este é um exemplo de uma definição de cartão Hero:
# 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
]
Observação
A LG fornece alguma variabilidade na definição do cartão, que é convertida para se alinhar com a definição do cartão do SDK. Por exemplo, ambos os campos de image
e images
têm suporte em todas as definições de cartão na LG, embora só images
tenha suporte na definição de cartão do SDK.
Os valores definidos em todos os campos de image
e images
e em um cartão HeroCard ou miniatura são combinados e convertidos em uma lista de imagens no cartão gerado. Para os outros tipos de cartões, o último valor definido no modelo será atribuído ao campo de image
. Os valores atribuídos ao campo de image/images
podem ser uma sequência, uma expressão adaptável ou uma matriz no formato que usa |.
Veja abaixo a combinação dos modelos anteriores:
# 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
]
Por padrão, qualquer referência de modelo é avaliada uma vez durante a avaliação de um modelo estruturado.
Por exemplo, # AskForAge.prompt
retorna o mesmo texto de resolução para as propriedades Speak
e Text
.
# AskForAge.prompt
[Activity
Text = ${GetAge()}
Speak = ${GetAge()}
]
# GetAge
- how old are you?
- what is your age?
Use <TemplateName>!()
para solicitar uma nova avaliação em cada referência dentro de um modelo estruturado.
No exemplo abaixo, Speak
e Text
podem ter um texto de resolução diferente, porque GetAge
é reavaliado em cada instância.
[Activity
Text = ${GetAge()}
Speak = ${GetAge!()}
]
# GetAge
- how old are you?
- what is your age?
Veja como exibir um carrossel de cartões:
# 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
]
Use \ como um caractere de escape.
> 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
]
Composição de modelo estruturado
Há suporte para o seguinte comportamento de composição nos modelos estruturados:
- A composição tem reconhecimento de contexto da estrutura. Se o modelo de destino referenciado também for um modelo estruturado, o tipo de estrutura deverá ser correspondente. Por exemplo, um ActivityTemplate pode ser referenciado em outro ActivityTemplate.
- As referências a um modelo de resposta simples ou condicional podem existir em qualquer lugar dentro de um modelo estruturado.
Suponha que você tenha o seguinte modelo:
# T1
[Activity
Text = ${T2()}
Speak = foo bar ${T3().speak}
]
# T2
- This is awesome
# T3
[Activity
Speak = I can also speak!
]
Uma chamada a evaluateTemplate('T1')
resultará na seguinte estrutura interna:
[Activity
Text = This is awesome
Speak = I can also speak!
]
Referência completa a outro modelo estruturado
Você pode incluir uma referência a outro modelo estruturado como uma propriedade em outro modelo estruturado ou como uma referência em outro modelo de resposta simples ou condicional
Este é um exemplo de referência completa a outro modelo estruturado:
# ST1
[MyStruct
Text = foo
${ST2()}
]
# ST2
[MyStruct
Speak = bar
]
Com esse conteúdo, uma chamada a evaluateTemplate('ST1')
resultará na seguinte estrutura interna:
[MyStruct
Text = foo
Speak = bar
]
Quando a mesma propriedade existir no modelo de chamada, bem como no modelo chamado, o conteúdo no chamador substituirá qualquer conteúdo no modelo chamado.
Aqui está um exemplo:
# ST1
[MyStruct
Text = foo
${ST2()}
]
# ST2
[MyStruct
Speak = bar
Text = zoo
]
Com esse contexto, uma chamada a evaluateTemplate('ST1')
resultará na seguinte estrutura interna:
[MyStruct
Text = foo
Speak = bar
]
Observe que esse estilo de composição só pode existir no nível raiz. Se houver uma referência a outro modelo estruturado dentro de uma propriedade, a resolução será contextual para essa propriedade.
Referência de arquivo externo no anexo estruturado
Há duas funções predefinidas usadas para referenciar arquivos externamente
fromFile(fileAbsoluteOrRelativePath)
carrega um arquivo especificado. O conteúdo retornado por esta função dará suporte à avaliação do conteúdo. Referências de modelo, propriedades e expressões são avaliadas.ActivityAttachment(content, contentType)
define ocontentType
se ele ainda não estiver especificado no conteúdo.
Com essas duas funções predefinidas, você pode extrair qualquer conteúdo definido externamente, incluindo todos os tipos de cartões. Use a seguinte LG estruturada para compor uma atividade:
# AdaptiveCard
[Activity
Attachments = ${ActivityAttachment(json(fromFile('../../card.json')), 'adaptiveCard')}
]
# HeroCard
[Activity
Attachments = ${ActivityAttachment(json(fromFile('../../card.json')), 'heroCard')}
]
Use também anexos, vistos abaixo:
# AdaptiveCard
[Attachment
contenttype = adaptivecard
content = ${json(fromFile('../../card.json'))}
]
# HeroCard
[Attachment
contenttype = herocard
content = ${json(fromFile('../../card.json'))}
]
Informações adicionais
- Referência de API C#
- Referência de API JavaScript
- Leia Depurar com Ferramentas Adaptáveis para saber como analisar e depurar modelos.