IBM Watson – Conversation Service

Watson es un sistema informático desarrollado por IBM que haciendo uso de la inteligencia artificial es capaz, entre otras cosas, de responder a preguntas e interactuar mediante un lenguaje natural. IBM Watson tiene varios servicios disponibles, como es el servicio Conversation, del cuál se hablará en esta entrada.

Construcción de un chatbot

Watson Conversation es un servicio que nos permite la construcción de chatbots (agentes virtuales). Estos reciben inputs del usuario mediante un lenguaje natural que Watson es capaz de interpretar y, ante el cual, genera una respuesta.

El desarrollo del chatbot está dividido en dos partes:

Configuración de Watson En primer lugar, se explicará cómo crear un chatbot mediante Watson, cómo entrenarlo y cómo configurar los distintos diálogos con los que se podrá interactuar.
Desarrollo de la aplicación Se desarrollará también una aplicación que, haciendo uso de la API de Watson, nos permita interactuar con el chatbot creado anteriormente.

Cómo se configura Watson

Configuración bluemix

Antes de empezar, es necesario registrarse en bluemix para poder realizar los desarrollos. Tras el registro, se accede a “Crear Servicio”, y en la categoría Watson, se selecciona el servicio “Conversation“. Una vez seleccionado el servicio, es importante acceder a la parte de “Credenciales del servicio” para obtener los nombres de usuario y contraseña del servicio y poder tener acceso a través de la API.

Después de crearse el servicio, se lanza la herramienta mediante el botón Launch tool. Entonces, se abrirá una nueva página que permitirá crear nuestro propio Workspace. Es especialmente relevante anotar el ID del workspace para poder acceder a él desde la API.

Configuración de los intents

Por parte del desarrollador, es necesario identificar el conjunto de intents (temas de conversación o intenciones por parte del usuario) a los que Watson debe de dar respuesta. Un ejemplo de estos intents pueden ser: #greetings (para cuando el usuario quiera saludar al chatbot), #goodbye (para cuando el usuario quiera despedirse), etc. En definitiva, todas las acciones que el usuario pueda querer realizar y a los que se quiera dar respuesta.
Una vez identificados los intents, es necesario entrenarlos con las posibles entradas que Watson debería poder asociar a este intent.
watson-intentAsí, podemos probar los intents haciendo uso de “Ask Watson” (el icono de la esquina superior izquierda con forma de diálogo). Podría darse el caso que una de las entradas no encontrase su intent asociado, entonces, podríamos darlos de alta directamente desde ahí.

watson-ask-edit

Configuración de las entities

Las entities son partes especificas del texto introducido por el usuario. Es posible declarar una entity para poder identificar una o varias partes del texto del usuario.

Por lo tanto, en el caso de una pizzería podrían aparecer las siguientes entities:

watson-entity-1
watson-entity-2
Al estar creando un chatbot para una pizzería, se crea un nuevo intent que permite recibir ordenes de pizzas por parte de los usuarios.
watson-intent-2
Existen además unas entities propias de Watson que es capaz de identificar, las System Entities. En la ventana de entities, es posible activarlas en función a los requerimientos de nuestra aplicación.

watson-entity-sys

watson-ask-3

Creación de un diálogo

Una vez que ya sabemos captar las intenciones de los usuarios y ciertas palabras o conceptos que nos sean necesarios, es preciso dar respuesta a las peticiones de los usuarios.
Para ello, en la pestaña diálogos, creamos un nodo en el cuál siempre que se detecte el intent #order_pizza, más un tamaño y al menos un toppings, el bot responderá con un mensaje de “pedido confirmado”.

Así, al probar los nuevos cambios, el chatbot responde con el mensaje que hemos configurado:

watson-ask-4

Además es posible crear varias respuestas y elegir si mostrarlas de forma aleatoria o en orden secuencial.

Crear un diálogo con nodos

Los nodos permiten controlar la conversación y poder mostrar distintas respuestas para mismos intents en función del nodo en el que nos encontremos de la conversación. Es posible crear un nodo en el que solo se detecte el tamaño de la pizza y crear un nodo hijo preguntando por los toppings y viceversa.
Además, con el nodo “Otra cosa”, mediante la condición “anything_else“, es posible crear un nodo que actúe como un else. Así, todas las preguntas que no hayan sido macheadas con los nodos anteriores se asignarán a este intent.

Desarrollo de la aplicación

IBM provee de una API para poder interactuar con Watson. Esto nos permite controlar las entradas de los usuarios y la respuesta obtenida de Watson (así como los intents y entities asociados a esa respuesta). En este ejemplo, se usará la SDK para Java, toda la información de la API se puede encontrar aquí.

Este ejemplo utiliza maven para la gestión de dependencias, se puede encontrar más información sobre el uso del SDK mediante maven aquí.

En primer lugar creamos una clase ConversationService, donde se creará un constructor y un método para poder obtener la respuesta por parte de Watson a una entrada dada y un contexto. El contexto, permite a Watson “recordar” el estado o nodo de la conversación anterior.

public class ConvesationService {
    private String workspaceId;
    private ConversationService service = new ConversationService("2017-05-26");
    public ConvesationService(String username, String password, String workspaceId){
        this.workspaceId = workspaceId;
        service.setUsernameAndPassword(username, password);
    }
    public MessageResponse getResponse(String input, MessageResponse response) {
        //If request is not null, cotnext is passed.
        MessageRequest request;
        if (response != null) {
            request = new MessageRequest.Builder().inputText(input).context(response.getContext()).build();
        }
        else {
            request = new MessageRequest.Builder().inputText(input).build();
        }
        return service.message(workspaceId, request).execute();
    }
}

Por último, desde la clase principal se obtiene los inputs del usuario, leyendo de la consola de forma continua. Con este input y la respuesta anterior, se llama al método de la clase anterior para poder obtener la respuesta de Watson y mostrarlas por pantalla.

public class MainClass {
    public static void main(String[] args) throws IOException {
        //Setting up property file with configuration
        Properties prop = new Properties();
        InputStream inputProperty = new FileInputStream("config.properties");
        prop.load(inputProperty);
        System.out.println("-----Watson Conversation Chatbot-----");
        //Adding every property value.
        String workspaceId = prop.getProperty("WORKSPACE_ID");
        String username = prop.getProperty("USERNAME");
        String password = prop.getProperty("PASSWORD");
        ConvesationService service = new ConvesationService(username, password, workspaceId);
        MessageResponse response = null;
        do {
            //Getting inputs from system input
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String input = br.readLine();
            response = service.getResponse(input, response);
            System.out.println(response.getOutput().get("text"));
        } while (true);
    }
}

A continuación se pueden observar las pruebas realizadas, pudiendo ver así las llamadas http que se realizan a la API de Watson y la respuesta que Watson envía.

test

Watson es un gran servicio que permite el desarrollo de chatbots con entendimiento de lenguaje natural en un corto periodo de tiempo y de forma muy sencilla. Desde BI Geek hemos realizado el desarrollo de nuestro propio chatbot mediante el uso de Watson y Slack. Como resultado, hemos obtenido una mejora de la eficiencia en la gestión del equipo.