Language Generation and Cards
Start course

This course shows you the fundamentals of how to create, test, troubleshoot, and publish chatbots using the Microsoft Bot Framework Composer. You’ll learn about dialogs, triggers, and prompts and how these can be used to model conversational logic in your chatbots. We'll cover how to work with state and variables before moving on to how to control chatbot output by using language generation and how to implement adaptive cards to create rich user experiences.

Then we'll explore how the Bot Framework Emulator, Webchat Window, Watch Window, and Application Insights can be used to debug your chatbot. Finally, we'll show you how to get your chatbot published on Azure and how to test your chatbot using the Azure Portal.

Learning Objectives

  • Use Bot Framework Composer to create chatbots
  • Implement dialogs and maintain state
  • Implement logging for a bot conversation
  • Implement prompts for user input
  • Troubleshoot a conversational bot
  • Add language generation for a response
  • Design and implement adaptive cards
  • Test and publish a chatbot 

Intended Audience

This course is intended for developers or software architects who want to learn more about Bot Framework Composer and how it can be used to create conversational AI solutions in Microsoft Azure. 


To get the most out of this course, you should have:

  • Intermediate knowledge of coding techniques
  • Familiarity with Azure concepts such as App Service and resources
  • An understanding of JSON

Let's look at an overview of Language Generation and cards. In this lecture, we're going to introduce Language Generation. We'll look at Language Generation templates and how you can use them. You'll learn about the concept of cards. And finally, we'll see a demo of how you can modify chatbot output by using LG and Adaptive Cards. So let's explore Language Generation.

So what is Language Generation? Language Generation provides a way for you to extract hardcoded strings from your chatbot. You can manage these directly within Bot Framework Composer in the designer canvas. You also have the option of accessing a comprehensive list in a dedicated screen. Supporting this are a collection of LG files that are manipulated whilst you create and edit chatbot responses. And that the core of this is a templating system that can perform entity and data value substitution.

Some of the key features of Language Generation include being able to define variations of a response. For example, Language Generation allows you to add multiple ways of sending a greeting. The Bot Framework runtime will then select one at random. This can add more personality to your chatbots. A powerful feature of Language Generation is the ability to inject data stored in state. This makes it possible for you to create dynamic bot responses using previously collected or calculated data.

You also have the option of running simple expressions and logic in the Language Generation file. For example, you might introduce an if-then-else evaluation to select an appropriate value. Language Generation also lets you define different response types that can include sending a single regular string in a response, sending a multi-line string in a response, or even sending data in a complex object, such as a card. We'll cover cards a little bit later in this lecture. Language Generation features make it simple for you to separate business logic and dialogues from the presentation of the response your chatbot can send.

So how is Language Generation implemented in Bot Framework Composer? Language Generation is implemented as a markdown file. Each dialogue you're creating in Bot Framework Composer has an associated Language Generation file. Each Language Generation file has an .lg extension. Any Language Generation files that are created also have access to chatbot memory and state. You can use this feature to data-bind calculated or processed data to chatbot responses. This could help you create rich user experiences.

We can see an example LG file here. This LG file contains a simple text response and some variations. This line is the markdown expression for a comment within an LG file. This line indicates the template name, "Greeting." These lines indicate each of the potential responses the chatbot can pick from, "Hi," "Hello," and "What's up!?" There are a few templates to pick from when working with Language Generation in Bot Framework Composer, the simple response, the conditional response, and the structured response.

The option you select really depends on your solution requirements and how you'd like users to interact with your chatbot. The simple response template will generate a simple text response in your chatbot. The text can be a single-line, multi-line, and can also include data-bound parameters. We can see an example of a simple response here. In this example, three variations are defined, Hi, Hello, and What's up!? The Bot Framework will select one of these variations at runtime and display the text response to the user.

One thing to note is the hyphen character. This is part of the markdown and doesn't get displayed by your chatbot. We can see an example of this simple response template in action here. The conditional response template lets you supply simple logic to the way Language Generation is rendered in your chatbot. In this example, we can see a variable that's set to the value, afternoon. A conditional response template has been created to perform an evaluation on the property and send a relevant message. That's what we can see here.

We can see an example of the output of this conditional response template in action here. The dialogue is invoked, the property is set, and the relevant message is displayed. The structured response template contains the features in the simple and conditional response templates. In addition to this, you can use a structured response template to define complex structures in your chatbot responses. In this example, a hero card has been defined. The hero card defines a combination of text and images and buttons. We can see an example of the output of this structured response template here. It includes the text, images, and buttons that were defined in the structured response template. You can think of Language Generation as being the presentation layer for your chatbot.

Next, we'll learn more about cards and how you can use these. Let's take a look at cards and see how you can use these in Bot Framework Composer. So what are cards? Cards are defined using the structured response template that we've just looked at. Cards provide you with additional ways to interact with users. For example, using the hero card that we've just seen earlier. They also let you create new ways to collect information from users to interact with your chatbot.

All cards are defined in LG files and are part of the dialogue creation process. When creating cards, you can opt to select text, images, gifs, and video, audio, or buttons. This means that you can create a rich variety of experiences for people that interact with your chatbot. Cards are created directly in Bot Framework Composer. You do this by configuring the template markup and the bot responses property for inactivity. There are many types of card you can define in Bot Framework Composer.

We saw the hero card earlier. This lets you create a card with a single large image, multiple buttons, and text. The thumbnail card contains a single thumbnail image, one or more buttons, and simple text. The sign-in card contains text and buttons, and prompts the user to start a sign-in process. The animation card lets you play animated gifs of short clips. Video card lets you define and play videos. The audio card will let you play an audio file. The Adaptive Card is one of the most customizable cards in Bot Framework Composer. It lets you combine text, speech, images, buttons, and many different types of input fields.

Cards are defined using the response editor in Composer. That's what we can see here. In this example, the hero card has been defined. The title, subtitle, and text values are also set. An image is defined, which is being read from a URL. Three buttons are also defined in this hero card, Option 1, 2, and 3. Clicking on the button will invoke an event in the chatbot. You can then process business logic related to the button click. So let's take a closer look at Adaptive Cards. Adaptive Cards deserve a special call-out. These are highly configurable cards and let you configure multiple UI elements within a single card. This can help you create rich user experiences for people that interact with your chatbot.

To implement an Adaptive Card, you create and configure a JSON object. A JSON is added as an attachment when defining the bot response template. We can see an example of an Adaptive Card being created in Composer here. The Send a response activity has been defined to use an attachment. That's what we can see here. The attachment has been defined using the Adaptive Card markup. When this activity is rendered by the Bot Framework runtime, a text block with the text, "default text," will be displayed in bold. You can learn more about Adaptive Cards by visiting the URL on this slide.

Creating Adaptive Cards can involve constructing multiple nested JSON structures. This can be time consuming, but you don't have to do this manually. The website provides you with a click and create interface to let you visually construct Adaptive Cards. This simplifies the creation process. The preview window lets you visualize your Adaptive Card as you create it. You can then export the auto-generated JSON and input this into Bot Framework Composer. Samples and predefined templates are also included. You can find all of this at It's now time for a demo.

In this demo, you'll learn how to modify chatbot output using LG. You'll also see how to implement an Adaptive Card. So what we can see here is we have an empty dialogue called StudentRecords, and this is where we're going to start building out the logic for our chatbot. The first thing that we have to do is to add a prompt that collects the user's name, so we'll do that just now. We have to store this information, so we'll set the User input property.

Next, we'll set a dialogue scope variable to store the time of day. Here, we'll use two adaptive expressions, get timeOfDay and utcNow. Here, we input the adaptive expressions. Let's return the string, and the value can be morning, afternoon, or evening. We need to send the welcome message to the user, so we'll use the Send a response activity. Here, we add some LG to programmatically set the presentation of the welcome message.

Now that we have the welcome message, we need to create an Adaptive Card. I've prepared some JSON here. In this JSON, we can see there are fields and labels that let a user supply a first name, last name, and email address. We can scroll down further here, and we can also see down towards the bottom, between lines 30 and 34, that a Submit button is also available. We'll take a copy of this JSON and return back into Composer. We'll use this JSON to create a new Send a response.

This time, we'll use Ask a question. Here, we need to send the Adaptive Card JSON as an attachment. We can do this by clicking on the plus sign and selecting Attachments. You click on the following link, Create from template, and select Adaptive Card. It's a little bit tricky to read the markup here, so we can expand this editor by clicking on the Pop out editor button. Here, we can update the Adaptive Card JSON. So we'll paste in the JSON that we took from Notepad, and click on cross. We need to capture the button click in our Adaptive Card. We can do that by adding a Message received trigger to our dialogue. Here, we have to select the appropriate type of trigger. Activities and Message received.

Next, we can extract data from the button click by using data currently stored in turn scope. We'll use the send an activity action to show us this data. We can do one for lastname, we can do one for firstname, and we can do another for email address. Finally, we need to set the new dialogue to launch when our chatbot starts. We can do that by selecting the root dialogue and Begin a new dialogue. With the dialogue set, we can now run the chatbot. We'll select Test in Emulator, this time. So here, we're prompted for our name. We now have a greeting message of good afternoon.

We can now input some information into our Adaptive Card. Our button click will be captured. And here we can see the information that was captured as part of the button click and echoed back to us in three separate activities. We can pull the emulator window over here, and look into our dialogue and events. And if we pull the emulator back over, we can see we have email, firstname, and lastname. In this demo, we've seen how to use LG and adaptive expressions to create an appropriate welcome message. We've seen how to create an Adaptive Card. We've also seen how to extract data from Adaptive Cards. Next, we'll learn more about debugging chatbots with Bot Framework Composer.

About the Author

Jamie Maguire is a Software Architect, Developer, Microsoft MVP (AI), and lifelong tech enthusiast with over 20 years of professional experience.

Jamie is passionate about using AI technologies to help advance systems in a wide range of organizations. 

He has collaborated on many projects including working with Twitter, National Geographic, and the University of Michigan. Jamie is a keen contributor to the technology community and has gained global recognition for articles he has written and software he has built. 

He is a STEM Ambassador and Code Club volunteer, inspiring interest at grassroots level. Jamie shares his story and expertise at speaking events, on social media, and through podcast interviews. 

He has co-authored a book with 16 fellow MVPs demonstrating how Microsoft AI can be used in the real world and regularly publishes material to encourage and promote the use of AI and .NET technologies.