Quickstart: Language Understanding (LUIS) SDK client libraries to create and query your LUIS app

Create and query a LUIS app with the LUIS SDK client libraries with this quickstart using C#, Python, or JavaScript.

Language Understanding (LUIS) enables you to apply custom machine-learning intelligence to a user's conversational, natural language text to predict overall meaning, and pull out relevant, detailed information.

  • The authoring SDK client library allows you to create, edit, train, and publish your LUIS app. * The prediction runtime SDK client library allows you to query the published app.

Use the Language Understanding (LUIS) client libraries for .NET to:

  • Create an app
  • Add an intent, a machine-learned entity, with an example utterance
  • Train and publish app
  • Query prediction runtime

Reference documentation | Authoring and Prediction Library source code | Authoring and Prediction NuGet | C# Sample

Prerequisites

  • The current version of .NET Core and .NET Core CLI.
  • Azure subscription - Create one for free
  • Once you have your Azure subscription, create a Language Understanding authoring resource in the Azure portal to get your key and endpoint. Wait for it to deploy and click the Go to resource button.
    • You will need the key and endpoint from the resource you create to connect your application to Language Understanding authoring. You'll paste your key and endpoint into the code below later in the quickstart. You can use the free pricing tier (F0) to try the service.

Setting up

Create a new C# application

Create a new .NET Core application in your preferred editor or IDE.

  1. In a console window (such as cmd, PowerShell, or Bash), use the dotnet new command to create a new console app with the name language-understanding-quickstart. This command creates a simple "Hello World" C# project with a single source file: Program.cs.

    dotnet new console -n language-understanding-quickstart
    
  2. Change your directory to the newly created app folder.

    cd language-understanding-quickstart
    
  3. You can build the application with:

    dotnet build
    

    The build output should contain no warnings or errors.

    ...
    Build succeeded.
     0 Warning(s)
     0 Error(s)
    ...
    

Install the NuGet libraries

Within the application directory, install the Language Understanding (LUIS) client libraries for .NET with the following commands:

dotnet add package Microsoft.Azure.CognitiveServices.Language.LUIS.Authoring --version 3.2.0-preview.3
dotnet add package Microsoft.Azure.CognitiveServices.Language.LUIS.Runtime --version 3.1.0-preview.1

Authoring Object model

The Language Understanding (LUIS) authoring client is a LUISAuthoringClient object that authenticates to Azure, which contains your authoring key.

Code examples for authoring

Once the client is created, use this client to access functionality including:

Prediction Object model

The Language Understanding (LUIS) prediction runtime client is a LUISRuntimeClient object that authenticates to Azure, which contains your resource key.

Code examples for prediction runtime

Once the client is created, use this client to access functionality including:

Code examples

These code snippets show you how to do the following with the Language Understanding (LUIS) client library for python:

Add the dependencies

From the project directory, open the Program.cs file in your preferred editor or IDE. Replace the existing using code with the following using directives:

using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Azure.CognitiveServices.Language.LUIS.Authoring;
using Microsoft.Azure.CognitiveServices.Language.LUIS.Authoring.Models;
using Microsoft.Azure.CognitiveServices.Language.LUIS.Runtime;
using Microsoft.Azure.CognitiveServices.Language.LUIS.Runtime.Models;
using Newtonsoft.Json;

Add boilerplate code

  1. Change the signature of the Main method to allow async calls:

    public static async Task Main()
    
  2. Add the rest of the code in the Main method of the Program class unless otherwise specified.

Create variables for the app

Create two sets of variables: the first set you change, the second set leave as they appear in the code sample.

  1. Create variables to hold your authoring key and resource names.

    var key = "REPLACE-WITH-YOUR-AUTHORING-KEY";
    
    var authoringResourceName = "REPLACE-WITH-YOUR-AUTHORING-RESOURCE-NAME";
    var predictionResourceName = "REPLACE-WITH-YOUR-PREDICTION-RESOURCE-NAME";
    
  2. Create variables to hold your endpoints, app name, version, and intent name.

    var authoringEndpoint = String.Format("https://{0}.cognitiveservices.azure.com/", authoringResourceName);
    var predictionEndpoint = String.Format("https://{0}.cognitiveservices.azure.com/", predictionResourceName);
    
    var appName = "Contoso Pizza Company";
    var versionId = "0.1";
    var intentName = "OrderPizzaIntent";
    

Authenticate the client

Create an ApiKeyServiceClientCredentials object with your key, and use it with your endpoint to create an LUISAuthoringClient object.

var credentials = new Microsoft.Azure.CognitiveServices.Language.LUIS.Authoring.ApiKeyServiceClientCredentials(key);
var client = new LUISAuthoringClient(credentials) { Endpoint = authoringEndpoint };

Create a LUIS app

A LUIS app contains the natural language processing (NLP) model including intents, entities, and example utterances.

Create a ApplicationCreateObject. The name and language culture are required properties. Call the Apps.AddAsync method. The response is the app ID.

var newApp = new ApplicationCreateObject
{
    Culture = "en-us",
    Name = appName,
    InitialVersionId = versionId
};

var appId = await client.Apps.AddAsync(newApp);

Create intent for the app

The primary object in a LUIS app's model is the intent. The intent aligns with a grouping of user utterance intentions. A user may ask a question, or make a statement looking for a particular intended response from a bot (or other client application). Examples of intentions are booking a flight, asking about weather in a destination city, and asking about contact information for customer service.

Create a ModelCreateObject with the name of the unique intent then pass the app ID, version ID, and the ModelCreateObject to the Model.AddIntentAsync method. The response is the intent ID.

The intentName value is hard-coded to OrderPizzaIntent as part of the variables in the Create variables for the app section.

await client.Model.AddIntentAsync(appId, versionId, new ModelCreateObject()
{
    Name = intentName
});

Create entities for the app

While entities are not required, they are found in most apps. The entity extracts information from the user utterance, necessary to fullfil the user's intention. There are several types of prebuilt and custom entities, each with their own data transformation object (DTO) models. Common prebuilt entities to add to your app include number, datetimeV2, geographyV2, ordinal.

It is important to know that entities are not marked with an intent. They can and usually do apply to many intents. Only the example user utterances are marked for a specific, single intent.

Creation methods for entities are part of the Model class. Each entity type has its own data transformation object (DTO) model, usually containing the word model in the Models namespace.

The entity creation code creates a machine-learning entity with subentities and features applied to the Quantity subentities.

Partial screenshot from portal showing the entity created, a machine-learning entity with subentities and features applied to the `Quantity` subentities.

// Add Prebuilt entity
await client.Model.AddPrebuiltAsync(appId, versionId, new[] { "number" });

// Define ml entity with children and grandchildren
var mlEntityDefinition = new EntityModelCreateObject
{
    Name = "Pizza order",
    Children = new[]
    {
        new ChildEntityModelCreateObject
        {
            Name = "Pizza",
            Children = new[]
            {
                new ChildEntityModelCreateObject { Name = "Quantity" },
                new ChildEntityModelCreateObject { Name = "Type" },
                new ChildEntityModelCreateObject { Name = "Size" }
            }
        },
        new ChildEntityModelCreateObject
        {
            Name = "Toppings",
            Children = new[]
            {
                new ChildEntityModelCreateObject { Name = "Type" },
                new ChildEntityModelCreateObject { Name = "Quantity" }
            }
        }
    }
};

// Add ML entity 
var mlEntityId = await client.Model.AddEntityAsync(appId, versionId, mlEntityDefinition); ;

// Add phraselist feature
var phraselistId = await client.Features.AddPhraseListAsync(appId, versionId, new PhraselistCreateObject
{
    EnabledForAllModels = false,
    IsExchangeable = true,
    Name = "QuantityPhraselist",
    Phrases = "few,more,extra"
});

// Get entity and subentities
var model = await client.Model.GetEntityAsync(appId, versionId, mlEntityId);
var toppingQuantityId = GetModelGrandchild(model, "Toppings", "Quantity");
var pizzaQuantityId = GetModelGrandchild(model, "Pizza", "Quantity");

// add model as feature to subentity model
await client.Features.AddEntityFeatureAsync(appId, versionId, pizzaQuantityId, new ModelFeatureInformation { ModelName = "number", IsRequired = true });
await client.Features.AddEntityFeatureAsync(appId, versionId, toppingQuantityId, new ModelFeatureInformation { ModelName = "number"});

// add phrase list as feature to subentity model
await client.Features.AddEntityFeatureAsync(appId, versionId, toppingQuantityId, new ModelFeatureInformation { FeatureName = "QuantityPhraselist" });

Use the following method to the class to find the Quantity subentity's ID, in order to assign the features to that subentity.

static Guid GetModelGrandchild(NDepthEntityExtractor model, string childName, string grandchildName)
{
    return model.Children.
        Single(c => c.Name == childName).
        Children.
        Single(c => c.Name == grandchildName).Id;
}

Add example utterance to intent

In order to determine an utterance's intention and extract entities, the app needs examples of utterances. The examples need to target a specific, single intent and should mark all custom entities. Prebuilt entities do not need to be marked.

Add example utterances by creating a list of ExampleLabelObject objects, one object for each example utterance. Each example should mark all entities with a dictionary of name/value pairs of entity name and entity value. The entity value should be exactly as it appears in the text of the example utterance.

Partial screenshot showing the labeled example utterance in the portal.

Call Examples.AddAsync with the app ID, version ID, and the example.

// Define labeled example
var labeledExampleUtteranceWithMLEntity = new ExampleLabelObject
{
    Text = "I want two small seafood pizzas with extra cheese.",
    IntentName = intentName,
    EntityLabels = new[]
    {
        new EntityLabelObject
        {
            StartCharIndex = 7,
            EndCharIndex = 48,
            EntityName = "Pizza order",
            Children = new[]
            {
                new EntityLabelObject
                {
                    StartCharIndex = 7,
                    EndCharIndex = 30,
                    EntityName = "Pizza",
                    Children = new[]
                    {
                        new EntityLabelObject { StartCharIndex = 7, EndCharIndex = 9, EntityName = "Quantity" },
                        new EntityLabelObject { StartCharIndex = 11, EndCharIndex = 15, EntityName = "Size" },
                        new EntityLabelObject { StartCharIndex = 17, EndCharIndex = 23, EntityName = "Type" }
                    }
                },
                new EntityLabelObject
                {
                    StartCharIndex = 37,
                    EndCharIndex = 48,
                    EntityName = "Toppings",
                    Children = new[]
                    {
                        new EntityLabelObject { StartCharIndex = 37, EndCharIndex = 41, EntityName = "Quantity" },
                        new EntityLabelObject { StartCharIndex = 43, EndCharIndex = 48, EntityName = "Type" }
                    }
                }
            }
        },
    }
};

// Add an example for the entity.
// Enable nested children to allow using multiple models with the same name.
// The quantity subentity and the phraselist could have the same exact name if this is set to True
await client.Examples.AddAsync(appId, versionId, labeledExampleUtteranceWithMLEntity, enableNestedChildren: true); 

Train the app

Once the model is created, the LUIS app needs to be trained for this version of the model. A trained model can be used in a container, or published to the staging or product slots.

The Train.TrainVersionAsync method needs the app ID and the version ID.

A very small model, such as this quickstart shows, will train very quickly. For production-level applications, training the app should include a polling call to the GetStatusAsync method to determine when or if the training succeeded. The response is a list of ModelTrainingInfo objects with a separate status for each object. All objects must be successful for the training to be considered complete.

await client.Train.TrainVersionAsync(appId, versionId);
while (true)
{
    var status = await client.Train.GetStatusAsync(appId, versionId);
    if (status.All(m => m.Details.Status == "Success"))
    {
        // Assumes that we never fail, and that eventually we'll always succeed.
        break;
    }
}

Publish app to production slot

Publish the LUIS app using the PublishAsync method. This publishes the current trained version to the specified slot at the endpoint. Your client application uses this endpoint to send user utterances for prediction of intent and entity extraction.

await client.Apps.PublishAsync(appId, new ApplicationPublishObject { VersionId = versionId, IsStaging=false});

Authenticate the prediction runtime client

Use an ApiKeyServiceClientCredentials object with your key, and use it with your endpoint to create an LUISRuntimeClient object.

Caution

This quickstart uses the authoring key as as part of the runtime credentials. The authoring key is allowed to query the runtime with a few queries. For staging and production-level code, replace the authoring key with a prediction runtime key.

var runtimeClient = new LUISRuntimeClient(credentials) { Endpoint = predictionEndpoint };

Get prediction from runtime

Add the following code to create the request to the prediction runtime.

The user utterance is part of the PredictionRequest object.

The GetSlotPredictionAsync method needs several parameters such as the app ID, the slot name, the prediction request object to fulfill the request. The other options such as verbose, show all intents, and log are optional.

// Production == slot name
var request = new PredictionRequest { Query = "I want two small pepperoni pizzas with more salsa" };
var prediction = await runtimeClient.Prediction.GetSlotPredictionAsync(appId, "Production", request);
Console.Write(JsonConvert.SerializeObject(prediction, Formatting.Indented));

The prediction response is a JSON object including the intent and any entities found.

{
    "query": "I want two small pepperoni pizzas with more salsa",
    "prediction": {
        "topIntent": "OrderPizzaIntent",
        "intents": {
            "OrderPizzaIntent": {
                "score": 0.753606856
            },
            "None": {
                "score": 0.119097039
            }
        },
        "entities": {
            "Pizza order": [
                {
                    "Pizza": [
                        {
                            "Quantity": [
                                2
                            ],
                            "Type": [
                                "pepperoni"
                            ],
                            "Size": [
                                "small"
                            ],
                            "$instance": {
                                "Quantity": [
                                    {
                                        "type": "builtin.number",
                                        "text": "two",
                                        "startIndex": 7,
                                        "length": 3,
                                        "score": 0.968156934,
                                        "modelTypeId": 1,
                                        "modelType": "Entity Extractor",
                                        "recognitionSources": [
                                            "model"
                                        ]
                                    }
                                ],
                                "Type": [
                                    {
                                        "type": "Type",
                                        "text": "pepperoni",
                                        "startIndex": 17,
                                        "length": 9,
                                        "score": 0.9345611,
                                        "modelTypeId": 1,
                                        "modelType": "Entity Extractor",
                                        "recognitionSources": [
                                            "model"
                                        ]
                                    }
                                ],
                                "Size": [
                                    {
                                        "type": "Size",
                                        "text": "small",
                                        "startIndex": 11,
                                        "length": 5,
                                        "score": 0.9592077,
                                        "modelTypeId": 1,
                                        "modelType": "Entity Extractor",
                                        "recognitionSources": [
                                            "model"
                                        ]
                                    }
                                ]
                            }
                        }
                    ],
                    "Toppings": [
                        {
                            "Type": [
                                "salsa"
                            ],
                            "Quantity": [
                                "more"
                            ],
                            "$instance": {
                                "Type": [
                                    {
                                        "type": "Type",
                                        "text": "salsa",
                                        "startIndex": 44,
                                        "length": 5,
                                        "score": 0.7292897,
                                        "modelTypeId": 1,
                                        "modelType": "Entity Extractor",
                                        "recognitionSources": [
                                            "model"
                                        ]
                                    }
                                ],
                                "Quantity": [
                                    {
                                        "type": "Quantity",
                                        "text": "more",
                                        "startIndex": 39,
                                        "length": 4,
                                        "score": 0.9320932,
                                        "modelTypeId": 1,
                                        "modelType": "Entity Extractor",
                                        "recognitionSources": [
                                            "model"
                                        ]
                                    }
                                ]
                            }
                        }
                    ],
                    "$instance": {
                        "Pizza": [
                            {
                                "type": "Pizza",
                                "text": "two small pepperoni pizzas",
                                "startIndex": 7,
                                "length": 26,
                                "score": 0.812199831,
                                "modelTypeId": 1,
                                "modelType": "Entity Extractor",
                                "recognitionSources": [
                                    "model"
                                ]
                            }
                        ],
                        "Toppings": [
                            {
                                "type": "Toppings",
                                "text": "more salsa",
                                "startIndex": 39,
                                "length": 10,
                                "score": 0.7250252,
                                "modelTypeId": 1,
                                "modelType": "Entity Extractor",
                                "recognitionSources": [
                                    "model"
                                ]
                            }
                        ]
                    }
                }
            ],
            "$instance": {
                "Pizza order": [
                    {
                        "type": "Pizza order",
                        "text": "two small pepperoni pizzas with more salsa",
                        "startIndex": 7,
                        "length": 42,
                        "score": 0.769223332,
                        "modelTypeId": 1,
                        "modelType": "Entity Extractor",
                        "recognitionSources": [
                            "model"
                        ]
                    }
                ]
            }
        }
    }
}

Run the application

Run the application with the dotnet run command from your application directory.

dotnet run

Use the Language Understanding (LUIS) client libraries for Node.js to:

  • Create an app
  • Add an intent, a machine-learned entity, with an example utterance
  • Train and publish app
  • Query prediction runtime

Reference documentation | Authoring and Prediction Library source code | Authoring and Prediction NPM | Samples

Prerequisites

  • Node.js
  • Azure subscription - Create one for free
  • Once you have your Azure subscription, create a Language Understanding authoring resource in the Azure portal to get your key and endpoint. Wait for it to deploy and click the Go to resource button.
    • You will need the key and endpoint from the resource you create to connect your application to Language Understanding authoring. You'll paste your key and endpoint into the code below later in the quickstart. You can use the free pricing tier (F0) to try the service.

Setting up

Create a new JavaScript application

  1. In a console window create a new directory for your application and move into that directory.

    mkdir quickstart-sdk && cd quickstart-sdk
    
  2. Initialize the directory as a JavaScript application by creating a package.json file.

    npm init -y
    
  3. Create a file named index.js for your JavaScript code.

    touch index.js
    

Install the NPM libraries

Within the application directory, install the dependencies with the following commands, executed one line at a time:

npm install @azure/ms-rest-js
npm install @azure/cognitiveservices-luis-authoring
npm install @azure/cognitiveservices-luis-runtime

Your package.json should look like:

{
  "name": "quickstart-sdk",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@azure/cognitiveservices-luis-authoring": "^4.0.0-preview.3",
    "@azure/cognitiveservices-luis-runtime": "^5.0.0",
    "@azure/ms-rest-js": "^2.0.8"
  }
}

Authoring Object model

The Language Understanding (LUIS) authoring client is a LUISAuthoringClient object that authenticates to Azure, which contains your authoring key.

Code examples for authoring

Once the client is created, use this client to access functionality including:

Prediction Object model

The Language Understanding (LUIS) authoring client is a LUISAuthoringClient object that authenticates to Azure, which contains your authoring key.

Code examples for prediction runtime

Once the client is created, use this client to access functionality including:

Code examples

These code snippets show you how to do the following with the Language Understanding (LUIS) client library for python:

Add the dependencies

Open the index.js file in your preferred editor or IDE named then add the following dependencies.

const msRest = require("@azure/ms-rest-js");
const LUIS_Authoring = require("@azure/cognitiveservices-luis-authoring");
const LUIS_Prediction = require("@azure/cognitiveservices-luis-runtime");

Add boilerplate code

  1. Add the quickstart method and its call. This method holds most of the remaining code. This method is called at the end of the file.

    const quickstart = async () => {
    
        // add calls here
    
    
    }
    quickstart()
        .then(result => console.log("Done"))
        .catch(err => {
            console.log(`Error: ${err}`)
            })
    
  2. Add the remaining code in the quickstart method unless otherwise specified.

Create variables for the app

Create two sets of variables: the first set you change, the second set leave as they appear in the code sample.

  1. Create variables to hold your authoring key and resource names.

    const authoringKey = 'REPLACE-WITH-YOUR-ASSIGNED-AUTHORING-KEY';
    
    const authoringResourceName = "REPLACE-WITH-YOUR-AUTHORING-RESOURCE-NAME";
    const predictionResourceName = "REPLACE-WITH-YOUR-PREDICTION-RESOURCE-NAME";
    
  2. Create variables to hold your endpoints, app name, version, and intent name.

    const authoringEndpoint = `https://${authoringResourceName}.cognitiveservices.azure.com/`;
    const predictionEndpoint = `https://${predictionResourceName}.cognitiveservices.azure.com/`;
    
    const appName = "Contoso Pizza Company";
    const versionId = "0.1";
    const intentName = "OrderPizzaIntent";
    

Authenticate the client

Create an CognitiveServicesCredentials object with your key, and use it with your endpoint to create an LUISAuthoringClient object.

const luisAuthoringCredentials = new msRest.ApiKeyCredentials({
    inHeader: { "Ocp-Apim-Subscription-Key": authoringKey }
});
const client = new LUIS_Authoring.LUISAuthoringClient(
    luisAuthoringCredentials,
    authoringEndpoint
);

Create a LUIS app

A LUIS app contains the natural language processing (NLP) model including intents, entities, and example utterances.

Create a AppsOperation object's add method to create the app. The name and language culture are required properties.

const create_app_payload = {
    name: appName,
    initialVersionId: versionId,
    culture: "en-us"
};

const createAppResult = await client.apps.add(
    create_app_payload
);

const appId = createAppResult.body

Create intent for the app

The primary object in a LUIS app's model is the intent. The intent aligns's with a grouping of user utterance intentions. A user may ask a question, or make a statement looking for a particular intended response from a bot (or other client application). Examples of intentions are booking a flight, asking about weather in a destination city, and asking about contact information for customer service.

Use the model.add_intent method with the name of the unique intent then pass the app ID, version ID, and new intent name.

The intentName value is hard-coded to OrderPizzaIntent as part of the variables in the Create variables for the app section.

await client.model.addIntent(
    appId,
    versionId,
    { name: intentName }
);

Create entities for the app

While entities are not required, they are found in most apps. The entity extracts information from the user utterance, necessary to fullfil the user's intention. There are several types of prebuilt and custom entities, each with their own data transformation object (DTO) models. Common prebuilt entities to add to your app include number, datetimeV2, geographyV2, ordinal.

It is important to know that entities are not marked with an intent. They can and usually do apply to many intents. Only example user utterances are marked for a specific, single intent.

Creation methods for entities are part of the Model class. Each entity type has its own data transformation object (DTO) model.

The entity creation code creates a machine-learning entity with subentities and features applied to the Quantity subentities.

Partial screenshot from portal showing the entity created, a machine-learning entity with subentities and features applied to the `Quantity` subentities.

// Add Prebuilt entity
await client.model.addPrebuilt(appId, versionId, ["number"]);

// Define ml entity with children and grandchildren
const mlEntityDefinition = {
    name: "Pizza order",
    children: [
        {
            name: "Pizza",
            children: [
                { name: "Quantity" },
                { name: "Type" },
                { name: "Size" }
            ]
        },
        {
            name: "Toppings",
            children: [
                { name: "Type" },
                { name: "Quantity" }
            ]
        }
    ]
};

// Add ML entity 
const response = await client.model.addEntity(appId, versionId, mlEntityDefinition);
const mlEntityId = response.body;

// Add phraselist feature
const phraselistResponse = await client.features.addPhraseList(appId, versionId, {
    enabledForAllModels: false,
    isExchangeable: true,
    name: "QuantityPhraselist",
    phrases: "few,more,extra"
});
const phraseListId = phraselistResponse.body;

// Get entity and subentities
const model = await client.model.getEntity(appId, versionId, mlEntityId);
const toppingQuantityId = getModelGrandchild(model, "Toppings", "Quantity");
const pizzaQuantityId = getModelGrandchild(model, "Pizza", "Quantity");

// add model as feature to subentity model
await client.features.addEntityFeature(appId, versionId, pizzaQuantityId, { modelName: "number", isRequired: true });
await client.features.addEntityFeature(appId, versionId, toppingQuantityId, { modelName: "number" });

// add phrase list as feature to subentity model
await client.features.addEntityFeature(appId, versionId, toppingQuantityId, { featureName: "QuantityPhraselist" });

Put the following method above the quickstart method to find the Quantity subentity's ID, in order to assign the features to that subentity.

const getModelGrandchild = (model, childName, grandchildName) => {

    return model.children.find(c => c.name == childName).children.find(c => c.name == grandchildName).id

}

Add example utterance to intent

In order to determine an utterance's intention and extract entities, the app needs examples of utterances. The examples need to target a specific, single intent and should mark all custom entities. Prebuilt entities do not need to be marked.

Add example utterances by creating a list of ExampleLabelObject objects, one object for each example utterance. Each example should mark all entities with a dictionary of name/value pairs of entity name and entity value. The entity value should be exactly as it appears in the text of the example utterance.

Partial screenshot showing the labeled example utterance in the portal.

Call examples.add with the app ID, version ID, and the example.

// Define labeled example
const labeledExampleUtteranceWithMLEntity =
{
    text: "I want two small seafood pizzas with extra cheese.",
    intentName: intentName,
    entityLabels: [
        {
            startCharIndex: 7,
            endCharIndex: 48,
            entityName: "Pizza order",
            children: [
                {
                    startCharIndex: 7,
                    endCharIndex: 30,
                    entityName: "Pizza",
                    children: [
                        {
                            startCharIndex: 7,
                            endCharIndex: 9,
                            entityName: "Quantity"
                        },
                        {
                            startCharIndex: 11,
                            endCharIndex: 15,
                            entityName: "Size"
                        },
                        {
                            startCharIndex: 17,
                            endCharIndex: 23,
                            entityName: "Type"
                        }]
                },
                {
                    startCharIndex: 37,
                    endCharIndex: 48,
                    entityName: "Toppings",
                    children: [
                        {
                            startCharIndex: 37,
                            endCharIndex: 41,
                            entityName: "Quantity"
                        },
                        {
                            startCharIndex: 43,
                            endCharIndex: 48,
                            entityName: "Type"
                        }]
                }
            ]
        }
    ]
};

console.log("Labeled Example Utterance:", JSON.stringify(labeledExampleUtteranceWithMLEntity, null, 4 ));

// Add an example for the entity.
// Enable nested children to allow using multiple models with the same name.
// The quantity subentity and the phraselist could have the same exact name if this is set to True
await client.examples.add(appId, versionId, labeledExampleUtteranceWithMLEntity, { enableNestedChildren: true });

Train the app

Once the model is created, the LUIS app needs to be trained for this version of the model. A trained model can be used in a container, or published to the staging or product slots.

The train.trainVersion method needs the app ID and the version ID.

A very small model, such as this quickstart shows, will train very quickly. For production-level applications, training the app should include a polling call to the get_status method to determine when or if the training succeeded. The response is a list of ModelTrainingInfo objects with a separate status for each object. All objects must be successful for the training to be considered complete.

await client.train.trainVersion(appId, versionId);
while (true) {
    const status = await client.train.getStatus(appId, versionId);
    if (status.every(m => m.details.status == "Success")) {
        // Assumes that we never fail, and that eventually we'll always succeed.
        break;
    }
}

Publish app to production slot

Publish the LUIS app using the app.publish method. This publishes the current trained version to the specified slot at the endpoint. Your client application uses this endpoint to send user utterances for prediction of intent and entity extraction.

await client.apps.publish(appId, { versionId: versionId, isStaging: false });

Authenticate the prediction runtime client

Use an msRest.ApiKeyCredentials object with your key, and use it with your endpoint to create an LUIS.LUISRuntimeClient object.

Caution

This quickstart uses the authoring key as as part of the runtime credentials. The authoring key is allowed to query the runtime with a few queries. For staging and production-level code, replace the authoring key with a prediction runtime key.

const luisPredictionClient = new LUIS_Prediction.LUISRuntimeClient(
    luisAuthoringCredentials,
    predictionEndpoint
);

Get prediction from runtime

Add the following code to create the request to the prediction runtime. The user utterance is part of the predictionRequest object.

The luisRuntimeClient.prediction.getSlotPrediction method needs several parameters such as the app ID, the slot name, and the prediction request object to fulfill the request. The other options such as verbose, show all intents, and log are optional.

// Production == slot name
const request = { query: "I want two small pepperoni pizzas with more salsa" };
const response = await luisPredictionClient.prediction.getSlotPrediction(appId, "Production", request);
console.log(JSON.stringify(response.prediction, null, 4 ));

The prediction response is a JSON object including the intent and any entities found.

{
    "query": "I want two small pepperoni pizzas with more salsa",
    "prediction": {
        "topIntent": "OrderPizzaIntent",
        "intents": {
            "OrderPizzaIntent": {
                "score": 0.753606856
            },
            "None": {
                "score": 0.119097039
            }
        },
        "entities": {
            "Pizza order": [
                {
                    "Pizza": [
                        {
                            "Quantity": [
                                2
                            ],
                            "Type": [
                                "pepperoni"
                            ],
                            "Size": [
                                "small"
                            ],
                            "$instance": {
                                "Quantity": [
                                    {
                                        "type": "builtin.number",
                                        "text": "two",
                                        "startIndex": 7,
                                        "length": 3,
                                        "score": 0.968156934,
                                        "modelTypeId": 1,
                                        "modelType": "Entity Extractor",
                                        "recognitionSources": [
                                            "model"
                                        ]
                                    }
                                ],
                                "Type": [
                                    {
                                        "type": "Type",
                                        "text": "pepperoni",
                                        "startIndex": 17,
                                        "length": 9,
                                        "score": 0.9345611,
                                        "modelTypeId": 1,
                                        "modelType": "Entity Extractor",
                                        "recognitionSources": [
                                            "model"
                                        ]
                                    }
                                ],
                                "Size": [
                                    {
                                        "type": "Size",
                                        "text": "small",
                                        "startIndex": 11,
                                        "length": 5,
                                        "score": 0.9592077,
                                        "modelTypeId": 1,
                                        "modelType": "Entity Extractor",
                                        "recognitionSources": [
                                            "model"
                                        ]
                                    }
                                ]
                            }
                        }
                    ],
                    "Toppings": [
                        {
                            "Type": [
                                "salsa"
                            ],
                            "Quantity": [
                                "more"
                            ],
                            "$instance": {
                                "Type": [
                                    {
                                        "type": "Type",
                                        "text": "salsa",
                                        "startIndex": 44,
                                        "length": 5,
                                        "score": 0.7292897,
                                        "modelTypeId": 1,
                                        "modelType": "Entity Extractor",
                                        "recognitionSources": [
                                            "model"
                                        ]
                                    }
                                ],
                                "Quantity": [
                                    {
                                        "type": "Quantity",
                                        "text": "more",
                                        "startIndex": 39,
                                        "length": 4,
                                        "score": 0.9320932,
                                        "modelTypeId": 1,
                                        "modelType": "Entity Extractor",
                                        "recognitionSources": [
                                            "model"
                                        ]
                                    }
                                ]
                            }
                        }
                    ],
                    "$instance": {
                        "Pizza": [
                            {
                                "type": "Pizza",
                                "text": "two small pepperoni pizzas",
                                "startIndex": 7,
                                "length": 26,
                                "score": 0.812199831,
                                "modelTypeId": 1,
                                "modelType": "Entity Extractor",
                                "recognitionSources": [
                                    "model"
                                ]
                            }
                        ],
                        "Toppings": [
                            {
                                "type": "Toppings",
                                "text": "more salsa",
                                "startIndex": 39,
                                "length": 10,
                                "score": 0.7250252,
                                "modelTypeId": 1,
                                "modelType": "Entity Extractor",
                                "recognitionSources": [
                                    "model"
                                ]
                            }
                        ]
                    }
                }
            ],
            "$instance": {
                "Pizza order": [
                    {
                        "type": "Pizza order",
                        "text": "two small pepperoni pizzas with more salsa",
                        "startIndex": 7,
                        "length": 42,
                        "score": 0.769223332,
                        "modelTypeId": 1,
                        "modelType": "Entity Extractor",
                        "recognitionSources": [
                            "model"
                        ]
                    }
                ]
            }
        }
    }
}

Run the application

Run the application with the node index.js command on your quickstart file.

node index.js

Use the Language Understanding (LUIS) client libraries for Python to:

  • Create an app
  • Add an intent, a machine-learned entity, with an example utterance
  • Train and publish app
  • Query prediction runtime

Reference documentation | Authoring and Prediction Library source code | Package (Pypi) | Samples

Prerequisites

  • The current version of Python 3.x.
  • Azure subscription - Create one for free
  • Once you have your Azure subscription, create a Language Understanding authoring resource in the Azure portal to get your key and endpoint. Wait for it to deploy and click the Go to resource button.
    • You will need the key and endpoint from the resource you create to connect your application to Language Understanding authoring. You'll paste your key and endpoint into the code below later in the quickstart. You can use the free pricing tier (F0) to try the service.

Setting up

Create a new Python application

  1. In a console window create a new directory for your application and move into that directory.

    mkdir quickstart-sdk && cd quickstart-sdk
    
  2. Create a file named authoring_and_predict.py for your Python code.

    touch authoring_and_predict.py
    

Install the client library with Pip

Within the application directory, install the Language Understanding (LUIS) client library for python with the following command:

pip install azure-cognitiveservices-language-luis

Authoring Object model

The Language Understanding (LUIS) authoring client is a LUISAuthoringClient object that authenticates to Azure, which contains your authoring key.

Code examples for authoring

Once the client is created, use this client to access functionality including:

Prediction Object model

The Language Understanding (LUIS) prediction runtime client is a LUISRuntimeClient object that authenticates to Azure, which contains your resource key.

Code examples for prediction runtime

Once the client is created, use this client to access functionality including:

Code examples

These code snippets show you how to do the following with the Language Understanding (LUIS) client library for python:

Add the dependencies

Add the client libraries to the python file.

from azure.cognitiveservices.language.luis.authoring import LUISAuthoringClient
from azure.cognitiveservices.language.luis.runtime import LUISRuntimeClient
from msrest.authentication import CognitiveServicesCredentials
from functools import reduce

import json, time

Add boilerplate code

  1. Add the quickstart method and its call. This method holds most of the remaining code. This method is called at the end of the file.

    def quickstart():
    
        # add calls here, remember to indent properly
    
    quickstart()
    
  2. Add the remaining code in the quickstart method unless otherwise specified.

Create variables for the app

Create two sets of variables: the first set you change, the second set leave as they appear in the code sample.

  1. Create variables to hold your authoring key and resource names.

    authoringKey = 'REPLACE-WITH-YOUR-ASSIGNED-AUTHORING-KEY'
    authoringResourceName = "REPLACE-WITH-YOUR-AUTHORING-RESOURCE-NAME"
    predictionResourceName = "REPLACE-WITH-YOUR-PREDICTION-RESOURCE-NAME"
    
  2. Create variables to hold your endpoints, app name, version, and intent name.

    authoringEndpoint = f'https://{authoringResourceName}.cognitiveservices.azure.com/'
    predictionEndpoint = f'https://{predictionResourceName}.cognitiveservices.azure.com/'
    
    appName = "Contoso Pizza Company"
    versionId = "0.1"
    intentName = "OrderPizzaIntent"
    

Authenticate the client

Create an CognitiveServicesCredentials object with your key, and use it with your endpoint to create an LUISAuthoringClient object.

client = LUISAuthoringClient(authoringEndpoint, CognitiveServicesCredentials(authoringKey))

Create a LUIS app

A LUIS app contains the natural language processing (NLP) model including intents, entities, and example utterances.

Create a AppsOperation object's add method to create the app. The name and language culture are required properties.

# define app basics
appDefinition = {
    "name": appName,
    "initial_version_id": versionId,
    "culture": "en-us"
}

# create app
app_id = client.apps.add(appDefinition)

# get app id - necessary for all other changes
print("Created LUIS app with ID {}".format(app_id))

Create intent for the app

The primary object in a LUIS app's model is the intent. The intent aligns's with a grouping of user utterance intentions. A user may ask a question, or make a statement looking for a particular intended response from a bot (or other client application). Examples of intentions are booking a flight, asking about weather in a destination city, and asking about contact information for customer service.

Use the model.add_intent method with the name of the unique intent then pass the app ID, version ID, and new intent name.

The intentName value is hard-coded to OrderPizzaIntent as part of the variables in the Create variables for the app section.

client.model.add_intent(app_id, versionId, intentName)

Create entities for the app

While entities are not required, they are found in most apps. The entity extracts information from the user utterance, necessary to fullfil the user's intention. There are several types of prebuilt and custom entities, each with their own data transformation object (DTO) models. Common prebuilt entities to add to your app include number, datetimeV2, geographyV2, ordinal.

It is important to know that entities are not marked with an intent. They can and usually do apply to many intents. Only example user utterances are marked for a specific, single intent.

Creation methods for entities are part of the ModelOperations class. Each entity type has its own data transformation object (DTO) model.

The entity creation code creates a machine-learning entity with subentities and features applied to the Quantity subentities.

Partial screenshot from portal showing the entity created, a machine-learning entity with subentities and features applied to the `Quantity` subentities.

# Add Prebuilt entity
client.model.add_prebuilt(app_id, versionId, prebuilt_extractor_names=["number"])

# define machine-learned entity
mlEntityDefinition = [
{
    "name": "Pizza",
    "children": [
        { "name": "Quantity" },
        { "name": "Type" },
        { "name": "Size" }
    ]
},
{
    "name": "Toppings",
    "children": [
        { "name": "Type" },
        { "name": "Quantity" }
    ]
}]

# add entity to app
modelId = client.model.add_entity(app_id, versionId, name="Pizza order", children=mlEntityDefinition)

# define phraselist - add phrases as significant vocabulary to app
phraseList = {
    "enabledForAllModels": False,
    "isExchangeable": True,
    "name": "QuantityPhraselist",
    "phrases": "few,more,extra"
}

# add phrase list to app
phraseListId = client.features.add_phrase_list(app_id, versionId, phraseList)

# Get entity and subentities
modelObject = client.model.get_entity(app_id, versionId, modelId)
toppingQuantityId = get_grandchild_id(modelObject, "Toppings", "Quantity")
pizzaQuantityId = get_grandchild_id(modelObject, "Pizza", "Quantity")

# add model as feature to subentity model
prebuiltFeatureRequiredDefinition = { "model_name": "number", "is_required": True }
client.features.add_entity_feature(app_id, versionId, pizzaQuantityId, prebuiltFeatureRequiredDefinition)

# add model as feature to subentity model
prebuiltFeatureNotRequiredDefinition = { "model_name": "number" }
client.features.add_entity_feature(app_id, versionId, toppingQuantityId, prebuiltFeatureNotRequiredDefinition)

# add phrase list as feature to subentity model
phraseListFeatureDefinition = { "feature_name": "QuantityPhraselist", "model_name": None }
client.features.add_entity_feature(app_id, versionId, toppingQuantityId, phraseListFeatureDefinition)

Put the following method above the quickstart method to find the Quantity subentity's ID, in order to assign the features to that subentity.

def get_grandchild_id(model, childName, grandChildName):
    
    theseChildren = next(filter((lambda child: child.name == childName), model.children))
    theseGrandchildren = next(filter((lambda child: child.name == grandChildName), theseChildren.children))
    
    grandChildId = theseGrandchildren.id
    
    return grandChildId

Add example utterance to intent

In order to determine an utterance's intention and extract entities, the app needs examples of utterances. The examples need to target a specific, single intent and should mark all custom entities. Prebuilt entities do not need to be marked.

Add example utterances by creating a list of ExampleLabelObject objects, one object for each example utterance. Each example should mark all entities with a dictionary of name/value pairs of entity name and entity value. The entity value should be exactly as it appears in the text of the example utterance.

Partial screenshot showing the labeled example utterance in the portal.

Call examples.add with the app ID, version ID, and the example.

# Define labeled example
labeledExampleUtteranceWithMLEntity = {
    "text": "I want two small seafood pizzas with extra cheese.",
    "intentName": intentName,
    "entityLabels": [
        {
            "startCharIndex": 7,
            "endCharIndex": 48,
            "entityName": "Pizza order",
            "children": [
                {
                    "startCharIndex": 7,
                    "endCharIndex": 30,
                    "entityName": "Pizza",
                    "children": [
                        {
                            "startCharIndex": 7,
                            "endCharIndex": 9,
                            "entityName": "Quantity"
                        },
                        {
                            "startCharIndex": 11,
                            "endCharIndex": 15,
                            "entityName": "Size"
                        },
                        {
                            "startCharIndex": 17,
                            "endCharIndex": 23,
                            "entityName": "Type"
                        }]
                },
                {
                    "startCharIndex": 37,
                    "endCharIndex": 48,
                    "entityName": "Toppings",
                    "children": [
                        {
                            "startCharIndex": 37,
                            "endCharIndex": 41,
                            "entityName": "Quantity"
                        },
                        {
                            "startCharIndex": 43,
                            "endCharIndex": 48,
                            "entityName": "Type"
                        }]
                }
            ]
        }
    ]
}

print("Labeled Example Utterance:", labeledExampleUtteranceWithMLEntity)

# Add an example for the entity.
# Enable nested children to allow using multiple models with the same name.
# The quantity subentity and the phraselist could have the same exact name if this is set to True
client.examples.add(app_id, versionId, labeledExampleUtteranceWithMLEntity, { "enableNestedChildren": True })

Train the app

Once the model is created, the LUIS app needs to be trained for this version of the model. A trained model can be used in a container, or published to the staging or product slots.

The train.train_version method needs the app ID and the version ID.

A very small model, such as this quickstart shows, will train very quickly. For production-level applications, training the app should include a polling call to the get_status method to determine when or if the training succeeded. The response is a list of ModelTrainingInfo objects with a separate status for each object. All objects must be successful for the training to be considered complete.

client.train.train_version(app_id, versionId)
waiting = True
while waiting:
    info = client.train.get_status(app_id, versionId)

    # get_status returns a list of training statuses, one for each model. Loop through them and make sure all are done.
    waiting = any(map(lambda x: 'Queued' == x.details.status or 'InProgress' == x.details.status, info))
    if waiting:
        print ("Waiting 10 seconds for training to complete...")
        time.sleep(10)
    else: 
        print ("trained")
        waiting = False

Publish app to production slot

Publish the LUIS app using the app.publish method. This publishes the current trained version to the specified slot at the endpoint. Your client application uses this endpoint to send user utterances for prediction of intent and entity extraction.

responseEndpointInfo = client.apps.publish(app_id, versionId, is_staging=False)

Authenticate the prediction runtime client

Use the credentials object with your key, and use it with your endpoint to create an LUISRuntimeClientConfiguration object.

Caution

This quickstart uses the authoring key as as part of the runtime credentials. The authoring key is allowed to query the runtime with a few queries. For staging and production-level code, replace the authoring key with a prediction runtime key.

runtimeCredentials = CognitiveServicesCredentials(authoringKey)
clientRuntime = LUISRuntimeClient(endpoint=predictionEndpoint, credentials=runtimeCredentials)

Get prediction from runtime

Add the following code to create the request to the prediction runtime.

The user utterance is part of the prediction_request object.

The get_slot_prediction method needs several parameters such as the app ID, the slot name, and the prediction request object to fulfill the request. The other options such as verbose, show all intents, and log are optional. The request returns a PredictionResponse object.

# Production == slot name
predictionRequest = { "query" : "I want two small pepperoni pizzas with more salsa" }

predictionResponse = clientRuntime.prediction.get_slot_prediction(app_id, "Production", predictionRequest)
print("Top intent: {}".format(predictionResponse.prediction.top_intent))
print("Sentiment: {}".format (predictionResponse.prediction.sentiment))
print("Intents: ")

for intent in predictionResponse.prediction.intents:
    print("\t{}".format (json.dumps (intent)))
print("Entities: {}".format (predictionResponse.prediction.entities))

The prediction response is a JSON object including the intent and any entities found.

{
    "query": "I want two small pepperoni pizzas with more salsa",
    "prediction": {
        "topIntent": "OrderPizzaIntent",
        "intents": {
            "OrderPizzaIntent": {
                "score": 0.753606856
            },
            "None": {
                "score": 0.119097039
            }
        },
        "entities": {
            "Pizza order": [
                {
                    "Pizza": [
                        {
                            "Quantity": [
                                2
                            ],
                            "Type": [
                                "pepperoni"
                            ],
                            "Size": [
                                "small"
                            ],
                            "$instance": {
                                "Quantity": [
                                    {
                                        "type": "builtin.number",
                                        "text": "two",
                                        "startIndex": 7,
                                        "length": 3,
                                        "score": 0.968156934,
                                        "modelTypeId": 1,
                                        "modelType": "Entity Extractor",
                                        "recognitionSources": [
                                            "model"
                                        ]
                                    }
                                ],
                                "Type": [
                                    {
                                        "type": "Type",
                                        "text": "pepperoni",
                                        "startIndex": 17,
                                        "length": 9,
                                        "score": 0.9345611,
                                        "modelTypeId": 1,
                                        "modelType": "Entity Extractor",
                                        "recognitionSources": [
                                            "model"
                                        ]
                                    }
                                ],
                                "Size": [
                                    {
                                        "type": "Size",
                                        "text": "small",
                                        "startIndex": 11,
                                        "length": 5,
                                        "score": 0.9592077,
                                        "modelTypeId": 1,
                                        "modelType": "Entity Extractor",
                                        "recognitionSources": [
                                            "model"
                                        ]
                                    }
                                ]
                            }
                        }
                    ],
                    "Toppings": [
                        {
                            "Type": [
                                "salsa"
                            ],
                            "Quantity": [
                                "more"
                            ],
                            "$instance": {
                                "Type": [
                                    {
                                        "type": "Type",
                                        "text": "salsa",
                                        "startIndex": 44,
                                        "length": 5,
                                        "score": 0.7292897,
                                        "modelTypeId": 1,
                                        "modelType": "Entity Extractor",
                                        "recognitionSources": [
                                            "model"
                                        ]
                                    }
                                ],
                                "Quantity": [
                                    {
                                        "type": "Quantity",
                                        "text": "more",
                                        "startIndex": 39,
                                        "length": 4,
                                        "score": 0.9320932,
                                        "modelTypeId": 1,
                                        "modelType": "Entity Extractor",
                                        "recognitionSources": [
                                            "model"
                                        ]
                                    }
                                ]
                            }
                        }
                    ],
                    "$instance": {
                        "Pizza": [
                            {
                                "type": "Pizza",
                                "text": "two small pepperoni pizzas",
                                "startIndex": 7,
                                "length": 26,
                                "score": 0.812199831,
                                "modelTypeId": 1,
                                "modelType": "Entity Extractor",
                                "recognitionSources": [
                                    "model"
                                ]
                            }
                        ],
                        "Toppings": [
                            {
                                "type": "Toppings",
                                "text": "more salsa",
                                "startIndex": 39,
                                "length": 10,
                                "score": 0.7250252,
                                "modelTypeId": 1,
                                "modelType": "Entity Extractor",
                                "recognitionSources": [
                                    "model"
                                ]
                            }
                        ]
                    }
                }
            ],
            "$instance": {
                "Pizza order": [
                    {
                        "type": "Pizza order",
                        "text": "two small pepperoni pizzas with more salsa",
                        "startIndex": 7,
                        "length": 42,
                        "score": 0.769223332,
                        "modelTypeId": 1,
                        "modelType": "Entity Extractor",
                        "recognitionSources": [
                            "model"
                        ]
                    }
                ]
            }
        }
    }
}

Run the application

Run the application with the python command on your quickstart file.

python authoring_and_predict.py

Clean up resources

You can delete the app from the LUIS portal and delete the Azure resources from the Azure portal.

Troubleshooting

  • Authenticating to the client library - authentication errors usually indicate that the wrong key & endpoint were used. This quickstart uses the authoring key and endpoint for the prediction runtime, as a convenience but will only work if you haven't already used the monthly quota. If you can't use the authoring key and endpoint, you need to use the prediction runtime key and endpoint when accessing the prediction runtime SDK client library.
  • Creating entities - if you get an error creating the nested machine-learning entity used in this tutorial, make sure you copied the code and didn't alter the code to create a different entity.
  • Creating example utterances - if you get an error creating the labeled example utterance used in this tutorial, make sure you copied the code and didn't alter the code to create a different labeled example.
  • Training - if you get a training error, this usually indicates an empty app (no intents with example utterances), or an app with intents or entities that are malformed.
  • Miscellaneous errors - because the code calls into the client libraries with text and JSON objects, make sure you haven't changed the code.

Other errors - if you get an error not covered in the preceding list, let us know by giving feedback at the bottom on this page. Include the programming language and version of the client libraries you installed.

Next steps