[電話対応無人化] 「はい」「いいえ」を聞き取るAmazon Lexボットを作成し、Amazon Connectフローから呼び出す

2024.06.05

はじめに

Amazon ConnectでAIによる電話の自動応答を実装する場合、以下のように「はい」「いいえ」を聞き取る機会があります。

  • ユーザーの発話内容を復唱した際、問題ないか「はい」「いいえ」で確認
  • 発信元番号から本人確認時、「はい」「いいえ」で確認

今回は、「はい」「いいえ」を聞き取るAmazon Lexボットを作成し、Amazon Connectのフローから呼び出してみます。

Lexについて

Lexは、Alexaと同じテクノロジーを利用したチャットボット向けの会話型 AIサービスで、音声やテキストを使用してあらゆるアプリケーションに対話型インターフェイスを構築可能です。

自然言語理解(NLU)と自動音声認識(ASR)を用いて、ユーザーの発話から意図(インテント)を理解し、適切な応答を返します。

今回のユースケースでは、「はい」「いいえ」という限定的な応答を判定するため、比較的シンプルな実装で実現可能です。

Lexボットでは、ユーザーの発話パターンをサンプル発話として登録しておくことで、実際の発話とマッチングさせてインテントを特定します。

音声データは、内部でAmazon Transcribeによってテキスト変換され、そのテキストがサンプル発話とマッチングされるという流れです。

今回の実装方法は単純で、1つのLexボットで「はい」と「いいえ」の2つのインテントを作成し、それぞれトリガーとなるサンプル発話を登録後、ConnectからLexを呼び出すようにConnectフローを作成します。

そして、フロー内でLexボットを呼び出し、ユーザーの応答を「はい」もしくは「いいえ」と判定することで、適切な分岐処理を行うことができます。

Lexボット構築

Amazon Lex のコンソールから「ボットの作成」をクリック後、ボット名を入力し、以下の設定通り次へ進みます。

日本語を選択し、完了です。

インテント

「はい」と「いいえ」を聞き取るインテントを作成します。

「はい」用のインテントは、インテント名を入力後、サンプル発話でいくつかフレーズを入力します。他は設定不要です。

「いいえ」用のインテントも同様に、インテント名を入力後、サンプル発話でいくつかフレーズを入力します。他は設定不要です。

作成後、インテントを保存し、ビルドします。

Connectフロー作成

Connectの[問い合わせフロー]から作成したLexボットを追加します。

フローは以下の通りです。

フローのコード (クリックすると展開します)
{
  "Version": "2019-10-30",
  "StartAction": "6f1a8209-b81b-45ba-b414-4776d673dc82",
  "Metadata": {
    "entryPointPosition": { "x": 40, "y": 40 },
    "ActionMetadata": {
      "6f1a8209-b81b-45ba-b414-4776d673dc82": {
        "position": { "x": 144.8, "y": 49.6 }
      },
      "1277a717-3c8b-4457-b89b-577bc423457b": {
        "position": { "x": 1159.2, "y": 121.6 }
      },
      "a3b32a48-1833-4b5c-ae34-99d59ba9d6b4": {
        "position": { "x": 348.8, "y": 40 },
        "children": ["668d5b73-34db-48ce-a84d-87b76d11665b"],
        "overrideConsoleVoice": true,
        "fragments": {
          "SetContactData": "668d5b73-34db-48ce-a84d-87b76d11665b"
        },
        "overrideLanguageAttribute": true
      },
      "668d5b73-34db-48ce-a84d-87b76d11665b": {
        "position": { "x": 348.8, "y": 40 },
        "dynamicParams": []
      },
      "4c8d53fe-b7b7-4793-94bf-b2220d863ef1": {
        "position": { "x": 864, "y": 425.6 }
      },
      "7541bc16-e26d-4a0e-b7e3-ea29b941aed8": {
        "position": { "x": 860, "y": 224.8 }
      },
      "f7461826-99ab-4de5-9c14-709e01d41f44": {
        "position": { "x": 855.2, "y": 40.8 }
      },
      "ae978741-3278-486d-b48e-8c75a33f111d": {
        "position": { "x": 568.8, "y": 44 },
        "parameters": {
          "LexV2Bot": {
            "AliasArn": {
              "displayName": "TestBotAlias",
              "useLexBotDropdown": true,
              "lexV2BotName": "cm-hirai-yes-or-no"
            }
          }
        },
        "useLexBotDropdown": true,
        "lexV2BotName": "cm-hirai-yes-or-no",
        "lexV2BotAliasName": "TestBotAlias",
        "conditionMetadata": [
          {
            "id": "f20bbcba-447c-468c-bac0-2e7b61cd6c5c",
            "operator": {
              "name": "Equals",
              "value": "Equals",
              "shortDisplay": "="
            },
            "value": "yes"
          },
          {
            "id": "e74d8757-d099-4bd6-929d-52546a42088a",
            "operator": {
              "name": "Equals",
              "value": "Equals",
              "shortDisplay": "="
            },
            "value": "no"
          }
        ]
      }
    },
    "Annotations": [],
    "name": "cm-hirai-yes-or-no",
    "description": "",
    "type": "contactFlow",
    "status": "PUBLISHED",
    "hash": {}
  },
  "Actions": [
    {
      "Parameters": { "FlowLoggingBehavior": "Enabled" },
      "Identifier": "6f1a8209-b81b-45ba-b414-4776d673dc82",
      "Type": "UpdateFlowLoggingBehavior",
      "Transitions": { "NextAction": "a3b32a48-1833-4b5c-ae34-99d59ba9d6b4" }
    },
    {
      "Parameters": {},
      "Identifier": "1277a717-3c8b-4457-b89b-577bc423457b",
      "Type": "DisconnectParticipant",
      "Transitions": {}
    },
    {
      "Parameters": {
        "TextToSpeechEngine": "Neural",
        "TextToSpeechStyle": "None",
        "TextToSpeechVoice": "Kazuha"
      },
      "Identifier": "a3b32a48-1833-4b5c-ae34-99d59ba9d6b4",
      "Type": "UpdateContactTextToSpeechVoice",
      "Transitions": { "NextAction": "668d5b73-34db-48ce-a84d-87b76d11665b" }
    },
    {
      "Parameters": { "LanguageCode": "ja-JP" },
      "Identifier": "668d5b73-34db-48ce-a84d-87b76d11665b",
      "Type": "UpdateContactData",
      "Transitions": {
        "NextAction": "ae978741-3278-486d-b48e-8c75a33f111d",
        "Errors": [
          {
            "NextAction": "ae978741-3278-486d-b48e-8c75a33f111d",
            "ErrorType": "NoMatchingError"
          }
        ]
      }
    },
    {
      "Parameters": { "Text": "エラーとなりました。" },
      "Identifier": "4c8d53fe-b7b7-4793-94bf-b2220d863ef1",
      "Type": "MessageParticipant",
      "Transitions": {
        "NextAction": "1277a717-3c8b-4457-b89b-577bc423457b",
        "Errors": [
          {
            "NextAction": "1277a717-3c8b-4457-b89b-577bc423457b",
            "ErrorType": "NoMatchingError"
          }
        ]
      }
    },
    {
      "Parameters": { "Text": "いいえ、と答えました。" },
      "Identifier": "7541bc16-e26d-4a0e-b7e3-ea29b941aed8",
      "Type": "MessageParticipant",
      "Transitions": {
        "NextAction": "1277a717-3c8b-4457-b89b-577bc423457b",
        "Errors": [
          {
            "NextAction": "1277a717-3c8b-4457-b89b-577bc423457b",
            "ErrorType": "NoMatchingError"
          }
        ]
      }
    },
    {
      "Parameters": { "Text": "はい、と答えました。" },
      "Identifier": "f7461826-99ab-4de5-9c14-709e01d41f44",
      "Type": "MessageParticipant",
      "Transitions": {
        "NextAction": "1277a717-3c8b-4457-b89b-577bc423457b",
        "Errors": [
          {
            "NextAction": "1277a717-3c8b-4457-b89b-577bc423457b",
            "ErrorType": "NoMatchingError"
          }
        ]
      }
    },
    {
      "Parameters": {
        "Text": "はい、または、いいえと、お伝え下さい。",
        "LexV2Bot": {
          "AliasArn": "arn:aws:lex:ap-northeast-1:540835513398:bot-alias/W2GNJPPTAK/TSTALIASID"
        }
      },
      "Identifier": "ae978741-3278-486d-b48e-8c75a33f111d",
      "Type": "ConnectParticipantWithLexBot",
      "Transitions": {
        "NextAction": "4c8d53fe-b7b7-4793-94bf-b2220d863ef1",
        "Conditions": [
          {
            "NextAction": "f7461826-99ab-4de5-9c14-709e01d41f44",
            "Condition": { "Operator": "Equals", "Operands": ["yes"] }
          },
          {
            "NextAction": "7541bc16-e26d-4a0e-b7e3-ea29b941aed8",
            "Condition": { "Operator": "Equals", "Operands": ["no"] }
          }
        ],
        "Errors": [
          {
            "NextAction": "4c8d53fe-b7b7-4793-94bf-b2220d863ef1",
            "ErrorType": "NoMatchingCondition"
          },
          {
            "NextAction": "4c8d53fe-b7b7-4793-94bf-b2220d863ef1",
            "ErrorType": "NoMatchingError"
          }
        ]
      }
    }
  ]
}

[顧客の入力を取得する]ブロックでは、以下のテキストを読み上げます。

はい、または、いいえと、お伝え下さい。

「はい」と伝えると、yesインテントがトリガーし、[プロンプト再生]ブロックで、以下のテキストを読み上げます。

はい、と答えました。

「いいえ」と伝えると、noインテントがトリガーし、[プロンプト再生]ブロックで、以下のテキストを読み上げます。

いいえ、と答えました。

テスト

それでは、作成したフローとConnectで発行した電話番号を紐づけて、架電しテストします。

以下を発話するとyesインテントがトリガーされました

  • はい
  • そうですね
  • はい、お願いします
  • はい、それで
  • そうではないです

「そうではないです」は、「はい」と判定されました。

以下を発話するとnoインテントがトリガーされました

  • いいえ
  • 違います
  • 全然違います
  • お願いします

「お願いします」は、「いいえ」と判定されました。

以下を発話するとエラーと判定されました

  • (4秒だんまり)
    • デフォルトでは4秒間無音でタイムアウトです。
      • https://docs.aws.amazon.com/ja_jp/lexv2/latest/dg/session-attribs-speech.html#voice-input-time-out
  • OKです
  • その通りです
  • ノーです
  • キャンセルです。

改善

認識精度が低い場合や意図していない判定の場合、インテントのサンプル発話に追加することで、適切なインテントがトリガーされるようになります。

エラーになる場合、Lexボットのタイムアウト値を適切に設定することやループブロックを導入し、数回の失敗を許容することが考えられます。

最後に

Amazon Connectで電話対応の無人化を実装する際によく利用する、「はい」「いいえ」を聞き取るシンプルなAmazon Lexボットを作成しました。

構築内容も単純であることが分かります。

音声インターフェースの設計には、技術的な側面だけでなく、ユーザー心理への配慮も必要です。

どんなシーンでどのように話しかけるのか、ユーザーの行動を想定しながら丁寧に設計していくことが大切だと言えます。

本記事が参考になれば幸いです。