【问题标题】:How can I properly prompt a user without having LUIS attempt to recognize the response?如何在不让 LUIS 尝试识别响应的情况下正确提示用户?
【发布时间】:2018-05-19 13:11:18
【问题描述】:

我有一个配置了 LUIS 意图识别器的机器人,虽然初始根对话框在 LUIS 识别出意图时按预期启动,但如果我从该对话框中提示用户,则用户发回的响应不会恢复暂停的对话框而是通过 LUIS 识别器发回并完全开始一个新的对话框。

这是我的机器人设置:

const connector = new builder.ChatConnector({
  appId: config.get('bot.id'),
  appPassword: config.get('bot.secret')
})

super(connector, (session) => this.help(session))

this.set('storage', new BotStorage())

this.use(builder.Middleware.sendTyping(), new MessageSanitizer())

this.on('conversationUpdate', (message: any) => {
  console.log(message)
})

const recognizer = new builder.LuisRecognizer(config.get('bot.model'))
this.recognizer(recognizer)

我的对话设置:

    this.dialog('/send', [(session, context, next) => {
  const amount = builder.EntityRecognizer.findEntity(context.intent.entities, 'builtin.currency')
  const recipient = builder.EntityRecognizer.findEntity(context.intent.entities, 'recipient')
  const product = builder.EntityRecognizer.findEntity(context.intent.entities, 'product')

  session.send('Sure, I can do that.')
  session.beginDialog('/send/product', product ? product.entity : null)
}]).triggerAction({
  matches: 'send'
})

this.dialog('/send/product', [(session, query, next) => {
  if (query) {
    session.dialogData.productQuery = query
    next()
  } else {
    builder.Prompts.text(session, 'What type of product did you want to send?')
  }
}, (session, results) => {
  if (results && results.response) {
    session.dialogData.productQuery = results.response
  }

  session.sendTyping()
  ProductService.search(session.dialogData.productQuery).then(products => {
    if (!products.length) {
      session.send('Sorry, I couldn\'t find any products by that name.')
      session.replaceDialog('/send/product')
    }

    const attachments = products.map(product => {
      const image = builder.CardImage.create(session, product.configuration.image)
      const valueLine = `$${product.value.min} - $${product.value.max}`

      const card = new builder.HeroCard(session)
        .title(product.name)
        .images([image])
        .text(product.description)
        .subtitle(valueLine)
        .tap(builder.CardAction.postBack(session, product.id))

      return card
    })

    const message = new builder.Message(session)
      .text('Okay, I found the following products. Please select the one you\'d like to send.')
      .attachments(attachments)
      .attachmentLayout(builder.AttachmentLayout.carousel)

    builder.Prompts.text(session, message)
  }).catch((err: Error) => {
    session.error(err)
  })
}, (session, response, next) => {
  console.log(response)
}])

根据下面回复的建议,我还尝试将识别器设置为 IntentDialog 的一部分,而不是在机器人本身上,然后将后续对话框映射到该根对话框,如下所示:

const recognizer = new builder.LuisRecognizer(config.get('bot.model'))
this.intents = new builder.IntentDialog({ recognizers: [recognizer] })

this.intents.matches('send', '/send')

this.dialog('/', this.intents)
this.dialog('/send', [(session, context, next) => {
  const amount = builder.EntityRecognizer.findEntity(context.entities, 'builtin.currency')
  const recipient = builder.EntityRecognizer.findEntity(context.entities, 'recipient')
  const product = builder.EntityRecognizer.findEntity(context.entities, 'product')

  session.send('Sure, I can do that.')
  session.beginDialog('/send/product', product ? product.entity : null)
}, (session) => {
  console.log('hello')
}])

但是,这没有帮助,我仍然收到以下错误:

/ - WARN: IntentDialog - 没有找到 None 的意图处理程序

表明响应正在尝试匹配新的意图,而不是恢复暂停的对话。

与机器人交互的示例说明了此问题:

“打字”指示器将无限期地继续下去,因为它试图匹配“无”意图但不存在。

【问题讨论】:

    标签: node.js botframework


    【解决方案1】:

    triggerAction 中的匹配项将优先,因为机器人收到的每条消息都是通过路由系统发送的。您可以对其进行自定义,但您也可以尝试使用IntentDialog 将您的一些流程与其隔离。

    更多:Botframework No Interruptions from other Intent Dialogs until done with current Intent Dialog

    【讨论】:

    • 嘿,修改了原始帖子以包含我从您的建议中获得的发现。感谢您的回复!
    • @DavidK,你能分享一下用户话语和机器人响应的顺序吗?
    【解决方案2】:

    在最新的 SDK 中,您无需使用 IntentDialog 即可实现此目的。您所要做的就是在LuisRecognizer 上使用.onEnabled,而无需修改任何现有对话框:

    var recognizer = new builder.LuisRecognizer(url) 
        .onEnabled(function (context, callback) {
            // LUIS is only ON when there are no tasks pending(e.g. Prompt text) 
            var enabled = context.dialogStack().length === 0; 
            callback(null, enabled); 
        });
    

    【讨论】:

      猜你喜欢
      • 2013-12-12
      • 1970-01-01
      • 2011-07-19
      • 1970-01-01
      • 1970-01-01
      • 2011-02-19
      • 2021-11-20
      • 1970-01-01
      相关资源
      最近更新 更多