Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DCR] [Adaptive] Data model definition for adaptive dialog #2322

Closed
vishwacsena opened this issue Jul 25, 2019 · 2 comments
Closed

[DCR] [Adaptive] Data model definition for adaptive dialog #2322

vishwacsena opened this issue Jul 25, 2019 · 2 comments
Labels
composer Impacts composer

Comments

@vishwacsena
Copy link
Contributor

Today, the input/ output for an adaptive dialog is a black box which gets in the way of ability to effectively compose them as well as gets in the way of easily being able to define an adaptive dialog as a reusable component. Providing a clear interface definition of what the adaptive dialog expects and accepts as input as well as defining what the adaptive dialog would return as possible value and its structure + type information can help with composition as well as export/ import an adaptive dialog as a functional unit. We will need to invest in a data model definition for adaptive dialogs to enable that.

@vishwacsena vishwacsena added P0 Must Fix. Release-blocker Adaptive 4.6 October 31, 2019 Release P1 Painful if we don't fix, won't block releasing composer Impacts composer and removed P0 Must Fix. Release-blocker labels Jul 25, 2019
@vishwacsena
Copy link
Contributor Author

Adaptive dialog - data model definition

Concept of a dialog today broadly serves one of two main purposes -

  1. To route incoming user message to an appropriate dialog that can fulfill user request

  2. To perform a specific task for the user including answering a question, completing a form and fulfilling an action etc.

Task completion style dialogs (#2 above) could benefit significantly by having the user either start with or provide a data model to enhance the capabilities that adaptive dialogs can provide.

This document outlines the requirements and design considerations for a data model definition for Adaptive dialog.

Opportunities

A data model can help solve for a variety of core gaps we have today including but not limited to the following -

  • Today, users have to define entities separately across sub-systems and there is no easy way to share those definitions across sub-systems. Here's an example that illustrates this core gap via a scenario. The duplication of this core construct once per subsystem is super painful to create, manage and keep in sync. Let's say the user is building a dialog to get user's favorite color. This list of possible color options is an enumeration with possible synonyms for each enum. To achieve this today, the user will have to:

    • Define a Closed list entity type for LUIS that includes normalized values, synonyms and possibly roles - e.g. favoriteColor .vs. hatedColor

    • Define a choice input with value and synonyms via steps

    • Define a the set of color options to generate an adaptive card via language generation to present user with list of color options.

  • There is no functional equivalent of a Form dialog like the one we had in V3. We do not have this in the V4 SDK, in adaptive dialog.

    • Several competing products offer a simple form based dialog definition that helps define expected and optional variables that is then used to drive a multi-turn conversation to fulfill the model before invoking the task completion action.

User scenarios

  • I should be able to specify the set of input properties that my dialog accepts including those that it expects to be present on invocation as well as describe the output my dialog generates/ returns. With that information specified, I have the ability to

    • present UX that allows users to data bind to inputs and outputs in a more structured way

    • componentize a set of actions into a reusable dialog

  • I should be able to specify the set of variables that my dialog needs including its data type and any constraints on possible values it can have etc. With that information specified, I have the ability to

    • use the core data model definition across the sub-systems that power my bot's conversations including LU, LG, dialog, QnA, memory and other subsystems.

    • get auto-suggest, auto-complete and validation intellisense as I refer to these variables in my conversation sub-systems

    • auto-generate a set of skeleton action (set of steps/ plan) that I can then completely manage manually

    • automatically save entities recognized via language understanding recognizers as well as card responses (e.g. adaptive card) to be automatically data-bound to memory scopes defined in the data model. E.g. without this happening automatically, users today need to use setProperty to manually save recognized entities into relevant memory scopes. Also given the current recognizer results come through the turn scope, any recognized information is lost unless the user explicitly persists them to one of the non-transient memory scopes.

    • drive a multi-turn conversation that is sorely focused on prompting -> validating -> fulfilling required variables for my dialog to lead up to action fulfillment

    • enable validations on inputs against a core set of memory variables + validations specified.

Example definition data model

Here's a conceptual example of a data model definition for an adaptive dialog that includes a definition for its inputs and outputs. I'd expect to be able to tie any adaptive dialog to this data model via a dataModel property.

{

    "$schema": "../../app.schema",

    "$type": "Microsoft.AdaptiveDialog",

    "generator": "common.lg",

    "recognizer": "dialog.lu",

    // Data model definition for this adaptive dialog

    "dataModel": "dialog.model.json",

    "$description": "Guesses the favorite movie given user's name, age and their favorite color"

}

Variable definition

At the core of the data model definition is units of information that are at play in the adaptive dialog. By design, I'm not calling this Slot or Entity or property since they all have different meanings/ interpretation. So let's start with variable since that is an established pattern across programming languages for representing a piece of information the application deals with. Also variable resonated well with non-technical audience in user studies.

The subsequent set of examples use a simple scenario for an adaptive dialog that suggests a possible favorite movie title for a user given their name, age and favorite color. The adaptive dialog can accept values for name, age and color as input to the dialog and if missing will prompt user for that information. The dialog will finally return the favorite movie guess as a string back to the caller.

Here's an example definition of the variables collection for this adaptive dialog.

{

    "$schema": "../../app.schema",

    "$type": "Microsoft.AdaptiveDialog.DataModel",

    "variables": [

        {

            "name": "userAge",

            "type": "number",                           // possible types are string, number, dateTime, list, bool, object, array

            "constraints": [                            // Each constraint has a name and either an expression or values

                {

                    "name": "minUserAgeReq",

                    "expression": "int(~input) >= 1"    // ~input is a short hand for turn.value. May be turn.value should really be turn.recognized.<entityType> instead of turn.value?

                },

                {

                    "name": "maxUserAgeReq",

                    "expression": "int(~input) <= 150"

                }

            ]

        },

        {

            "name": "userName",

            "type": "string",

            "constraints": [

                {

                    "name": "minLengthReq",

                    "expression": "length(~input) > 2"

                },

                {

                    "name": "maxLengthReq",

                    "expression": "length(~input) <= 150"

                }

            ]

        },

        {

            "name": "userFavColor",

            "type": "list",

            "enum": [

                {

                    "value": "red",

                    "synonyms": "scarlet, vermilion, ruby, cherry, claret, blood"

                },

                {

                    "value": "green",

                    "synonyms": "greenish, viridescent, olive green, pea green"

                }

            ],

            "constraints": []       // no additional constraints specified.

        }

    ]

}

Using data model in LU, LG and dialog

Once I have the data model definition for my adaptive dialog, I should be able to immediately use it in LU, LG and dialog sub-systems.

Use in dialog

With the above data model, I can immediately use it in dialogs. Here is an example of how this can be used in a choiceInput action that asks the user for their favorite color -

{

    "$type": "Microsoft.ChoiceInput",

    // This will pull choices list from the data model and I do not have to define it inline.

    "variable": "userFavColor",

    "prompt": "What is your favorite color?",        

    // This corresponds to the LU model that automatically adds the variable as a list entity type.

    // This is optional since the LU model will by default suggest an entity name that matches the variable name.

 

    "value": "@userFavColor",     

 

    // This is optional once a variable is set. By default all variables value will go to $variableName  

 

    "property": "$userFavColor"      

}

Here's the number input -

{

    "$type": "Microsoft.NumberInput",

    "variable": "userAge",

    "prompt": "What is your age?"

 

    // Constraints are automatically applied if defined in the data model.

    // Any constraints locally defined in the input will be additive to what's defined in the data model

}

Use in LU

By default for inputs, once a variable is attached to that input, we will automatically pre-seed the LU section with relevant LU configuration based on that type.

e.g. for choiceInput that is set to the userFavColor variable, we will add the following to the LU configuration for that input -

$ userFavColor : red =

    - scarlet, vermilion, ruby, cherry, claret, blood

$ userFavColor : green =

    - greenish, viridescent, olive green, pea green

e.g. for numberInput that is set to the userAge variable, we will add the following to the LU configuration for that input -

$ prebuilt : number Role = [userAge]

> I'd really like to simplify this to just this definition instead -

> $ number : userAge

For use cases outside of a visual authoring tool where we can automatically do this, we will update the .lu file format to natively support import of the .model file.

[ModelDefinition](../../dialog.model.json)

 

> Once we have a model definition, we can simply add an entity of that type via this short hand and the parser will expand the description

$ userAge

Use in LG

You always will have access to the data model definition as a JSON object in all templates and expressions inside LG for that particular dialog, accessible via '$.variableName'

Here's an example of constructing a suggested action based on the favorite color definition in the data model -

# AskForColor

- What is your favorite color? [ColorSuggestions]

 

# ColorSuggestions

- ```

[Suggestions=@{join($.userFavColor.enum.value, ' | ')}

Call to AskForColor template is expected to return


What is your favorite color?

[Suggestions=red | green]

Input and output definition

Once I have the variables defined, I can define the structure of inputs and outputs for this dialog based on that information. Here's an example of that.

{

    "$schema": "../../app.schema",

    "$type": "Microsoft.AdaptiveDialog.DataModel",

    "variables": [

        {

            "name": "userAge",

            "type": "number",                           // possible types are string, number, dateTime, list, bool, object, array

            "constraints": [                            // Each constraint has a name and either an expression or values

                {

                    "name": "minUserAgeReq",

                    "expression": "int(~input) >= 1"    // ~input is a short hand for turn.value. May be turn.value should really be turn.recognized.<entityType> instead of turn.value?

                },

                {

                    "name": "maxUserAgeReq",

                    "expression": "int(~input) <= 150"

                }

            ]

        },

        {

            "name": "userName",

            "type": "string",

            "constraints": [

                {

                    "name": "minLengthReq",

                    "expression": "length(~input) > 2"

                },

                {

                    "name": "maxLengthReq",

                    "expression": "length(~input) <= 150"

                }

            ]

        },

        {

            "name": "userFavColor",

            "type": "list",

            "enum": [

                {

                    "value": "red",

                    "synonyms": "scarlet, vermilion, ruby, cherry, claret, blood"

                },

                {

                    "value": "green",

                    "synonyms": "greenish, viridescent, olive green, pea green"

                }

            ],

            "constraints": []       // no additional constraints specified.

        }

    ],

    // Input definition for this dialog.

    "input": [

        {

            "variable": "userName",                             

            // %abcd is a short hand for dialog.options.userName -> value that is passed in to this dialog.

            // It is conceivable that we could use expressions with prebuilt functions to walk incoming dialog.options object to find a specific value that meets the variable constraints

            "value": "%userName",                          

            "optional": true,

        },

        {

            "variable": "userAge",

            "value": "%userAge",

            "optional": true

        },

        {

            "variable": "userFavColor",

            "value": "%userFavColor",

            "optional": true

        }

    ],

    // output definition for this dialog.

    "output": {

        "variable": "favMovieGuess",

        "optional": false

    }

}

Other capabilities listed in requirements should build on top of this core definition – e.g. multi-turn conversations just using the data model definition, etc.

Pre-seeding actions based on data model definition

It is conceivable that given just the data model definition, that a visual authoring tool would be able to automatically get the user set up with a series of actions that prompt user for required information.

An experience like this could be backed by the Add new dialog wizard that gets the user to spend time on providing a data model and then botify the data model into a series of actions.

Note: The initial botification from data model would be a one way street. As users continue to build out their actions, a visual authoring tool could prompt the author to consider adding relevant information from their actions collection into the data model.

As an example, with the above data model, we should be able to generate the following adaptive dialog actions via the botify affordance in a visual authoring tool.

{

    "$schema": "../../app.schema",

    "$type": "Microsoft.AdapiveDialog",

    "dataModel": "dialog.model.json",

    "recognizer": "dialog.lu",

    "generator": "common.lg",

    "events": [

        {

            "$type": "Microsoft.BeginDialog",

            "actions": [

                {

                    "$type": "Microsoft.TextInput",

                    "variable": "userName",

                    "prompt": "e.g. give me a value for userName",

                    "invalidPrompt": "e.g. {turn.value} does not work. Give me a value for userName",

                    "maxTurnCount": 3,

                    "defaultValue": "'Human'",

                    "value": "coalesce(@userName, @personName)",

                },

                {

                    "$type": "Microsoft.NumberInput",

                    "variable": "userAge",

                    "prompt": "e.g. give me a value for userAge",

                    "invalidPrompt": "e.g. {turn.value} does not work. Give me a value for userAge",

                    "maxTurnCount": 3,

                    "defaultValue": "30",

                    "value": "coalesce(@userAge, @age, @number)",

                },

                {

                    "$type": "Microsoft.ChoiceInput",

                    "variable": "userFavColor",

                    "prompt": "e.g. give me a value for userFavColor",

                    "invalidPrompt": "e.g. {turn.value} does not work. Give me a value for userFavColor. \n \[Suggestions=@{join($.userFavColor.enum.value, ' | ')}\]",

                    "maxTurnCount": 3,

                    "defaultValue": "red",

                    "value": "@userFavColor"

                }

            ]

        }

    ]

}

Generic FormInput action

We could also replace the flat botify suggestion by natively supporting a generic FormInput action. Here's an example of what that would look like.

Note: the core data model does not contain any definition for conversation behavior. Those are always specified and managed at actions level to have clear separate between the constructs as well as have the core data model be reusable across functions.

As an example, with the above data model, user should be able to add a FormInput action and configure it for conversation management constructs.

{

    "$schema": "../../app.schema",

    "$type": "Microsoft.AdaptiveDialog",

    "dataModel": "dialog.model.json",

    "generator": "common.lg",

    "recognizer": "dialog.lu",

    "events": [

        {

            "$type": "Microsoft.BeginDialog",

            "actions": [

                {

                    "$type": "Microsoft.FormInput",

                    "slots": [

                        {

                            "variable": "userName",

                            "prompt": "what is your name?",

                            "unrecognizedPrompt": "Sorry, I do not understand '{turn.activity.text}'. What is your name?",

                            "maxTurnCount": 3,

                            "defaultValue": "'Human'",

                            "validations": [

                                {

                                    // These named constraints come from the schema

                                    "name": "minLengthReq",

                                    "invalidPrompt": "Sorry, '{turn.value}' does not work. I'm looking for a value that is at least 3 characters in length. What is your name?"

                                },

                                {

                                    "name": "maxLengthReq",

                                    "invalidPrompt": "Sorry, '{turn.value}' does not work. I'm looking for a value that is up to 150 characters in length. What is your name?"

                                }

                            ]

                        },

                        // configuration for additional slots.

                    ]

                }

            ]

        }

    ]

}

@vishwacsena vishwacsena self-assigned this Aug 8, 2019
@vishwacsena vishwacsena changed the title [Adaptive] Data model definition for adaptive dialog [DCR] [Adaptive] Data model definition for adaptive dialog Aug 17, 2019
@tomlm tomlm added the DCR label Aug 19, 2019
@vishwacsena vishwacsena removed the P1 Painful if we don't fix, won't block releasing label Aug 20, 2019
@vishwacsena vishwacsena removed the 4.6 October 31, 2019 Release label Oct 8, 2019
@vishwacsena vishwacsena added the R7 Release 7 - December 10th, 2019 label Oct 20, 2019
@vishwacsena vishwacsena removed their assignment Oct 21, 2019
@github-actions
Copy link

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days

@github-actions github-actions bot added the stale The issue hasn't been updated in a long time and will be automatically closed. label Nov 21, 2019
@vishwacsena vishwacsena removed R7 Release 7 - December 10th, 2019 stale The issue hasn't been updated in a long time and will be automatically closed. labels Dec 11, 2019
@vishwacsena vishwacsena reopened this Dec 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
composer Impacts composer
Projects
None yet
Development

No branches or pull requests

2 participants