Reconnaître les commandes

Lors du développement de robots pour Telegram et d'autres messagers, la tâche de reconnaître et de répondre aux demandes exprimées en langage humain se pose périodiquement. C'est cette "fonctionnalité", selon certains avis, qui est la principale différence entre les bots et les applications en ligne de commande. Sous la coupe, un cadre propriétaire pour l'exécution de commandes vocales arbitraires est décrit. Les descriptions des concepts clés sont accompagnées d'exemples en langage Kotlin.





Prenons les représentations sémantiques normalisées comme base pour la reconnaissance vocale. Leur choix est principalement dû à la simplicité et la facilité de mise en œuvre. Commençons par les bases, un exemple tiré des sources du framework :





/**      */
typealias Rule = (String) -> Boolean

/**    */
open class Semnorm(vararg val rules: Rule)

/**       */
fun stem(vararg stems: String): Rule = { stems.any(it::startsWith) }

/**        */
fun word(vararg words: String): Rule = { words.any(it::equals) }

/**      */
fun String.matches(norm: Semnorm) = norm.rules.any { it(this) }
      
      



Nous avons maintenant la possibilité de définir des représentations sémantiques normalisées prédéfinies sous forme d'objets :





object Day : Semnorm(stem("day", "", "", "", "", ""))
      
      



Le cadre les met en ligne avec les jetons des phrases entrantes, et la phrase commence à ressembler à ceci :





assertThat(
  "   5 ".tokenize(), 
  equalTo(
   listOf(
     Token("", Ban), 
     Token("", null),
     Token("", null), 
     Token("5", Number),
     Token("", Minute)
   )
  )
)
      
      



Nous avons traité de la reconnaissance vocale. Le code tokenizer est joint dans le référentiel disponible à la fin de l'article. Passons à l'exécution des commandes du discours. Et c'est là que commence la chose la plus intéressante : le framework permet à chaque représentation sémantique d'accrocher le comportement spécifié. Encore une fois, l'exemple le plus simple de la façon de reconnaître une demande d'aide en deux langues :





object Help : ExecutableSemnorm(stem(
  "", "", "", "help", 
  "rule", "faq", "start", "",
)) {
  override fun execute(bot: Bot, m: Message) {
    val faq = message.from.relatedFaq()
    bot.sendMessage(m.chat.id, faq)
  }
}
      
      



, ? , , , , :





object Ban : DurableSemonrm(stem(
  "ban", "block", "mute", "", "",
  "", "", "",
)) {
  override fun execute(
    bot: Bot, attackerMessage: Message, duration: Duration) {

    val victimMessage = attackerMessage.replyToMessage
    val victimId = victimMessage.from.id
    val untilSecond = now().epochSecond + duration.inWholeSeconds

    bot.restrictChatMember(
      attackerMessage.chat.id, victimId, untilSecond)
  }
}
      
      



? , . , :





object Week : Semnorm(stem("week", "")) {
  override fun toDuration(number: Long) = 
    days(number) * 7
}
      
      



, :





class DurableSemnorm(vararg rules: Rule) : ExecutableSemnorm(*rules) {

  final override fun execute(
    token: Iterator<Token>, bot: Bot, m: Message) = 
      execute(bot, message, token.parseDuration())

  abstract fun execute(bot: Bot, m: Message, duration: Duration)
}
      
      



, . . , , Github.








All Articles