【问题标题】:How do you get to the original message text in a Microsoft Bot Framework LuisIntent method如何在 Microsoft Bot Framework LuisIntent 方法中获取原始消息文本
【发布时间】:2016-04-07 16:51:25
【问题描述】:

我正在尝试从LuisDialog 中标记为LuisIntent 的方法中访问完整的原始文本。

文档显示这些方法采用两个参数:

IDialogContext context, LuisResult result

两者都没有公开暴露消息的原始文本。上下文对象确实包含消息,但位于不可访问的私有属性 (context.data.message.text) 中。

有没有办法在context 中访问它,或者可以将它传递到对话框构造函数中?

【问题讨论】:

    标签: c# botframework azure-language-understanding


    【解决方案1】:

    在新版本的 Bot Framework (1.0.2) 中,LuisResult 对象现在有一个 Query 参数,其中包含发送到 LUIS 的原始查询。

    【讨论】:

      【解决方案2】:

      您可以覆盖 LuisDialog 的 MessageReceived(...) 函数,将您需要的消息字段保留为成员变量,并在您的意图处理程序中访问这些字段。下面我修改了 SimpleAlarmDialog 以展示如何在其中一个意图处理程序中访问“message.Text”:

      [LuisModel("c413b2ef-382c-45bd-8ff0-f76d60e2a821", "6d0966209c6e4f6b835ce34492f3e6d9")]
      [Serializable]
      public class SimpleAlarmDialog : LuisDialog<object>
      {
          private readonly Dictionary<string, Alarm> alarmByWhat = new Dictionary<string, Alarm>();
      
          [Serializable]
          public class PartialMessage
          {
              public string Text { set; get; }
          }
      
          private PartialMessage message;
      
          protected override async Task MessageReceived(IDialogContext context, IAwaitable<Message> item)
          {
              var msg =  await item;
              this.message = new PartialMessage { Text = msg.Text };
              await base.MessageReceived(context, item);
          }
      
          [LuisIntent("builtin.intent.alarm.delete_alarm")]
          public async Task DeleteAlarm(IDialogContext context, LuisResult result)
          {
              await context.PostAsync($"echo: {message.Text}");
              Alarm alarm;
              if (TryFindAlarm(result, out alarm))
              {
                  this.alarmByWhat.Remove(alarm.What);
                  await context.PostAsync($"alarm {alarm} deleted");
              }
              else
              {
                  await context.PostAsync("did not find alarm");
              }
      
              context.Wait(MessageReceived);
          }
      }
      

      【讨论】:

      • 尽管 1.0.2 版本的 Bot Framework 添加了消息文本,但它仍然不包括控制器的消息对象中包含的所有附加信息,ConversationId 等。这允许我添加我需要的任何其他字段。谢谢!
      • 虽然这适用于 Bot Framework 的 V1,但对于 V3 似乎失败了。如果您尝试覆盖异步方法,它会在调用 base.MessageReceived 时返回内部服务器错误。
      【解决方案3】:

      如果你闯入这个方法,你可以在快速观察中看到上下文对象有一个非公共属性到 context.data.mesage.Text(注意“mesage”的拼写错误)。由于该属性是非公开的,因此您可以通过反射来作弊(参见 How to get the value of private field in C#? 中的 GetInstanceField)

              Microsoft.Bot.Builder.Dialogs.Internals.JObjectBotData data = GetInstanceField(typeof (Microsoft.Bot.Builder.Dialogs.Internals.DialogContext), context, "data") as Microsoft.Bot.Builder.Dialogs.Internals.JObjectBotData;            
              Microsoft.Bot.Connector.Message originalMessage = GetInstanceField(typeof(Microsoft.Bot.Builder.Dialogs.Internals.JObjectBotData), data, "mesage") as Microsoft.Bot.Connector.Message;
              string originalMessageText = originalMessage.Text;
      

      【讨论】:

        【解决方案4】:

        您可以通过使用 LuisResult 的 Query 属性来做到这一点,

        [LuisIntent(intentName: "someIntentName")]
        private async Task Eligibility(IDialogContext context, LuisResult result)
         {
           await context.PostAsync($"The original text is: {result.Query}");
           context.Wait(MessageReceivedAsync);
        }
        

        【讨论】:

          猜你喜欢
          • 2023-03-06
          • 1970-01-01
          • 1970-01-01
          • 2017-04-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-05
          • 1970-01-01
          相关资源
          最近更新 更多