Está en la página 1de 91

Guía para desarrolladores de Azure

IA en acción
Tres casos prácticos técnicos muestran
cómo los desarrolladores están usando
la IA de Azure para crear la siguiente
generación de aplicaciones
Índice 2

01 / 02 / 03 /
Introducción Caso práctico técnico: Three Caso práctico técnico:
(Reino Unido) Powel (Europa)

04 / 05 / 06 /
Caso práctico técnico: Conclusión Siguientes pasos
NAVITIME (Japón)
Introducción 3

Los desarrolladores de todo


el mundo utilizan la IA para
crear aplicaciones más
útiles, flexibles e intuitivas.
Esta colección de casos
prácticos técnicos destaca tres
ejemplos reales de cómo los
desarrolladores han utilizado
los servicios de IA de Azure
para crear aplicaciones que
reducen las barreras entre
las personas y la tecnología.
Introducción 4

Ejemplos de IA de Azure en acción


El proveedor de telecomunicaciones Three El creador de aplicaciones de viajes
creó un bot impulsado por IA con unas NAVITIME desarrolló un chatbot
API de Cognitive Services que proporciona que los viajeros pueden utilizar para
un mejor autoservicio para las tareas encontrar atracciones locales o buscar
de los clientes, como la activación restaurantes atractivos, superando
de tarjetas SIM, la portabilidad de los al mismo tiempo las barreras del
números o la actualización del servicio. idioma local previendo los miles
de visitantes que asistirán a los
Ir al caso práctico de Three Juegos Olímpicos de Tokio en 2020.

El proveedor de servicios municipales


Ir al caso práctico de NAVITIME
Powel ayuda a los técnicos que trabajan
en infraestructuras eléctricas peligrosas a
tener las manos libres y estar seguros con
un chatbot llamado André, que ayuda
a administrar la lista de comprobación
de trabajo a la vez que proporciona
información útil.

Ir al caso práctico de Powel

Cada caso práctico técnico muestra cómo los


desarrolladores han creado sus aplicaciones
con la IA de Azure, y la experiencia de usuario
resultante. Los estudios también demuestran
cómo cualquier desarrollador puede crear
sus propias aplicaciones mejoradas con
IA rápidamente.
Caso práctico técnico: Three 5

Caso
práctico
técnico:
Three
Caso práctico técnico:
Febrero Lorem
Threeipsum dolor sit amet, consectetur 6
2018 adipiscing elit

Caso práctico técnico Three, el proveedor de servicios

El proveedor
de telecomunicaciones e Internet,
ha experimentado informalmente con
varios servicios de chatbot en diferentes
de Internet plataformas, pero está interesado
en garantizar la mayor reutilización

Three mejora posible del código y reducir la sobrecarga


de mantenimiento. El webchat existente

la asistencia ha ofrecido muy buenos resultados, pero


todavía hay consultas de usuarios sin

al cliente con resolver a través de esta interfaz existente.


Para resolver este problema, Three colaboró

un chatbot con Microsoft para crear un bot que


guiara a los usuarios por varios escenarios

de autoservicio de autoservicio (que no requieren un agente


humano), como la activación de una tarjeta
SIM y la respuesta a preguntas generales
Lilian Kasem
con el fin de pasar rápidamente a producción.
13 de junio de 2017
La solución final fue un chatbot que
responde preguntas generales en cualquier
momento de una conversación. También
proporciona dos flujos de autoservicio que
permiten a los usuarios activar sus tarjetas
SIM y portar sus números usando el bot,
sin tener que salir de la interfaz de chat. Por
último, el bot también proporcionó a los
usuarios información sobre cómo cancelar
o actualizar su contrato con Three. Detrás
de todo el bot, usamos Azure Application
Insights para realizar el seguimiento
de la telemetría de todos los diálogos que
esperamos usar más tarde como comentarios
en el bot para mejorar la conversación
o la experiencia del usuario.
Caso práctico técnico: Three 7

Perfil del
Tecnologías clave
cliente:
• Microsoft Bot Framework
(Node.js)
• Microsoft QnA Maker
• Language Understanding
Intelligent Service (LUIS)
• Característica Web Apps de
Azure App Service
• Azure Application Insights

Three es un proveedor de servicios de


telecomunicaciones e Internet que opera
en el Reino Unido. La empresa se lanzó
en marzo de 2003 como la primera red
móvil de vídeo comercial del Reino Unido.
Proporciona servicios 3G y 4G a través
de su propia infraestructura de red.

Three quiere hacer la vida más fácil a sus


clientes ayudándoles a sacar el máximo
provecho de sus dispositivos móviles,
ofreciendo un valor real de los servicios
que presta y eliminando las barreras que
les frustran.
Caso práctico técnico: Three 8

Los problemas Soluciones


planteados y pasos
Durante los últimos 18 meses,
Requisitos previos
la funcionalidad de webchat existente
de Three ha ofrecido muy buenos resultados,
• Instalar Visual Studio Code
pero todavía hay consultas de clientes sin
• Instalar Node.js
resolver a través de esta interfaz existente.
• Obtener las claves de Cognitive Services
Se incluyen
• Obtener la suscripción a Azure

• Cancelar o actualizar un contrato.


• Nuevo cliente de Three.
Medidas del éxito
• Comprar un nuevo teléfono/contrato. de Three
• Comunicar el robo o la pérdida
de un dispositivo o una tarjeta SIM. • Reducción del número de webchats
• Agregar o quitar servicios y contratar relacionados con temas para los
complementos. que existen suficientes recursos
• Informar de que no hay servicio de autoayuda online.
de Internet o de que la cobertura • Aumento del número de visitas a los
móvil es escasa o nula. procesos de autoservicio seleccionados
• Recargar el uso del servicio. para resolver las consultas de los
• Modificar datos de usuario. clientes.
• Consultas de saldo de cuenta. • Validación interna en el bot; por
ejemplo, el número de personas que
dicen que la sesión de bot fue útil
y que no tuvieron que llamar o charlar,
entre otros.
• Determinar el esfuerzo que requieren
los recursos de Three para configurar,
mantener y optimizar los casos
de usuario y las respuestas del bot.
Febrero Lorem ipsum dolor sit amet, consectetur 9
2018 adipiscing elit

Solución y arquitectura
La solución final en el hackfest fue
un chatbot que:

• Responde a las preguntas más


frecuentes mediante el servicio
Microsoft QnA Maker.
• Permite a los usuarios activar sus
tarjetas SIM de Three.
◦◦ Los usuarios rellenan un formulario
a través de una conversación con
el bot.
• Permite a los usuarios portar su número
de teléfono existente a Three.
• Permite a los usuarios actualizar
o cancelar su contrato con Three.
• Realiza el seguimiento de la telemetría
de todos los diálogos mediante Azure
Application Insights, que después
se usará para aplicar los resultados
al bot y mejorar el flujo de conversación
y la experiencia del usuario.
Caso práctico técnico: Three 10
Caso práctico técnico: Three 11
Caso práctico técnico: Three 12
Caso práctico técnico: Three 13
Caso práctico técnico: Three 14
Caso práctico técnico: Three 15

El bot comienza con un mensaje de bienvenida que se activa cuando un usuario agrega un bot a sus
contactos o abre una conversación con el bot. Desde aquí el usuario puede:

• Usar texto libre para hacer una pregunta (que la administra QnA Maker).
◦◦ Por ejemplo: "¿Qué es 3G?".
• Usar texto libre para decirle al bot que haga algo (lo que activa el diálogo correspondiente).
◦◦ Por ejemplo: "Quiero portar mi número".
• Hacer clic en un botón para activar el diálogo correspondiente.
◦◦ Por ejemplo: clic en el botón "Activar SIM".

Todos los diálogos del bot incorporan telemetría (mediante Azure Application Insights) para
realizar el seguimiento de por dónde navegan los usuarios en el flujo de conversación del bot:
qué tipo de preguntas hacen y cuánto tiempo tarda en completarse una solicitud.

Toda la implementación técnica de lo anterior se encuentra en la sección "Ejecución técnica"


de este documento.

Los botones
(Nodo) seleccionados (Nodo)
Diálogo de activan diálogos Diálogo Telemetría Azure
bienvenida relevante Application
con opciones. activado Insights

Texto Texto
**Todos los formularios se pasan por
Reconoci- Entidades
miento de para campos "commonFormIntro.js", que:
(QnAMaker) entidad LUIS de formulario 1. Pregunta al usuario si desea rellenar el formulario
Diálogo de a través del recurso HTML o el bot.
bienvenida 2. Si elige la opción de bot se presentan al usuario
con opciones. antes de que se inicie el formulario para que
pueda confirmar que tiene todos los datos
necesarios.

** Iniciar un generador de formularios de nodos activeSIMForm.js que reconocerá cualquier


entidad introducida por el usuario y la utilizará en el formulario (después de que la
vuelva a validar el usuario).
Caso práctico técnico: Three 16

Los flujos principales que Three quería crear durante el hack para la solución inicial de bot eran:

• Activar la SIM
• Portar un número
• Cancelar o actualizar un contrato
Caso práctico técnico: Three 17

Ejecución técnica
En esta sección se describen los detalles de implementación de la solución.

Capacidades básicas del bot


Activar la SIM

Este flujo de bot se compone de varios diálogos:

• ActivateSIM
• ActivateSIMForm
• CommonFormIntro
• ActivateSIMSubmit

ActivateSIM

En primer lugar, se pregunta a los usuarios qué perfil se adapta mejor a ellos, lo que ayudará al bot
de Three a rellenar el formulario correcto en función del tipo de cliente con el que interactúa. Esto
se hace mediante una solicitud de elección. Según la respuesta del usuario, se llaman diferentes
diálogos como CommonFormIntro o ActivateSIMForm. Muchos de los siguientes diálogos usarán
una solicitud similar, como se muestra a continuación, para guiar a los usuarios.
Caso práctico técnico: Three 18

builder.Prompts.choice(
session,
'OK\n which of these best describes you?',
[
'I ordered a replacement for a missing or broken SIM',
'I ordered a different size SIM',
'I have just upgraded',
'I am a new customer'
],
{listStyle: builder.ListStyle.button}
)
Caso práctico técnico: Three 19

ActivateSIMForm

Este diálogo hace a los usuarios una serie de preguntas que son necesarias para completar
el formulario necesario con el fin de activar su SIM. Es un método útil para crear fácilmente
un formulario en el marco de bot.

function (session, args) {


// Save entity data to dialogData
if (args.entityData) {
session.dialogData.entityData = args.entityData
}
session.dialogData.index = args.index ? args.index : 0
session.dialogData.form = args.form ? args.form : {}

// Check if entityData exists


if (session.dialogData.entityData) {
// If the entityData exists and it possesses the property for this
question, send a confirm prompt
if
(session.dialogData.entityData.hasOwnProperty(questions[session.dialog
Data.index].field)) {
var prompt = questions[session.dialogData.index].prompt
prompt = prompt.replace('{' +
questions[session.dialogData.index].field + '}',

session.dialogData.entityData[questions[session.dialogData.index].fiel
d])
builder.Prompts.confirm(session, prompt)
} else {
// If the entityData exists but the property for this question
doesn't, send a text prompt
builder.Prompts.text(session,
questions[session.dialogData.index].question)
}
} else {
// If there is no entityData, proceed as normal
builder.Prompts.text(session,
questions[session.dialogData.index].question)
}
},
function (session, results, next) {
// Check if the user responding via a Confirm or Text prompt
if (results.response === true) {
// If the confirm prompt is true then we save the entity to the
form object and increment the index
var field = questions[session.dialogData.index++].field
session.dialogData.form[field] =
session.dialogData.entityData[field]
} else if (results.response === false) {
// If the confirm prompt is false then we delete the entity from
the entityData object but we do NOT increment the index
field = questions[session.dialogData.index].field
delete session.dialogData.entityData[field]
Caso práctico técnico: Three 20

CommonFormIntro

Este diálogo presenta el formulario al usuario y describe la información necesaria.

var requirements = ['You will need the following information: \n'];


for (var requirement in session.dialogData.formRequirements) {
requirements.push('\n * ' +
session.dialogData.formRequirements[requirement])
}
requirements = requirements.join('');
session.send(requirements);
Caso práctico técnico: Three 21
Caso práctico técnico:
Febrero Lorem
Threeipsum dolor sit amet, consectetur 22
2018 adipiscing elit

ActivateSIMSubmit

Este diálogo se llama una vez que se ha completado ActivateSIMForm y envía el formulario
a Three mediante la solicitud para completar una llamada REST POST a la API de Three. La imagen
siguiente muestra lo que el usuario ve después de enviar correctamente un formulario.

Portar un número

Este diálogo es muy similar a ActivateSIMForm y le hace al usuario las preguntas necesarias para
enviar un formulario para portar el número del cliente. El envío también se hace con una llamada
POST a Three.

var questions = [
{field: 'mobileNumber', question: 'What is the
existing number you want to keep?'},
{field: 'mobileNumber2', question: 'What is your
temporary new Three number?'},
{field: 'pac', question: 'What is your PAC
number?'},
{field: 'emailPayMonthly', question: 'What is your
email address?'},
{field: 'fullName', question: 'What is your full
name?'},
{field: 'dob', question: 'What is your birthday
(e.g. 01/01/1901)?'},
{field: 'address1', question: 'What is the first
line of your address?'},
{field: 'postcode', question: 'What is your
postcode?'}
];

function (session, args) {


session.dialogData.index = args ? args.index : 0;
session.dialogData.form = args ? args.form : {};

builder.Prompts.text(session,
questions[session.dialogData.index].question);
},
function (session, results) {
{field: 'dob', question: 'What is your birthday
(e.g. 01/01/1901)?'},
{field: 'address1', question: 'What is the first
line of your address?'},
Caso práctico técnico: Three 23
{field: 'postcode', question: 'What is your
postcode?'}
];

function (session, args) {


session.dialogData.index = args ? args.index : 0;
session.dialogData.form = args ? args.form : {};

builder.Prompts.text(session,
questions[session.dialogData.index].question);
},
function (session, results) {
// Save users reply
var field = questions[session.dialogData.index+
+].field
session.dialogData.form[field] = results.response
Caso práctico técnico: Three 24

Cancelar o actualizar

Este flujo contiene tres diálogos:

• UpgradeOrCancel
• Cancel
• Upgrade

UpgradeOrCancel

Este diálogo pregunta a los usuarios si desean actualizar o cancelar y, a continuación, llama al diálogo
correspondiente en función de la elección del usuario. Esto se implementa mediante una solicitud
de elección.

Cancel

Pregunta a los usuarios, mediante una solicitud de elección, si quieren un código PAC o saber la
fecha de finalización de su contrato. Dependiendo de la respuesta, contesta con el número de
teléfono al que se debe llamar o el sitio web al que se debe ir.
Caso práctico técnico: Three 25
Caso práctico técnico: Three 26

Upgrade

Este diálogo hace lo mismo que el diálogo "cancel". Pide el tipo de contrato y, a continuación,
según la respuesta, le indica al usuario el sitio web al que debe ir para actualizarse.
Caso práctico técnico:
Febrero Lorem
Threeipsum dolor sit amet, consectetur 27
2018 adipiscing elit

Inteligencia de bot
LUIS

En este proyecto, nos hemos basado principalmente en el uso de expresiones regulares para
determinar la intención del usuario. Sin embargo, también queríamos utilizar Microsoft Language
Understanding Intelligent Service (LUIS) como alternativa en caso de que el usuario decidiera
introducir consultas de texto libre. Creamos un modelo LUIS para controlar los intentos de los tres
flujos que habíamos integrado en este bot (activar SIM, portar un número o cancelar o actualizar).

Ejemplo de expresión regular utilizada:

matches: /^Activate SIM/i


matches: /^Port my number/i
matches: /^Upgrade or cancel/i

Modelo LUIS

En primer, configuramos el reconocedor LUIS en config.js:

// Import LUIS Model


var recognizer = new
builder.LuisRecognizer(process.env.LUIS_MODEL_URL);
bot.recognizer(recognizer);

A continuación, establecimos acciones de activación para cada diálogo de flujo principal, de modo
que si el modelo LUIS reconocía la intención, activaría el diálogo requerido.

Por ejemplo, si el usuario dice: "Quiero activar mi tarjeta SIM", LUIS lo interpretaría como un intento
ActivateSIM, que activaría el inicio del diálogo ActivateSIM porque el intento coincide con la palabra
clave de triggerAction (consulta más adelante). También establecimos intentThreshold para el
activador de intención de LUIS de modo que solo las coincidencias superiores a un valor de confianza
de 0,5 activarían el diálogo.

.triggerAction({
matches: 'ActivateSIM',
intentThreshold: 0.5
})
Caso práctico técnico:
Febrero Lorem
Threeipsum dolor sit amet, consectetur 28
2018 adipiscing elit

En el sitio web de LUIS puedes aprender fácilmente a hacer tu propio modelo LUIS.
Caso práctico técnico:
Febrero Lorem
Threeipsum dolor sit amet, consectetur 29
2018 adipiscing elit

QnA Maker

Three usó el servicio QnA Maker de Microsoft Cognitive Services para responder a preguntas
sencillas de los clientes que están disponibles online (página de preguntas frecuentes de Three).
La implementación fue rápida y ayudó a separar las consultas simples de los clientes y la asistencia
humana directa.

El diálogo QnA se ocupa de todas las preguntas frecuentes. Llamamos a endDialog para que el bot
vuelva al diálogo en el que estaba el usuario cuando hizo la pregunta.

module.exports = function () {
bot.dialog('QnA', (session, results) => {
console.log(process.env)
var client = restify.createJsonClient('https://
westus.api.cognitive.microsoft.com')
var options = {
path: '/qnamaker/v2.0/knowledgebases/' + process.env.QNA_KB_ID +
'/generateAnswer',
headers: {
'Ocp-Apim-Subscription-Key': process.env.QNA_SUBSCRIPTION_KEY
}
}

var question = {'question': results.question}

client.post(options, question, (err, req, res, obj) => {


if (err == null && obj.answers.length > 0) {
for (var i in obj.answers) {
if (parseInt(obj.answers[i].score) > 0.80) {
session.endDialog(obj.answers[i].answer)
} else {
session.endDialog('Sorry, I couldn\'t find an answer in
our FAQs. Don\'t forget, you can type
\'help\'
if you need assistance')
}
}
} else {
session.endDialog('Sorry, there was an error!')
}
})
})
}
Caso práctico técnico:
Febrero Lorem
Threeipsum dolor sit amet, consectetur 30
2018 adipiscing elit

Este diálogo se llama a través de UniversalBot. Esto significa que QnA Maker está presente en todo
el bot. Si la consulta del usuario no la reconocen LUIS ni una de las expresiones regulares, se enviará
al diálogo de QnA.

global.bot = new builder.UniversalBot(connector, function (session) {


session.send('I\'ll just check that for you...',
session.message.text)
session.replaceDialog('QnA', { question: session.message.text })
});

La funcionalidad de QnA Maker también se activa cuando el usuario dice ayuda, salir, problema
o soporte, y no quiere el menú principal:

if (results.response && results.response.entity === 'no') {


builder.Prompts.text(session, 'Ok, why don\'t you try asking your
query here and I\'ll search our FAQs');
}
.
.
.
function (session, results, next) {
session.replaceDialog('QnA', { question: session.message.text });
}
Caso práctico técnico:
Febrero Lorem
Threeipsum dolor sit amet, consectetur 31
2018 adipiscing elit

Azure Application Insights


Configuramos Application Insights para capturar telemetría en el bot. Se usa para realizar el
seguimiento de los flujos de conversación por los que ha pasado el usuario en el bot y también de
las métricas para saber cuánto tiempo se ha tardado en completar una tarea concreta.

En primer lugar, configuramos el cliente de Application Insights en el archivo config:

global.telemetryModule = require('./telemetry-module')
const appInsights = require('applicationinsights')
appInsights.setup(process.env.APPINSIGHTS_INSTRUMENTATION_KEY).start()
global.appInsightsClient = appInsights.getClient()

Después, creamos un módulo de telemetría para gestionar el trabajo de telemetría:

Por último, creamos diferentes objetos de telemetría en cada diálogo para realizar el seguimiento
del usuario que ha visitado el diálogo. Por ejemplo:

// Store entity data in dialogData


session.dialogData.entities = data;
// Create a new telemetry module with session data
session.dialogData.telemetry =
telemetryModule.createTelemetry(session, { setDefault: false });
// Track that the user has been to the activate sim dialog
appInsightsClient.trackTrace('activateSIM',
session.dialogData.telemetry);
Caso práctico técnico:
Febrero Lorem
Threeipsum dolor sit amet, consectetur 32
2018 adipiscing elit

Luego podemos recuperar los resultados de seguimiento en el portal Analytics en Azure


Application Insights:

Para realizar el seguimiento del tiempo que se ha tardado en enviar un formulario, se utilizó
el siguiente código:

// Setup a telemetry module


session.dialogData.measuredEventTelemetry =
telemetryModule.createTelemetry(session);
// Start timer. We want to track how long it takes for us to submit a
SIM activation request
session.dialogData.timerStart = process.hrtime();
.
.
.
// Submittion has been made, calculate how long it took.
var timerEnd = process.hrtime(session.dialogData.timerStart);
// Save the time it took to 'metrics' within the
measuredEventTelemetry module
session.dialogData.measuredEventTelemetry.metrics = (timerEnd[0],
timerEnd[1] / 1000000);
// Track the above metric as 'timeTaken'
appInsightsClient.trackEvent('timeTaken',
session.dialogData.measuredEventTelemetry);
Caso práctico técnico:
Febrero Lorem
Threeipsum dolor sit amet, consectetur 33
2018 adipiscing elit
Caso práctico técnico: Three 34

Conclusión Dificultades

Iniciamos este proyecto con el objetivo • La documentación del SDK de Node.js


de crear un bot que pudiera guiar a los puede ser difícil de seguir en su formato
usuarios a través de varios escenarios actual y parece limitada en comparación
de autoservicio, como la activación de con la documentación del SDK de
una tarjeta SIM y la respuesta a preguntas C#. En ocasiones, esto dificultaba la
frecuentes generales, con la idea de pasar búsqueda de la información necesaria
rápidamente a producción. para crear el bot. Sin embargo, hay
disponibles muchos ejemplos de
Como resultado, hemos desarrollado código útiles.
un bot convincente que debería ahorrar
bastante tiempo y dinero a Three. Facilitará • Los comentarios de errores de los
el trabajo a los agentes del servicio servicios LUIS y QnA son limitados
de atención al cliente, ya que no tendrán o inexistentes en el caso de QnA Maker.
que ocuparse de las preguntas más Esto dificultó depurar y averiguar
sencillas o generales que se formulan con por qué las cosas no funcionaron
más frecuencia, por lo que podrán disponer del modo previsto.
de más tiempo para tratar consultas más
específicas y complicadas. El bot también • Todavía está en desarrollo una guía
debe proporcionar a los clientes un clara de las prácticas recomendadas
método más simple y rápido para obtener de desarrollo para el marco de bot.
respuestas a sus preguntas a través de una Al desarrollar un bot destinado
experiencia de conversación guiada. a producción, sería útil conocer las
Three considera que esto cambiará prácticas recomendadas para llevar
el comportamiento tanto de los clientes a cabo acciones como las siguientes:
como de los agentes, aumentando
su productividad. ◦◦ Determinar la estructura del
proyecto.
◦◦ Pedir comentarios al usuario
al final de un diálogo.
◦◦ Usar LUIS en vez de expresiones
regulares.
Caso práctico técnico:
Febrero Lorem
Threeipsum dolor sit amet, consectetur 35
2018 adipiscing elit

Aprendizaje
Los mensajes de bienvenida no funcionan con Slack

A diferencia de otros canales, onConversationUpdate no se activa cuando se agrega un bot


a Slack. Además, contactRelationUpdate no se activa cuando se agrega un usuario a Slack. Esto
significa que actualmente no hay manera de dar la bienvenida a un usuario de Slack y presentarlo
al bot, sin antes interactuar con el bot. Descubrimos que el canal nativo de Slack se ocupa de esto.
Si se utiliza un socket web, el marco de Slack envía un evento bot_added para avisarle cuando
un usuario ha añadido un bot a su canal de Slack. Sin embargo, Microsoft Bot Framework no usa
sockets web con Slack y no recibe una notificación de este evento.

El paquete QnA Maker pregenerado es "semipermanente"

Si inicia el diálogo de QnA, no hay una salida evidente de este flujo de diálogo. El usuario se quedaría
bloqueado usando el servicio QnA y no podría continuar usando los demás diálogos del bot,
a menos que se use el comando global restart. La solución es llamar directamente a la API de QnA
y finalizar el diálogo después de responder a la pregunta. De esta manera, los usuarios pueden hacer
una pregunta en medio de otro diálogo, obtener su respuesta mediante el servicio QnA y, después,
continuar en el último diálogo en el que estaban. La implementación de esto se puede encontrar
en la sección "Ejecución técnica" de este documento (en QnA Maker) o en este repositorio de GitHub
de ejemplo.

Cómo implementar palabras seguras

Con las expresiones regulares y las acciones, podemos configurar comandos globales que los usuarios
pueden usar en cualquier punto del bot. De este modo, los usuarios pueden volver de un diálogo
cuando se queden bloqueados en un flujo de conversación.

bot.endConversationAction('goodbye', 'Goodbye :)', { matches: /^bye/


i });
bot.beginDialogAction('home', '/start', { matches: /^home/i });
bot.beginDialogAction('help', '/help', { matches: /^help/i });
Caso práctico técnico:
Febrero Lorem
Threeipsum dolor sit amet, consectetur 36
2018 adipiscing elit

Uso de las intenciones de LUIS mediante triggerActions y ajuste de intentThreshold

En lugar de usar el método habitual de establecer coincidencias con las intenciones de LUIS:

intents = new builder.IntentDialog({recognizers: [recognizer]});

intents
.matches('LUIS_Intent', '/dialog')
.matches('LUIS_Intent', '/dialog')
.onDefault(builder.DialogAction.send("I'm sorry. I didn't
understand."));

Averiguamos que era mucho más limpio establecer las coincidencias de las intenciones de LUIS
con los diálogos mediante triggerActions (que simplemente se agrega al final de un diálogo).
Esto también nos llevó a descubrir que se puede establecer un umbral que deben cumplir las
intenciones de LUIS para que se activen mediante intentThreshold. El valor predeterminado es
activar acciones aunque la confianza de la coincidencia sea inferior a 0,1.

.triggerAction({
matches: 'ActivateSIM',
intentThreshold: 0.5
})

También se puede añadir intentThreshold a nivel global, de modo que se aplique a todas las
coincidencias de LUIS:

intents = new builder.IntentDialog({ recognizers: [recognizer],


intentThreshold: 0.5 });
Caso práctico técnico:
Febrero Lorem
Threeipsum dolor sit amet, consectetur 37
2018 adipiscing elit

Una manera fácil y limpia de rellenar formularios

Desarrollamos una forma limpia de hacer preguntas a los usuarios para rellenar un formulario
mediante la recursión de diálogos.

En primer lugar, se crea una matriz de preguntas:

var questions = [
{field: 'mobileNumber', question: 'What is the existing number you
want to keep?'},
{field: 'mobileNumber2', question: 'What is your temporary new
Three number?'},
{field: 'pac', question: 'What is your PAC number?'},
{field: 'emailPayMonthly', question: 'What is your email
address?'},
{field: 'fullName', question: 'What is your full name?'},
{field: 'dob', question: 'What is your birthday (e.g.
01/01/1901)?'},
{field: 'address1', question: 'What is the first line of your
address?'},
{field: 'postcode', question: 'What is your postcode?'}
]

Después, se recorre cada pregunta llamando al mismo diálogo y pasándole un índice de contador;
después de que se conteste cada pregunta se guarda la respuesta del usuario:

bot.dialog('FillOutForm', [ Puedes encontrar


function (session, args) { un ejemplo de código
session.dialogData.index = args ? args.index : 0
session.dialogData.form = args ? args.form : {} de seguimiento aquí:
Muestra de formulario
builder.Prompts.text(session,
questions[session.dialogData.index].question) simple para el SDK
}, de Node
function (session, results) {
// Save users reply
var field = questions[session.dialogData.index++].field
session.dialogData.form[field] = results.response

// Check for end of form


if (session.dialogData.index >= questions.length) {
session.privateConversationData.portForm = session.dialogData.form
session.beginDialog('EndofForm')
} else {
session.replaceDialog('FillOutForm', session.dialogData)
}
}
Caso práctico técnico:
Febrero Lorem
Threeipsum dolor sit amet, consectetur 38
2018 adipiscing elit

Planes de producción
El plan para este bot es implementarlo en pruebas A/B en las próximas semanas para poder
probarlo con clientes reales. Después de la prueba A/B de una semana, el plan es poner este
bot en producción en unos meses.

De cara al futuro, Three reconoce que puede proporcionar una experiencia más
enriquecedora si cumple con lo siguiente:

• En lugar de establecer el enlace con los recursos del sitio web de Three, el usuario puede
hacer las preguntas al bot en función del tema de la página y recibir respuestas en función
de su contenido.

• Integración con las API: existen API basadas en red para resolver problemas de cobertura
e interrupciones, así como para informar de un problema, que podrían incorporarse
en una experiencia de bot.

• Publicación en formularios: por ejemplo, la solicitud de una tarjeta SIM o la portabilidad


de un número a Three se pueden facilitar a través del bot.

• Entrega a un centro de llamadas o agentes en directo.

• Personalidad y personalización: dirigirse al usuario por su nombre y personalizar


el contenido para que se adapte a él.
Caso práctico técnico:
Febrero Lorem
Threeipsum dolor sit amet, consectetur 39
2018 adipiscing elit

“Gracias a todos por invitarnos


a esta increíble semana. Ha sido
muy divertido y tenemos algo
más que un esqueleto de un
producto real para comercializarlo.
Nos duele tener que volver
al trabajo de verdad mañana".
Justin Beasley
Director jefe de desarrollo digital

“Gracias a @microsoft-simon
y a todos los amigos de MS.
Lo pasamos muy bien
y aprendimos mucho".
Stuart Brown
Director de desarrollo digital
Caso práctico técnico: Three 40

Recursos Documentación:
Microsoft Bot Framework

adicionales QnA Maker


LUIS

Código:
Ejemplo de solicitud individual de QnA para el SDK
de Node.js
Ejemplo simple del SDK de Node.js para rellenar
un formulario

Equipo Microsoft:
Lilian Kasem: evangelista técnica
Simon Michael: evangelista técnico sénior
Bill Barnes: ingeniero principal de desarrollo de software

Three:
Justin Beasley: director jefe de desarrollo digital
Nick Bishop: director jefe de desarrollo digital
Stuart Brown: director jefe de desarrollo digital
Thomas Barton: maestro Scrum
Dimos Fountoukos: desarrollador de software
Caso práctico técnico: Powel 41

Caso
práctico
técnico:
Powel
Caso práctico técnico:
Febrero Lorem
Powelipsum dolor sit amet, consectetur 42
2018 adipiscing elit

Caso práctico técnico En marzo de 2017, en las oficinas

Uso de CaaP
de Microsoft en Lysaker, Noruega,
Microsoft se asoció con Powel para crear

y André, el
un nuevo bot llamado André. El objetivo del
hackfest era crear un chatbot controlado

bot asistente
por voz que pudiera ayudar a los ingenieros
de campo de las redes eléctricas a responder

controlado por
preguntas y proporcionar capacidades
de informe durante las inspecciones para

voz, para mejorar
que tuvieran libres las manos. La solución
se creó con herramientas de Microsoft

la inspección in situ
y aprovechando las tecnologías de chatbots
y conversaciones como plataforma (CaaP).

Pedro Dias y Anders Gill


19 de junio de 2017
Caso práctico técnico: Powel 43

En este hackfest, utilizamos las


siguientes tecnologías clave:
Equipo central
• Microsoft Bot Framework
• Microsoft Cognitive Services
• Language Understanding Intelligent
Powel
Services (LUIS) • Damian Plaza,
• Xamarin.Forms ingeniero de software
• Bing Speech API
• GitHub • Jakub Hiszczyn,
• Visual Studio Team Services
ingeniero de software
• Visual Studio 2017 • Karol Stosik,
ingeniero de software
Además, el equipo expresó la necesidad
de obtener más experiencia práctica con • Maksymilian Jastrzebski,
ingeniero de software
• Automatización de pruebas • Tor Hovland,
• Escenarios de integración continua ingeniero de software
y entrega continua (CI/CD)
• Simen Karlsen,
El hackfest se llevó a cabo después
habilitador de red inteligente
de varias llamadas en las que se desmitificó • Øystein Askeland,
el área problemática y estableció el ámbito diseñador de interacción
de las ambiciones del hackfest.
Microsoft

• Pedro Dias,
evangelista técnico sénior

• Anders Gill,
evangelista técnico
Caso práctico técnico: Powel 44

Información general
de la solución
Powel prevé un futuro en el que los El objetivo era poder diseñar dos diálogos
ingenieros in situ puedan utilizar la voz de conversación claramente diferenciados
como principal impulsor del soporte con suficiente funcionalidad para probarse
asistido por ordenador durante las en el campo. Basándose en estos diálogos,
inspecciones de las centrales eléctricas. Powel habría acumulado suficiente
Durante la inspección de una estación experiencia con CaaP como para enriquecer
eléctrica o de una línea eléctrica, el uso André e idear aplicaciones de conversación
de André, una aplicación telefónica basada similares para usarse en otras áreas.
en Xamarin, liberará las manos de los
ingenieros, proporcionando un proceso más Usamos Xamarin.Forms, Microsoft Bot
fluido que el hecho de tener que rellenar Framework, LUIS y Cognitive Services
un formulario en papel o registrar datos para desarrollar un bot que permitiera
en una aplicación de dispositivo. Mediante al ingeniero hablar con la aplicación
las capacidades de un dispositivo portátil, Android Xamarin.Forms. La aplicación
como un teléfono móvil, la aplicación utiliza el motor de reconocimiento de
sabrá automáticamente qué instalación voz de Google para transformar el audio
se está inspeccionando al obtener la en texto; el texto se envía a LUIS para
ubicación GPS del usuario y proporcionará determinar la intención del usuario
las listas de puntos de control y los diálogos en cualquier momento de la conversación.
necesarios apropiados para esa instalación. Basándose en la intención y las
entidades detectadas, Bot Framework
El hackfest se centró en dos objetivos envía la respuesta apropiada de vuelta
de inspección distintos: a la aplicación cliente, la cual le lee
la respuesta al ingeniero, ayudándole
• Centrales eléctricas a mantener su seguridad ya que
• Líneas eléctricas no tiene las manos ocupadas.
Caso práctico técnico: Powel 45

Una característica concreta que realmente amplía la utilidad de este bot fue la integración de Bot
Framework en el sistema de back-end de Powel. Integramos correctamente el bot en los sistemas
que, por ejemplo, permitirían a los ingenieros extraer información valiosa, como

• el historial inspecciones en instalaciones específicas


• piezas concretas propensas a un mantenimiento constante
• información ampliada sobre las instalaciones
• la ruta más rápida a la siguiente instalación prioritaria crítica que necesita reparación
• una lista de comprobación de métodos posibles de rectificación

“Microsoft Bot Framework y


Cognitive Services nos ayudarán en
Powel a capacitar a nuestros clientes
al ofrecerles una jornada laboral más
sencilla, más segura y más eficiente".
Simen Karlsen
Habilitador de red inteligente, Powel
Caso práctico técnico: Powel 46

Perfil del Los problemas


cliente: planteados
El principal aspecto que todas las
empresas hacen cumplir es la seguridad
de los trabajadores. Powel no es ninguna
excepción. Sin embargo, algunos trabajos
son más peligrosos que otros. Powel
tiene algunos de los mayores clientes
Powel se extiende por toda Europa con
de Noruega que mantienen y desarrollan
una base de clientes amplia y sostenible,
redes eléctricas. Estas inspecciones
además de una larga historia como
deben realizarse una vez al año en cada
proveedor de confianza de soluciones
instalación. Una vez cada diez años deben
de software para ciudades, municipios,
realizarse otras inspecciones técnicas más
condados, el sector energético y el sector
exhaustivas de todos los componentes
de la contratación. Powel genera alrededor
de la red eléctrica. Estos períodos de
de 50 millones USD de ingresos cada año
inspección se aplican por ley.
y se fundó en Noruega en 1996. Powel
se ha convertido en una corporación
Para realizar una inspección, es posible
internacional con una plantilla de 460
que un ingeniero tenga que escalar
empleados con oficinas en estos seis países,
postes altos que pueden crear situaciones
además de Noruega: Suecia, Dinamarca,
peligrosas dependiendo del clima y otros
Suiza, Chile, Turquía y Polonia.
factores. Estas inspecciones se llevan
a cabo especialmente en invierno, cuando
Segmentos de negocio de Powel:
el hielo en el suelo dificulta el desarrollo
de nuevas redes. Esto obliga a las empresas
• Energía Inteligente
a centrarse en el mantenimiento, que
• Rendimiento de activos
también es una tarea importante. Por
• Medición
este motivo, sería muy incómodo tener
• Agua y comunidad
un teléfono móvil o un cuaderno en
• Construcción
la mano cuando se podría estar colgado
a muchos metros del suelo.
Caso práctico técnico: Powel 47

Por consiguiente, un ingeniero ha Una inspección podría ser cualquier cosa,


de recordar qué debe comprobar, qué desde la evaluación de las instalaciones
problemas potenciales podrían existir, y el envío de datos sobre los tipos de
si se ha realizado otro mantenimiento problemas descubiertos (actualmente
en este determinado poste o estación, qué mediante una lista de comprobación) hasta
tipos de soluciones contrarrestan cualquier la resolución efectiva de los problemas.
problema descubierto, etcétera. Basándose Los problemas habituales van desde
en estos datos, el ingeniero tiene que que los pájaros carpinteros picoteen los
regresar a la oficina principal para entregar postes o grafitis hasta problemas más
la información a sus colegas o digitalizarla graves, como errores en los componentes
él mismo. Durante este tránsito, puede eléctricos de alto voltaje.
perderse información valiosa y el contexto
específico recopilados durante la inspección. En resumen, el chatbot

• evitará problemas de seguridad al dejar


Powel requiere una solución que permita las manos libres
a los ingenieros tener las manos libres • proporcionará conocimiento específico
y que, al mismo tiempo, agregue valor relacionado con instalaciones concretas
a la conversación. Un chatbot activado • administrará la entrega tomando
por un simple "Hola, André" podría aliviar notas de la inspección actual para que
potencialmente al ingeniero de tener no se pierdan datos durante la misma
que recordar todas las tareas que debe • prestará soporte al ingeniero con otra
ejecutar durante la inspección. Lo bueno información relevante que pueda ser
de un chatbot de este tipo es que podría importante conocer o que haya podido
estar conectado con todos los sistemas olvidar durante la inspección
que sean relevantes y podría proporcionar
la información que el ingeniero necesitara.
Este fue uno de nuestros objetivos para
el hackfest: poder desarrollar un chatbot
simple que pudiera dialogar con sistemas
externos y devolver conocimiento valioso
que pudiera aumentar la eficiencia durante
la inspección.
Caso práctico técnico: Powel 48

Solución La historia de usuario era la siguiente:

y pasos
Como trabajador de campo, quería
poder enviar inspecciones que fueran
correctas a un bot para no tener que
rellenar un formulario al efecto.
Pedro inició el hackfest y presentó Bot
Framework al equipo, mostrando ejemplos Definimos las características y tareas para
de un bot en funcionamiento, explicando facilitar la distribución del trabajo entre
las características y asegurándose de que el equipo. Creamos dos repositorios: uno
todo el equipo estuviera al día antes para la aplicación ASP.NET bot y otro para
de que empezáramos el desarrollo. la aplicación Xamarin.Forms. También
configuramos CI en Bot Framework,
El objetivo del hackfest de tres días era para que se compilara e implementara
crear una aplicación cliente en Xamarin. en Microsoft Azure después de cada
Forms para Android que pudiera visualizar confirmación.
la conversación que el ingeniero tendría
usando Bot Framework con LUIS y
Cognitive Services. Creamos una historia
de usuario en Visual Studio Team Services
que consistía en múltiples tareas.
Caso práctico técnico: Powel 49

Panel Kanban

Decidimos usar Android para la El bot de prueba de concepto (PoC)


parte de visualización porque todos desarrollado durante el hackfest se
los desarrolladores de Powel tenían utilizaría como base que le serviría a Powel
dispositivos Android. Además de para llevar su propio bot a producción
desarrollar una aplicación de trabajo, después de un desarrollo posterior.
el objetivo también era formar
a los desarrolladores de Powel en Bot
Framework y CaaP, para que pudieran
aportar su conocimiento al diseño
a la hora de desarrollar y ampliar
sus aplicaciones para escenarios que
pudieran aprovechar Bot Framework
y Cognitive Services.
Caso práctico técnico: Powel 50

Esbozo de cómo un ingeniero de campo inspeccionaría normalmente una central eléctrica

Al final del hackfest se logró lo siguiente: Lo siguiente no se implementó pero estaba


en el ámbito del hackfest:
• Inspección de central eléctrica
◦◦ Listas de puntos de control • Inspección de líneas eléctricas
y diálogos apropiados para una • Traducción del texto del noruego
instalación específica al inglés
◦◦ Selección de subestaciones • Carga de la imagen desde la aplicación
◦◦ Selección del tipo de discrepancia móvil
◦◦ Registro de discrepancias con • Activación de la conversación por
comentarios, integrados con voz sin usar un botón
el back-end de Powel
Caso práctico técnico: Powel 51

El chatbot PoC actual permite al ingeniero de campo llevar a cabo una inspección iniciando una
conversación con la voz, preguntar por sus capacidades, seleccionar una subestación y registrar
una discrepancia de un tipo específico con un comentario. De este modo se satisface el bucle
de comentarios enviando los datos directamente al back-end de Powel para que el ingeniero de
campo ya no tenga que estar físicamente presente en las oficinas para registrar la misma información.

Diagrama de la arquitectura
Caso práctico técnico: Powel 52

Ejecución
Ahora tienes todo lo que necesitas para
crear una aplicación de bot. Para obtener

técnica
una referencia completa sobre cómo
comenzar a usar Bot Builder, consulta SDK
de Bot Builder para .NET.

Configuración del
entorno de desarrollo Logros día 1
André es una aplicación Xamarin.Forms, por
Para empezar con el proyecto, tuvimos que
lo que necesitábamos implementar servicios
instalar y configurar lo siguiente:
nativos para que la aplicación móvil
escuchara y hablara a través de la interfaz
Visual Studio
de reconocimiento de voz de Google.
También empezamos a trabajar en los
• Instalar Visual Studio 2017 (Visual Studio
componentes de chat de la aplicación.
2015 también sirve)
Nota: Asegúrate de que Xamarin está incluido
Con LUIS, tuvimos 10 intentos descritos
en tu instalación de Visual Studio para
y entrenados con expresiones. Empezamos
desarrollar la aplicación André.
a escribir diálogos imaginarios entre
un usuario y la aplicación para entender
• Descargar e instalar el emulador de Bot
mejor cómo fluiría la conversación.
Framework
También comenzamos a experimentar con
entidades de LUIS y que se reconocieran las
• Descargar e instalar la plantilla de bot
intenciones y se usaran estas entidades.
para Visual Studio para C#

Para Bot Framework, creamos una


Language Understanding Intelligent
aplicación de bot en el espacio dev.
Services (LUIS)
framework.com y un sitio en Azure
para la API web.
Para usar LUIS, ve a la página principal
de LUIS y crea una cuenta. Puedes probarlo
gratuitamente para recibir un generoso
número de mensajes por día.
Caso práctico técnico: Powel 53

Configuración del bot en Azure Configuramos CI en Visual Studio Team


Services para compilar e implementar
Bot Framework funciona esencialmente el bot en Azure en cada confirmación.
como cualquier servicio de aplicación ASP. Después agregamos la integración de LUIS
NET. Tiene un controlador que controla para empezar a trabajar con los intentos.
los mensajes de conversación, por lo que, En este momento, teníamos dos intentos
básicamente, todo lo que necesitas hacer implementados.
es lo siguiente:

• Crear o registrar un nuevo bot en el sitio


para desarrolladores de Bot Framework.
Obtendrás un identificador de bot
(GUID) y un secreto de aplicación
para tu bot.

• Anota el identificador de la aplicación


y la contraseña en el mismo portal.

• Implementa el código del bot


en Azure App Service.

• Configura tus opciones para incluir


el identificador de aplicación y
la contraseña de modo que puedas
conectar la API web con Bot
Framework.

(Para obtener una referencia completa


de este proceso, consulta Implementar
un bot en el cloud).

Decidimos utilizar la clase


CloudConfigurationManager para leer
la configuración directamente desde
App Service.
Caso práctico técnico: Powel 54

Logros día 2
Finalizamos la conexión directa mediante la biblioteca de clases portátil (PCL) WebSockets
pero acabamos usando HTTP porque no pudimos hacer funcionar la PCL. Esto se debió en gran
medida a la dificultad de conseguir que WebSockets funcionara en Android: no estábamos
seguros de si teníamos una solución rápida, así que, en aras del tiempo, optamos por no hacerlo
y centramos nuestros esfuerzos en hacer que todo funcionara.

Conectamos correctamente la aplicación de bot con el back-end de Powel (una API llamada
Condition Monitoring) mediante el uso de las API.

Nota acerca de las API de back-end

Conectamos las API de back-end de Powel mediante algunos paquetes NuGet internos
de Powel y llamamos a los métodos en los objetos que contenían.

Fue muy sencillo obtener acceso a estos paquetes NuGet a través de Visual Studio
Team Services para CI. Debido a la confidencialidad del código, no podemos compartir
ejemplos de código específicos, pero, en esencia, utilizamos las API para obtener los
identificadores de instalación mediante ubicación GPS (longitud/latitud) y para enviar
los datos de informe.

Conectamos la aplicación móvil al bot y la hicimos funcionar. También pasamos algún tiempo
diseñando la aplicación Xamarin.Forms y asegurándonos de que la interfaz y la experiencia
de usuario fueran buenas.
Caso práctico técnico: Powel 55

La siguiente imagen es un boceto inicial de la interfaz de diseño, creada con


PowerPoint Storyboarding.

Además, trabajamos para conseguir que los paquetes NuGet de las API principales de Powel
(específicamente, la API de supervisión de estado) se incluyeran en la compilación del bot.
Trabajamos en algunos planes de flujo de conversación para su posterior implementación
y dedicamos tiempo a trabajar en los intentos y a entrenar a LUIS para que los reconociera.
Caso práctico técnico: Powel 56

Dedicamos mucho tiempo a los objetos PromptDialog porque nos olvidamos de establecer
la implementación del diálogo como [Serializable].

Otras dificultades que tuvimos:

Algunos problemas con la discrepancia de la versión de .NET Framework y Bot Framework


WebApiConfig de la plantilla de bot convirtieron todos los nombres de parámetros a mayúsculas
y minúsculas tipo JSON. Esto no lo aceptó la API de Powel interna, lo que llevó algún tiempo
averiguarlo.
La configuración inicialmente se parecía a la siguiente.

JsonConvert.DefaultSettings = () => new JsonSerializerSettings()


{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Formatting = Newtonsoft.Json.Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore,
};

Simplemente quitamos la línea ContractResolver y eso pareció solucionar el problema.

Finalizamos el día probando el bot en exteriores


para ver cómo gestionaba el ruido de fondo
y si sería capaz de capturar la intención del
ingeniero de campo. La ubicación elegida
fue un entorno ruidoso (una autopista) que
podría ser un sitio de inspección real donde
un ingeniero de campo tuviera que inspeccionar
una línea aérea o un poste eléctrico. La prueba
tuvo resultados positivos.
Caso práctico técnico: Powel 57

Logros día 3
La parte final de la configuración del hackfest fue la automatización de la compilación del proyecto
Xamarin.Forms utilizando Visual Studio Mobile Center, así como la búsqueda de posibilidades para
crear una conversación que fluyera en diferentes diálogos.

El siguiente diagrama muestra el flujo final del chatbot PoC. (Lamentablemente, no implementamos
la traducción de textos debido a limitaciones de tiempo, pero incluimos esa parte en la siguiente
imagen).

Un trabajador de campo habla con André (la aplicación móvil) en su lenguaje natural. El motor
de reconocimiento de voz de Google transforma la voz en texto y la devuelve a la aplicación móvil.
La aplicación envía el texto a traducir y recibe el texto totalmente traducido. A continuación,
la aplicación pasa el texto traducido a LUIS, que captura la intención y las entidades, y devuelve
la respuesta a la aplicación móvil. La aplicación móvil envía la intención y las entidades detectadas
(incluido el identificador del trabajador de campo) a Bot Framework, que envía una solicitud al
back-end de Powel. Se devuelve la respuesta apropiada a la aplicación móvil, que traduce el texto
al idioma del trabajador de campo y dice el texto en voz alta.
Caso práctico técnico: Powel 58

Gestión de los diálogos


En Bot Framework, un diálogo funciona como el "cerebro" del chatbot.

Un diálogo proporciona un par de características que administran el estado de la conversación


y las sesiones, así como la persistencia que se basa en una implementación de una interfaz llamada
IDialog. Esta interfaz administra la transición de estado mediante IDialogContext. Estos
principios se han incluido en la forma en que trabajamos con el bot durante el hackfest y forman
parte integral del bot, lo que le permite dirigir una conversación usando la pila subyacente, donde
guarda los datos en el objeto de sesión, al que se puede acceder a lo largo de la conversación.

Un ejemplo: cuando LUIS reconoce la intención del usuario de ser feliz, Bot Framework irá a ese
método concreto con la intención y ofrecerá la respuesta apropiada.

[LuisIntent("happy")]
public async Task Happy(IDialogContext context, LuisResult result)
{
await context.PostAsync("That's so kind of you!");
context.Wait(MessageReceived);
}
Caso práctico técnico: Powel 59

Otro ejemplo sería cuando LUIS reconoce que el usuario quiere seleccionar una subestación.

[LuisIntent("selectSubstation")]
public async Task SelectSubstation(IDialogContext context, LuisResult
result)
{
AssetService assetService = new AssetService(new
AssetRepository());
string extractedName;
string message = "I'm sorry, I didn't catch the name of the
substation.";

if (TryExtractingSubstationName(result, out extractedName))


{
var asset = await assetService.GetByName(extractedName);
substationName = asset != null ? extractedName : null;
message = asset != null ? $"The substation {substationName}
has been chosen." : $"Sorry, I didn't find a substation called
'{extractedName}'.";
}

await context.PostAsync(message);
context.Wait(MessageReceived);
}
Caso práctico técnico: Powel 60

También se desarrollaron diálogos más complejos en los que Bot Framework se comunica con
el back-end de Powel apropiado y enumera los posibles tipos de discrepancia entre los que puede
elegir el ingeniero de campo.

[LuisIntent("getDiscrepancyType")]
public async Task SelectControlPoints(IDialogContext context,
LuisResult result)
{
if (String.IsNullOrEmpty(substationName))
{
await context.PostAsync($"You need to tell what substation you
want to select.");
context.Wait(MessageReceived);
}
else
{
DiscrepancyTypeService discrepancyService = new
DiscrepancyTypeService(new DiscrepancyTypeRepository(new
InspectionRepository(new AssetRepository()), new AssetRepository()));
AssetService assetService = new AssetService(new
AssetRepository());
InspectionService inspectionService = new
InspectionService(new InspectionRepository(new AssetRepository()));
var asset = await assetService.GetByName(substationName);
var inspection = await
inspectionService.GetNotPerformedByAssetId(asset.ObjectId);
var discrepancyTypes = await
discrepancyService.Get(asset.ObjectId, inspection.Id);

await context.PostAsync($"You have your discrepancy types


here:\n {JsonConvert.SerializeObject(discrepancyTypes)}");
context.Wait(MessageReceived);
}
}
Caso práctico técnico: Powel 61

Diálogo de solicitud
Bot Framework incluye varias solicitudes incorporadas que pueden obtener información de un usuario.
Este tipo de solicitud se utilizó a lo largo de todo el proyecto del bot, por ejemplo, cuando André
pregunta al ingeniero de campo si está satisfecho con la inspección y quiere terminar. Se basa en el
reconocimiento de una intención de LUIS de assetAllGood.

[LuisIntent("assetAllGood")]
public async Task AssetAllGood(IDialogContext context, LuisResult
result)
{
if (String.IsNullOrEmpty(substationName))
{
await context.PostAsync($"You need to tell what substation you
want to select.");
context.Wait(MessageReceived);
}
else
{
PromptDialog.Confirm(context, AfterConfirmAsync, "Are you sure
that you want to finish this inspection?");
await Task.FromResult<Object>(null);
}
}

En el escenario anterior, se le pide al ingeniero de campo que confirme con "Sí" o "No" (ya sea
tocando el botón apropiado o usando la voz para responder), pero se pueden elegir otros muchos
tipos de entradas de recopilación de datos:

• Prompts.text: pide al usuario que introduzca una cadena de texto


• Prompts.confirm: pide al usuario que confirme una acción
• Prompts.number: pide al usuario que introduzca un número
• Prompts.time: pide al usuario una hora o una fecha
• Prompts.choice: pide al usuario que elija en una lista de opciones
• Prompts.attachment: pide al usuario que cargue una imagen o un vídeo
Caso práctico técnico: Powel 62

FormFlow

Como hemos visto, los diálogos funcionan como un mecanismo potente para guiar una
conversación, pero pueden volverse complejos cuando el rompecabezas tiene muchas piezas
pequeñas, como pedir un bocadillo. Para simplificar una conversación guiada, Bot Framework
ofrece FormFlow, una forma mucho más fácil de construir un diálogo. Un diálogo FormFlow guía
al usuario por el proceso de rellenar el formulario, a la vez que le proporciona ayuda y orientación
a lo largo del proceso. Se utilizó el diálogo de formulario cuando el ingeniero  de campo necesita
enviar una discrepancia, para lo cual tiene que rellenar los campos restantes, incluido el tipo
de discrepancia y el comentario.

[Serializable]
public class DiscrepancyFormDialogBuilder
{
public string DiscrepancyType;
public string Comment;

public static IForm<DiscrepancyFormDialogBuilder> BuildForm()


{
return new FormBuilder<DiscrepancyFormDialogBuilder>()
.AddRemainingFields()
.Build();
}

public static IFormDialog<DiscrepancyFormDialogBuilder>


Build(FormOptions options = FormOptions.PromptInStart)
{
// Generated a new FormDialog<T> based on IForm<BasicForm>
return FormDialog.FromForm(BuildForm, options);
}
};
Caso práctico técnico: Powel 63

Connector
El componente Connector de Bot Framework proporciona una única API para que el bot se
comunique a través de varios servicios de cliente, como Skype, correo electrónico y Slack. Debido
a que ya estábamos usando Slack para la comunicación durante el hackfest, decidimos configurar
la integración con Slack para que pudiéramos hablar con el bot de un modo eficiente (lee los
pasos para configurar canales de bot en la sección "Configuración de canales" de Introducción al
conector).

En la siguiente imagen, puedes ver el aspecto que tiene la prueba de la conversación usando Slack.

Conseguimos configurar la integración de Slack mediante el registro el bot en el espacio de


dev botframework y la selección del tipo de conector sin necesidad de codificación.
Caso práctico técnico: Powel 64

Comunicación con el bot


Direct Line es una simple API REST para conectarse directamente al bot. El objetivo principal
de esta API es permitir a los desarrolladores conectar agentes personalizados al bot para habilitar
las conversaciones. Tal como se ha mencionado anteriormente, inicialmente nos propusimos
implementar la conectividad a través de WebSockets en la aplicación móvil desarrollada en
Xamarin.Forms, pero decidimos cambiar a HTTP porque no podíamos hacer funcionar la PCL.
El siguiente código muestra una tarea de envío simple.

public async Task Send<T>(T item)


{
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new
MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new
AuthenticationHeaderValue("Bearer",
_conversationStartedResponse.Token);
var content = JsonConvert.SerializeObject(item);

var response = await client.PostAsync($"https://


directline.botframework.com/api/conversations/
{_conversationStartedResponse.ConversationId}/messages", new
StringContent(content, Encoding.UTF8, "application/json"));
}

Otras medidas implementadas


En Bot Framework, se tienen que proporcionar directamente BotId, MicrosoftAppId y
MicrosoftAppPassword en el archivo web.config para establecer la configuración apropiada
de la aplicación. Debido a problemas de seguridad, no queríamos hacer esto. Para proporcionar
la configuración de una forma más segura, tomamos los valores de configuración de
CloudConfigurationManager o de un archivo JSON local con la configuración del bot.
Caso práctico técnico: Powel 65

Escribimos el siguiente código para el lector de la configuración.

public string this[string index]


{
get
{
var settingValue =
CloudConfigurationManager.GetSetting(index);

if (string.IsNullOrEmpty(settingValue))
settingValue = GetByLocalJsonFile(index);

return settingValue;
}
}

private string GetByLocalJsonFile(string index)


{
var path =
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserP
rofile), "FieldWorkerBotSettings.Json");
if (!File.Exists(path))
return string.Empty;

var fileContent = File.ReadAllText(path);


if (string.IsNullOrEmpty(fileContent))
return string.Empty;

var json = JObject.Parse(fileContent);

if (!json.HasValues)
return string.Empty;

return json[index].Value<string>();
}
Caso práctico técnico: Powel 66

Esto nos permite crear un nuevo objeto LuisModelAttribute al pasar appId y appKey
en el controlador de mensajes.

private static readonly LuisService _service;

static MessagesController()
{
var settings = new SettingsReader();
var appId = settings["LUIS:AppId"];
var appKey = settings["LUIS:AppKey"];
var model = new LuisModelAttribute(appId, appKey);
_service = new LuisService(model);
}

Debido a que hay demasiado código para mostrar y explicar en este informe, puedes encontrar
todo el código fuente del hackfest en el repositorio de GitHub readyforchaos/Powel-power-station-
inspection-bot.
Caso práctico técnico: Powel 67

Interfaz de usuario del agente


El siguiente GIF animado muestra la aplicación móvil del cliente a la izquierda desarrollada en
Xamarin.Forms y la aplicación Powel Condition Monitoring a la derecha que muestra el estado
de una central eléctrica.
Caso práctico técnico: Powel 68

Conclusión
Los resultados del hackfest fueron tiempo diseñando flujos de conversación y
brillantes y es fascinante pensar que menos tiempo codificando.
los desarrolladores de Powel pasaron
de no saber nada sobre Bot Framework El hecho de poder obtener acceso a toda
a compilar correctamente un chatbot la información del back-end de Powel
integrado que pudiera gestionar con la voz desde una aplicación permite
conversaciones en varios sistemas al ingeniero tomar decisiones basadas
y proporcionar conocimiento muy en la información que puede solicitar
necesario a los ingenieros de campo. simplemente a través de la aplicación,
Powel continuará el desarrollo del chatbot lo que produce informes de inspección
durante los próximos meses para incluir más precisos.
análisis y vistas de historial de partes
específicas antes de pasar a producción, La posibilidad de registrar discrepancias
pero también para ampliar el concepto sobre la marcha, solicitar detalles
a áreas y dominios de aplicación de Powel de la inspección y obtener otra información
distintos del segmento del negocio relacionada permite a los ingenieros
energético. no hacer uso del papel durante las
inspecciones, de modo que es menos
Desde el punto de vista del desarrollador, probable que se olviden de un punto
todas las partes necesarias están ahí de inspección y no tienen el gasto
y su integración para crear una solución adicional de tener que volver a la oficina
parece casi demasiado fácil. Las para digitalizar las conclusiones después
dificultades que encontramos no estaban de su labor.
relacionadas directamente con Bot
Framework en sí, sino específicamente con Lo bueno de este hackfest es que logramos
los desafíos relacionados con Xamarin. crear algo que realmente funciona y que
podría ponerse en producción en muy
La guía proporcionada para Bot Framework poco tiempo. Con LUIS y Bot Framework,
y LUIS tiene el potencial de mejorar, pero ahora podemos dar al trabajador de campo
es suficiente para empezar y, una vez el soporte que necesita cuando lo necesita
que aprendas pasarás la mayor parte del y sin usar las manos.
Caso práctico técnico: Powel 69

De cara al futuro
No conseguimos incluir todas las características que habíamos previsto para el hackfest de tres días.
Las características previstas que se omitieron fueron las siguientes:

• Traducción de texto
• Carga de imágenes desde la aplicación cliente
• Activación de André por voz en vez de usar un botón
• Determinación y corrección de la PCL de WebSockets

Powel tiene la intención de resolver estos problemas poco después del hackfest para producir
un prototipo funcional que se probará en el campo lo antes posible.

Recursos adicionales
¿Quieres probar Bot Framework ahora mismo? Empieza aquí:
Microsoft Bot Framework

¿Quieres probar LUIS y Microsoft Cognitive Services? Ve a


Microsoft Cognitive Services

El código fuente del hackfest se puede encontrar en GitHub:


readyforchaos/Powel-power-station-inspection-bot
Caso práctico técnico: NAVITIME 70

Caso
práctico
técnico:
NAVITIME
Caso práctico técnico:
Febrero Lorem
NAVITIME
ipsum dolor sit amet, consectetur 71
2018 adipiscing elit

Caso práctico técnico Los viajeros quieren experiencias únicas,

NAVITIME
pero encontrar comida local, lugares de
interés, etc., puede ser todo un reto. Con

agrega chatbots
las aplicaciones de viaje típicas, los viajeros
pueden encontrar restaurantes y lugares

para mejorar
famosos, pero no información local. Así
que los viajeros preguntan a los lugareños,

la experiencia
lo cual puede ser difícil dadas las barreras
del idioma. Por ejemplo, muchos viajeros

de la aplicación
conocen el sushi como comida japonesa,
pero desconocen la buena comida local

de viajes
como el shirasu-don y el motsu-yaki.

NAVITIME quiere resolver el problema,


Masayuki Ota por lo que ha implementado un chatbot
28 de junio de 2017 en la aplicación Kamakura Travel Guide.
Los usuarios pueden usar la aplicación
para obtener información sobre lugares
de interés turístico. Además, pueden
comunicarse con el bot para encontrar
comida local y lugares interesantes.
Caso práctico técnico: NAVITIME 72

Tecnologías utilizadas:
• Language Understanding Intelligent • Azure Cosmos DB (antes se llamaba
Service (LUIS) DocumentDB)
• API de Bing Spell Check • Búsqueda de Azure
• API de Bing Images Search • Azure Storage
• Custom Vision Service • Power BI
• API de Text Analytics
• Microsoft Bot Framework
• API de Direct Line
• Azure Web Apps
• Azure Functions
• API Management

Miembros del proyecto Ayako Omori (@ayako_omori):


evangelista técnico, Microsoft Japan
NAVITIME Travel:
Hiroyuki Watanabe (@hiwatan007):
Ikuo Odanaka: director de desarrollo,
evangelista técnico, Microsoft Japan
NAVITIME JAPAN

Naoki Sato (@satonaoki): evangelista


Shinichi Tanabe: ingeniero de desarrollo
técnico sénior, Microsoft Japan
de software sénior, NAVITIME JAPAN

Daiyu Hatakeyama (@dahatake):


Makoto Yoshihama: ingeniero de desarrollo
desarrollador de software principal,
de software, NAVITIME JAPAN
Microsoft Japan

Naoya Sasaki: ingeniero de desarrollo


Masayuki Ota (@masota0517):
de software, NAVITIME JAPAN
evangelista técnico, Microsoft Japan
Caso práctico técnico: NAVITIME 73

Perfil del cliente

NAVITIME JAPAN es un proveedor líder de tecnología y servicios de navegación. Ofrece


principalmente aplicaciones de navegación business-to-business (B2B) y business-to-consumer (B2C).

Para B2B, ofrece aplicaciones de navegación para empresarios, consultoría para transporte
y publicidad. Para B2C, ofrece aplicaciones de navegación para viajar en tren, autobús, coche,
bicicleta o a pie y comenzó un negocio de viajes llamado NAVITIME Travel.

Los problemas planteados


Las barreras lingüísticas pueden suponer un reto incluso para los viajeros más experimentados.
Navitime quería abordar este desafío antes de los Juegos Olímpicos de Tokio en 2020, cuando
los viajeros extranjeros visiten Japón.
Caso práctico técnico: NAVITIME 74

Solución y pasos
Arquitectura

Custom Vision Service


Cognitive
Services
API de Bing Image Search

LUIS API de Bing


API Spell Check
Management
API de Text Analytics
Azure
Web Apps
Azure
Búsqueda Storage Power BI
marco de bot

Direct
Line

Azure Azure Cosmos DB


Functions (datos para búsqueda)

Azure Cosmos DB (registro de comunicaciones)

Usamos Bot Framework para implementar un chatbot y también usamos la API de Direct Line para
comunicarnos con el chatbot desde nuestra aplicación iOS (las aplicaciones Android y Windows
también pueden usar Direct Line). Para extraer la intención y las entidades de la entrada del usuario,
usamos LUIS. Admitimos la corrección ortográfica con la API de Bing Spell Check antes de pasar
el texto a LUIS. Después de extraer la intención y las entidades, llamamos a Búsqueda de Azure para
obtener información sobre la comida local y los lugares turísticos almacenados en Cosmos DB.
Caso práctico técnico: NAVITIME 75

Los usuarios pueden introducir texto libremente, lo que significa que a veces LUIS no puede
identificar las entidades. Por este motivo, también utilizamos la API de Text Analytics para obtener
la frase clave. Consulta Detectar sentimientos, frases clave e idiomas en la Guía de inicio rápido
de Azure Text Analytics. Luego pasamos la frase clave a Búsqueda de Azure.

Los usuarios también pueden comunicarse con el bot usando fotos. Para respaldar este escenario,
implementamos el reconocimiento de imágenes utilizando la API de Bing Images Search y la API
de Custom Vision.

DevOps y la mejora continua también son importantes a la hora de desarrollar bots. Para
administrar las versiones de bot, utilizamos API Management. Para almacenar el registro
de la entrada de usuario, llamamos a Azure Functions y guardamos los datos en Cosmos DB.
También utilizamos Búsqueda de Azure, Azure Storage y Power BI para supervisar los términos
de búsqueda. Podemos obtener las demandas de los usuarios a partir de los registros de texto
y repasar el bot una y otra vez.

Experiencia de usuario por combinación de aplicación y


chatbot
Implementamos el bot en una aplicación iOS porque pensamos que un chatbot podría extender la
experiencia de usuario de la aplicación. Mostramos un mensaje de notificación (la ventana verde de
la siguiente imagen) en la aplicación e invitamos a los usuarios a usar el chatbot en dos situaciones:

1. Cuando un usuario inicia la aplicación por primera vez, el mensaje de notificación dice:
"¡Bienvenido! No dudes en pedirme consejos de viaje e información sobre lugares.".

2. Si la aplicación detecta que el usuario ha visto varios artículos recomendados pero no ha


seleccionado uno, llega a la conclusión de que el usuario no puede encontrar la información
adecuada y dice: "¿No te interesan nuestros artículos recomendados? También puedes...".
Caso práctico técnico: NAVITIME 76

Los usuarios pueden tocar el botón de chat (el cuarto desde la izquierda) en la lista de menú
para iniciar la comunicación con el chatbot. Los usuarios pueden introducir texto libre en inglés
y japonés, por ejemplo, "Quiero comer soba". El bot responde "¿Quieres...?" y recomienda un
restaurante. La aplicación también muestra un menú en el que los usuarios pueden seleccionar
la siguiente acción.
Caso práctico técnico: NAVITIME 77

El usuario puede tocar "Ver más resultados" para ver otra recomendación o "Probar otra palabra
clave" para introducir otras palabras clave. Al tocar el botón "Mapa" se muestra un mapa; al pulsar
"Ir al lugar (obtener indicaciones)" el usuario puede ver el mapa y cómo llegar al lugar. Como
NAVITIME tiene su propia tecnología de enrutamiento, el bot redirige al usuario a la aplicación
web de enrutamiento de NAVITIME.
Caso práctico técnico: NAVITIME 78

El usuario puede tocar "Ver más resultados" para ver otra recomendación o "Probar otra palabra
clave" para introducir otras palabras clave. Al tocar el botón "Mapa" se muestra un mapa; al pulsar
"Ir al lugar (obtener indicaciones)" el usuario puede ver el mapa y cómo llegar al lugar. Como
NAVITIME tiene su propia tecnología de enrutamiento, el bot redirige al usuario a la aplicación
web de enrutamiento de NAVITIME.
Caso práctico técnico: NAVITIME 79

Los viajeros tienden a cargar fotos en servicios de redes sociales como Instagram y Facebook.
Cuando otros usuarios ven las fotos, quieren ir a ese lugar o comer esa comida, pero no saben
dónde está ni cómo conseguirla. Los usuarios pueden enviar fotos a nuestro bot, lo que ayuda
a reconocer las imágenes e indicar a los usuarios qué es y cómo obtenerlo.
Caso práctico técnico: NAVITIME 80

Ejecución
MultiDialogSample en GitHub. Como
queríamos lanzar una aplicación iOS,

técnica
usamos la API de Direct Line.

Extraer la intención y las


En esta sección se describe cómo
entidades con LUIS y la
implementar un bot similar utilizando
Bot Framework, Cognitive Services y Azure.
API de Bing Spell Check
Para extraer la intención y la entidad de los
Requisitos previos mensajes del usuario, usamos LUIS. Como
los usuarios a veces escriben mal y LUIS
• Instala Visual Studio y el SDK de Bot
no puede extraer la intención, también
Builder siguiendo los pasos del tutorial
utilizamos la API de Bing Spell Check para
Crear un bot con el SDK de Bot Builder
detectar y corregir los errores tipográficos
para .NET.
antes de enviar los mensajes a LUIS con los
• Instala el emulador de Bot Framework;
pasos que se indican a continuación.
consulta Depurar bots con el emulador
de Bot Framework para obtener más
1. En el portal Azure, agrega la API
información.
de Bing Spell Check.
• Crea una cuenta gratuita de Azure
2. En el menú LUIS, elige Mis claves.
si aún no tienes una.
3. Elige Claves externas y Agregar una
• Crea una aplicación con LUIS que se
nueva clave para agregar una clave
ajuste a tu escenario y llámala desde
de la API de Bing Spell Check API a LUIS.
el bot (consulta Vinculación de acciones
4. Ve a tu aplicación LUIS y elige Publicar
de LUIS para aplicaciones web).
aplicación en el menú de la izquierda.
5. En la parte inferior, elige el botón
Desarrollar un bot con Agregar asociación de claves para
Bot Framework vincular la API de Bing Spell Check
con LUIS.
Después de los pasos de requisitos previos, 6. Selecciona Habilitar corrector
empezamos a implementar nuestro propio ortográfico de Bing, que cambia la URL
bot con el código del punto de conexión. Usa esta URL
para llamar a LUIS con la API de Bing
Spell Check.
Caso práctico técnico: NAVITIME 81

Guardar los datos NoSQL en Cosmos DB


Utilizamos el servicio de base de datos NoSQL Cosmos DB para almacenar la información
de ubicación de NAVITIME, que tiene formato JSON. También usamos Cosmos DB para
almacenar los registros de comunicación entre los usuarios y los bots.

Si quieres aprender a inicializar Cosmos DB y escribir código para la base de datos, empieza con
el tutorial Azure CosmosDB: desarrollar con la API de DocumentDB en .NET. Debes importar datos
para las pruebas y la producción siguiendo las instrucciones de Cómo importar datos a Azure
Cosmos DB para la API de DocumentDB.

Implementar Búsqueda de Azure


Aunque LUIS puede extraer correctamente las intenciones, a veces los usuarios solo introducen
palabras, no frases, por lo que también utilizamos Búsqueda de Azure. Con la siguiente arquitectura,
podemos gestionar oraciones y palabras, así como responder con la información correcta.

Para usar Búsqueda de Azure, escribimos código C# como el siguiente.


Caso práctico técnico: NAVITIME 82

[Serializable]
public class AzureSearchService
{
private static readonly string QueryString = $"https://
{WebConfigurationManager.AppSettings["SearchName"]}.search.windows.net
/indexes/{WebConfigurationManager.AppSettings["IndexName"]}/docs?api-
key={WebConfigurationManager.AppSettings["SearchKey"]}&api-
version=2015-02-28&";

public async Task<SearchResult> SearchByName(string name)


{
using (var httpClient = new HttpClient())
{
string nameQuey = $"{QueryString}search={name}";
string response = await
httpClient.GetStringAsync(nameQuey);
return
JsonConvert.DeserializeObject<SearchResult>(response);
}
}

public async Task<FacetResult> FetchFacets()


{
using (var httpClient = new HttpClient())
{
string facetQuey = $"{QueryString}facet=Era";
string response = await
httpClient.GetStringAsync(facetQuey);
return
JsonConvert.DeserializeObject<FacetResult>(response);
}
}

public async Task<SearchResult> SearchByEra(string era)


{
using (var httpClient = new HttpClient())
{
Caso práctico técnico: NAVITIME 83

Puedes usarlo desde Bot Framework con el siguiente código. Si deseas ver un proyecto
de muestra, ve a ryanvolum/AzureSearchBot en GitHub. Este proyecto describe cómo configurar
Búsqueda de Azure y Cosmos DB, y cómo llamar a Búsqueda de Azure desde un bot.

public virtual async Task MessageRecievedAsync(IDialogContext context,


IAwaitable<IMessageActivity> result)
{
var message = await result;
try
{
SearchResult searchResult = await
searchService.SearchByName(message.Text);
if(searchResult.value.Length != 0)
{
CardUtil.showHeroCard(message, searchResult);
}
else{
await context.PostAsync($"No musicians by the name
{message.Text} found");
}
}
catch(Exception e)
{
Debug.WriteLine($"Error when searching for musician:
{e.Message}");
}
context.Done<object>(null);
}
Caso práctico técnico: NAVITIME 84

Reconocer imágenes con Bing Image Search y


Custom Vision Service
Podemos usar Bing Image Search para buscar imágenes similares y "mejores consultas
representativas". Por ejemplo, si envías una foto del templo visto anteriormente en este artículo a
Bing Image Search, responderá con las URL de imágenes similares y "Tsuruoka Hachimangu Temple,
Kamakura" como bestRepresentativeQuery. Bing tiene un enorme conocimiento de imágenes
y podemos usarlo para reconocer lugares y alimentos famosos con el siguiente código. Para usar
Búsqueda de Azure, escribimos código C# como el siguiente.

public virtual async Task MessageRecievedAsync(IDialogContext context,


IAwaitable<IMessageActivity> result)
{
var message = await result;
try
{
SearchResult searchResult = await
searchService.SearchByName(message.Text);
if(searchResult.value.Length != 0)
{
CardUtil.showHeroCard(message, searchResult);
}
else{
await context.PostAsync($"No musicians by the name
{message.Text} found");
}
}
catch(Exception e)
{
Debug.WriteLine($"Error when searching for musician:
{e.Message}");
}
context.Done<object>(null);
}
Caso práctico técnico: NAVITIME 85

Puedes encontrar un proyecto de ejemplo en el repositorio de GitHub NT-D/suggesttriplocationBot


y para obtener información cómo publicar imágenes en un bot y cómo usar Bing Image Search
para reconocer imágenes y obtener bestRepresentativeQuery. Puedes obtener más detalles
en la Referencia de la API de Bing Image Search.

Aunque Bing Image Search nos ayuda a encontrar lugares y comidas famosos, es difícil reconocer
los lugares y los alimentos locales o menos conocidos. Por lo tanto, decidimos utilizar Custom Vision
Service. Para compilar, probar y utilizar esta API, comenzamos con el documento de introducción
Crear un clasificador utilizando el machine learning de Custom Vision Service.
Caso práctico técnico: NAVITIME 86

Impulsar los ciclos de comentarios de la unidad con Power


BI, Cosmos DB y Búsqueda de Azure
Debido a que es importante mejorar la lógica del bot con los datos reales de los usuarios, queremos
ver fácilmente los datos de los usuarios y los registros de búsqueda.

Para guardar las búsquedas de usuario, llamamos a Azure Functions y almacenamos los datos en
Cosmos DB. Azure Functions admite de forma nativa los enlaces de Cosmos DB y puede guardar
datos con poco código, como el siguiente.

#r "Newtonsoft.Json"
Puedes utilizar Power
using System; BI para acceder a los
using System.Net;
datos en Cosmos DB
using Newtonsoft.Json;
según la información
public static HttpResponseMessage Run(HttpRequestMessage req, de Orígenes de datos en
TraceWriter log, out string outputDocument)
Power BI Desktop. Para
{
log.Info($"Webhook was triggered!"); analizar los registros
string jsonContent = req.Content.ReadAsStringAsync().Result; de búsqueda, consulta
//Store Data in Cosmos DB
Análisis de los datos con
outputDocument = jsonContent;
Power BI.
dynamic data = JsonConvert.DeserializeObject(jsonContent);

//Return HTTP Response (BadRequest or OK)


if (data.first == null || data.last == null) {
return req.CreateResponse(HttpStatusCode.BadRequest, new {
error = "Please pass first/last properties in the input
object"
});
}

return req.CreateResponse(HttpStatusCode.OK, new {


greeting = $"Hello {data.first} {data.last}!"
});
}
Caso práctico técnico: NAVITIME 87

Mejorar el rendimiento
de la respuesta

Implementamos el bot en la región Oeste provocó una lenta respuesta porque,


de EE. UU. para minimizar el tiempo cuando el bot llama a LUIS y al servicio
de respuesta. El servicio State de Bot State, el tráfico cruza el Océano Pacífico
Framework y LUIS están alojados en una y otra vez. Si obtienes una respuesta
la región Oeste de EE. UU., y los puntos lenta, puedes mejorar el rendimiento si
de conexión de Direct Line se encuentran mueves el bot a la región Oeste de EE. UU.
en Asia Oriental, Europa y Norteamérica.

En primer lugar implementamos nuestro


bot en la región Japón Oriental, lo que

Web Apps en la región Servicio Connector


Japón Oriental y State del bot

Conectar al servicio Connector y State del bot

Usuarios
finales
La aplicación se
comunica entre
Japón y EE. UU. con
flujos de ida y vuelta.
Caso práctico técnico: NAVITIME 88

Conclusión
Los viajeros quieren tener una experiencia única del viaje, pero es difícil encontrar comida
local, lugares de interés, etc., con una aplicación normal. También resulta difícil encontrar esta
información comunicándose con los lugareños debido a la barrera del idioma.

El chatbot está ahora activo en la aplicación Kamakura Travel Guide. Los usuarios pueden encontrar
información local famosa y difícil de hallar usando tanto la aplicación como su bot incorporado.

“Es difícil crear lógica NLP en varios idiomas, pero LUIS resuelve
este problema. LUIS es realmente bueno en obtener las intenciones
del mensaje".
Ikuo Odanaka
Director de desarrollo, NAVITIME JAPAN

“[Cosmos DB] es un almacén de datos genial. Podemos guardar


datos NoSQL en él y obtener datos con consultas tipo SQL, por
lo que es muy fácil de usar. La velocidad de lectura y escritura
es muy rápida; la integración con Búsqueda de Azure es perfecta".
Shinichi Tanabe
Desarrollador de software sénior, NAVITIME JAPAN

“Es el proyecto más fácil para mí. PaaS como Cosmos DB y Búsqueda
de Azure pueden ayudarnos a crear cosas nuevas rápidamente".
Shinichi Tanabe
Desarrollador de software sénior, NAVITIME JAPAN
Conclusión 89

Como han demostrado


estos casos prácticos, la IA
de Azure supone una verdadera
diferencia en la forma en que
los desarrolladores trabajan
y crean. Las herramientas de IA
listas para usar, la infraestructura
avanzada del cloud y una
plataforma flexible ofrecen a los
desarrolladores lo que necesitan
para trasladar sus aplicaciones
a un nuevo mundo de productos
apasionantes, un servicio al cliente
superior y una mayor agilidad
empresarial.
Conclusión 90

Los desarrolladores 1. Herramientas potentes


y productivas.
tienen grandes
Los desarrolladores no quieren dedicar
oportunidades tiempo a escribir código para las
características básicas de la IA. Necesitan
a medida que la IA API listas para usar que se implementen
cobra más importancia fácilmente en las aplicaciones.

en un mundo enfocado
2.
Datos e IA para
en la experiencia del cada desarrollador.
cliente y a medida
Los desarrolladores quieren aumentar sus
que las empresas aplicaciones con IA de la mejor manera
para ellos. Para sacar el máximo partido de
buscan nuevas formas la IA, quieren integrarla en sus aplicaciones
de obtener una ventaja utilizando una amplia gama de lenguajes
de programación, así como elegir entre
competitiva. Para una amplia variedad de orígenes de datos.

aprovechar al máximo
estas oportunidades, los
desarrolladores buscan:
3. Una plataforma
abierta y flexible.

Los desarrolladores se sienten más


satisfechos cuando pueden elegir
la tecnología y los marcos que mejor
se adaptan a sus escenarios.
y habilidades.
Siguientes pasos 91

Siguientes pasos

Te invitamos a explorar los servicios de IA


de Azure a través de los siguientes enlaces:

Más información acerca de la IA de Azure

Prueba las API de Cognitive Services de forma gratuita

Crea tu cuenta gratuita de Azure

Copyright © 2018 Microsoft, Inc. Todos los derechos reservados. Este contenido solo tiene
fines informativos. Microsoft no ofrece ninguna garantía, expresa o implícita, con respecto
a la información que aquí se ofrece.

También podría gustarte