结构化响应模板
适用于:SDK v4
结构化响应模板允许开发人员定义支持语言生成 (LG) 的广泛功能的复杂结构(如模板化、组合),同时将结构化响应的解释留给 LG 库的调用方。
对于机器人应用程序,提供了以下支持:
Bot Framework 活动模板包含多个可自定义字段。 以下属性是最常用的,可通过活动模板定义进行配置:
properties | 用例 |
---|---|
文本 | 显示通道用于直观呈现的文本 |
Speak | 显示通道用于有声呈现的口述文本 |
附件 | 附件的列表及其类型。 由通道用于呈现为 UI 卡或其他泛型文件附件类型。 |
SuggestedActions | 作为建议呈现给用户的操作列表。 |
InputHint | 控制支持口述输入的设备上的音频捕获流状态。 可能的值包括 accepting 、expecting 或 ignoring 。 |
模板解析器没有实现默认的回退行为。 如果未指定属性,则将保持未指定状态。 例如,如果仅指定了 Text
属性,则不会自动将 Speak
属性指定为 Text
属性。
定义
以下是结构化模板的定义:
# 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
]
下面是基本文本模板的示例:
# AskForAge.prompt
[Activity
Text = ${GetAge()}
Speak = ${GetAge()}
]
# GetAge
- how old are you?
- what is your age?
下面是包含建议操作的文本示例。 使用 | 来表示列表。
> With '|' you are making attachments a list.
# AskForAge.prompt
[Activity
Text = ${GetAge()}
SuggestedActions = 10 | 20 | 30
]
下面是一个英雄卡定义的示例:
# 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
]
注意
LG 提供卡片定义中的一些变量,转换为与 SDK 卡片定义保持一致。 例如,虽然 SDK 卡片定义中仅支持 images
,但 LG 的卡片定义都支持 image
和 images
字段。
HeroCard 或缩略图卡片中 image
和 images
字段中定义的值都进行合并并转换为所生成卡片中的图像列表。 对于其他类型的卡片,模板中最后一个定义值将分配给 image
字段。 分配给 image/images
字段的值可以是字符串、自适应表达式或使用 | 的格式的数组。
下面是上述模板的组合:
# 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
]
默认情况下,任何模板引用在计算结构化模板时只计算一次。
例如,# AskForAge.prompt
为 Speak
和 Text
属性返回相同的解析文本。
# AskForAge.prompt
[Activity
Text = ${GetAge()}
Speak = ${GetAge()}
]
# GetAge
- how old are you?
- what is your age?
你可以使用 <TemplateName>!()
来针对结构化模板中的每个引用请求新的计算。
在下面的示例中,Speak
和 Text
可能具有不同的解析文本,因为会在每个实例上重新计算 GetAge
。
[Activity
Text = ${GetAge()}
Speak = ${GetAge!()}
]
# GetAge
- how old are you?
- what is your age?
下面介绍如何显示卡轮播:
# 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
]
使用 作为转义字符\。
> 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
]
结构化模板组合
结构化模板支持以下组合行为:
- 组合可识别结构上下文。 如果所引用的目标模板也是结构化模板,则结构类型必须匹配。 例如,可以在另一个 ActivityTemplate 中引用 ActivityTemplate。
- 对简单或带条件的响应模板的引用可以存在于结构化模板中的任何位置。
假设有以下模板:
# T1
[Activity
Text = ${T2()}
Speak = foo bar ${T3().speak}
]
# T2
- This is awesome
# T3
[Activity
Speak = I can also speak!
]
对 evaluateTemplate('T1')
的调用会产生以下内部结构:
[Activity
Text = This is awesome
Speak = I can also speak!
]
对另一个结构化模板的完整引用
可以将对另一个结构化模板的引用作为另一个结构化模板中的属性,或作为另一个简单或带条件的响应模板中的引用
下面是对另一个结构化模板的完整引用的示例:
# ST1
[MyStruct
Text = foo
${ST2()}
]
# ST2
[MyStruct
Speak = bar
]
使用此内容时,对 evaluateTemplate('ST1')
的调用将产生以下内部结构:
[MyStruct
Text = foo
Speak = bar
]
如果调用模板和被调用模板中同时存在相同属性,则调用方中的内容将覆盖被调用模板中的任何内容。
下面是一个示例:
# ST1
[MyStruct
Text = foo
${ST2()}
]
# ST2
[MyStruct
Speak = bar
Text = zoo
]
使用此上下文时,对 evaluateTemplate('ST1')
的调用将产生以下内部结构:
[MyStruct
Text = foo
Speak = bar
]
请注意,此样式组合只能存在于根级别。 如果在属性中有对另一个结构化模板的引用,则解析与该属性相关。
结构化附件中的外部文件引用
有两个用于外部引用文件的预生成函数
fromFile(fileAbsoluteOrRelativePath)
加载指定文件。 此函数返回的内容将为内容评测提供支持。 评测模板参考、属性和表达式。ActivityAttachment(content, contentType)
设置contentType
(如果尚未在内容中指定)。
利用这两个预生成的函数,可以提取任何外部定义的内容,包括所有卡类型。 使用以下结构化 LG 编写活动:
# AdaptiveCard
[Activity
Attachments = ${ActivityAttachment(json(fromFile('../../card.json')), 'adaptiveCard')}
]
# HeroCard
[Activity
Attachments = ${ActivityAttachment(json(fromFile('../../card.json')), 'heroCard')}
]
还可以使用下面所示的附件:
# AdaptiveCard
[Attachment
contenttype = adaptivecard
content = ${json(fromFile('../../card.json'))}
]
# HeroCard
[Attachment
contenttype = herocard
content = ${json(fromFile('../../card.json'))}
]
其他信息
- C# API 参考
- JavaScript API 参考
- 阅读使用自适应工具进行调试,了解如何分析和调试模板。