viernes, 28 de septiembre de 2018

Octavo lugar de Momo en el premio Loebner de 2018





Por segundo año consecutivo, hemos presentado a un bot, llamado Momo, y desarrollado por Antakira Software al premio Loebner, una de las más prestigiosas competiciones de chabots a nivel mundial, que se celebra desde 1991 y organiza AISB. Los resultados pueden consultarse aquí.

Respecto al año pasado, nuestra evolución ha sido muy positiva. Hemos ascendido a la octava plaza, y sólo cuatro puntos nos han separado de poder acceder a la fase final, para la que se clasificaban los cuatro primeros.

En particular, estamos muy satisfechos con las respuestas que dió Momo a cuestiones derivadas de los esquemas de Winograd. Varios expertos nos han dado públicamente su enhorabuena, como puede comprobarse aquí.

Pueden verse las conversaciones de todos los contendientes, también las de nuestro Momo (en inglés), en el sitio del AISB.

La clasificación de la competición en la primera parte de la misma fue la siguiente:

Pos.  Nombre        Puntuación
1     Tutor                    27
2     Mitsuku               25
3     Uberbot               22
4     Colombina          21
5     Arckon                20
6     Midge                 19
7     Mary                   18
8     Momo                 17
9     Talk2Me             14
10   Aidan                  13
11    Johnny & Co.     12

El ganador de la competición fue Mitsuko, por cuarta ocasión.

martes, 17 de octubre de 2017

Cuento interactivo: «El expreso intergaláctico» de Javier Perea

Fieles a nuestra tradición de innovar y buscar nuevas experiencias que combinen ocio y cultura, nos enorgullece presentar el cuento infantil interactivo «El expreso intergaláctico» escrito por Javier Perea e ilustrado por Miriam Roig. A la manera de las novelas del tipo «Elige tu propia aventura», en este cuento el lector tiene la oportunidad de elegir entre varias opciones en diversas situaciones, participando así en el desarrollo de la historia. Este tipo de novelas, muy populares en los ochenta, se ha revitalizado ahora con los libros electrónicos creando los llamados librojuegos, que permiten ofrecer historias mucho más ricas y complejas, a la vez que simplifican la búsqueda de la página por la que debe continuar su historia.

El expreso intergaláctico



Una mención especial merecen las ilustraciones de la artista Miriam Roig, que transportan a los jóvenes lectores a esta curiosa aventura espacial.

En este caso, nuestra labor ha consistido en la creación de un software específico con el que es posible generar la historia interactiva, comprobar que la historia está bien hilvanada y tiene la variedad deseada en número de bifurcaciones y finales, además de generar directamente un archivo HTML que es posible cargar a la principal plataforma de libros electrónicos, el Kindle de Amazon. Para crear una historia con esta herramienta, solo se necesita una escribir en una hoja de cálculo las diferentes situaciones, enlazándolas con una sintaxis muy intuitiva y sencilla.

La herramienta está todavía en proceso de desarrollo, ya que tenemos previstas varias funciones para hacerla todavía más cómoda y útil. Cuando esté totalmente terminada, estamos barajando la posibilidad de publicarla en nuestra página, para que todo el mundo pueda crear su propia novela interactiva.

Por otro lado, informamos que ya están iniciados los trabajos para la traducción de «El expreso intergaláctico» al inglés y al italiano.

lunes, 15 de mayo de 2017

MoMo: Mil maneras de decir lo mismo

Al hablar, tenemos una variedad infinita de maneras diferentes de expresar prácticamente la misma idea, lo cual con frecuencia supone todo un desafío cuando queremos crear un chat de conversación. Por ejemplo, imaginemos las siguientes frases que puede decir un usuario:
>Háblame del amor.
>¿Qué opinas del amor?
>¿Qué te parece el amor?
>¿Cuál es tu opinión sobre el amor?
>Quiero que me hables del amor.

Cinco maneras diferentes de, básicamente, interrogar a un bot sobre el amor. Dado que todas estas opciones solo comparten una palabra en común «amor», podemos pensar que basta con crear una regla sobre el amor. Por ejemplo,
amor Cuando el amor llega así de esa manera, uno no se da ni cuenta.

Esta regla saltará en todas las ocasiones anteriores, así que problema solucionado, ¿o no?

Lamentablemente la respuesta es que no necesariamente. Sí, la regla se activará en todos los casos anteriores, pero siempre que no haya una regla que tenga mayor prioridad.

Por tanto, surgirá un problema si se nos ocurre crear una regla como:
me hables del * No sé qué decir del *1.

La idea de la regla es buena. Aunque no sepa exactamente qué decir, el bot se está dando cuenta de que se le está preguntando sobre un tema y reconoce su ignorancia. El problema es que antes teníamos una regla que nos hubiera dado una respuesta bastante mejor cuando el usuario está interesado en cuestiones de amor, pero ha dejado de activarse porque la nueva regla tiene prioridad cuando el usuario dice cosas como:
>Quiero que me hables del amor.

A simple vista parece el típico caso en el que, al aumentar el número de reglas, disminuye la calidad de ciertas respuestas. Afortunadamente, con un poco de ingenio y un pequeño script, podemos crear un bot que aúne lo mejor de ambos mundos. Para ver cómo hacerlo, vamos a crear un bot con solo cinco líneas:
%id="xhello" Hola.
me hables del * $respuesta$%script="$especifica$=1;$respuesta$=getOutput(*1);if($especifica$==0){$respuesta$=No sé qué decir del *1.;}"
amor Cuando el amor llega así de esa manera, uno no se da ni cuenta.
* %script="$especifica$=0;"
%id="xnone" No sé que decir.

La magia de este pequeño bot se concentra en un par de scripts. Ahora vemos que cuando el usuario dice «Quiero que me hables del amor.» se ejecuta el siguiente script, que pasamos a comentar línea por línea:
$especifica$=1; 
Esta línea consiste sencillamente en una instrucción que establece una variable que utilizaremos a modo de baliza.
$respuesta$=getOutput(*1);
La instrucción getOutput() nos permite obtener una respuesta al texto que queramos. En este caso *1=amor, con lo que nos quitamos de encima todo el enunciado genérico del texto del usuario y nos quedamos con la palabra clave. El problema de este método es que el bot normalmente siempre encontrará una respuesta y, en el peor de los casos, mostrará el xnone, algo que no nos interesa.
Y aquí viene el truco, podemos ver que hay una regla que siempre se cumple y que consiste únicamente en un script.
script="$especifica$=0;"

Pues bien, si el bot encuentra una respuesta antes de esta regla, $especifica$ conservará el valor 1, pero si no la encuentra, tomará el valor 0. De esta manera, podemos dividir el archivo de reglas en dos partes: una con las reglas que preferimos a una respuesta genérica y otra con las que no.

if($especifica$==0){$respuesta$=No sé qué decir del *1.;}

Ahora lo único que queda por hacer es que si no hemos encontrado una respuesta que nos satisfaga, procederemos a mostrar una respuesta que al menos demuestre que hemos entendido la intención del usuario. De lo contrario, se mostrará la respuesta que se encontró en la instrucción anterior.

Una de las grandes ventajas de MoMo es que, gracias a las variables y las funciones, podemos modelar comportamientos mucho más inteligentes de lo permiten las reglas estáticas. Y no se necesitan complicados programas para ello. En el ejemplo anterior, hemos visto que bastan cuatro instrucciones y un par de variables para resolver un problema bastante complicado.

Esperamos que este tutorial os anime a comenzar a utilizar las funciones de script de MoMo y, si tenéis cualquier duda, será un placer atenderos bien a través de este blog o mediante nuestro foro sobre MoMo.

¡Feliz programación!

domingo, 30 de abril de 2017

MoMo: Cómo crear un chatbot que gestione los contactos

Una de las grandes ventajas de MoMo es la gran flexibilidad que ofrece el lenguaje de script y la gestión automática de los recuerdos, lo que nos permite abordar rápidamente todo tipo de tareas.



Por ejemplo, supongamos que queremos que nuestro flamante bot incluya una pequeña base de datos con nuestros contactos. En principio, vamos a almacenar solo el nombre del contacto y su número de teléfono. Esta sencilla regla se encarga de ello:

<rule>
    <input>teléfono de <wildcard lengthmin="1" name="$name$" /> es el <wildcard lengthmin="1" name="$phone$" /></input>
    <output script="forget();recentMemoryGetByItem(contact);recentMemoryFilterByAttributeValue(name,$name$);if(getRecentMemoryCount()==0){recentMemoryCreate(contact);recentMemorySetAttribute(name,$name$);};recentMemorySetAttribute(phone,$phone$);">Muy bien, el teléfono de $name$ es el $phone$.</output>
</rule>

El corazón de esta regla es un script, que vamos a analizar en detalle ahora:

forget();
Esta línea sencillamente indica que gestionaremos personalmente cómo se almacena la información (si no, el bot la almacenará en un formato predeterminado menos cómodo).
recentMemoryGetByItem(contact);
Cargamos en la memoria reciente del bot todos los datos de los contactos.
recentMemoryFilterByAttributeValue(name,$name$);
Filtramos los datos de los contactos, para dejar solo aquellos en los que el atributo "name" tiene como valor el nombre que el usuario ha indicado mediante el comodín $name$.
if(getRecentMemoryCount()==0){recentMemoryCreate(contact);recentMemorySetAttribute(name,$name$);};Si no se ha encontrado ningún contacto, creamos un nuevo contacto y definimos que su atributo "name" sea el valor del comodín $name$ especificado por el usuario.
recentMemorySetAttribute(phone,$phone$);
Definimos que su atributo "phone" sea el valor del comodín $phone$ especificado por el usuario.

¡Solo 7 instrucciones y hemos creado un sistema que no solo almacena los datos que nos interesan, sino que además evita que se introduzca información duplicada! Por supuesto, nuestro script podría ser más sofisticado. Por ejemplo, podría comprobar si ya se ha indicado el número de teléfono y, en tal caso, dependiendo de si coincide o no con el que ha indicado el usuario, mostrar una advertencia o, sencillamente, informar que ya se conocía el número de teléfono.

Claro que, por interesante que sea almacenar los datos de nuestros contactos, necesitamos una manera de recuperar esta información. Para ello, utilizaremos los siguientes reglas:

<rule>
    <input>teléfono de <wildcard lengthmin="1" name="$name$" /> ?</input>
    <output script="forget();recentMemoryGetByItem(contact);recentMemoryFilterByAttributeValue(name,$name$);if(getRecentMemoryCount()==0){throwExceptionById(xContactPhoneUnknown);};$result$=getRecentMemoryAttribute(phone);if(length($result$)==0){$data$=número de teléfono;throwExceptionById(xContactMissingData);}">El teléfono de $name$ es el $result$.</output>
</rule>
 <rule id="xContactPhoneUnknown">
    <output>No conozco a $name$.</output>
</rule>
 <rule id="xContactMissingData">
    <output>No sé su $data$.</output>
</rule>

Aunque son un total de tres reglas, dos de ellas se limitan a mostrar mensajes de advertencia, por lo que el corazón se encuentra, al igual que para la introducción de datos en un sencillo script, que también analizaremos a continuación:

forget();
Una vez más, indicamos que procesaremos nosotros la información.
recentMemoryGetByItem(contact);
Recuperamos todos los contactos...
recentMemoryFilterByAttributeValue(name,$name$);
...y dejamos solo aquellos en los que el atributo "name" sea el nombre indicado por el usuario.
if(getRecentMemoryCount()==0){throwExceptionById(xContactPhoneUnknown);};Si no hay ningún contacto con este nombre, es que se trata de un contacto desconocido.
$result$=getRecentMemoryAttribute(phone);
Recuperamos como resultado el atributo "phone" del contacto obtenido.
if(length($result$)==0){$data$=número de teléfono;throwExceptionById(xContactMissingData);}
Si la longitud del resultado es cero, indicamos que no conocemos el dato en cuestión.

Lo más enfoque es que este método es muy ampliable. Es decir, hemos escrito las reglas para guardar y recuperar los nombres y los números de teléfono de nuestros contactos, pero esa misma estructura puede utilizarse para guardar más datos, como el número de móvil, la dirección, el correo electrónico, etc. La información queda almacenada para utilizarla en cualquier otro punto del bot. Por ejemplo, el bot podría preguntarnos cada cierto tiempo si hemos visto a un contacto, pedir que le rellenemos los datos que desconoce, etc. ¡Y todo ello utilizando únicamente funciones básicas!

Si quieres practicar estos conocimientos, ¿podrías crear las reglas necesarias para registrar también el número de móvil? Y, si te tropiezas con alguna dificultad, ¡no dudes en avisarnos!

jueves, 30 de marzo de 2017

¡La primavera trae la mejor versión de «Habla con Cervantes» jamás creada!

A nadie le agrada encender su teléfono móvil y encontrarse con tropocientas actualizaciones que luego no suponen mejoras apreciables ni ofrecen nuevas funciones. En Antakira Software somos perfectamente conscientes de ello, por lo que preferimos limitar lanzar actualizaciones únicamente cuando confiamos en que la nueva versión supondrá una mejora claramente apreciable de la experiencia del usuario.

Y ahora, ese momento ha llegado: podemos decir que la versión que hoy puedes descargar de «Habla con Cervantes» en Google Play supone sin duda un hito en la creación de bots conversacionales en castellano. Las mejoras abarcan prácticamente todos los aspectos: el número de posibilidades de conversación ha aumentado espectacularmente, el bot es mucho más hábil a la hora de adivinar lo que se ha querido decir cuando se cometen errores de ortografía y su castellano es, sin duda, mucho más fluido a la hora de responder al usuario.

También hemos añadido muchas pequeñas funciones que marcan una sutil, pero clara diferencia. ¿Quieres saber cuál es la capital de un país? Probablemente don Miguel de Cervantes lo sepa y también descubrirás que resulta mucho más ducho a la hora de efectuar cálculos, aparte de ser perfectamente consciente del momento del año en que se encuentra... y lo que está por venir.

No obstante, probablemente la novedad más importante de esta versión es el mimo que se le ha prestado a la calidad. Antes del lanzamiento hemos realizado innumerables tests de calidad, apoyándonos en el lenguaje de programación que hemos desarrollado para escribir bots, Momo, y en las herramientas complementarias de que disponemos, para así asegurarnos de que la versión que se descarga es, desde el día uno, la mejor posible.

Os recordamos que «Habla con Cervantes» forma parte del Programa Oficial del IV Centenario de la muerte de Cervantes, y esperamos que disfrutéis de esta nueva versión, la décima, tanto como hemos disfrutado nosotros creándola. Estamos ansiosos por recibir vuestras sugerencias mientras, por supuesto, comenzamos a trabajar en la próxima versión.

miércoles, 30 de noviembre de 2016

Taller de MoMo: Cómo añadir reglas (ii) - Pasito a pasito...

¿La repetición de conversaciones ya no tiene misterios para ti? Si todavía tienes dudas, tal vez debas echarle un vistazo a nuestro tutorial anterior, pero si ya eres capaz de guardar conversaciones y repetirlas como si no hubiera un mañana, probablemente ha llegado el momento de pasar a un nuevo nivel.

Continuando con el ejemplo anterior, supongamos que nos hemos fijado la meta de que nuestro bot pueda responder a frases como:

Si Carlos tiene ocho coches y Daniel tiene cuatro coches, ¿cuántos coches tienen entre los dos?

Todo un reto, ¿verdad? Tenemos que extraer como mínimo dos datos y admitir bastante variabilidad, a no ser que queramos crear una regla que diga que la respuesta es doce y pasar a otra cosa.

Si escribimos la regla de corrido, lo más probable es que nos equivoquemos, pero es normal, ¡es algo muy complicado!

Probablemente tengamos que repetir esta conversación una y otra vez, así que lo primero que tendremos que hacer es guardar esta conversación siguiendo las instrucciones de nuestro tutorial anterior.

Ahora vamos a cerrar el programa y abriremos el archivo rules.xml con las reglas de nuestro bot. Normalmente estará en la siguiente carpeta:

MomoDesktop/bots/Pepito_ES

donde tendremos que sustituir Pepito por el nombre de nuestro bot.

Si tenemos problemas para localizar este archivo tal vez podamos buscar simplemente el archivo rules.xml con nuestro explorador de archivos favorito.

Bien, ahora tenemos que abrir este archivo y dirigirnos a la primera línea, donde insertaremos la siguiente regla:

<rule>
    <input>coches</input>
    <output script="forget()">Ya veo por dónde vas.</output>
</rule>


¿Por qué lo hacemos así? Bueno, hay un par de buenos motivos:

1. Al colocar la regla al principio del archivo nos aseguramos de que no haya conflicto con ninguna otra regla. Si esta regla no se ejecuta, es porque no coincide con la entrada.

2. Si solemos trabajar convirtiendo las reglas de una hoja de cálculo en el formato xml, esta es una operación que requiere un precioso tiempo que perdemos.

Al escribir la regla en el archivo rules.xml, la actualización es casi inmediata. Solo tenemos que cerrar y volver a abrir MoMo o, todavía más rápido, volver a cargar el personaje seleccionándolo en el menú Bots. Un proceso que dura solo unos segundos en lugar del pesado Copiar-Pegar-Guardar-Convertir que había que hacer antes.

Por supuesto, cuando tengamos nuestra flamante nueva regla terminada, no hay problema en copiar nuestra valiosa regla a la hoja de cálculo y continuar el desarrollo ahí.

Y bueno, para resolver este problema concreto, la clave está en avanzar poquito a poco. Por ejemplo, la mitad del problema parece estar resuelto con la siguiente regla:

<rule>
    <input>~nombreMasculino tiene <wildcard length="1" name="$name1$" /></input>
    <output script="forget()">$nombreMasculino$ tiene $name1$.</output>
</rule>


El resultado con esto, parece ir tomando forma, ¿qué habrá que hacer para continuar?

Solo una última nota, tal vez te extrañe el script que se ha incluido en la regla:
script="forget()". ¿Realmente hace falta? La respuesta es que no, sencillamente lo hemos incluido para indicar un espacio por si necesitas escribir un script, pero puede borrar este comando con total y absoluta tranquilidad.

Taller de MoMo: Cómo añadir reglas (i) - La clave está en repetir, repetir, repetir...

Tanto si queremos crear una regla sencilla como una muy sofisticada, la única manera de asegurarnos de que funciona es... pues... eso, comprobar que el bot nos dice lo que esperamos. Tal vez con las reglas simple baste con probarla una vez, pero a medida que creamos reglas más complicadas, es posible que necesitemos ajustarla varias veces, repitiendo la misma con el bot una y otra vez hasta conseguir por fin lo que queríamos.

Imaginemos que queremos crear una regla para nada menos que la siguiente entrada del usuario:

Si Carlos tiene ocho coches y Daniel tiene cuatro coches, ¿cuántos coches tienen entre los dos?

Bueno, no parece que sea el tipo de regla que funciona a la primera y es obvio que el texto es tan largo que pronto nos aburriremos de escribirlo una y otra vez. ¿Qué podemos hacer?

MoMo ofrece una solución muy sencilla. Basta con escribirlo una vez y elegir en los menús ArchivoGuardar. Aparecerá un cuadro de diálogo que nos preguntará dónde queremos guardar el archivo con la conversación.

¡Es muy importante que dejemos la ruta predeterminada y escribamos c.txt como nombre del archivo!

Por supuesto, podemos indicar otro nombre y otra ruta, pero dejar la ruta predeterminada y utilizar el nombre c.txt tiene una gran ventaja: cada vez que queramos repetir la conversación nos bastará con elegir ArchivoCargar reciente o, lo que es todavía más rápido, pulsar Control + 1 para que se cargue automáticamente la conversación.

No es posible insistir demasiado en lo importante que es guardar conversaciones y repetirlas una y otra vez. Tal vez tengamos que dedicar media hora a redactar una regla, ¡pero podrá ser tan inteligente que dejará boquiabierto al usuario!

Todo esto está muy bien, pero ¿y si en lugar de escribir una regla sencilla, queremos depurar una conversación con un montón de preguntas y respuestas? Por supuesto, los pasos anteriores siguen siendo válidos, pero en este caso nos interesará en particular comparar automáticamente las respuestas del bot antes y después de una modificación. Para ello, basta con seleccionar Ver y activar la opción de menú Mostrar comparación.

Al hacerlo, cuando repitamos una conversación se nos mostrará lo que dijo antes el bot y lo ha dicho en esta ocasión, resaltando en rojo los casos en los que la respuesta es diferente. Por ejemplo:


Esta opción nos da bastante flexibilidad. Cuando no nos interese lo que dijo el bot antes, suele ser mejor desactivarla,  para conseguir una presentación en pantalla más limpia, pero cuando estamos trabajando con conversaciones largas, esta posibilidad puede ser muy útil.

Bueno, estos conceptos son bastante básicos pero resultan extremadamente útiles por lo que recomiendo practicarlos hasta que se dominen a la perfección porque cualquier avance suele conseguirse con un número considerable de pruebas y, quién sabe, quizás empezando con esto puedas acabar superando la prueba de Turing.