结构化响应模板

适用于:SDK v4

结构化响应模板允许开发人员定义支持语言生成 (LG) 的广泛功能的复杂结构(如模板化、组合),同时将结构化响应的解释留给 LG 库的调用方。

对于机器人应用程序,提供了以下支持:

Bot Framework 活动模板包含多个可自定义字段。 以下属性是最常用的,可通过活动模板定义进行配置:

properties 用例
文本 显示通道用于直观呈现的文本
Speak 显示通道用于有声呈现的口述文本
附件 附件的列表及其类型。 由通道用于呈现为 UI 卡或其他泛型文件附件类型。
SuggestedActions 作为建议呈现给用户的操作列表。
InputHint 控制支持口述输入的设备上的音频捕获流状态。 可能的值包括 acceptingexpectingignoring

模板解析器没有实现默认的回退行为。 如果未指定属性,则将保持未指定状态。 例如,如果仅指定了 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 的卡片定义都支持 imageimages 字段。

HeroCard 或缩略图卡片中 imageimages 字段中定义的值都进行合并并转换为所生成卡片中的图像列表。 对于其他类型的卡片,模板中最后一个定义值将分配给 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.promptSpeakText 属性返回相同的解析文本。

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

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

你可以使用 <TemplateName>!() 来针对结构化模板中的每个引用请求新的计算。

在下面的示例中,SpeakText 可能具有不同的解析文本,因为会在每个实例上重新计算 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
]

请注意,此样式组合只能存在于根级别。 如果在属性中有对另一个结构化模板的引用,则解析与该属性相关。

结构化附件中的外部文件引用

有两个用于外部引用文件的预生成函数

  1. fromFile(fileAbsoluteOrRelativePath) 加载指定文件。 此函数返回的内容将为内容评测提供支持。 评测模板参考、属性和表达式。
  2. 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'))}
]

其他信息