0

[ LuisIntent("")]属性使用ILuisService根据LUISModel属性的值查询 LUIS,然后找出得分最高的意图并匹配重写的MessageRecievedAsync方法中的IntentHandler Delegate,并在以下方法中动态加载 LUISResult而调试继承自LuisDialog的类。

public async Task None(IDialogContext context, LuisResult result)
{
  //some stuff
}

我的问题是如何制作一个自定义属性,将其映射到正确的意图处理程序。

我正在尝试将 RASA NLU 服务与 C# 中的 Microsoft Bot Framework 一起用作我的 NLP 引擎。

我正在尝试将从查询 RASA NLU 以获取 LUISResult 类型 JSON 的 HttpClient.GetAsync() 方法获得的 LUISEmulatedResult 映射到遵循此委托的方法。

我取得的进展:

[RASAIntentAttribute("IntentName")]

using Microsoft.Bot.Builder.Dialogs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;

namespace DemoFlightRASA.Models
{
    public class RASAIntentAttribute : Attribute
    {
        private readonly string _intentName;

        public RASAIntentAttribute(string IntentName)
        {
            this._intentName = IntentName;
        }

        //The intent handler delegate
        //Now I want to map LUISEmulatedResult which I get from HttpClient.GetAsync() method to a method which follows this delegate
        public delegate Task RASAIntentHandler(IDialogContext context, LUISEmulatedResult result);


    }
}

LUISEmulatedResult 模型类:

namespace DemoFlightRASA.Models
{
    public class LUISEmulatedResult
    {
        public string query { get; set; }
        public Topscoringintent topScoringIntent { get; set; }
        public Intent[] intents { get; set; }
        public Entity[] entities { get; set; }
    }

    public class Topscoringintent
    {
        public string intent { get; set; }
        public float score { get; set; }
    }

    public class Intent
    {
        public string intent { get; set; }
        public float score { get; set; }
    }

    public class Entity
    {
        public string entity { get; set; }
        public string type { get; set; }
        public int startIndex { get; set; }
        public int endIndex { get; set; }
        public Resolution resolution { get; set; }
        public float score { get; set; }
    }

    public class Resolution
    {
        public string[] values { get; set; }
    }

}

我也试过这个,但这似乎不起作用

我想创建一个端到端的流程,它在机器人框架中使用 RASA NLU 而不是 LUIS。我已经准备好 RASA NLU 端点,只是无法创建 RASAIntentAttribute。

任何关于如何将委托映射到方法的指针、提示、教程、代码片段都将不胜感激。谢谢你。

4

1 回答 1

1

注意:我认为您不能将委托作为属性参数:是否可以将委托作为属性参数?您打算如何使用 RASAIntentHandler 委托?

.net Bot Framework sdk 使用反射来确定 LuisDialog 中的哪些方法是意图处理程序:https ://github.com/Microsoft/BotBuilder/blob/b6cd3ff85e8dc57ac586a11db489a0c75c635ae2/CSharp/Library/Microsoft.Bot.Builder/Dialogs/LuisDialog.cs #L362

public static IEnumerable<KeyValuePair<string, IntentActivityHandler>> EnumerateHandlers(object dialog)
        {
            var type = dialog.GetType();
            var methods = type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
            foreach (var method in methods)
            {
                var intents = method.GetCustomAttributes<LuisIntentAttribute>(inherit: true).ToArray();
                IntentActivityHandler intentHandler = null;

                try
                {
                    intentHandler = (IntentActivityHandler)Delegate.CreateDelegate(typeof(IntentActivityHandler), dialog, method, throwOnBindFailure: false);
                }
                catch (ArgumentException)
                {
                    // "Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type."
                    // https://github.com/Microsoft/BotBuilder/issues/634
                    // https://github.com/Microsoft/BotBuilder/issues/435
                }

                // fall back for compatibility
                if (intentHandler == null)
                {
                    try
                    {
                        var handler = (IntentHandler)Delegate.CreateDelegate(typeof(IntentHandler), dialog, method, throwOnBindFailure: false);

                        if (handler != null)
                        {
                            // thunk from new to old delegate type
                            intentHandler = (context, message, result) => handler(context, result);
                        }
                    }
                    catch (ArgumentException)
                    {
                        // "Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type."
                        // https://github.com/Microsoft/BotBuilder/issues/634
                        // https://github.com/Microsoft/BotBuilder/issues/435
                    }
                }

                if (intentHandler != null)
                {
                    var intentNames = intents.Select(i => i.IntentName).DefaultIfEmpty(method.Name);

                    foreach (var intentName in intentNames)
                    {
                        var key = string.IsNullOrWhiteSpace(intentName) ? string.Empty : intentName;
                        yield return new KeyValuePair<string, IntentActivityHandler>(intentName, intentHandler);
                    }
                }
                else
                {
                    if (intents.Length > 0)
                    {
                        throw new InvalidIntentHandlerException(string.Join(";", intents.Select(i => i.IntentName)), method);
                    }
                }
            }
        }

这是 LuisDialog 中的代码,它调用与从 LUIS 返回的 IntentRecommendation 中的最佳意图相对应的处理程序:https ://github.com/Microsoft/BotBuilder/blob/b6cd3ff85e8dc57ac586a11db489a0c75c635ae2/CSharp/Library/Microsoft.Bot.Builder/Dialogs /LuisDialog.cs#L252

protected virtual async Task DispatchToIntentHandler(IDialogContext context,
                                                            IAwaitable<IMessageActivity> item,
                                                            IntentRecommendation bestIntent,
                                                            LuisResult result)
        {
            if (this.handlerByIntent == null)
            {
                this.handlerByIntent = new Dictionary<string, IntentActivityHandler>(GetHandlersByIntent());
            }

            IntentActivityHandler handler = null;
            if (result == null || !this.handlerByIntent.TryGetValue(bestIntent.Intent, out handler))
            {
                handler = this.handlerByIntent[string.Empty];
            }

            if (handler != null)
            {
                await handler(context, item, result);
            }
            else
            {
                var text = $"No default intent handler found.";
                throw new Exception(text);
            }
        }

这就是将 LUIS 结果映射到在 LUISDialogs 上用 LUISIntentAttribute 标记的方法的方式。此功能或类似功能需要在 RASA 实现中。

于 2017-11-14T00:42:54.360 回答