Search code examples
c#asp.netjsonbotframeworkazure-language-understanding

How can I access an entities score information and or existence from the luis.ai RecognizerAsync method which returns the RecognizerResult


The sample bot built through azure has a basis from this documentation

https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-howto-v4-luis?view=azure-bot-service-4.0&tabs=csharp

I am trying to refactor parts of the functionality of the dialog and I need access to parts of the json that I assume should come back from the luis call. However, when I try to access from $instance I get an error that I cannot access child elements of the response.

Here is an exmaple of the json:

+       Entities    {{
  "$instance": {
    "To": [
      {
        "startIndex": 10,
        "endIndex": 15,
        "text": "paris",
        "type": "To",
        "score": 0.987954
      }
    ]
  },
  "To": [
    {
      "$instance": {
        "Airport": [
          {
            "startIndex": 10,
            "endIndex": 15,
            "text": "paris",
            "type": "Airport"
          }
        ]
      },
      "Airport": [
        [
          "Paris"
        ]
      ]
    }
  ]
}}  Newtonsoft.Json.Linq.JObject

Here is the code accessing the json:

bookingDetails.Origin = recognizerResult.Entities["From"]?.FirstOrDefault()?["Airport"]?.FirstOrDefault()?.FirstOrDefault()?.ToString();

I understand how this accesses the Entity from luis.ai call but how can I access the other parts of the json response?

As well, is there a way to access whether or not an entity came back for the intent in general such as a bool valued response?

Lastly, accessing the json in general via the above method seems not ideal. Is there a more formatted way to access what would be the json return and with the new asp.net core 2+ is there a way to do it without using newtonsoft?


Solution

  • You are correct that accessing the JSON via the above method is not ideal. What I would do it use a tool such as QuickType to create a class from JSON, or at least the basis of a class that you can tweak. You can then use the NewtonSoft JSON library (or an alternative JSON library since you don't want to use NewtonSoft) to Deserialize the JSON into an object and access the Score property of the object.

    Alternatively, as shown in the guide that you linked you can obtain the score from the GetTopScoringIntent method call.

    Regarding checking if any entities were returned you can plug the JSON shown on the LUIS API reference page under the 200 response into the quicktype tool I linked above to create a class then check against the Entities collection to see if it has any items - you could use LINQs .Any() method for this.


    Edit

    The OP ended up using LUISGen to output a class to deserialize the response from the LUIS API.

    1. Go to the LUIS portal.
    2. Navigate into the relevant LUIS app.
    3. Go the the Manage tab.
    4. On the left, select the Versions item.
    5. Check the box next to the version you want to export.
    6. From the dropdown, select Export as JSON.
    7. Save the JSON into the root directory of your project.
    8. Open a command prompt in the root directory of your project.
    9. Run the following commands:
    dotnet tool install -g LUISGen
    
    LUISGen <exported-luis-app>.json -cs ClassToGenerate -o
    
    1. Add the generated file to your project in Visual Studio.
      • Right click on the project > Add existing item
    2. Using the generated class in code:
    var result = recognizer.Recognize<ClassToGenerate>("<user-input-text>", CancellationToken.None);