Generators in adaptive dialogs

APPLIES TO: SDK v4

Generators tie a specific language generation (LG) system to an adaptive dialog. In this article you'll learn about the LG templates that add variety and personality to bot responses, and how to call those templates in your root dialog using the TemplateEngineLanguageGenerator.

Prerequisites

Language generation

Language Generation (LG) allows developers to extract embedded strings from their code and resource files and manage them through an LG runtime and file format. With LG, developers can create a more natural conversational experience by defining multiple variations on a phrase, executing simple expressions based on context, and referring to conversational memory.

LG, along with recognizers, enables clean separation and encapsulation of a dialog's Language Understanding and language generation assets. Recognizers give your bot the ability to understand input and LG lets your bot respond to that input in an intelligent way.

LG templates

Templates are the core concept of the language generation system. Variations in templates are used by your bot to respond to user input. Each template has a name and one of the following:

  • a list of one-of variation text values
  • a structured content definition
  • a collection of conditions, each with:

Templates are defined in .lg files, which can contain one or more templates. There are three types of templates:

Simple response template

A simple response template includes one or more variations of text that are used for composition and expansion. When this template is evaluated, the LG runtime will randomly pick one of these variations.

Here's an example of a simple response template with two variations:

> Greeting template with 2 variations.
# GreetingPrefix
- Hi
- Hello

Conditional response template

Conditional response templates let you author content that's selected based on a condition. All conditions are expressed using adaptive expressions, both prebuilt and custom.

There are two types of conditional response templates: if-else and switch.

If-else template

The if-else template lets you build a template that picks a collection based on a cascading order of conditions. Like simple response templates, can have inline variations in IF or ELSE blocks. Nesting is achieved through composition.

Here's an example of an if-else conditional response template:

> time of day greeting reply template with conditions.
# timeOfDayGreeting
- IF: ${timeOfDay == 'morning'}
    - Good morning!
    - Wake up.
- ELSE:
    - Good evening
    - Sleep well!
    - Goodnight.

Switch template

The switch template lets you design a template that matches an expression's value to a CASE clause and produces output based on that case.

Here's an example of a switch conditional response template:

# TestTemplate
- SWITCH: ${condition}
- CASE: ${case-expression-1}
    - output1
- CASE: ${case-expression-2}
    - output2
- DEFAULT:
   - final output

Structured response template

Structured response templates let you define a complex structure that supports major LG functionality, like templating, composition, and substitution, while leaving the interpretation of the structured response up to the caller of the LG library. Activity and card definitions are currently supported for bot applications.

Here's the definition of a structured response template:

# 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
]

Read structured response template for more information and examples of complex templates.

Call templates in your root dialog

After creating templates for your bot you can add them to your adaptive dialog. You can set the generator to an .lg file or set the generator to a TemplateEngineLanguageGenerator instance where you explicitly manage the one or more .lg files. The example below shows the latter approach.

Say you want to add templates from RootDialog.lg to an adaptive dialog. Add the following packages to your code:

using Microsoft.Bot.Builder.LanguageGeneration;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Templates;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Generators;

Then you need to resolve the path of the .lg file:

string[] paths = { ".", "Dialogs", "RootDialog.lg" };
string fullPath = Path.Combine(paths);

This will ensure that you're calling the correct template files for you bot.

Now you can create the TemplateEngineLanguageGenerator in your adaptive dialog that manages the templates in RootDialog.lg:

var rootDialog = new AdaptiveDialog(nameof(AdaptiveDialog)){
.
.
.
Generator = new TemplateEngineLanguageGenerator(Templates.ParseFile(fullPath))
}

You can now call templates in your bot by name, using the format ${<template-name>}.

new SendActivity("${FinalUserProfileReadOut()}")

In the example above, the bot calls the FinalUserProfileReadOut template and responds with the contents of the template.

Additional Information