Detecta intents con salida de audio

En muchas aplicaciones, se necesita que un bot le responda verbalmente al usuario final. Dialogflow puede usar Cloud Text-to-Speech con tecnología de DeepMind WaveNet para generar respuestas de voz de tu agente. Esta conversión de respuestas de texto de intent a audio se conoce como salida de audio, síntesis de voz, texto a voz o TTS.

En esta guía, se muestra un ejemplo en el que se usa audio tanto para la entrada como para la salida cuando se detecta un intent. Este caso práctico es común en el desarrollo de apps que se comunican con usuarios a través de una interfaz solo de audio.

Para obtener una lista de los idiomas compatibles, consulta la columna TTS en la página Idiomas.

Antes de comenzar

Esta función solo se aplica cuando se usa la API para las interacciones del usuario final. Si usas una integración, puedes omitir esta guía.

Debes hacer lo siguiente antes de leer esta guía:

  1. Lee los conceptos básicos de Dialogflow.
  2. Realiza los pasos de configuración.

Crea un agente

En los pasos que se brindan esta guía, damos por sentado determinadas características de tu agente. Por eso, es recomendable que comiences con un agente nuevo. Debes borrar cualquier agente existente en tu proyecto antes de crear uno nuevo. Para borrar un agente existente, haz lo siguiente:

  1. Ve a la Consola de Dialogflow.
  2. Si se te solicita, accede a la consola de Dialogflow. Consulta Descripción general de la consola de Dialogflow para obtener más información.
  3. Selecciona el agente que deseas borrar.
  4. Haz clic en el botón de configuración settings ubicado junto al nombre del agente.
  5. Desplázate hasta la parte inferior de la pestaña de configuración General.
  6. Haz clic en Borrar este agente.
  7. Ingresa BORRAR en el campo de texto.
  8. Haz clic en Borrar.

Para crear un agente, haz lo siguiente:

  1. Ve a la Consola de Dialogflow.
  2. Si se te solicita, accede a la consola de Dialogflow. Consulta Descripción general de la consola de Dialogflow para obtener más información.
  3. Haz clic en Crear agente en el menú de la barra lateral izquierda. Si ya tienes otros agentes, haz clic en el nombre del agente, desplázate hasta la parte inferior y haz clic en Crear agente nuevo.
  4. Ingresa el nombre del agente, y el idioma y la zona horaria predeterminados.
  5. Si ya creaste un proyecto, ingrésalo. Si deseas permitir que la consola de Dialogflow cree el proyecto, selecciona Crear un proyecto de Google nuevo.
  6. Haz clic en el botón Crear.

Importa el archivo de ejemplo al agente

La importación agregará intents y entidades al agente. Si hay intents o entidades con el mismo nombre que los del archivo importado, se reemplazarán los primeros por los segundos.

Para importar el archivo, sigue estos pasos:

  1. Descarga el archivo RoomReservation.zip.
  2. Ve a la Consola de Dialogflow.
  3. Selecciona el agente.
  4. Haz clic en el botón de configuración settings ubicado junto al nombre del agente.
  5. Selecciona la pestaña Importar y exportar.
  6. Selecciona Importar desde el archivo ZIP y, luego, importa el archivo ZIP que descargaste.

Detecta intents

Para detectar un intent, llama al método detectIntent en el tipo Sessions.

REST Y LÍNEA DE COMANDOS

1. Prepara el contenido de audio

Descarga el archivo de audio de entrada de muestra, que dice “book a room” (“reservar una habitación”). El archivo de audio debe estar codificado en base64 para este ejemplo, por lo que se puede proporcionar en la solicitud JSON a continuación. El siguiente es un ejemplo de Linux:

base64 -w 0 book_a_room.wav > book_a_room.b64

Para ver ejemplos en otras plataformas, consulta Contenido de audio codificado en Base64 en la documentación de la API de Cloud Speech.

2. Realiza una solicitud de intent de detección

Llama al método detectIntent en el tipo Sessions y especifica el audio codificado en base64.

Antes de usar cualquiera de los datos de solicitud que se muestran a continuación, realiza los siguientes reemplazos:

  • project-id: el ID de tu proyecto de GCP
  • base64-audio: el contenido Base64 del archivo de salida anterior

Método HTTP y URL:

POST https://dialogflow.googleapis.com/v2/projects/project-id/agent/sessions/123456789:detectIntent

Cuerpo JSON de la solicitud:

    {
      "queryInput": {
        "audioConfig": {
          "languageCode": "en-US"
        }
      },
      "outputAudioConfig" : {
        "audioEncoding": "OUTPUT_AUDIO_ENCODING_LINEAR_16"
      },
      "inputAudio": "base64-audio"
    }
    

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

    {
      "responseId": "b7405848-2a3a-4e26-b9c6-c4cf9c9a22ee",
      "queryResult": {
        "queryText": "book a room",
        "speechRecognitionConfidence": 0.8616504,
        "action": "room.reservation",
        "parameters": {
          "time": "",
          "date": "",
          "duration": "",
          "guests": "",
          "location": ""
        },
        "fulfillmentText": "I can help with that. Where would you like to reserve a room?",
        "fulfillmentMessages": [
          {
            "text": {
              "text": [
                "I can help with that. Where would you like to reserve a room?"
              ]
            },
            "platform": "FACEBOOK"
          },
          {
            "text": {
              "text": [
                "I can help with that. Where would you like to reserve a room?"
              ]
            }
          }
        ],
        "outputContexts": [
          {
            "name": "projects/project-id/agent/sessions/123456789/contexts/e8f6a63e-73da-4a1a-8bfc-857183f71228_id_dialog_context",
            "lifespanCount": 2,
            "parameters": {
              "time.original": "",
              "time": "",
              "duration.original": "",
              "date": "",
              "guests.original": "",
              "location.original": "",
              "duration": "",
              "guests": "",
              "location": "",
              "date.original": ""
            }
          },
          {
            "name": "projects/project-id/agent/sessions/123456789/contexts/room_reservation_dialog_params_location",
            "lifespanCount": 1,
            "parameters": {
              "date.original": "",
              "time.original": "",
              "time": "",
              "duration.original": "",
              "date": "",
              "guests": "",
              "duration": "",
              "location.original": "",
              "guests.original": "",
              "location": ""
            }
          },
          {
            "name": "projects/project-id/agent/sessions/123456789/contexts/room_reservation_dialog_context",
            "lifespanCount": 2,
            "parameters": {
              "date.original": "",
              "time.original": "",
              "time": "",
              "duration.original": "",
              "date": "",
              "guests.original": "",
              "guests": "",
              "duration": "",
              "location.original": "",
              "location": ""
            }
          }
        ],
        "intent": {
          "name": "projects/project-id/agent/intents/e8f6a63e-73da-4a1a-8bfc-857183f71228",
          "displayName": "room.reservation"
        },
        "intentDetectionConfidence": 1,
        "diagnosticInfo": {},
        "languageCode": "en-us"
      },
      "outputAudio": "UklGRs6vAgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AA..."
    }
    

Ten en cuenta que el valor del campo queryResult.action es room.reservation y que el campo outputAudio contiene una string de audio en base64 grande.

3. Reproduce el audio de salida

Copia el texto del campo outputAudio y guárdalo en un archivo llamado output_audio.b64. Este archivo necesita convertirse en audio. El siguiente es un ejemplo de Linux:

base64 -d output_audio.b64 > output_audio.wav

Para ver ejemplos en otras plataformas, consulta la página sobre cómo decodificar contenido de audio codificado en Base64 en la documentación de la API de Text-to-Speech.

Ahora puedes reproducir el archivo de audio output_audio.wav y escuchar que coincide con el texto del campo queryResult.fulfillmentMessages[1].text.text[0] anterior. Se elige el segundo elemento fulfillmentMessages porque es la respuesta de texto de la plataforma predeterminada.

Java


    /**
     * Returns the result of detect intent with texts as inputs.
     *
     * <p>Using the same `session_id` between requests allows continuation of the conversation.
     *
     * @param projectId    Project/Agent Id.
     * @param texts        The text intents to be detected based on what a user says.
     * @param sessionId    Identifier of the DetectIntent session.
     * @param languageCode Language code of the query.
     * @return The QueryResult for each input text.
     */
    public static Map<String, QueryResult> detectIntentWithTexttoSpeech(
        String projectId,
        List<String> texts,
        String sessionId,
        String languageCode) throws Exception {
      Map<String, QueryResult> queryResults = Maps.newHashMap();
      // Instantiates a client
      try (SessionsClient sessionsClient = SessionsClient.create()) {
        // Set the session name using the sessionId (UUID) and projectID (my-project-id)
        SessionName session = SessionName.of(projectId, sessionId);
        System.out.println("Session Path: " + session.toString());

        // Detect intents for each text input
        for (String text : texts) {
          // Set the text (hello) and language code (en-US) for the query
          Builder textInput = TextInput.newBuilder().setText(text).setLanguageCode(languageCode);

          // Build the query with the TextInput
          QueryInput queryInput = QueryInput.newBuilder().setText(textInput).build();

          //
          OutputAudioEncoding audioEncoding = OutputAudioEncoding.OUTPUT_AUDIO_ENCODING_LINEAR_16;
          int sampleRateHertz = 16000;
          OutputAudioConfig outputAudioConfig =
              OutputAudioConfig.newBuilder()
                  .setAudioEncoding(audioEncoding)
                  .setSampleRateHertz(sampleRateHertz)
                  .build();

          DetectIntentRequest dr =
              DetectIntentRequest.newBuilder()
                  .setQueryInput(queryInput)
                  .setOutputAudioConfig(outputAudioConfig)
                  .setSession(session.toString())
                  .build();

          // Performs the detect intent request
          DetectIntentResponse response = sessionsClient.detectIntent(dr);

          // Display the query result
          QueryResult queryResult = response.getQueryResult();

          System.out.println("====================");
          System.out.format("Query Text: '%s'\n", queryResult.getQueryText());
          System.out.format(
              "Detected Intent: %s (confidence: %f)\n",
              queryResult.getIntent().getDisplayName(), queryResult.getIntentDetectionConfidence());
          System.out.format("Fulfillment Text: '%s'\n", queryResult.getFulfillmentText());

          queryResults.put(text, queryResult);
        }
      }
      return queryResults;
    }

Node.js

// Imports the Dialogflow client library
    const dialogflow = require('dialogflow').v2;

    // Instantiate a DialogFlow client.
    const sessionClient = new dialogflow.SessionsClient();

    /**
     * TODO(developer): Uncomment the following lines before running the sample.
     */
    // const projectId = 'ID of GCP project associated with your Dialogflow agent';
    // const sessionId = `user specific ID of session, e.g. 12345`;
    // const query = `phrase(s) to pass to detect, e.g. I'd like to reserve a room for six people`;
    // const languageCode = 'BCP-47 language code, e.g. en-US';
    // const outputFile = `path for audio output file, e.g. ./resources/myOutput.wav`;

    // Define session path
    const sessionPath = sessionClient.sessionPath(projectId, sessionId);
    const fs = require(`fs`);
    const util = require(`util`);

    async function detectIntentwithTTSResponse() {
      // The audio query request
      const request = {
        session: sessionPath,
        queryInput: {
          text: {
            text: query,
            languageCode: languageCode,
          },
        },
        outputAudioConfig: {
          audioEncoding: `OUTPUT_AUDIO_ENCODING_LINEAR_16`,
        },
      };
      sessionClient.detectIntent(request).then(responses => {
        console.log('Detected intent:');
        const audioFile = responses[0].outputAudio;
        util.promisify(fs.writeFile)(outputFile, audioFile, 'binary');
        console.log(`Audio content written to file: ${outputFile}`);
      });
    }
    detectIntentwithTTSResponse();

Python

def detect_intent_with_texttospeech_response(project_id, session_id, texts,
                                                 language_code):
        """Returns the result of detect intent with texts as inputs and includes
        the response in an audio format.

        Using the same `session_id` between requests allows continuation
        of the conversation."""
        import dialogflow_v2 as dialogflow
        session_client = dialogflow.SessionsClient()

        session_path = session_client.session_path(project_id, session_id)
        print('Session path: {}\n'.format(session_path))

        for text in texts:
            text_input = dialogflow.types.TextInput(
                text=text, language_code=language_code)

            query_input = dialogflow.types.QueryInput(text=text_input)

            # Set the query parameters with sentiment analysis
            output_audio_config = dialogflow.types.OutputAudioConfig(
                audio_encoding=dialogflow.enums.OutputAudioEncoding
                .OUTPUT_AUDIO_ENCODING_LINEAR_16)

            response = session_client.detect_intent(
                session=session_path, query_input=query_input,
                output_audio_config=output_audio_config)

            print('=' * 20)
            print('Query text: {}'.format(response.query_result.query_text))
            print('Detected intent: {} (confidence: {})\n'.format(
                response.query_result.intent.display_name,
                response.query_result.intent_detection_confidence))
            print('Fulfillment text: {}\n'.format(
                response.query_result.fulfillment_text))
            # The response's audio_content is binary.
            with open('output.wav', 'wb') as out:
                out.write(response.output_audio)
                print('Audio content written to file "output.wav"')

Consulta la sección Respuestas de detección de intent para obtener una descripción de los campos de respuesta relevantes.

Respuestas de detección de intent

La respuesta para una solicitud de detección de intent es un tipo DetectIntentResponse.

El procesamiento normal de la detección de intent controla el contenido del campo DetectIntentResponse.queryResult.fulfillmentMessages.

El campo DetectIntentResponse.outputAudio se completa con el audio en función de los valores de las respuestas de texto de la plataforma predeterminada que se encuentran en el campo DetectIntentResponse.queryResult.fulfillmentMessages. Si existen múltiples respuestas de texto predeterminadas, se las concatena cuando se genera el audio. Si no existen respuestas de texto de la plataforma predeterminada, el contenido de audio generado estará vacío.

El campo DetectIntentResponse.outputAudioConfig se completa con la configuración de audio que se usó para generar el audio de salida.

Detecta intents en una transmisión

Cuando se detectan intents en una transmisión, se envían solicitudes similares a las del ejemplo que no usa audio de salida: Detecta intents en una transmisión de audio. Sin embargo, debes proporcionar un campo OutputAudioConfig a la solicitud. Se propagan datos a los campos output_audio y output_audio_config en la última respuesta de transmisión que obtienes del servidor de la API de Dialogflow. Para obtener más información, consulta StreamingDetectIntentRequest y StreamingDetectIntentResponse.

Configuración de voz del agente

Puedes controlar varios aspectos de la síntesis de voz. Consulta Configuración de agentes.

Usa el simulador de Dialogflow

Puedes interactuar con el agente y recibir respuestas de audio a través del simulador de Dialogflow:

  1. Sigue los pasos anteriores para habilitar el texto a voz automático.
  2. Escribe o di "reservar una habitación" en el simulador.
  3. Consulta la sección audio de salida en la parte inferior del simulador.