如何在 IRecognizerConvert 中反序列化 luis 实体

How to deserialize luis entity in IRecognizerConvert

在 Luis 中,我用一个简单的实体创建了一个简单的模式,如下所示:

list bots {Name}

其中 "Name" 是我希望在 C# 中获得的实体。模式和意图工作正常,我理解正确。

我按照官方示例构建了一个 IRecognizerConvert class 因此我可以反序列化结果。它很好地反序列化了意图,但未能反序列化实体。

在 _Entities 子 class 中,我只有要反序列化的 "Name" 变量,没有其他任何东西。我没有任何其他部分class。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Bot.Builder;
using Newtonsoft.Json;
using Microsoft.Bot.Builder.AI.Luis;

namespace EmptyBot1.Models
{
    public class ChatbotIntent : IRecognizerConvert
    {
        public string Text;
        public string AlteredText;
        public enum Intent
        {
            CreateBot,
            ListBots,
            ListAllBots,
            RunBot,
            Cancel,
            Greet,
            None
        };
        public Dictionary<Intent, IntentScore> Intents;

        public class _Entities
        {
            public string Name;
        }
        public _Entities Entities;

        [JsonExtensionData(ReadData = true, WriteData = true)]
        public IDictionary<string, object> Properties { get; set; }

        public void Convert(dynamic result)
        {
            var _result = JsonConvert.DeserializeObject<ChatbotIntent>(JsonConvert.SerializeObject(result, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }));
            Text = _result.Text;
            AlteredText = _result.AlteredText;
            Intents = _result.Intents;
            Entities = _result.Entities;
            Properties = _result.Properties;
        }

        public (Intent intent, double score) TopIntent()
        {
            Intent maxIntent = Intent.None;
            var max = 0.0;
            foreach (var entry in Intents)
            {
                if (entry.Value.Score > max)
                {
                    maxIntent = entry.Key;
                    max = entry.Value.Score.Value;
                }
            }
            return (maxIntent, max);
        }
    }
}

在前面的代码片段中,重要的部分是 _Entities class,它定义了从 Luis 返回时实体的外观。由于我只有 1 个简单的字符串实体 "Name",我认为这就足够了。

        public class _Entities
        {
            public string Name;
        }

然而,当我 运行 它并且我给它一个像这样的话语时:

"list bots mybots"

Luis 会正确地分配 Name="mybots" 并获得正确的意图,但它在 JsonConvert.DeserializeObject 行崩溃并指出 json 格式不正确。我想这是在抱怨我做的class?而不是来自 luis?

的实际 JSON 结果

我需要向 _Entities 添加什么 class 才能成功反序列化 luis 实体?

按照@ranusharao 的建议,使用 LUISGen 工具,将自动生成一个 class 与 bot 框架一起工作。

我知道这是一个老问题,但我现在面临着同样的情况,所以我想按照对我有用的步骤做出贡献。 正如@ranusharao 和 Bill 所说,您需要下载 LUISGen from GitHub。 启动 CMD,转到您的解决方案目录

cd C:\MySolutionFolder

和运行

luis init

如果您还没有完成。 它会询问您的 App ID 和您在 luis.ai 中获得的信息。 之后,转到 luis.ai / 管理 / 版本,单击您当前的版本,然后单击导出为 Json。 将 JSON 文件放在解决方案的文件夹中。 完成后,运行 在控制台中执行以下命令:

LUISGen C:\MyJSONPath\MyBot.json -cs MyClassName -o C:\MySolutionFolder

-cs 代表 C#,但如果您使用 Typescript,则将其更改为“-ts”。 所以你有它,你可以访问你的 class 像这样:

var result = await _luisRecognizerService._recognizer.RecognizeAsync<MyClassName>(turnContext, cancellationToken);
Console.WriteLine(result.Entities.Producto);

_luisRecognizerService 是我的 LuisRecognizer 实例(依赖注入)