📜 ⬆️ ⬇️

The robot, which does answer the question about the weather in Tokyo (in fact - no, but close)

Actually, after one of the recent @IBM posts , an idea arose to cross the hedgehog with Dialog with the Natural Language Classifier . And here is Tokyo? And if it is possible to define it as an entity of the “city” type in the dialog and save it in a profile for processing. However, it will not receive the weather under the cut. However, in theory, you can attach the processing of the corresponding "team".

Before you begin, you will need to register with Bluemix , create an application, and get credentials for Dialog and Natural Language Classifer. The application itself may be local.

The code of the resulting library (on Kotlin, should be easily combined with Java and, probably, other languages ​​on the JVM platform) - here . The binary build is here (by the way, where is it better to drop it? CVS is still about the source code). In short, the main points:


Sample script code is shown below. Please note - references to classes in input / grammar are designed as [class name]:
')
Lots of xml
<? xml version = "1.0" encoding = "UTF-8"?>
<dialog xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi: noNamespaceSchemaLocation = "WatsonDialogDocument_1.0.xsd">
<flow>
<folder label = "Main">
<output>
<prompt selectionType = "RANDOM">
<item> Hello, I'm chatting and can tell you about weather. </ item>
</ prompt>
<goto ref = "introSearch" />
</ output>
<output>
<prompt selectionType = "RANDOM">
<item> Goodbye. </ item>
</ prompt>
<getUserInput id = "introSearch">
<search ref = "introSearchFolder" />
<default>
<output>
<prompt selectionType = "RANDOM">
<item> I don't understand you. </ item>
</ prompt>
</ output>
</ default>
</ getUserInput>
</ output>
</ folder>
<folder label = "Library">
<folder id = "introSearchFolder" label = "Live Content">
<input>
<grammar>
<item> [temperature] * </ item>
</ grammar>

<input>
<grammar>
<item> $ (City) = {City} </ item>
</ grammar>
<output>
<prompt selectionType = "SEQUENTIAL">
<item> I processed your request. Temperature in [Text: $ City] is [Temperature: $ City] </ item>
</ prompt>
</ output>
</ input>
<input>
<grammar>
<item> * </ item>
</ grammar>
<output>
<prompt selectionType = "SEQUENTIAL">
<item> Send a city name. </ item>
</ prompt>
<getUserInput id = "temperatureCitySelectionInput">
<search ref = "temperatureCitySelectionSearch" />
<default>
<output>
<prompt selectionType = "RANDOM">
<item> I can't process this request. </ item>
</ prompt>
</ output>
</ default>
</ getUserInput>
</ output>
</ input>
</ input>

<input>
<grammar>
<item> [conditions] * </ item>
</ grammar>

<input>
<grammar>
<item> $ (City) = {City} </ item>
</ grammar>
<output>
<prompt selectionType = "SEQUENTIAL">
<item> I processed your request. Conditions in [Text: $ City] is [Conditions: $ City] </ item>
</ prompt>
</ output>
</ input>
<input>
<grammar>
<item> * </ item>
</ grammar>
<output>
<prompt selectionType = "SEQUENTIAL">
<item> Send a city name. </ item>
</ prompt>
<getUserInput id = "conditionsCitySelectionInput">
<search ref = "conditionsCitySelectionSearch" />
<default>
<output>
<prompt selectionType = "RANDOM">
<item> I can't process your request </ item>
</ prompt>
</ output>
</ default>
</ getUserInput>
</ output>
</ input>
</ input>
</ folder>

<folder id = "temperatureCitySelectionSearch" label = "Live Content">
<input>
<grammar>
<item> $ (City) = {City} </ item>
</ grammar>
<output>
<prompt selectionType = "SEQUENTIAL">
<item> I processed your request. Temperature in [Text: $ City] is [Temperature: $ City] </ item>
</ prompt>
</ output>
</ input>
</ folder>

<folder id = "conditionsCitySelectionSearch" label = "Live Content">
<input>
<grammar>
<item> $ (City) = {City} </ item>
</ grammar>
<output>
<prompt selectionType = "SEQUENTIAL">
<item> I processed your request. Conditions in [Text: $ City] is [Conditions: $ City] </ item>
</ prompt>
</ output>
</ input>
</ folder>
</ folder>
<folder label = "Global" />
<folder label = "Concepts" />
</ flow>
<entities>
<entity name = "City">
<value name = "Tokyo" value = "Tokyo">
<grammar>
<item> Tokyo </ item>
</ grammar>
</ value>
<value name = "Ottawa" value = "Ottawa">
<grammar>
<item> Ottawa </ item>
</ grammar>
</ value>
<value name = "Moscow" value = "Moscow">
<grammar>
<item> Moscow </ item>
</ grammar>
</ value>
</ entity>
</ entities>
<variables>
<var_folder name = "Home">
<var name = "City" type = "TEXT" />
</ var_folder>
</ variables>
<settings />
<specialSettings />
<classes>
<class name = "conditions">
<item> Is it windy? </ item>
<item> Will it rain today? </ item>
<item> What are the chances for rain? </ item>
<item> Will we get snow? </ item>
<item> Are we expecting sunny? </ item>
<item> Is it overcast? </ item>
<item> Will it be cloudy? </ item>
<item> How much rain will fall today? </ item>
<item> How much snow are we expecting? </ item>
<item> Is it windy outside? </ item>
<item> How much snow do we expect? </ item>
<item> Is the forecast for snow today? </ item>
<item> Will we see some sun? </ item>
<item> When will the rain subside? </ item>
<item> Is it cloudy? </ item>
<item> Is it sunny now? </ item>
<item> Will it rain? </ item>
<item> Will we have much snow? </ item>
<item> Are the winds dangerous? </ item>
<item> What is the expected snowfall today? </ item>
<item> Will it be dry? </ item>
<item> Will it be breezy? </ item>
<item> Will it be humid? </ item>
<item> What is today's expected humidity? </ item>
<item> Will the blizzard hit us? </ item>
<item> Is it drizzling? </ item>
</ class>
<class name = "temperature">
<item> How hot is it today? </ item>
<item> Is it hot outside? </ item>
<item> Will it be uncomfortably hot? </ item>
<item> Will it be sweltering? </ item>
<item> How cold is it today? </ item>
<item> Is it cold outside? </ item>
<item> Will it be uncomfortably cold? </ item>
<item> Will it be frigid? </ item>
<item> What is the high for today? </ item>
<item> What is the expected temperature? </ item>
<item> Will high temperatures be dangerous? </ item>
<item> Is it dangerously cold? </ item>
<item> When will the heat subside? </ item>
<item> Is it hot? </ item>
<item> Is it cold? </ item>
<item> How cold is it now? </ item>
<item> Will we have a cold day today? </ item>
<item> When will the cold subside? </ item>
<item> What highs are we expecting? </ item>
<item> What are we expecting? </ item>
<item> Is it warm? </ item>
<item> Is it chilly? </ item>
<item> What's the current temp in Celsius? </ item>
<item> What is the temperature in Fahrenheit? </ item>
</ class>
</ classes>
</ dialog>

As you can see, the scripts define the classes [temperature, conditions] and the type of the City entity with possible values ​​[Tokyo, Ottava, Moscow].

An example of code that will start the training and will issue an “introductory” message upon its completion:

Source code
package com.alex4321.botdemo import com.alex4321.bot.* fun main(args: Array<String>) { if (args.size != 7 && args.size != 6) { println("Need arguments [path, dialogUsername, dialogPassword, nlcUsername, nlcPassword, dialogID, nlcID] or " + "[path, dialogUsername, dialogPassword, nlcUsername, nlcPassword, robotName]") return } val path = args[0] val dialogUsername = args[1] val dialogPassword = args[2] val nlcUsername = args[3] val nlcPassword = args[4] val robotName = if (args.size == 6) { args[5] } else { "" } val dialogId = if (args.size == 7) { args[5] } else { "" } val nlcId = if (args.size == 7) { args[6] } else { "" } val new = dialogId == "" && nlcId == "" val code = WatsonProgramPath(path).read() val program = WatsonNlcDialogProgram(code) val auth = WatsonRobotAuth(dialogUsername, dialogPassword, nlcUsername, nlcPassword) val robot = WatsonRobot(program, dialogId, nlcId, auth) if (new) { robot.train(robotName) print("Dialog ID : ") println(robot.dialogID) print("NLC ID : ") println(robot.nlcID) println("Training") while (! robot.available) { Thread.sleep(10000) } } println("Ready") val conversation = robot.converse() val intro =conversation.intro() println(intro.response) println(intro.profile) } 


To get started, you need to pass arguments:


After starting and learning (not the fastest process, yes) we get something like:

 Dialog ID : 93791233-53fb-42c7-8581-6bc2bb761e6a NLC ID : 2374f9x68-nlc-7617 Training Ready [Hello, I'm Watson-based chatbot and can tell you about weather.] {} 

Add user input:

Source code
 package com.alex4321.botdemo import com.alex4321.bot.* fun main(args: Array<String>) { if (args.size != 7 && args.size != 6) { println("Need arguments [path, dialogUsername, dialogPassword, nlcUsername, nlcPassword, dialogID, nlcID] or " + "[path, dialogUsername, dialogPassword, nlcUsername, nlcPassword, robotName]") return } val path = args[0] val dialogUsername = args[1] val dialogPassword = args[2] val nlcUsername = args[3] val nlcPassword = args[4] val robotName = if (args.size == 6) { args[5] } else { "" } val dialogId = if (args.size == 7) { args[5] } else { "" } val nlcId = if (args.size == 7) { args[6] } else { "" } val new = dialogId == "" && nlcId == "" val code = WatsonProgramPath(path).read() val program = WatsonNlcDialogProgram(code) val auth = WatsonRobotAuth(dialogUsername, dialogPassword, nlcUsername, nlcPassword) val robot = WatsonRobot(program, dialogId, nlcId, auth) if (new) { robot.train(robotName) print("Dialog ID : ") println(robot.dialogID) print("NLC ID : ") println(robot.nlcID) println("Training") while (! robot.available) { Thread.sleep(10000) } } println("Ready") val conversation = robot.converse() val intro = conversation.intro() println(intro.response) println(intro.profile) while(true) { val input = readLine() as String if (input == "exit") { break } val answer = conversation.answer(input) println(answer.response) println(answer.profile) } } 


As a result, something like this:

 Ready [Hello, I'm Watson-based chatbot and can tell you about weather.] {} Isn't it too cold in Moscow? [I processed your request. Temperature in Text is Temperature, , Goodbye.] {City=Moscow} 

Or

 Ready [Hello, I'm Watson-based chatbot and can tell you about weather.] {} Isn't it cold now? [Send a city name.]{} Moscow [I processed your request. Temperature in Text is Temperature.] {City=Moscow} 

Well, actually processing commands. Handlers are of type BiFunction <List, String, String>. At the entrance - the list obtained from the analysis of the arguments and user input. At the exit - the text received when processing the command. For example:

More source
 package com.alex4321.botdemo import com.alex4321.bot.* import java.util.function.BiFunction fun main(args: Array<String>) { CommandHandler.register("Text", BiFunction { args, input -> args[0] }) if (args.size != 7 && args.size != 6) { println("Need arguments [path, dialogUsername, dialogPassword, nlcUsername, nlcPassword, dialogID, nlcID] or " + "[path, dialogUsername, dialogPassword, nlcUsername, nlcPassword, robotName]") return } val path = args[0] val dialogUsername = args[1] val dialogPassword = args[2] val nlcUsername = args[3] val nlcPassword = args[4] val robotName = if (args.size == 6) { args[5] } else { "" } val dialogId = if (args.size == 7) { args[5] } else { "" } val nlcId = if (args.size == 7) { args[6] } else { "" } val new = dialogId == "" && nlcId == "" val code = WatsonProgramPath(path).read() val program = WatsonNlcDialogProgram(code) val auth = WatsonRobotAuth(dialogUsername, dialogPassword, nlcUsername, nlcPassword) val robot = WatsonRobot(program, dialogId, nlcId, auth) if (new) { robot.train(robotName) print("Dialog ID : ") println(robot.dialogID) print("NLC ID : ") println(robot.nlcID) println("Training") while (! robot.available) { Thread.sleep(10000) } } println("Ready") val conversation = robot.converse() val intro = conversation.intro() println(intro.response) println(intro.profile) while(true) { val input = readLine() as String if (input == "exit") { break } val answer = conversation.answer(input) println(answer.response) println(answer.profile) } } 


Now the output looks like this:

 Ready [Hello, I'm Watson-based chatbot and can tell you about weather.] {} Isn't it too cold in Moscow? [I processed your request. Temperature in Moscow is Temperature, , Goodbye.] {City=Moscow} 

PS: and yes, the code is clearly not the best, I agree. Waiting for critics.
UPD. Fixed a bug in the repository address.

Source: https://habr.com/ru/post/304282/


All Articles