Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the acf domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/planetac/desa.planetachatbot.com/wp-includes/functions.php on line 6170

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the all-in-one-seo-pack domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/planetac/desa.planetachatbot.com/wp-includes/functions.php on line 6170

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wp-user-avatar domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/planetac/desa.planetachatbot.com/wp-includes/functions.php on line 6170

Warning: Cannot modify header information - headers already sent by (output started at /home/planetac/desa.planetachatbot.com/wp-includes/functions.php:6170) in /home/planetac/desa.planetachatbot.com/wp-content/plugins/all-in-one-seo-pack/app/Common/Meta/Robots.php on line 87

Warning: Cannot modify header information - headers already sent by (output started at /home/planetac/desa.planetachatbot.com/wp-includes/functions.php:6170) in /home/planetac/desa.planetachatbot.com/wp-includes/feed-rss2.php on line 8
Justina Petraitytė - Planeta Chatbot https://desa.planetachatbot.com Comunidad de expertos en IA Conversacional Mon, 06 Jun 2022 13:34:00 +0000 es hourly 1 https://wordpress.org/?v=7.0.2 https://desa.planetachatbot.com/wp-content/uploads/2021/05/cropped-favicon-32x32.png Justina Petraitytė - Planeta Chatbot https://desa.planetachatbot.com 32 32 Cómo construir un asistente de voz con herramientas de código abierto como Rasa y Mozilla https://desa.planetachatbot.com/tutorial-como-construir-asistente-voz-con-herramientas-de-codigo-abierto-rasa-y-mozilla/?utm_source=rss&utm_medium=rss&utm_campaign=tutorial-como-construir-asistente-voz-con-herramientas-de-codigo-abierto-rasa-y-mozilla https://desa.planetachatbot.com/tutorial-como-construir-asistente-voz-con-herramientas-de-codigo-abierto-rasa-y-mozilla/#comments Mon, 30 Sep 2019 09:43:38 +0000 https://desa.planetachatbot.com/?p=1039 Las plataformas como Google Assistant facilitan la creación de asistentes de voz personalizados (chatbots). Pero, ¿qué pasaría si quisieras crear un asistente que se ejecute localmente y garantice la privacidad de tus datos? Puedes hacerlo utilizando las herramientas de código abierto Rasa, Mozilla DeepSpeech y Mozilla TTS. Si quieres saber cómo, echa un vistazo a […]

The post Cómo construir un asistente de voz con herramientas de código abierto como Rasa y Mozilla first appeared on Planeta Chatbot.

]]>
Las plataformas como Google Assistant facilitan la creación de asistentes de voz personalizados (chatbots). Pero, ¿qué pasaría si quisieras crear un asistente que se ejecute localmente y garantice la privacidad de tus datos? Puedes hacerlo utilizando las herramientas de código abierto Rasa, Mozilla DeepSpeech y Mozilla TTS. Si quieres saber cómo, echa un vistazo a este tutorial.

Con plataformas como Google Assistant y Alexa que son cada vez más populares, los asistentes de voz están destinados a ser la próxima herramienta para las interacciones con los clientes en varias industrias. Sin embargo, a menos que utilices soluciones comerciales alojadas, el desarrollo de asistentes de voz viene con un conjunto completamente nuevo de desafíos que van más allá de la NLU y la gestión del diálogo; además de esos temas, debes ocuparte de la transcripción del habla a texto, componentes de texto a voz, la interfaz… Tocamos el tema de la voz hace algún tiempo cuando experimentamos con la construcción de un Google Assistant con tecnología Rasa. Aprovechar plataformas como Google Assistant elimina el obstáculo de implementar el procesamiento de voz y los frontend components, pero obliga a comprometer la seguridad de tus datos y la flexibilidad de las herramientas que utilizas. Entonces, ¿qué opciones tienes si deseas crear un asistente de voz que se ejecute localmente y garantice la seguridad de tus datos? Bueno, descubrámoslo. En este post, aprenderás cómo puedes crear un asistente de voz utilizando solo herramientas de código abierto, desde el backend hasta la interfaz.

Outline

  • Resumen de herramientas y software
  • El asistente de Rasa
  • Implementación del componente de voz a texto
  • Implementación del componente de texto a voz
  • Poniéndolo todo junto
  • ¿Qué sigue?
  • Resumen y recursos

1. Herramientas y descripción general del software

El objetivo de esta publicación es mostrarte cómo puedes crear tu propio asistente de voz utilizando solo herramientas de código abierto. En general, hay cinco componentes principales que son necesarios para construir un asistente de voz:

    1. Interfaz de voz: una interfaz que los usuarios usan para comunicarse con el asistente (aplicación web o móvil, altavoz inteligente, etc.)
    2. Voz a texto (STT) : un componente de procesamiento de voz que toma la entrada del usuario en un formato de audio y produce una representación de texto
    3. NLU: un componente que toma la entrada del usuario en formato de texto y extrae datos estructurados (intentos y entidades) que ayuda a comprender lo que el usuario quiere
    4. Gestión del diálogo: un componente que determina cómo debe responder un asistente en un estado específico de la conversación y genera esa respuesta en un formato de texto
    5. Texto a voz (TTS): un componente que toma la respuesta del asistente en un formato de texto y produce una representación de voz que luego se envía al usuario.

Si bien Rasa de código abierto es una opción bastante obvia para NLU y la gestión de diálogo, decidir sobre STT y TTS es una tarea más difícil simplemente porque no hay muchos marcos de código abierto para elegir. Después de explorar las opciones disponibles actualmente: CMUSphinx, Mozilla DeepSpeech, Mozilla TTS, Kaldi, decidimos utilizar las herramientas de Mozilla : Mozilla DeepSpeech y Mozilla TTS . Esto es porque:

      • Las herramientas de Mozilla vienen con un conjunto o modelos pre-entrenados, pero también puedes entrenar los tuyos usando datos personalizados. Esto te permite implementar cosas rápidamente, pero también te da toda la libertad para construir componentes personalizados.
      • En comparación con las alternativas, las herramientas de Mozilla parecen ser las más independientes del sistema operativo.
      • Ambas herramientas están escritas en Python, lo que facilita un poco la integración con Rasa.
      • Tiene una comunidad de código abierto grande y activa lista para ayudar con preguntas técnicas.

¿Qué es Mozilla DeepSpeech y Mozilla TTS? Mozilla DeepSpeech es un marco de voz a texto que toma la entrada del usuario en un formato de audio y utiliza el aprendizaje automático para convertirlo a un formato de texto que luego puede ser procesado por la NLU y el sistema de diálogo. Mozilla TTS se encarga de lo contrario: toma la entrada (en nuestro caso, la respuesta del asistente producido por un sistema de diálogo) en un formato de texto y utiliza el aprendizaje automático para crear una representación de audio.

Los componentes de NLU, gestión de diálogo y procesamiento de voz cubren el backend del asistente de voz, ¿qué pasa con la interfaz? Bueno, aquí es donde radica el mayor problema: si buscas los widgets de interfaz de voz de código abierto, es muy probable que termines sin resultados. ¡Al menos esto es lo que nos pasó y es por eso que desarrollamos nuestra propia interfaz de voz Rasa que utilizamos para este proyecto y estamos felices de compartirla con la comunidad!

Para resumir, aquí están los ingredientes del asistente de voz de código abierto:

2. El Asistente de Rasa

Para este proyecto, vamos a utilizar un asistente de Rasa existente: Sara . Es un asistente de código abierto impulsado por Rasa que puede responder varias preguntas sobre el marco Rasa y ayudarte a comenzar. A continuación se muestra un ejemplo de conversación con Sara:

Estos son los pasos sobre cómo configurar Sara en su entorno de desarrollo:

  1. Clonar el repositorio de Sara:
git clone https://github.com/RasaHQ/rasa-demo.git 
cd rasa-demo

2. Instala las dependencias necesarias:

pip install -e .

3. Capacitar a la NLU y los modelos de diálogo:

rasa train --augmentation 0

4. Prueba Sara en tu terminal:

docker run -p 8000:8000 rasa/duckling 
rasa run actions --actions demo.actions 
make run-cmdline

Para convertir a Sara en un asistente de voz, tendremos que editar algunos de los archivos del proyecto en las etapas posteriores de la implementación. Antes de hacer eso, implementamos los componentes TTS y STT.

3. Implementando el componente de voz a texto

Implementemos el componente de voz a texto: modelo Mozilla DeepSpeech. Echa un vistazo a esta publicación del blog de Rouben Morais para obtener más información sobre cómo funciona Mozilla DeepSpeech bajo el capó. Mozilla DeepSpeech viene con algunos modelos previamente entrenados y te permite entrenar el tuyo. En aras de la simplicidad, utilizamos un modelo previamente capacitado para este proyecto. Estos son los pasos para configurar STT en tu entorno de desarrollo:

  1. Clonar el repositorio de deepspeech:
pip3 install deepspeech

2. Descarga un modelo de texto a voz previamente capacitado y descomprímelo en el directorio de su proyecto:

wget https://github.com/mozilla/DeepSpeech/releases/download/v0.5.1/deepspeech-0.5.1-models.tar.gz 
tar xvfz deepspeech-0.5.1-models.tar.gz

3. Prueba el modelo.

La mejor manera de verificar si el componente se configuró correctamente es probar el modelo en algunas entradas de audio de muestra. El siguiente script te ayudará a hacer eso:

    • La función record_audio () captura un audio de 5 segundos y lo guarda como un archivo test_audio.wav
    • La función deepspeech_predict () carga un modelo de deep voice y pasa un archivo test_audio.wav para hacer una predicción sobre cómo debería verse la entrada de voz en un formato de texto

Ejecuta el script usando el comando a continuación y una vez que veas el mensaje ‘ Grabando… ‘ pronuncia una oración con la que te gustaría probar el modelo:

python deepspeech_test_prediction.py

En la siguiente parte de este post, aprenderás cómo configurar la tercera parte del proyecto: el componente de texto a voz.

4. Implementación del componente de texto a voz

Para permitir que el asistente responda con voz en lugar de texto, tenemos que configurar el componente de texto a voz que tomará la respuesta generada por Rasa y la convertirá en un sonido. Para eso, utilizamos Mozilla TTS . Al igual que Mozilla DeepSpeech, viene con modelos previamente entrenados, pero también puedes entrenar tus propios modelos utilizando datos personalizados. Esta vez también utilizaremos un modelo TTS pre-entrenado. Aquí se explica cómo configurar el componente TTS en tu entorno de desarrollo:

      1. Clonar el repositorio de TTS:
git clone https://github.com/mozilla/TTS.git 
cd TTS 
git checkout db7f3d3

2. Instala el paquete:

python setup.py develop

3. Descarga el modelo:

En tu directorio de Sara, crea una carpeta llamada tts_model y coloca los archivos de modelo descargados desde aquí (solo necesitas config.json y best_model.th.tar )

4. Prueba el componente:

Puedes usar el siguiente script para probar el componente de texto a voz. Esto es lo que hace el script:

    • La función load_model () carga el modelo tts y prepara todo para el procesamiento
    • La función tts () toma la entrada de texto y crea un archivo de audio test_tts.wav

Puedes cambiar la variable de oración con una entrada personalizada en la que te gustaría probar el modelo. Una vez que el script deja de ejecutarse, el resultado se guardará en el archivo test_tts.wav que puedes escuchar para probar el rendimiento del modelo.

import os
import sys
import io
import torch
from collections import OrderedDict

from TTS.models.tacotron import Tacotron
from TTS.layers import *
from TTS.utils.data import *
from TTS.utils.audio import AudioProcessor
from TTS.utils.generic_utils import load_config
from TTS.utils.text import text_to_sequence
from TTS.utils.synthesis import synthesis
from utils.text.symbols import symbols, phonemes
from TTS.utils.visual import visualize

# Set constants
MODEL_PATH = './tts_model/best_model.pth.tar'
CONFIG_PATH = './tts_model/config.json'
OUT_FILE = 'tts_out.wav'
CONFIG = load_config(CONFIG_PATH)
use_cuda = False

def tts(model, text, CONFIG, use_cuda, ap, OUT_FILE):
    waveform, alignment, spectrogram, mel_spectrogram, stop_tokens = synthesis(model, text, CONFIG, use_cuda, ap)
    ap.save_wav(waveform, OUT_FILE)
    return alignment, spectrogram, stop_tokens



def load_model(MODEL_PATH, sentence, CONFIG, use_cuda, OUT_FILE):
	# load the model
	num_chars = len(phonemes) if CONFIG.use_phonemes else len(symbols)
	model = Tacotron(num_chars, CONFIG.embedding_size, CONFIG.audio['num_freq'], CONFIG.audio['num_mels'], CONFIG.r, attn_windowing=False)

	# load the audio processor
	# CONFIG.audio["power"] = 1.3
	CONFIG.audio["preemphasis"] = 0.97
	ap = AudioProcessor(**CONFIG.audio)


	# load model state
	if use_cuda:
		cp = torch.load(MODEL_PATH)
	else:
		cp = torch.load(MODEL_PATH, map_location=lambda storage, loc: storage)

	# load the model
	model.load_state_dict(cp['model'])
	if use_cuda:
		model.cuda()
	model.eval()


	model.eval()
	model.decoder.max_decoder_steps = 1000
	align, spec, stop_tokens = tts(model, sentence, CONFIG, use_cuda, ap, OUT_FILE)

if __name__ == '__main__':
	sentence =  "Hello, how are you doing? My name is Sara"
	load_model(MODEL_PATH, sentence, CONFIG, use_cuda, OUT_FILE)

En este punto, debes tener todos los componentes más importantes ejecutándose en el entorno de desarrollo: el asistente Rasa, componentes de voz a texto y de texto a voz. Todo lo que queda por hacer es juntar todos estos componentes y conectar el asistente a la interfaz de voz Rasa. Aprende cómo puedes hacerlo en el siguiente paso de este post.

5. Poniendo todo junto

Para juntar todas las piezas y poner el asistente de voz en acción, necesitamos dos cosas:

      1. Interfaz de voz
      2. Un conector para establecer la comunicación entre la interfaz de usuario y el backend (componentes de Mozilla y Rasa)

Primero configuremos la interfaz de voz Rasa. Aquí esos dejo cómo hacerlo:

      1. Instala npm y node siguiendo las instrucciones proporcionadas aquí .
      2. Clona el repositorio de la interfaz de usuario de Rasa Voice:
git clone https://github.com/RasaHQ/rasa-voice-interface.git 
cd rasa-voice-interface

3. Instala el componente:

npm install

4. Pruébalo:

npm run serve

Una vez que ejecutes el comando anterior, abre un navegador y entra en https: //localhost: 8080 para verificar si la interfaz de voz se está cargando. Una pelota que salta indica que se ha cargado correctamente y está esperando la conexión.

Para conectar el asistente a la interfaz, necesitas un conector. El conector también determinará qué sucede cuando el usuario dice algo y cómo la respuesta de audio se devuelve al frontend component. Para crear un conector, podemos usar un conector socketio existente y actualizarlo con algunos componentes nuevos:

      • El evento de clase SocketIOInput () ‘user_utter’ se actualiza para recibir los datos de audio enviados como un enlace desde la interfaz de voz Rasa y guardarlos en el disco como un archivo .wav. Luego, cargamos el modelo STT de Mozilla para convertir el audio en representación de texto y pasarlo a Rasa:
      • La clase SocketIOutput () obtiene un nuevo método _send_audio_message () que recupera una respuesta predicha por el modelo de gestión de diálogo Rasa en un formato de texto, carga el modelo Mozilla TTS que luego convierte el texto en un formato de audio y lo envía de vuelta a la interfaz.

A continuación, puede encontrar un código completo del conector actualizado:

import logging
import uuid
from sanic import Blueprint, response
from sanic.request import Request
from socketio import AsyncServer
from typing import Optional, Text, Any, List, Dict, Iterable

from rasa.core.channels.channel import InputChannel
from rasa.core.channels.channel import UserMessage, OutputChannel

import deepspeech
from deepspeech import Model
import scipy.io.wavfile as wav

import os
import sys
import io
import torch
import time
import numpy as np
from collections import OrderedDict
import urllib

import librosa

from TTS.models.tacotron import Tacotron
from TTS.layers import *
from TTS.utils.data import *
from TTS.utils.audio import AudioProcessor
from TTS.utils.generic_utils import load_config
from TTS.utils.text import text_to_sequence
from TTS.utils.synthesis import synthesis
from utils.text.symbols import symbols, phonemes
from TTS.utils.visual import visualize


logger = logging.getLogger(__name__)

def load_deepspeech_model():
    N_FEATURES = 25
    N_CONTEXT = 9
    BEAM_WIDTH = 500
    LM_ALPHA = 0.75
    LM_BETA = 1.85

    ds = Model('deepspeech-0.5.1-models/output_graph.pbmm', N_FEATURES, N_CONTEXT, 'deepspeech-0.5.1-models/alphabet.txt', BEAM_WIDTH)
    return ds


def load_tts_model():

    MODEL_PATH = './tts_model/best_model.pth.tar'
    CONFIG_PATH = './tts_model/config.json'
    CONFIG = load_config(CONFIG_PATH)
    use_cuda = False

    num_chars = len(phonemes) if CONFIG.use_phonemes else len(symbols)
    model = Tacotron(num_chars, CONFIG.embedding_size, CONFIG.audio['num_freq'], CONFIG.audio['num_mels'], CONFIG.r, attn_windowing=False)


    num_chars = len(phonemes) if CONFIG.use_phonemes else len(symbols)
    model = Tacotron(num_chars, CONFIG.embedding_size, CONFIG.audio['num_freq'], CONFIG.audio['num_mels'], CONFIG.r, attn_windowing=False)

    # load the audio processor
    # CONFIG.audio["power"] = 1.3
    CONFIG.audio["preemphasis"] = 0.97
    ap = AudioProcessor(**CONFIG.audio)


    # load model state
    if use_cuda:
        cp = torch.load(MODEL_PATH)
    else:
        cp = torch.load(MODEL_PATH, map_location=lambda storage, loc: storage)

    # load the model
    model.load_state_dict(cp['model'])
    if use_cuda:
        model.cuda()


    #model.eval()
    model.decoder.max_decoder_steps = 1000
    return model, ap, MODEL_PATH, CONFIG, use_cuda

ds = load_deepspeech_model()
model, ap, MODEL_PATH, CONFIG, use_cuda  = load_tts_model()


class SocketBlueprint(Blueprint):
    def __init__(self, sio: AsyncServer, socketio_path, *args, **kwargs):
        self.sio = sio
        self.socketio_path = socketio_path
        super(SocketBlueprint, self).__init__(*args, **kwargs)

    def register(self, app, options):
        self.sio.attach(app, self.socketio_path)
        super(SocketBlueprint, self).register(app, options)


class SocketIOOutput(OutputChannel):

    @classmethod
    def name(cls):
        return "socketio"

    def __init__(self, sio, sid, bot_message_evt, message):
        self.sio = sio
        self.sid = sid
        self.bot_message_evt = bot_message_evt
        self.message = message


    def tts(self, model, text, CONFIG, use_cuda, ap, OUT_FILE):
        import numpy as np
        waveform, alignment, spectrogram, mel_spectrogram, stop_tokens = synthesis(model, text, CONFIG, use_cuda, ap)
        ap.save_wav(waveform, OUT_FILE)
        wav_norm = waveform * (32767 / max(0.01, np.max(np.abs(waveform))))
        return alignment, spectrogram, stop_tokens, wav_norm


    def tts_predict(self, MODEL_PATH, sentence, CONFIG, use_cuda, OUT_FILE):

        align, spec, stop_tokens, wav_norm = self.tts(model, sentence, CONFIG, use_cuda, ap, OUT_FILE)
        return wav_norm


    async def _send_audio_message(self, socket_id, response,  **kwargs: Any):
        # type: (Text, Any) -> None
        """Sends a message to the recipient using the bot event."""

        ts = time.time()
        OUT_FILE = str(ts)+'.wav'
        link = "http://localhost:8888/"+OUT_FILE

        wav_norm = self.tts_predict(MODEL_PATH, response['text'], CONFIG, use_cuda, OUT_FILE)


        await self.sio.emit(self.bot_message_evt, {'text':response['text'], "link":link}, room=socket_id)



    async def send_text_message(self, recipient_id: Text, message: Text, **kwargs: Any) -> None:
        """Send a message through this channel."""

        await self._send_audio_message(self.sid, {"text": message})





class SocketIOInput(InputChannel):
    """A socket.io input channel."""

    @classmethod
    def name(cls):
        return "socketio"

    @classmethod
    def from_credentials(cls, credentials):
        credentials = credentials or {}
        return cls(credentials.get("user_message_evt", "user_uttered"),
                   credentials.get("bot_message_evt", "bot_uttered"),
                   credentials.get("namespace"),
                   credentials.get("session_persistence", False),
                   credentials.get("socketio_path", "/socket.io"),
                   )

    def __init__(self,
                 user_message_evt: Text = "user_uttered",
                 bot_message_evt: Text = "bot_uttered",
                 namespace: Optional[Text] = None,
                 session_persistence: bool = False,
                 socketio_path: Optional[Text] = '/socket.io'
                 ):
        self.bot_message_evt = bot_message_evt
        self.session_persistence = session_persistence
        self.user_message_evt = user_message_evt
        self.namespace = namespace
        self.socketio_path = socketio_path


    def blueprint(self, on_new_message):
        sio = AsyncServer(async_mode="sanic")
        socketio_webhook = SocketBlueprint(
            sio, self.socketio_path, "socketio_webhook", __name__
        )

        @socketio_webhook.route("/", methods=['GET'])
        async def health(request):
            return response.json({"status": "ok"})

        @sio.on('connect', namespace=self.namespace)
        async def connect(sid, environ):
            logger.debug("User {} connected to socketIO endpoint.".format(sid))
            print('Connected!')

        @sio.on('disconnect', namespace=self.namespace)
        async def disconnect(sid):
            logger.debug("User {} disconnected from socketIO endpoint."
                         "".format(sid))

        @sio.on('session_request', namespace=self.namespace)
        async def session_request(sid, data):
            print('This is sessioin request')

            if data is None:
                data = {}
            if 'session_id' not in data or data['session_id'] is None:
                data['session_id'] = uuid.uuid4().hex
            await sio.emit("session_confirm", data['session_id'], room=sid)
            logger.debug("User {} connected to socketIO endpoint."
                         "".format(sid))

        @sio.on('user_uttered', namespace=self.namespace)
        async def handle_message(sid, data):

            output_channel = SocketIOOutput(sio, sid, self.bot_message_evt, data['message'])
            if data['message'] == "/get_started":
                message = data['message']
            else:
                ##receive audio
                received_file = 'output_'+sid+'.wav'

                urllib.request.urlretrieve(data['message'], received_file)
                path = os.path.dirname(__file__)

                fs, audio = wav.read("output_{0}.wav".format(sid))
                message = ds.stt(audio, fs)

                await sio.emit(self.user_message_evt, {"text":message}, room=sid)


            message_rasa = UserMessage(message, output_channel, sid,
                                  input_channel=self.name())
            await on_new_message(message_rasa)

        return socketio_webhook

Guarda este código en el directorio de tu proyecto como socketio_connector.py.

Lo último que debe configurarse antes de que puedas darle un giro es la configuración del conector, ya que creamos un conector personalizado, tenemos que decirle a Rasa que use este conector personalizado para recibir las entradas del usuario y enviar las respuestas. Para hacerlo, crea un archivo credentials.yml en el directorio del proyecto de Sara y proporciona los siguientes detalles (aquí socketio_connector es el nombre del módulo donde se implementa el conector personalizado, mientras que SocketIOInput es el nombre de la clase de entrada del conector personalizado):

socketio_connector.SocketIOInput: 
 bot_message_evt: bot_uttered 
 session_persistence: true 
 user_message_evt: user_uttered

¡Eso es! Todo lo que queda por hacer es iniciar el asistente y tener una conversación con él. Aquí te explico cómo hacerlo:

      1. Inicia el servido de Rasa:
rasa run --enable-api -p 5005

2. Inicia el servidor de acciones personalizadas Rasa:

rasa run actions --actions demo.actions

3. Uno de los componentes de Sara es el componente DucklingHTTPExtractor . Para usarlo, inicia un servidor:

docker run -p 8000:8000 rasa/duckling

4. Inicia un servidor http simple para enviar los archivos de audio al cliente:

python3 -m http.server 8888

Si actualizas la interfaz de voz Rasa en tu navegador, deberías ver que el asistente está listo para hablar:

¡Haz clic en Inicio y mantén una conversación con un asistente de voz creado utilizando solo herramientas de código abierto!

6. ¿Qué sigue?

El desarrollo de asistentes de voz viene con un conjunto completamente nuevo de desafíos: ya no se trata solo de la buena NLU y el diálogo, necesita buenos componentes STT y TTS y tu NLU debe ser lo suficientemente flexible como para compensar los errores cometidos por STT. Si replicas este proyecto, notarás que el asistente no es perfecto y que hay mucho margen de mejora, especialmente en la etapa STT y NLU. ¿Cómo puedes mejorarlo? Aquí hay algunas ideas:

      • Los modelos STT pre-entrenados se entrenan con datos bastante genéricos que hacen que el modelo sea propenso a errores cuando se usa en dominios más específicos. La construcción de un modelo STT personalizado con Mozilla DeepSpeech podría conducir a un mejor rendimiento de STT y NLU.
      • Mejorar la NLU podría compensar algunos de los errores cometidos por STT. Una forma bastante simple de mejorar el rendimiento del modelo NLU es mejorar los datos de entrenamiento con más ejemplos para cada intento y agregar un corrector ortográfico a la pipeline Rasa NLU para corregir algunos errores STT más pequeños.

7. Resumen y recursos

En Rasa, buscamos constantemente formas de superar los límites de las herramientas y el software que permiten a los desarrolladores construir grandes cosas. Al compilar este proyecto, queríamos mostrarte que puedes usar Rasa para construir no solo texto, sino también asistentes de voz e inspirarlo para crear aplicaciones excelentes sin comprometer la seguridad y la flexibilidad de las herramientas que usa. ¿Has construido un asistente de voz con Rasa? ¿Qué herramientas usaste? Comparte tu experiencia con nosotros publicando al respecto en el foro de la comunidad Rasa.

The post Cómo construir un asistente de voz con herramientas de código abierto como Rasa y Mozilla first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/tutorial-como-construir-asistente-voz-con-herramientas-de-codigo-abierto-rasa-y-mozilla/feed/ 1
Más allá de ‘Ok Google’: construyendo un asistente de Google impulsado por Rasa https://desa.planetachatbot.com/mas-alla-de-ok-google-construyendo-asistente-de-google-impulsado-por-rasa/?utm_source=rss&utm_medium=rss&utm_campaign=mas-alla-de-ok-google-construyendo-asistente-de-google-impulsado-por-rasa https://desa.planetachatbot.com/mas-alla-de-ok-google-construyendo-asistente-de-google-impulsado-por-rasa/#respond Mon, 28 Jan 2019 09:00:18 +0000 https://desa.planetachatbot.com/?p=1047 Desde el lanzamiento en 2016, Google Assistant se ha convertido rápidamente en una voz familiar en los hogares de las personas. Desde la reproducción de tu canción favorita hasta el control de las luces, el Asistente de Google se encarga de todo a través de interacciones de voz simples. Pero ¿qué hay de manejar conversaciones […]

The post Más allá de ‘Ok Google’: construyendo un asistente de Google impulsado por Rasa first appeared on Planeta Chatbot.

]]>
Desde el lanzamiento en 2016, Google Assistant se ha convertido rápidamente en una voz familiar en los hogares de las personas. Desde la reproducción de tu canción favorita hasta el control de las luces, el Asistente de Google se encarga de todo a través de interacciones de voz simples. Pero ¿qué hay de manejar conversaciones más complejas? Si has usado el Asistente de Google, probablemente hayas notado que cada solicitud debe comenzar con la frase mágica “Hola, Google” y que la mayoría de las conversaciones con el asistente no van más allá de una sola solicitud.

En este post, te mostraremos cómo puedes habilitar tu Asistente de Google para manejar conversaciones más profundas y más naturales al integrarlo con Rasa Stack. Hay una serie de razones por las que los desarrolladores eligen Rasa Stack para crear asistentes de conversación:

⦁ Es de código abierto, lo que permite la personalización completa del marco y garantiza que tenga la propiedad completa de los datos de su aplicación.

⦁ Utiliza el aprendizaje automático para dirigir el diálogo: aprende los patrones a partir de los datos conversacionales reales. Escala mucho mejor en producción que las reglas predefinidas o las máquinas de estado.

⦁ Puedes ejecutar tu asistente Rasa AI a través de múltiples canales, lo que significa que tu asistente puede ser accesible a través de diferentes plataformas de mensajería y voz.

Al combinar Rasa Stack con las poderosas capacidades de voz a texto de Google Assistant y una interfaz ampliamente utilizada, puedes llevar a tu asistente de AI a un nivel completamente nuevo. La integración de Rasa con interfaces de voz como el Asistente de Google es una función muy solicitada por nuestra Comunidad de Rasa , ¡así que sigue leyendo y aprende cómo realizar la integración tu mismo! Este es un ejemplo de lo que puedes lograr al seguir este tutorial:

Contorno

1. El asistente de Rasa AI.

2. Inicializando la habilidad personalizada de Google Assistant.

3. Creando la acción personalizada de Google Assistant.

4. Creando el Rasa Connector para el Asistente de Google.

5. Poniendo todas las piezas juntas.

Bloques de construcción

Estas son las herramientas y el software que necesitarás para crear un Asistente de Google basado en Rasa:

  • Altavoz inteligente de Google Assistant o una aplicación de Google Assistant: una herramienta para probar la habilidad personalizada de Google Assistant
  • Consola Google Actions: la plataforma para inicializar acciones personalizadas de Google Assistant.
  • Google Actions SDK: un paquete de software diseñado para desarrollar habilidades personalizadas de Google Assistant.
  • Rasa NLU y Rasa Core: pila de software de AI de conversación de código abierto
  • Ngrok : un túnel para exponer una aplicación que se ejecuta localmente al mundo exterior.

Paso 1: El asistente de Rasa AI

El objetivo principal de este tutorial es mostrarte cómo puedes conectar un agente de Rasa a Google Assistant y hacerlo más conversacional. Hay dos opciones de cómo puedes seguir este tutorial: puedes usar tu asistente Rasa personalizado o puedes tomar nuestro asistente de búsqueda de lugares preconstruido llamado Place Finder

y usarlo para hacer la integración.

Si eliges la primera opción, puedes ir al paso dos de este tutorial. Si eliges el segundo, ahora es el mejor momento para capturar el Place Finder mediante la clonación de este repositorio.

El asistente consta de los siguientes archivos:

⦁ data/nlu_data.md es un archivo que contiene los datos de entrenamiento para el modelo Rasa NLU. Estos datos consisten en ejemplos de consultas de usuarios junto con los intents y las entidades correspondientes.

⦁ El archivo config.yml contiene la configuración del canal de capacitación Rasa NLU. Define cómo se analizarán las entradas del usuario, cómo se extraerán las características y qué modelo de aprendizaje automático se usará para entrenar el modelo.

⦁ data/stories.md es un archivo que contiene datos de entrenamiento para el modelo Rasa Core. Estos datos consisten en historias: conversaciones reales entre un usuario y un asistente escritas en ⦁ formato Rasa , donde las entradas del usuario se expresan como intenciones y entidades correspondientes, y las respuestas del asistente se expresan como acciones.

⦁ domain.yml es un archivo que contiene la configuración del dominio del asistente. Se compone de las siguientes piezas:

⦁ Intenciones y entidades que se definen en los ejemplos de datos de capacitación de Rasa NLU;

⦁ Ranuras que funcionan como marcadores de posición para guardar los detalles que el asistente debe recordar durante la conversación;

⦁ Plantillas que definen las respuestas de texto que un asistente debe devolver cuando se pronostican las expresiones correspondientes

⦁ Acciones que el asistente debe poder predecir y ejecutar.

⦁ Actions.py es un archivo que contiene el código de la acción personalizada donde el asistente realiza una llamada a la API para recuperar los detalles sobre la ubicación actual del usuario y buscar el lugar especificado dentro del radio solicitado por el usuario. El asistente luego usa los detalles devueltos para generar la respuesta y almacena algunos de los detalles recuperados como espacios para que el asistente los use en las últimas etapas de la conversación.

⦁ Endpoints.yml contiene la configuración de webhook de acciones personalizadas.

⦁ Credentials.yml es un archivo para almacenar la clave de la API de Google Places.

Todos estos archivos están listos para su uso, todo lo que tienes que hacer es proporcionar tu clave API de Google Places al archivo credentials.yml y capacitar a los modelos. Entrena al modelo NLU usando el comando que encontrarás a continuación y que se encargará de llamar a la función NLU de Rasa, pasará los datos de entrenamiento y procesará los archivos de configuración de la pipeline, y guardará el modelo dentro del directorio models/current/nlu_model:

python -m rasa_nlu.train -c config.yml — data data/nlu_data.md -o models — fixed_model_name nlu_model — project current — verbose

Una vez que se haya capacitado al modelo NLU, adiestra el modelo Rasa Core utilizando el comando que verás a continuación y que llamará a la función de Rasa Core, pasará los datos de las historias y los archivos de dominio y guardará el modelo entrenado dentro del directorio de models/current/ dialogue:

python -m rasa_core.train -d domain.yml -s data/stories.md -o models/current/dialogue — epochs 200

Al capacitar a los modelos Rasa NLU y Rasa Core, crearás el cerebro de tu asistente de IA. Estos dos modelos serán responsables de comprender lo que dice el usuario y decidir cómo debe responder el asistente. Ahora es el momento de crear el oído y la boca del asistente utilizando el Asistente de Google.

Paso 2: Inicializando la acción personalizada de Google Assistant

La acción personalizada de Google Assistant empaquetará a tu agente Rasa como una habilidad personalizada y te permitirá utilizar el servicio de voz a texto de Google Assistant para habilitar la comunicación de voz con tu asistente. Primero, tienes que inicializar la acción personalizada de Google Assistant. Aquí sabrás como podrás hacerlo:

  1. Ves a la consola de acciones de Google y selecciona ‘Agregar / importar proyecto’.

2. Establece el nombre de tu proyecto y eligue el idioma que deseas que use tu asistente. Haz click en ‘Crear proyecto’.

3. Una vez que se haya creado el proyecto, se te pedirá que ingreses a una página donde puedes elegir la categoría de tu proyecto. Desplázate hasta la parte inferior de la página y eligue la opción ‘Acciones SDK’. Al hacerlo, le dice a tu Asistente de Google que implementará su propia acción personalizada con un sistema personalizado de gestión de diálogos y PNL.

4. Dentro de la ventana que se abrió después de seleccionar Actions SDK, encontrarás la guía Google Actions SDK y una función gactions que usarás más adelante para implementar la acción personalizada. Copia la función proporcionada o toma nota del valor del parámetro — proyecto y haz clic en Aceptar.

5. Ahora puedes elegir una categoría de proyecto u omitir este paso seleccionando “Omitir” en la parte superior de la página.

6. En la página de configuraciones del proyecto, puedes especificar cómo deseas que se invoque tu habilidad personalizada. Puedes hacerlo haciendo click en “Decidir cómo se invoca tu acción” en un panel de “Configuración rápida”.

7. Aquí puedes seleccionar el Nombre para mostrar: el nombre que el Asistente de Google busca para comenzar tu habilidad personalizada. Por ejemplo, si estableces el nombre para mostrar en ‘Localizador de lugares’, para comenzar esta habilidad personalizada tendrá que decir algo como ‘Hola Google, hable con un Localizador de lugares’. También puedes elegir la voz que deseas que use tu asistente de Google y una vez que estés satisfecho con las configuraciones, selecciona ‘Guardar’.

En esta etapa, has inicializado la acción personalizada de Google Assistant. Ahora es el momento de definir cómo debe comportarse el Asistente de Google cuando el usuario invoca esta acción y qué debe hacer cuando el usuario comienza a usar la habilidad.

Paso 3: Crear una acción personalizada de Google Assistant

Dado que la fuente abierta Rasa Stack se encargará de la comprensión del lenguaje natural y la gestión del diálogo, la acción personalizada de Google Assistant será responsable de solo dos cosas: comprender que un usuario invocó la acción personalizada y pasar todas las entradas del usuario a Rasa después de invocar la habilidad. Para lograr esto, tendrá que definir los intentos para estos dos comportamientos y cumplimientos: cosas que el Asistente de Google tendrá que hacer una vez que estos intentos coincidan después de realizar la voz a texto en las entradas de voz del usuario. Aquí está cómo hacerlo:

  1. Descarga la CLI de Google gactions y colócala en el directorio de tu proyecto.
  2. Dentro de ese directorio, inicializas el archivo de configuración de acción personalizada de Google Assistant ejecutando el siguiente comando:

gactions init

3. Abre el archivo actions.json que se inicializó después de ejecutar el comando anterior. Este archivo tiene la configuración básica de la acción de invocación de habilidad personalizada. Se compone de tres partes principales:

⦁ nombre — define el tipo de intento

 intención — corresponde a lo que se trata la acción

⦁ cumplimiento: un webhook al que el Asistente de Google debe enviar la solicitud una vez que coincida la intención correspondiente.

Todas las habilidades personalizadas de Google Assistant necesitan una acción de invocación, por lo que todo lo que tienes que hacer es proporcionar los detalles necesarios a la configuración anterior:

{
  "actions": [
    {
      "description": "Default Welcome Intent",
      "name": "MAIN",
      "fulfillment": {
        "conversationName": "<INSERT YOUR CONVERSATION NAME HERE>"
      },
      "intent": {
        "name": "actions.intent.MAIN",
        "trigger": {
          "queryPatterns": [
            "talk to <INSERT YOUR NAME HERE>"
          ]
        }
      }
    }
  ],
  "conversations": {
    "<INSERT YOUR CONVERSATION NAME HERE>": {
      "name": "<INSERT YOUR CONVERSATION NAME HERE>",
      "url": "<INSERT YOUR FULLFILLMENT URL HERE>"
    }
  },
  "locale": "en"
}

⦁ conversationName que funcionará como un conector entre la intención y un cumplimiento correspondiente. Para la acción de invocación de habilidad, un nombre de conversación podría ser algo así como “bienvenido”

⦁ queryPatterns: una frase de ejemplo que un usuario podría decir. Para la acción de invocación de habilidad, un patrón de consulta podría ser algo así como ‘Talk to Place Finder’.

Una vez que se configura la acción de invocación, todo lo que tienes que agregar es otra acción que pasará todas las entradas del usuario a la Pila Rasa después de invocar la habilidad personalizada. Para esto, tendrás que definir una nueva intención con el nombre ‘TEXTO’ que capturará todas las entradas del usuario después de que se realice el servicio de voz a texto y pasarlo a Rasa Stack utilizando el webhook que definirás en el próximo paso. A continuación se muestra la configuración completa de la acción personalizada de Google Assistant:

{
   "actions": [
      {
        "description": "Default Welcome Intent",
        "name": "MAIN",
        "fulfillment": {
          "conversationName": "welcome"
        },
        "intent": {
          "name": "actions.intent.MAIN",
          "trigger": {
            "queryPatterns":["talk to Place Finder"]
          }
        }
      },
	  {
        "description": "Rasa Intent",
        "name": "TEXT",
        "fulfillment": {
          "conversationName": "rasa_intent"
        },
        "intent": {
          "name": "actions.intent.TEXT",
          "trigger": {
            "queryPatterns":[]
          }
        }
      }],
    "conversations": {
      "welcome": {
        "name": "welcome",
        "url": "...",
        "fulfillmentApiVersion": 2
    },
      "rasa_intent": {
        "name": "rasa_intent",
        "url": "...",
        "fulfillmentApiVersion": 2
    }
  }
}

Para pasar las entradas de los usuarios a Rasa, el Asistente de Google necesita un URL de webhook que se utilizará para establecer la conexión entre los dos. En el siguiente paso, escribirás un conector personalizado para conectar Rasa a Google Assistant.

Paso 4: Creando un Rasa Connector para el Asistente de Google

De manera predeterminada, Rasa viene con un montón de conectores precompilados para las plataformas de mensajería más populares, pero como el conector de Google Assistant aún no está incluido, ¡aprenderás cómo crear uno! Aquí están los pasos de cómo hacerlo:

1. En el directorio de tu proyecto, crea un nuevo archivo llamado ‘ga_connector.py’. En este archivo, escribirás el código.

2. Abre el archivo ga_connector.py y comienza importando las bibliotecas necesarias que incluyen:

⦁ future(por la cordura del código).

⦁ logging(para la depuración)

⦁ flask(para crear el webhook)

⦁ Algunas clases de Rasa Core (para crear el conector personalizado)

⦁ json

import logging
import json
from sanic import Blueprint, response
from sanic.request import Request
from typing import Text, Optional, List, Dict, Any

from rasa.core.channels.channel import UserMessage, OutputChannel
from rasa.core.channels.channel import InputChannel
from rasa.core.channels.channel import CollectingOutputChannel

logger = logging.getLogger(__name__)

3. Crea una clase llamada GoogleAssistant que hereda la clase InputChannel del núcleo rasa. Esta clase constará de dos funciones: nombre y plano:

class GoogleAssistant(InputChannel):

  @classmethod
  def name(cls):

  def blueprint(self, on_new_message):

4. La función de nombre definirá tu prefijo de URL de webhook. Llámalo google_assistant:

@classmethod
def name(cls)
  return ‘google_assistant’

5. Ahora vamos a completar la función de plano. Esta función definirá el webhook que Google Assistant usará para pasar las entradas del usuario a Rasa Core, recopilar las respuestas y enviarlas de vuelta a Google Assistant. Comienza por inicializar el nombre de webhook:

def blueprint(self, on_new_message):
	google_webhook = Blueprint('google_webhook', __name__)
A continuación, debes definir las rutas de tu webhook. Debes incluir al menos dos rutas: ruta de salud para el punto final ‘/’ y una ruta de recepción para el punto final ‘/ webhook’. A continuación, se muestra la implementación de una ruta de salud: recibirás las solicitudes GET enviadas por el Asistente de Google y devolverás un mensaje de 200 OK confirmando que la conexión funciona bien.La ruta receive recibirá solicitudes POST de Google Assistant y pasará la carga útil recibida al agente Rasa. El siguiente bloque de código contiene la implementación de esta ruta, esto es lo que hace:

@google_webhook.route("/", methods=['GET'])
async def health(request):
        return response.json({"status": "ok"})

⦁ Una vez que se recibe la solicitud POST, el conector toma la carga útil de la solicitud.

⦁ La carga útil contiene los detalles sobre la entrada del usuario enviada por el Asistente de Google. Estos detalles incluyen la identificación del usuario, la intención (es una solicitud de inicio o un mensaje regular) y el mensaje real en un formato de texto. Todos estos detalles se extraen de la carga útil y se asignan a las variables correspondientes.

⦁ Si la intención es una solicitud de lanzamiento de habilidad, el Asistente responderá con un mensaje introductorio “Bienvenido a la habilidad Asistente de Google potenciada por Rasa. Puedes empezar diciendo hola “.

⦁ Si la intención es una entrada de usuario regular, entonces tiene que inicializar el canal de salida (CollectingOutputChannel es una buena opción para devolver las respuestas generadas por Rasa Core) y pasarlo a Rasa junto con la entrada del usuario y la identificación del remitente. Rasa Core hará una predicción de cómo debería responder el asistente y te permitirá recuperar el mensaje de respuesta del canal de salida.

⦁ Finalmente, el mensaje producido se incorpora a una respuesta json que se envía de vuelta a Google Assistant.

@google_webhook.route("/webhook", methods=['POST'])
async def receive(request):
    payload = request.json	
    intent = payload['inputs'][0]['intent'] 			
    text = payload['inputs'][0]['rawInputs'][0]['query'] 
	
    if intent == 'actions.intent.MAIN':	
        message = "Hello! Welcome to the Rasa-powered Google Assistant skill. You can start by saying hi."			 
    else:
        out = CollectingOutputChannel()			
        await on_new_message(UserMessage(text, out))
        responses = [m["text"] for m in out.messages]
        message = responses[0]
    r = {
          "expectUserResponse": 'true',
          "expectedInputs": [
            {
              "possibleIntents": [
                {
                  "intent": "actions.intent.TEXT"
                 }
            ],
            "inputPrompt": {
              "richInitialPrompt": {
                "items": [
                  {
                    "simpleResponse": {
                      "textToSpeech": message,
                      "displayText": message
                      }
                    }
                  ]
                }
              }
            }
          ]
        }

    return response.json(r)

A continuación se muestra el código completo de la clase de conector Asistente de Google:

import logging
import json
from sanic import Blueprint, response
from sanic.request import Request
from typing import Text, Optional, List, Dict, Any

from rasa.core.channels.channel import UserMessage, OutputChannel
from rasa.core.channels.channel import InputChannel
from rasa.core.channels.channel import CollectingOutputChannel



logger = logging.getLogger(__name__)


		
class GoogleConnector(InputChannel):
    """A custom http input channel.

    This implementation is the basis for a custom implementation of a chat
    frontend. You can customize this to send messages to Rasa Core and
    retrieve responses from the agent."""

    @classmethod
    def name(cls):
        return "google_assistant"


    def blueprint(self, on_new_message):
	    
        google_webhook = Blueprint('google_webhook', __name__)

        @google_webhook.route("/", methods=['GET'])
        async def health(request):
            return response.json({"status": "ok"})

        @google_webhook.route("/webhook", methods=['POST'])
        async def receive(request):
            payload = request.json	
            intent = payload['inputs'][0]['intent'] 			
            text = payload['inputs'][0]['rawInputs'][0]['query'] 
	
            if intent == 'actions.intent.MAIN':	
                message = "Hello! Welcome to the Rasa-powered Google Assistant skill. You can start by saying hi."			 
            else:
                out = CollectingOutputChannel()			
                await on_new_message(UserMessage(text, out))
                responses = [m["text"] for m in out.messages]
                message = responses[0]
            r = {
                  "expectUserResponse": 'true',
                  "expectedInputs": [
                    {
                      "possibleIntents": [
                        {
                          "intent": "actions.intent.TEXT"
                        }
                    ],
                    "inputPrompt": {
                      "richInitialPrompt": {
                        "items": [
                          {
                            "simpleResponse": {
                              "textToSpeech": message,
                              "displayText": message
                              }
                            }
                          ]
                        }
                      }
                    }
                  ]
                }

            return response.json(r)				
          		
        return google_webhook

Y eso es. ¡Acabas de escribir un conector personalizado de Google Assistant para Rasa! Ahora es el momento de juntar todas las piezas y probar al asistente.

Paso 5: Poniendo todas las piezas juntas.

Todo lo que queda por hacer es iniciar el servidor Rasa Core, que utilizará el conector personalizado para conectarse a Google Assistant. Puedes hacerlo utilizando el código siguiente que cargará el agente de Rasa Core utilizando el modelo Rasa NLU como intérprete e iniciará el webhook que escuchará las entradas del usuario entrante:

from rasa_core.agent import Agent
from rasa_core.interpreter import RasaNLUInterpreter
from custom import GoogleConnector
from rasa_core.utils import EndpointConfig

action_endpoint = EndpointConfig(url="http://localhost:5055/webhook")
nlu_interpreter = RasaNLUInterpreter('./models/current/nlu_model')
agent = Agent.load('./models/current/dialogue', interpreter = nlu_interpreter, action_endpoint=action_endpoint)

input_channel = GoogleConnector()
agent.handle_channels([input_channel], 5004, serve_forever=True)

Guarda este código dentro de un archivo llamado run_app.py y ejecútalo. Iniciará el servidor en el puerto 5004 y establecerá el webhook de GoogleConnector.

Como tu asistente Rasa se ejecuta localmente y Google Assistant se ejecuta en la nube, necesitarás un servicio de tunelización para exponer a tu asistente local Rasa al mundo exterior. Ngrok es una buena opción para eso, así que inicia ngrok en el mismo puerto en el que se está ejecutando el agente de Rasa: 5004. Ahora puedes conectarlo a Google Assistant pasando la URL de webhook a los cumplimientos de tu acción personalizada de Google Assistant. Para hacer eso, copia la url generada por ngrok (será diferente a la que obtuvimos para el siguiente ejemplo), adjunta el sufijo ‘/webhooks/google_assistant/webhook’, regresa al archivo action.json y proporciona la url a la parte de conversaciones del archivo de configuración:

{
   "actions": [
      {
        "description": "Default Welcome Intent",
        "name": "MAIN",
        "fulfillment": {
          "conversationName": "welcome"
        },
        "intent": {
          "name": "actions.intent.MAIN",
          "trigger": {
            "queryPatterns":["talk to Place Finder"]
          }
        }
      },
	  {
        "description": "Rasa Intent",
        "name": "TEXT",
        "fulfillment": {
          "conversationName": "rasa_intent"
        },
        "intent": {
          "name": "actions.intent.TEXT",
          "trigger": {
            "queryPatterns":[]
          }
        }
      }],
    "conversations": {
      "welcome": {
        "name": "welcome",
        "url": "https://145f1bf4.ngrok.io/webhooks/google_assistant/webhook",
        "fulfillmentApiVersion": 2
    },
      "rasa_intent": {
        "name": "rasa_intent",
        "url": "https://145f1bf4.ngrok.io/webhooks/google_assistant/webhook",
        "fulfillmentApiVersion": 2
    }
  }
}
Si tu asistente de Rasa incluye acciones personalizadas (al igual que Place Finder), asegúrate de iniciar el servidor de acciones ejecutando el siguiente comando:python -m rasa_core_sdk.endpoint --actions actions

Ahora, todo lo que queda por hacer es implementar tu habilidad personalizada de Google Assistant y habilitar las pruebas. Puedes implementar la habilidad personalizada de Google Assistant ejecutando el siguiente comando. Aquí, PROJECT_ID es un valor del parámetro — proyecto del cual tomó nota en el paso 2 de este tutorial.

gactions update --action_package action.json --project PROJECT_ID

Una vez que se carga la acción, habilita la prueba de la acción ejecutando el siguiente comando:

gactions test --action_package action.json --project PROJECT_ID

Sugerencia: si olvidaste tomar nota de tu ID de proyecto, puedes encontrarla dentro de la configuración de proyectos en la consola de Google Actions:

¡Felicidades! ¡Acabas de crear una habilidad personalizada de Google Assistant con Rasa Stack!

¡Ahora puedes continuar y probarlo en tu altavoz inteligente de Google Home o en tu aplicación Google Assistant (asegúrate de iniciar sesión con la misma cuenta de Google que usaste para desarrollar la habilidad personalizada en la consola de acciones de Google)!

¡Háznos saber cómo lo estás implementando y qué te parece!

Estamos deseando ver lo que puedes construir. Comparte tus proyectos en el Foro de la Comunidad de Rasa y publica cualquier pregunta que tengas sobre la integración de Rasa en el Asistente de Google.

Recursos

The post Más allá de ‘Ok Google’: construyendo un asistente de Google impulsado por Rasa first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/mas-alla-de-ok-google-construyendo-asistente-de-google-impulsado-por-rasa/feed/ 0
Construyendo asistentes contextuales con Rasa Forms https://desa.planetachatbot.com/construyendo-asistentes-contextuales-con-rasa-forms/?utm_source=rss&utm_medium=rss&utm_campaign=construyendo-asistentes-contextuales-con-rasa-forms https://desa.planetachatbot.com/construyendo-asistentes-contextuales-con-rasa-forms/#respond Wed, 16 Jan 2019 09:47:57 +0000 https://desa.planetachatbot.com/?p=1042 Un asistente contextual que va más allá de las simples interacciones de estilo de preguntas frecuentes requiere algo más que un algoritmo y una oración. Un asistente de conversación debe haber recopilado los detalles importantes necesarios para responder las preguntas de los usuarios en el contexto adecuado. De lo contrario, no se conseguirá un resultado positivo. Bastante […]

The post Construyendo asistentes contextuales con Rasa Forms first appeared on Planeta Chatbot.

]]>
Un asistente contextual que va más allá de las simples interacciones de estilo de preguntas frecuentes requiere algo más que un algoritmo y una oración. Un asistente de conversación debe haber recopilado los detalles importantes necesarios para responder las preguntas de los usuarios en el contexto adecuado. De lo contrario, no se conseguirá un resultado positivo. Bastante simple, y conocido como slot filling. Pero, ¿cómo reúnes y defines los detalles que son importantes antes de tomar acción o proporcionar una respuesta?

Este proceso es fácil con nuestra última novedad de FormPolicy. Esta es una característica nueva que implementa el slot filling de una manera fácil y efectiva. ¿Cómo? FormPolicy te permite cubrir todos los caminos felices con una sola historia. Los formularios también te permiten alterar la lógica en un camino feliz, sin necesidad de cambiar los datos de entrenamiento.

Entonces, ¿cómo implementar esta nueva técnica? Me alegra que hayas preguntado. Aquí te indicamos cómo hacer que FormPolicy lo haga todo por ti.

Contorno

  1. Introducción al slot filling.

2. Construyendo un asistente de búsqueda de restaurantes usando los nuevos formularios:

  • Paso 1: Extraer detalles de las entradas del usuario utilizando Rasa NLU.
  • Paso 2: Entrenando el modelo de diálogo: manejando el camino feliz con formas.
  • Paso 3: Definiendo el dominio.
  • Paso 4: Definiendo la FormAction.
  • Paso 5: Expandir FormAction para manejar casos más avanzados.
  • Paso 6: Manejo de las desviaciones del camino feliz.
  • Paso 7: Probando el asistente de búsqueda de restaurante.

3. Resumen

4. Recursos útiles.

Introducción al slot filling

La presentación de slots es un proceso de recopilación de información importante para cumplir con la solicitud del usuario. Se trata de tener datos relevantes a mano que pueden ser útiles en una conversación determinada.

Tomemos como ejemplo un asistente de búsqueda de restaurantes para ilustrarlo. Antes de que el asistente pueda realizar una acción de búsqueda en un restaurante, debe conocer las preferencias de los usuarios, como el tipo de restauración, el rango de precios, la ubicación, etc., para poder hacer una sugerencia útil.

Para almacenar dicha información, Rasa Core utiliza ranuras (slots). En casos simples, puede implementar el slot filling utilizando solo ranuras (slots), pero las cosas se complican rápidamente una vez que la complejidad de las conversaciones crece. Con más detalles, vienen más posibles giros de diálogo, lo que crea mayores y mayores requisitos de datos de capacitación. Aquí es donde FormAction viene al rescate. Te permite imponer una lógica estricta en el proceso de recopilación de información y reducir considerablemente la cantidad de datos de capacitación necesarios para construir un buen modelo de diálogo.

Construyendo un asistente de búsqueda de restaurantes usando Rasa Forms

En la parte restante de este tutorial, aprenderás cómo usar la nueva FormPolicy en la realidad. Este tutorial se basa en un asistente de búsqueda de restaurantes llamado formbot. Puedes encontrar todo el código dentro del repositorio de Rasa Core GitHub :

git clone https://github.com/RasaHQ/rasa_core.git
cd rasa_core/examples/formbot

Al seguir este tutorial y usar el código dentro del repositorio, construirás un asistente divertido, capaz de sugerir restaurantes según las preferencias del usuario, como el tipo de cocina, el número de personas, el lugar que prefieres y otros requisitos posibles. Aquí puedes encontrar una recreación de una conversación real con el chatbot:

Paso 1: Extraer detalles de las entradas del usuario utilizando Rasa NLU

Antes de almacenar información importante como ranuras, el asistente debe extraerlas de las entradas del usuario.

Para que tu asistente pueda hacer eso, es necesario entrenar el modelo NLU que clasificará la intención de las entradas del usuario y extraerá detalles importantes como entidades.

El ejemplo de Formbot ya viene con ejemplos de entrenamiento que puedes usar para entrenar el modelo NLU. Utilizando los ejemplos de capacitación proporcionados, puedes enseñar a tu asistente a comprender entradas como saludos, consultas de búsqueda de restaurantes, entradas para suministrar la información solicitada, etc., y luego extraer entidades como tipo de restaurante, cantidad de personas, requisitos adicionales, etc. Puedes encontrar la capacitación de NLU ejemplos dentro del archivo data/nlu_data.md del ejemplo formbot.

Para entrenar el modelo, ejecuta el siguiente comando. Este comando es un comando de shell de acceso directo que llamará a la función Rasa NLU train, pasará los datos de entrenamiento y los archivos de configuración del modelo y guardará el modelo dentro del directorio models / nlu / current de su directorio de trabajo:

make train-nlu

Nota: si eres nuevo en Rasa NLU y deseas obtener más información al respecto, asegúrate de consultar la documentación de Rasa NLU.

Paso 2: Entrenando el modelo de diálogo: manejando el camino feliz con formas

Una vez que el asistente es capaz de comprender las entradas del usuario, es hora de construir un modelo de gestión de diálogo. Al usar Formularios para rellenar espacios, es mejor comenzar por entrenar al modelo para manejar los caminos felices, situaciones en las que el usuario proporciona toda la información requerida y le permite al asistente dirigir la conversación.

Lo mejor de las nuevas formas es que el asistente aprende a manejar todos los caminos felices de una sola historia de entrenamiento. Mira el video de abajo para ver la ilustración:

¿Cómo funciona?

Una vez que restaurant_form predice la “acción de formulario”, el asistente sigue pidiendo los detalles necesarios hasta que se configuren todos los espacios requeridos. No hay restricciones sobre la forma en que el usuario debe proporcionar los detalles: si un usuario especifica todas las preferencias en la solicitud inicial del restaurante, por ejemplo, “Reserve una mesa para dos en el restaurante chino”, el asistente omitirá las preguntas sobre la cocina y número de personas.

Si el usuario no especifica ninguno de estos detalles en una solicitud inicial, el asistente pregunta todos los detalles en las preguntas de seguimiento hasta que se proporcionen todos ellos. Ambas situaciones representan dos conversaciones diferentes (puede haber más de dos), pero al usar FormsPolicy, ambas se aprenderán usando la misma historia. A continuación se muestra un fragmento de la historia de entrenamiento utilizada para modelar todos los caminos felices en un ejemplo de formbot:

## happy path 
* greet
 - utter_greet 
* request_restaurant
 - restaurant_form
 - form{"name": "restaurant_form"}
 - form{"name": null}
 - utter_slots_values
 * thankyou
 - utter_noworries

Consulte el archivo data/stories.md del ejemplo de Formbot para investigar las historias de capacitación con más detalle.

Paso 3: Definiendo el dominio

Para entrenar el modelo de gestión de diálogos con Rasa Core, también necesitas definir el dominio . Aquí es donde puedes especificar qué detalles extraídos deben almacenarse como ranuras.

Hay tres cosas importantes que debes considerar al definir el dominio para un asistente con el llenado de espacios:

  1. En Rasa Core, diferentes tipos de slots tienen una influencia diferente en las predicciones de la siguiente acción. Cuando utilizas FormAction para llenar los espacios, estás aplicando reglas estrictas que le dicen a tu asistente qué información debe solicitar a continuación. De esta manera, permite que FormAction maneje todos los caminos felices en una sola historia, ya que verifica qué ranuras solicitadas están completas y cuáles no. Para que esto funcione, las ranuras solicitadas en tu archivo de dominio deben definirse como no modificadas.
  2. Los nombres de las plantillas que se utilizarán para solicitar las ranuras necesarias faltantes deben seguir el formato utter_ask_ {slotname}. Esto es importante para que FormAction sepa qué plantilla usar para qué ranura.
  3. Además de todas las partes habituales del dominio (intenciones, entidades, plantillas, acciones y ranuras), deberás incluir una sección adicional llamada formularios. Esta sección debe incluir los nombres de todas las acciones de formulario que tu asistente debe poder predecir en función de las historias definidas en un archivo de datos de entrenamiento.

A continuación se muestra un fragmento del dominio utilizado en un ejemplo de formbot:

entities:
 - cuisine
 - num_people
 - number
 - feedback
 - seatingslots:
 cuisine:
 type:unfeaturized
 auto_fill:false
 num_people: 
 type: unfeaturized 
 auto_fill: false 
 outdoor_seating: 
 type: unfeaturized 
 auto_fill: false 
 preferences: 
 type: unfeaturized 
 auto_fill: false 
 feedback: 
 type: unfeaturized 
 auto_fill: false 
 requested_slot: 
 type: unfeaturizedforms: 
 - restaurant_form

Paso 4: Definiendo la FormAction

El siguiente paso es implementar la FormAction que, una vez predicha, manejará el llenado de la ranura. Puedes implementar todas las FormActions en el archivo actions.py donde implementarías cualquier otra acción personalizada que te gustaría que tu asistente maneje. Vamos a definir la formAction para el relleno de la ranura auxiliar restaurante paso a paso (echa un vistazo a la actions.py archivo del ejemplo formbot para ver un código completo):

  • Primero, define la clase de acción de formulario. Ten en cuenta que las acciones de formulario, a diferencia de las acciones personalizadas normales, heredan de la clase FormAction:
  • La primera función que debes definir en una clase de acción de formulario se llama nombre, que simplemente define el nombre de la acción (la misma que definiste en el archivo de dominio). En un ejemplo de búsqueda de restaurante se define como restaurant_form:
  • A continuación, una función llamada required_slots se usa para definir una lista de ranuras que el asistente debe completar antes de responder a la solicitud del usuario:

Consejo profesional: la función required_slots es un gran lugar para introducir alguna lógica de ranura personalizada. Por ejemplo, podría tener sentido incluir la opción de asientos al aire libre solo para los restaurantes de una cocina específica. Puedes lograr esto introduciendo una lógica simple como en el ejemplo que te muestro a continuación, donde la ranura outdoor_seating solo será necesaria cuando los usuarios piden restaurantes que sirven comida griega:

  • El bloque de construcción final de una acción de formulario simple es una función llamada enviar que define lo que debería suceder una vez que se completen todos los espacios requeridos. En el caso de un asistente de búsqueda de restaurantes, una vez que se completen todas las ranuras, el asistente ejecutará la plantilla utter_submit que, en función de cómo se haya definido en un archivo domain.yml, confirmará que el asistente tiene toda la información que necesita para continuar:

Y ahí lo tienen, una implementación simple de FormAction. Hay mucho más que puedes agregar para permitir que tu asistente maneje casos aún más avanzados. Veamos esto en el siguiente paso de este tutorial.

Paso 5: Manejo de casos avanzados con FormAction

Algunas ranuras necesarias pueden provenir de entradas de usuario muy diferentes. Por ejemplo, el usuario podría responder a la pregunta “¿Te gustaría sentarte afuera?” Con las siguientes respuestas:

  • ‘Sí’
  • ‘No’
  • “Prefiero estar sentado en el interior” (o una respuesta directa similar).

Cada una de estas respuestas corresponde a diferentes intenciones o tiene diferentes entidades importantes, pero dado que proporcionan una respuesta viable a la pregunta, un asistente debe poder aceptarlo y establecer un espacio para avanzar.

Aquí es donde entra en juego la función slot_mappings en una FormAction: define cómo extraer valores de slot de las posibles respuestas de los usuarios y los asigna a un slot específico. A continuación se muestra un ejemplo de la función slot_mappings para la outdoor_seating comentada anteriormente . De acuerdo con la lógica definida, la outdoor_seating se rellenará utilizando:

  • Valor ‘Verdadero’ si el usuario responde con la intención ‘afirmar’ a la pregunta.
  • Valor ‘False’ si el usuario responde con la intención ‘deny’ a la pregunta.
  • Valor de la entidad extraída seating.

Puedes encontrar más ejemplos de asignación de ranura dentro de la slot_mappings función del actions.py archivo del ejemplo formbot.

def slot_mappings(self):
    # type: () -> Dict[Text: Union[Dict, List[Dict]]]
    """A dictionary to map required slots to
    - an extracted entity
    - intent: value pairs
    - a whole message or a list of them, where a first 
                                 match will be picked"""

    return { "outdoor_seating": [self.from_entity(entity="seating"),
                      self.from_intent(intent='affirm',
                                                 value=True),
                      self.from_intent(intent='deny',
                                                 value=False)]}

Otra cosa útil que puedes hacer con FormAction es la validación de espacios. Por ejemplo, antes de permitir que tu asistente continúe con las preguntas, es posible que desees verificar el valor de la ranura con los valores posibles en tu base de datos o verificar si el valor está en el formato correcto. Puedes lograrlo creando una función llamada validaren su clase de FormAction. De forma predeterminada, comprueba si se extrajo la ranura solicitada, pero puedes agregar tanta lógica adicional como sea necesario. A continuación se muestra un ejemplo de la función de validación que primero verifica si la ranura solicitada se completó y luego verifica si el número de personas proporcionado está en el formato correcto: si el número es un número entero, el asistente usará el valor proporcionado, si no responderá con un mensaje que indica que el formato del valor de la ranura no es válido, establece la ranura en Ninguno y solicítalo nuevamente.

def validate(self,
                 dispatcher: CollectingDispatcher,
                 tracker: Tracker,
                 domain: Dict[Text, Any]) -> List[Dict]:
    """Validate extracted requested slot
            else reject the execution of the form action
    """
    # extract other slots that were not requested
    # but set by corresponding entity
    slot_values = self.extract_other_slots(dispatcher, tracker, domain)

    # extract requested slot
    slot_to_fill = tracker.get_slot(REQUESTED_SLOT)
    if slot_to_fill:
        slot_values.update(self.extract_requested_slot(dispatcher,
                                                       tracker, domain))
        if not slot_values:
            # reject form action execution
            # if some slot was requested but nothing was extracted
            # it will allow other policies to predict another action
            raise ActionExecutionRejection(self.name(),
                                           "Failed to validate slot {0}"
                                           "with action {1}"
                                           "".format(slot_to_fill,
                                                         self.name()))

    # we'll check when validation failed in order
    # to add appropriate utterances
    for slot, value in slot_values.items():

        if slot == 'num_people':
            if not self.is_int(value) or int(value) <= 0:
                dispatcher.utter_template('utter_wrong_num_people',
                                              tracker)
                # validation failed, set slot to None
                slot_values[slot] = None

Puedes encontrar más ejemplos de la validación ranura (comprobación de la base de datos, cadena coincidente) en el actions.py archivo del ejemplo formbot.

Paso 6: Manejo de las desviaciones del camino feliz.

La idea principal detrás del relleno de ranuras con FormAction es que se aplica una lógica estricta para recopilar las piezas importantes de información y manejar el camino feliz, mientras que el aprendizaje automático normal se utiliza para manejar con gracia las desviaciones del camino feliz. Estas desviaciones pueden ser algunos mensajes de chat en medio de la sesión de acción de formulario o las situaciones en las que los usuarios se niegan a proporcionar todos los detalles necesarios. Para manejar situaciones como esta, tienes que escribir las historias que representan esos giros de conversación.

Por ejemplo, la historia a continuación representa la situación en la que el usuario decidió dejar de proporcionar la información en medio de la sesión de acción de formulario, pero luego regresó para proporcionar los detalles necesarios:

## stop but continue path
* request_restaurant
 - restaurant_form
 - form{"name": "restaurant_form"}
* stop
 - utter_ask_continue
* affirm
 - restaurant_form
 - form{"name": null}
 - utter_slots_values
* thankyou
 - utter_noworries

Para permitir que tu asistente maneje casos aún más avanzados, necesitas recopilar más historias como esta para cubrir diferentes turnos de diálogo. En algunas situaciones, es posible que desees manejar las rutas infelices de manera diferente según la ranura que el usuario solicite actualmente. Para lograrlo, dentro del archivo de dominio debe configurarse requested_slot categórico. Esto permitirá que las predicciones de la próxima respuesta se vean influenciadas según la ranura que se solicite actualmente.

Consulta el archivo data/stories.md del ejemplo de formbot para ver más posibles historias de ruta infelices.

Paso 7: Probando el asistente de búsqueda de restaurante

Ya has aprendido mucho sobre la implementación de FormAction y has definido todos los bits necesarios del modelo de gestión de diálogo. Ahora es el momento de la parte más emocionante: ¡probar al asistente!

Primero, entrena el modelo de gestión de diálogos utilizando el siguiente comando que llamará a la función de tren de Rasa Core, te pasará el dominio y los archivos de datos, y almacenará el modelo entrenado dentro del directorio de modelos / diálogo de tu directorio de trabajo:

make train-core

Una vez que el modelo está entrenado, ¡es hora de cargarlo junto con el modelo NLU previamente entrenado, y probar cómo funciona el robot de búsqueda de restaurantes!

Primero, en un nuevo terminal, inicia un servidor patito ejecutando el siguiente comando:

docker run -p 8000:8000 rasa/duckling

Inicia tu asistente ejecutando el siguiente comando que activará el servidor local para acciones personalizadas y cargará el asistente para que pueda chatear:

make run

Para ver mejor cómo funciona FormAction, dedica un tiempo a probar cómo se desempeña el asistente en diferentes caminos felices e infelices.

Resumen

Construir buenos asistentes contextuales no es fácil. La combinación de FormAction con el ML tradicional te permite crear asistentes que pueden manejar conversaciones más profundas sin tener que escribir muchas historias de entrenamiento para manejar el camino feliz. Además de esto, FormAction hace que sea mucho más fácil realizar cambios en el código y el diálogo de tu asistente, ya que las ranuras solicitadas no se utilizan directamente en las historias de capacitación.

¡Prueba los nuevos formularios en tus propios conjuntos de datos y comparte tus comentarios con nosotros uniéndote a la discusión en este hilo del Foro de la Comunidad Rasa!

Recursos

The post Construyendo asistentes contextuales con Rasa Forms first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/construyendo-asistentes-contextuales-con-rasa-forms/feed/ 0
Cómo migrar tu Chatbot de Google DialogFlow a Rasa https://desa.planetachatbot.com/como-migrar-chatbot-de-google-dialogflow-a-rasa/?utm_source=rss&utm_medium=rss&utm_campaign=como-migrar-chatbot-de-google-dialogflow-a-rasa https://desa.planetachatbot.com/como-migrar-chatbot-de-google-dialogflow-a-rasa/#respond Thu, 20 Sep 2018 09:51:42 +0000 https://desa.planetachatbot.com/?p=1045 Varios usuarios de Rasa han migrado desde plataformas de desarrollo de chatbot como LUIS, Wit.ai, o desde la que hemos visto en mayor porcentaje, DialogFlow (anteriormente Api.ai). Es seguro decir que podemos ver una tendencia en la que cada vez más desarrolladores comienzan a construir sus asistentes usando plataformas alojadas como DialogFlow, pero eventualmente enfrentan […]

The post Cómo migrar tu Chatbot de Google DialogFlow a Rasa first appeared on Planeta Chatbot.

]]>
Varios usuarios de Rasa han migrado desde plataformas de desarrollo de chatbot como LUIS, Wit.ai, o desde la que hemos visto en mayor porcentaje, DialogFlow (anteriormente Api.ai). Es seguro decir que podemos ver una tendencia en la que cada vez más desarrolladores comienzan a construir sus asistentes usando plataformas alojadas como DialogFlow, pero eventualmente enfrentan limitaciones de desarrollo y toman la decisión de cambiar a una solución de código abierto: Rasa Stack.

Estas son las razones principales por las que los desarrolladores eligen Rasa Stack sobre las plataformas alojadas:

Es de código abierto.

  • Puedes personalizar todo. Puedes sintonizar los modelos, integrar nuevos componentes o incluso personalizar todo el marco para adaptarlo mejor a tus necesidades.
  • Eres el dueño de tus datos. Puedes elegir dónde deseas alojar tus aplicaciones y tienes plena posesión de quién puede acceder a los datos de tu aplicación.

Gestión de diálogo con motor de aprendizaje automático.

  • El asistente utiliza el aprendizaje automático para aprender los patrones de conversaciones reales. Eso significa que no hay reglas predefinidas ni similares.
  • No necesitas grandes cantidades de datos de entrenamiento para comenzar. Puedes crear un primer asistente escalable desde una muestra de datos muy pequeña.

La migración de DialogFlow a Rasa es una de las solicitudes más comunes de la comunidad Rasa . En esta publicación veremos paso a paso cómo migrar un asistente DialogFlow existente a Rasa.

Puedes encontrar el código del asistente de ejemplo utilizado en este tutorial.

Outline

  • El asistente de DialogFlow
  • Paso 1: exportar el asistente de DialogFlow
  • Paso 2: entrenamiento del modelo Rasa NLU utilizando datos exportados
  • Paso 3: contextos de migración y entrenamiento del modelo Rasa Core
  • Paso 4: tu asistente de DialogFlow ahora se ejecuta en Rasa. ¿Que sigue?
  • Recursos útiles

El asistente DialogFlow

Como dijimos, el objetivo de esta publicación es mostrar un proceso paso a paso sobre cómo migrar un asistente DialogFlow existente a Rasa.

Para ilustrar el proceso, vamos a usar un ejemplo: un asistente de búsqueda personalizado llamado place_finder, capaz de buscar lugares como restaurantes, tiendas, bancos dentro del radio especificado por el usuario, y proporcionar detalles sobre el entorno como dirección, clasificación y horario de apertura del lugar. El asistente obtiene todos estos detalles utilizando un webhook para realizar llamadas a la API de Google Places.

A continuación hay una conversación de ejemplo con el asistente de place_finder:

Si deseas replicar este tutorial, puedes encontrar los archivos de datos y el código webhook del asistente place_finder dentro del directorio dialog-assistant del repositorio de este tutorial. Alternativamente, puedes seguir esta guía utilizando tu propio chatbot y ajustar que verás a continuación.

Cualquiera que sea la opción que elijas, en este punto deberías tener tu asistente de DialogFlow: ¡ahora es el momento de migrarlo a Rasa!

Consejo: si quieres jugar con el asistente de place_finder, debes obtener una clave API de Google Places y colocarla dentro del archivo credentials.yml de estos repositorios.

Paso 1: exportar el asistente DialogFlow

Recomendamos comenzar con la migración de la parte NLU del asistente DialogFlow.

Para migrarlo a Rasa, lo único que tienes que hacer es exportar los archivos del proyecto y usarlos para capacitar al modelo Rasa NLU; no se necesitan datos ni cambios de formato. Está diseñado para ser lo má fácil posible.

  1. Puedes exportar los datos del proyecto navegando a la pestaña de configuración de tu agente y seleccionando la pestaña ‘Exportar e Importar’.

2. En la pestaña ‘Exportar e Importar’, elije la opción ‘Exportar como ZIP’. Esto exportará los datos del proyecto como un archivo zip y lo descargará en tu ordenador.

3. Una vez descargado, puedes descomprimir el paquete e inspeccionar los archivos. El directorio del proyecto DialogFlow consta de los siguientes archivos y directorios:

  • entidades : un directorio que contiene archivos json de las entidades con las que se capacitó al asistente.
  • intents — un directorio que contiene los archivos json de las intents con las que tu asistente fue entrenado en DialogFlow.
  • agent.json — un archivo que contiene la configuración del asistente de DialogFlow
  • package.json — un archivo que contiene la información sobre el software utilizado para construir el asistente

Estos archivos se pueden usar directamente para entrenar el modelo Rasa NLU. Solo necesitas definir un archivo de configuración de canalización NLU y pasarlo al script de tren Rasa NLU. Eso se soluciona en el paso que veremos a continuación. Consulta el siguiente paso de este tutorial para ver las instrucciones detalladas.

Paso 2: entrenamiento del modelo Rasa NLU utilizando datos exportados

Rasa NLU permite la personalización completa de los modelos. Antes de entrenar el modelo NLU, debes definir una configuración de tu pipeline. Una canalización de proceso define cómo se analizan los ejemplos de formación y cómo se extraen las características. La configuración debe guardarse como un archivo .yml dentro del directorio del proyecto. A continuación te muestro un ejemplo de pipeline que podrías emplear en tu proyecto:

Archivo: rasa-assistant / config.yml

language: "en"pipeline: 
 - name: "nlp_spacy" 
 - name: "tokenizer_spacy" 
 - name: "ner_crf" 
 - name: "intent_featurizer_spacy"
 - name: "intent_classifier_sklearn"
 - name: "ner_duckling" 
 dimensions: ['number']

Una vez que hayas definido la canalización, puedes entrenar el modelo NLU siguiendo los pasos que muestro a continuación:

  1. Para entrenar al modelo, usa el siguiente comando que llama a la función de tren Rasa NLU, carga la configuración de la pipeline y los archivos de datos de entrenamiento y guarda el modelo entrenado dentro de un proyecto llamado ‘actual’:
python -m rasa_nlu.train -c config.yml — data data/place_finder -o models — project current — verbose

Puedes probar el modelo entrenado ejecutándolo como un servidor Rasa que puedes ejecutar utilizando el siguiente comando:

python -m rasa_nlu.server --path ./models

La función anterior iniciará un servidor local en un puerto 5000.

2. Ahora puedes emular los resultados del modelo Rasla NLU enviando solicitudes como la siguiente. Pasará el mensaje ‘Hello’ al modelo Rasa NLU y devolverá la respuesta.

curl 'localhost:5000/parse?q=Hello&project=current'

La respuesta del modelo Rasla NLU incluye los resultados de la clasificación de intención y la extracción de entidad. Por ejemplo, el mensaje “Hello” se clasificó como una intención “Default Welcome Intent” con la confianza de 0,83. Aquí hay una respuesta completa devuelta por el modelo NLU:

{ 
"intent":{ 
"name":"Default Welcome Intent",
"confidence":0.8342492802420313
 },
"entities":[ 

 ],
"intent_ranking":[ 
 { 
"name":"Default Welcome Intent",
"confidence":0.8342492802420313
 },
 { 
"name":"thanks",
"confidence":0.09805256693160122
 },
 { 
"name":"goodbye",
"confidence":0.05392708191432759
 },
 { 
"name":"address",
"confidence":0.003986386948676723
 },
 { 
"name":"place_search",
"confidence":0.0037102872949153686
 },
 { 
"name":"rating",
"confidence":0.003059348479049656
 },
 { 
"name":"opening_hours",
"confidence":0.0030150481893980153
 }
 ],
"text":"Hello",
"project":"current",
"model":"model_20180827-110057"
}

¡Y LISTO! ¡Acabas de migrar la parte NLU del asistente de DialogFlow a Rasa!

Consejo: El formato de datos exportado por DialogFlow es diferente del que utiliza Rasa NLU . Si deseas mejorar su modelo Rasa NLU después de la migración, puedes tomar un archivo de datos producido dentro del directorio del modelo después de que finalice la capacitación inicial (en este ejemplo, la ruta a este archivo es rasa-assistant / models / current / model_xxxxxxx / trainingdata.json), agrega nuevos ejemplos y vuelva a entrenar el modelo NLU que señala la train fuction del archivo.

Paso 3: Migración de contextos y capacitación del modelo Rasa Core

Nota: Si tu asistente DialogFlow personalizado no usa contextos o webhooks, puedes omitir esta parte del tutorial e ir directamente al punto cuatro.

Pero si los usas, tendrás que seguir los siguientes pasos:

  1. Para migrar la parte restante del asistente — manejo de contexto y acciones personalizadas — necesitas algunos datos de entrenamiento. DialogFlow lleva a cabo la gestión del diálogo a través del concepto de “contextos”, mientras que Rasa utiliza el aprendizaje automático para predecir qué acciones debe realizar un asistente en el estado específico de la conversación en función de acciones previas y detalles extraídos. Significa que para entrenar el modelo Rasa Core, necesitas algunos datos de entrenamiento en forma de historias. Dado que la gestión de diálogo de DialogFlow es un enfoque basado en reglas, no puedes exportar ningún dato de entrenamiento que puedas usar directamente para entrenar el modelo de diálogo Rasa Core. La buena noticia es que tienes acceso al historial de conversaciones en DialogFlow y puedes usarlo como base para generar datos de capacitación para el modelo Rasa Core. Aquí hay una conversación de ejemplo en DialogFlow:

Para convertir esta conversación en una historia de entrenamiento de Rasa Core, debes convertir las entradas del usuario a las intenciones y entidades correspondientes, mientras que las respuestas del agente deben expresarse como acciones. Así es como se vería la conversación anterior como una historia de Rasa:

Archivo: rasa-assistant / data / stories.md

## story_01 
 * Default Welcome Intent 
 utter_greet 
 * place_search{“query”:”restaurant”, “radius”:”600”}
 action_place_search 
 slots{“place_match”:”one”} 
 slots{“address”:”Ars Vini in Sredzkistraße 27, Hagenauer Straße 
 1, Berlin”} 
 slots{“rating”:”4.4”} 
 slots{“opening_hours”:”true”} 
 * opening_hours 
 utter_opening_hours 
 * rating 
 utter_rating

Para entrenar el modelo necesitarás algunas historias adicionales que representen diferentes turnos de conversación.

2. Crea el dominio de tu asistente que define todos los intentos, entidades, ranuras, plantillas y acciones con las que el asistente debe estar familiarizado. Por ejemplo, las plantillas del asistente de place_finder se ven así:

Archivo: domain.yml

templates:
 utter_greet: 
 — “Hello! How can I help?” 
 utter_goodbye: 
 — “Talk to you later!” 
 utter_thanks: 
 — “You are very welcome.” 
 utter_what_radius: 
 — “Within what radius?” 
 utter_rating: 
 — “The rating is {rating}.” 
 utter_address: 
 — “The address is {address}.” 
 utter_opening_hours: 
 — “The place is currently {opening_hours}.” 
 utter_no_results: 
 — “Sorry, I couldn’t find anything.”

Consejo: Todos los intentos y entidades definidos en el archivo de dominio deben coincidir con los nombres definidos en los ejemplos de capacitación.

3. Define acciones personalizadas. Si bien podemos escribir respuestas de texto simples dentro del archivo de dominio (al igual que en el fragmento de archivo de dominio anterior), las acciones más complicadas, como realizar una llamada API o conectarse a la base de datos para recuperar algunos datos, deben incluirse como una clase de acción personalizada. En DialogFlow, place_finder tenía un webhook para recuperar los datos de la API de Google Places, por lo que para migrarlo a Rasa, debes convertirlo en una clase de acción personalizada como la siguiente:

Esta clase asigna el nombre a esta acción personalizada, realiza la llamada API, recupera los datos solicitados, genera una respuesta que debe enviarse de vuelta al usuario y establece los detalles que deben mantenerse a lo largo de la conversación como espacios.

from rasa_sdk import Action, Tracker
from rasa_sdk.events import SlotSet, AllSlotsReset
import requests
import json
from random import randint
import datetime
import os
import yaml

class ActionPlaceSearch(Action):
    def name(self):
        #define the name of the action	
        return 'action_place_search'

    def run(self, dispatcher, tracker, domain):
        #retrieve slot values		
        query = tracker.get_slot('query')
        radius = tracker.get_slot('number')		

        #retrieve google api key	
        with open("./ga_credentials.yml", 'r') as ymlfile:
            cfg = yaml.load(ymlfile)
        key = cfg['credentials']['GOOGLE_KEY']
		
        #get user's current location		
        get_origin = requests.post(
            "https://www.googleapis.com/geolocation/v1/geolocate?key={}".format(key)).json()
        origin_lat = get_origin['location']['lat']
        origin_lng = get_origin['location']['lng']
				
        #look for a place using all the details
        place = requests.get('https://maps.googleapis.com/maps/api/place/nearbysearch/json?location={},{}&radius={}&type={}&key={}'.format(origin_lat, origin_lng, radius, query, key)).json()
        if len(place['results'])==0:
            dispatcher.utter_message("Sorry, I didn't find anything")
            return [SlotSet('location_match', 'none')]
        else:
            for i in place['results']:
                if 'rating' and 'vicinity' in i.keys():				
                    name = i['name']
                    rating = i['rating']
                    address = i['vicinity']
                    if i['opening_hours']['open_now']==True:
                        opening_hours = 'open'
                    else:
                        opening_hours = 'closed'
                    break
            speech = "I found a {} called {} based on your specified parameters.".format(query, name)
            dispatcher.utter_message(speech) #send the response back to the user	
            return [SlotSet('location_match', 'one'), SlotSet('rating', rating), SlotSet('address', address), SlotSet('opening_hours', opening_hours)] #set returned details as slots

4. Eso es todo lo que necesitas para entrenar el modelo Rasa Core que predecirá cómo debe responder el asistente a las entradas del usuario. ¡Ahora es el momento de entrenarlo!

Puedes entrenarlo utilizando el siguiente comando que llamará a la train fuction de rasa, cargará los archivos de datos de entrenamiento de dominio e historias y almacenará el modelo entrenado dentro del proyecto ‘actual’:

python -m rasa_core.train -d domain.yml -s data/stories.md -o models/current/dialogue --epochs 200

5. Y esto es todo: ¡has migrado con éxito un asistente de DialogFlow a Rasa! Ahora puedes probarlo localmente. Al ejecutar el siguiente comando, iniciará las acciones personalizadas webhook:

python -m rasa_core_sdk.endpoint — actions actions

Ahora, puedes cargar el agente usando el siguiente comando que cargará los modelos Rasa NLU y Rasa Core e inicie el asistente en la consola para que pueda chatear:

python -m rasa_core.run -d models/current/dialogue -u models/current/nlu_model --endpoints endpoints.yml

Paso 4: tu asistente de DialogFlow ahora se está ejecutando en Rasa. ¿Que sigue?

Como se suele decir, “Sky is the limit” si hablamos de las posibildiades que ofrece Rasa a la hora de desarrollar tus chatbots. Puedes personalizar los modelos, integrar componentes adicionales o conectarlo al mundo exterior utilizando los conectores de las plataformas de mensajería más populares. ¡Incluso puedes conectarlos a otros marcos y herramientas geniales para hacerlo aún más divertido!

Si has migrado tu asistente a Rasa, ¡nos encantaría conocer tu experiencia! ¡Únete al foro de la comunidad de Rasa y cuéntanos tu experiencia!

Recursos útiles

The post Cómo migrar tu Chatbot de Google DialogFlow a Rasa first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/como-migrar-chatbot-de-google-dialogflow-a-rasa/feed/ 0