利用音訊輸出偵測意圖

應用程式通常需要機器人回覆使用者。Dialogflow 應用程式通常需要機器人與使用者對話。Dialogflow 可讓您使用 DeepMind WaveNet 支援的 Cloud Text-to-Speech,從代理生成語音回覆。將意圖文字回覆轉換為音訊的過程稱為「音訊輸出」、「語音合成」

偵測意圖時,您可以使用音訊做為輸入和輸出。開發純音訊介面與使用者通訊的應用程式時,通常會發生這種情況。

如需支援語言清單,請參閱「語言」頁面上的「TTS」TTS欄。

事前準備

這項功能僅適用於使用 API 進行使用者互動的情況。如果您使用整合,可以略過本指南。

開始前,請先完成下列步驟:

建立虛擬服務專員

  1. 前往 Dialogflow ES 控制台。
  2. 如果出現提示,請登入控制台。詳情請參閱「Dialogflow 控制台總覽」。
  3. 在側欄選單中,展開「Loading agents」(載入代理程式)。
  4. 按一下「Create new agent」。
  5. 輸入代理名稱、預設語言和預設時區。
  6. 輸入現有專案。如要讓 Dialogflow 控制台建立專案,請選取「Create a new Google project」(建立新的 Google 專案)。
  7. 按一下「Create」(建立)。

偵測意圖

如要偵測意圖,請對 Sessions 類型呼叫 detectIntent 方法。

REST

1. 準備音訊內容

下載 book-a-room.wav 範例 input_audio 檔案,其中包含「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 方法和網址:

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] 欄位的文字相符。系統會選擇第二個 fulfillmentMessages 元素,因為這是預設平台的文字回應。

Java

如要向 Dialogflow CX 進行驗證,請設定應用程式預設憑證。詳情請參閱「為本機開發環境設定驗證機制」。


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 CX 進行驗證,請設定應用程式預設憑證。詳情請參閱「為本機開發環境設定驗證機制」。

// 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 CX 進行驗證,請設定應用程式預設憑證。詳情請參閱「為本機開發環境設定驗證機制」。

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.queryResult.fulfillmentMessages 欄位中預設平台文字回覆的值,在 DetectIntentResponse.outputAudio 欄位填入音訊:

  • 如果有多個預設文字回覆,系統會在生成音訊時將其串連。
  • 如果沒有預設平台文字回覆,生成的音訊內容會是空白。

系統會依據用來產生輸出音訊內容的音訊設定填入 DetectIntentResponse.outputAudioConfig 欄位。

利用串流偵測意圖

從串流偵測意圖時,您傳送的要求與不使用輸出音訊的範例類似:從串流偵測意圖。不過,您必須在要求中提供 OutputAudioConfig 欄位。output_audio 和 output_audio_config 欄位會填入從 Dialogflow API 伺服器取得的最終串流回應。詳情請參閱 StreamingDetectIntentRequest 和 StreamingDetectIntentResponse。

語音相關代理程式設定

您可以控制語音合成的各個面向。請參閱代理語音設定。

使用 Dialogflow 模擬器

您可以使用 Dialogflow 模擬器與代理互動,並接收語音回覆:

  1. 按照「代理語音設定」中的操作說明,啟用自動文字轉語音功能。
  2. 在模擬工具中輸入或說出「book a room」。
  3. 查看模擬器中的「輸出音訊」部分。