音声出力でインテントを検出

アプリケーションでは、エンドユーザーに音声で返答するためのボットが必要となることがよくあります。Dialogflow では、Cloud Text-to-SpeechDeepMind WaveNet 利用)を使用して、エージェントからの音声レスポンスを生成できます。インテントのテキスト レスポンスからオーディオへの変換は、音声出力、音声合成、テキスト読み上げ、または TTS と呼ばれています。

このガイドでは、インテントを検出するときに入力と出力の両方に音声を使用する例を示します。このユースケースは、開発するアプリがユーザーとの通信に純粋に音声だけのインターフェースを使用する場合に一般的なものです。

サポートされている言語のリストについては、言語ページの TTS の列をご覧ください。

始める前に

この機能は API をエンドユーザー インタラクションに使用する場合にのみ利用できます。統合を使用している場合は、このガイドをスキップできます。

このガイドを読む前に、次の手順を行ってください。

  1. Dialogflow の基本をご覧ください。
  2. 手順に沿って設定してください。

エージェントを作成する

エージェントをまだ作成していない場合は、ここで作成します。

  1. Dialogflow ES コンソールに移動します。
  2. Dialogflow コンソールにログインするよう求められたら、ログインします。詳細については、Dialogflow コンソールの概要をご覧ください。
  3. 左側のサイドバー メニューで [Create Agent] をクリックします。(すでに他のエージェントをお持ちの場合は、エージェント名をクリックし、一番下までスクロールして [Create new agent] をクリックします)。
  4. エージェント名、デフォルトの言語、デフォルトのタイムゾーンを入力します。
  5. すでにプロジェクトを作成している場合は、そのプロジェクトを入力します。Dialogflow コンソールでプロジェクトを作成できるようにする場合は、[Create a new Google project] を選択します。
  6. [Create] ボタンをクリックします。

エージェントにサンプル ファイルをインポートする

このガイドの手順でエージェントの前提条件を設定するため、このガイド用に準備されたエージェントをインポートする必要があります。インポート時に、この手順では restore オプションが使用されます。これにより、すべてのエージェント設定、インテント、エンティティが上書きされます。

ファイルをインポートする手順は次のとおりです。

  1. room-booking-agent.zip ファイルをダウンロードします。
  2. Dialogflow ES コンソールに移動します。
  3. エージェントを選択します。
  4. エージェント名の横にある設定 ボタンをクリックします。
  5. [Export and Import] タブを選択します。
  6. [Restore from Zip] を選択し、手順に従ってダウンロードした zip ファイルを復元します。

インテントの検出

インテントを検出するには、Sessions タイプの detectIntent メソッドを呼び出します。

REST

1.音声コンテンツを作成する

サンプルの入力音声ファイル book-a-room.wav をダウンロードします。このファイルには「book a room」という音声が収録されています。この例では、音声ファイルが Base64 でエンコードされている必要があります。これにより、下記の JSON リクエストでの指定が可能になります。Linux の例を次に示します。

wget https://cloud.google.com/dialogflow/es/docs/data/book-a-room.wav
base64 -w 0 book-a-room.wav > book-a-room.b64

他のプラットフォームの例については、Cloud Speech API のドキュメントの Base64 エンコード音声の埋め込みをご覧ください。

2.インテント検出リクエストを行う

Sessions タイプで detectIntent メソッドを呼び出し、Base64 エンコード音声を指定します。

リクエストのデータを使用する前に、次のように置き換えます。

  • PROJECT_ID: 実際の Google Cloud プロジェクト ID
  • SESSION_ID: セッション ID
  • BASE64_AUDIO: 上記の出力ファイルからの Base64 コンテンツ

HTTP メソッドと URL:

POST https://dialogflow.googleapis.com/v2/projects/PROJECT_ID/agent/sessions/SESSION_ID:detectIntent

リクエストの本文(JSON):

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

リクエストを送信するには、次のいずれかのオプションを展開します。

次のような JSON レスポンスが返されます。

{
  "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?"
          ]
        }
      }
    ],
    "intent": {
      "name": "projects/PROJECT_ID/agent/intents/e8f6a63e-73da-4a1a-8bfc-857183f71228",
      "displayName": "room.reservation"
    },
    "intentDetectionConfidence": 1,
    "diagnosticInfo": {},
    "languageCode": "en-us"
  },
  "outputAudio": "UklGRs6vAgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AA..."
}

queryResult.action フィールドの値が room.reservation であり、outputAudio フィールドに Base64 音声文字列が設定されていることに注意してください。

3.出力音声を再生する

outputAudio フィールドからテキストをコピーして、output_audio.b64 という名前のファイルに保存します。このファイルを音声に変換する必要があります。Linux の例を次に示します。

base64 -d output_audio.b64 > output_audio.wav

他のプラットフォームの例については、Text-to-Speech API ドキュメントの Base64 でエンコードされたオーディオ コンテンツのデコードをご覧ください。

これで、output_audio.wav 音声ファイルを再生できるようになりました。上記の queryResult.fulfillmentMessages[1].text.text[0] フィールドのテキストと一致する音声が聞こえます。2 番目の fulfillmentMessages 要素が選択されたのは、デフォルト プラットフォームのテキスト レスポンスであるためです。

Java

Dialogflow への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。


import com.google.api.gax.rpc.ApiException;
import com.google.cloud.dialogflow.v2.DetectIntentRequest;
import com.google.cloud.dialogflow.v2.DetectIntentResponse;
import com.google.cloud.dialogflow.v2.OutputAudioConfig;
import com.google.cloud.dialogflow.v2.OutputAudioEncoding;
import com.google.cloud.dialogflow.v2.QueryInput;
import com.google.cloud.dialogflow.v2.QueryResult;
import com.google.cloud.dialogflow.v2.SessionName;
import com.google.cloud.dialogflow.v2.SessionsClient;
import com.google.cloud.dialogflow.v2.TextInput;
import com.google.common.collect.Maps;
import java.io.IOException;
import java.util.List;
import java.util.Map;

public class DetectIntentWithTextToSpeechResponse {

  public static Map<String, QueryResult> detectIntentWithTexttoSpeech(
      String projectId, List<String> texts, String sessionId, String languageCode)
      throws IOException, ApiException {
    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
        TextInput.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.getFulfillmentMessagesCount() > 0
                ? queryResult.getFulfillmentMessages(0).getText()
                : "Triggered Default Fallback Intent");

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

Node.js

Dialogflow への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。

// Imports the Dialogflow client library
const dialogflow = require('@google-cloud/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.projectAgentSessionPath(
  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

Dialogflow への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。

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."""
    from google.cloud import 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.TextInput(text=text, language_code=language_code)

        query_input = dialogflow.QueryInput(text=text_input)

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

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

        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"')

関連するレスポンス フィールドの説明については、インテント検出のレスポンスをご覧ください。

インテント検出のレスポンス

インテント検出リクエストに対するレスポンスは、DetectIntentResponse オブジェクトです。

通常のインテント検出処理によって、DetectIntentResponse.queryResult.fulfillmentMessages フィールドのコンテンツが制御されます。

DetectIntentResponse.outputAudio フィールドには音声が格納されますが、この基になるのは、DetectIntentResponse.queryResult.fulfillmentMessages フィールドで見つかったデフォルトのプラットフォームのテキスト形式のレスポンスです。複数のデフォルト テキスト レスポンスが存在する場合は、音声を生成するときに連結されます。デフォルトのプラットフォームのテキスト形式のレスポンスが 1 つも存在しない場合は、生成された音声コンテンツが空になります。

DetectIntentResponse.outputAudioConfig フィールドには、出力音声の生成に使用する音声設定が入力されます。

ストリームからインテントを検出する

ストリームからインテントを検出するときに送信するリクエストは、出力音声を使用しない例(ストリームからインテントを検出する)と同様ですが、このリクエストでは OutputAudioConfig フィールドを指定します。output_audio フィールドと output_audio_config フィールドには、Dialogflow API サーバーから受け取った最後のストリーミング レスポンスが挿入されます。詳細については、StreamingDetectIntentRequestStreamingDetectIntentResponse をご覧ください。

読み上げのためのエージェント設定

音声合成のさまざまな側面を制御できます。詳しくは、エージェントの音声設定をご覧ください。

Dialogflow シミュレータを使用する

Dialogflow シミュレータを使用して、エージェントと対話して音声レスポンスを受け取ることができます。手順は次のとおりです。

  1. 前述の手順に従って自動テキスト読み上げを有効にします
  2. シミュレータで、キーボードから「book a room」と入力するか、声に出して言います。
  3. シミュレータの下部にある [output audio] セクションを見ます。