Amazon Web Services ブログ

Twilio Media Streams で対話型インターフェイスとして Amazon Lex を使用する

Twilio プラットフォームを使用して、顧客との新しいコミュニケーション方法を構築している企業があります。これらの企業は、対話型の音声自動応答 (IVR) でレストランの注文を完全自動化したり、次世代の高度なコンタクトセンターを構築したりしています。Twilio は Media Streams を立ち上げ、Voice プラットフォームを開放し、リアルタイムで電話による通話の未加工オーディオストリームにアクセスできるようになりました。

Media Streams を使用すると、Amazon Transcribe Streaming WebSockets で音声をリアルタイムで文字に起こし、コールセンターの生産性を向上させたり、エンドユーザーの対話を自動化し、Amazon Lex を使用する発信者の意図に基づいたレコメンドをエージェントに行うことができます。

このブログ投稿では、Amazon Lex を使用して、Twilio Media Streams が提供する未加工オーディオストリームを使った音声アプリケーションに対話型インターフェイス (チャットボット) を統合する方法をご紹介します。Lex は深層学習を利用して、人間のスピーチの意図を認識するのに必要な大きな作業を行い、魅力的なユーザーエクスペリエンスとリアルな会話を簡単に構築できるようにします。

ソリューションは次のような手順になります。

  1. Twilio からオーディオストリームを受信する
  2. 音声アクティビティ検出コンポーネントにオーディオストリームを送信して、オーディオの音声を判別する
  3. 音声が検出されたら、Amazon Lex へユーザーデータのストリーミングを開始する
  4. 無音を検出した場合、Amazon Lex へのユーザーデータのストリーミングを停止する
  5. Amazon Lex からの応答に基づいて、進行中の Twilio 呼び出しを更新する

このサンプルで提供する Voice Activity Detection (VAD) 実装は参照とデモだけの目的で、初歩的なアプローチを使って振幅を見ることで音声と無音を検出します。そのため、本番での使用は推奨しません。本番のシナリオでの使用には、安定した形式の VAD モジュールを実装する必要があります。

次の図で、手順を示しています。

Amazon Lex ボットと Twilio オーディオストリームを統合する手順は、次で説明します。

  • ステップ 1: Amazon Lex ボットを作成する
  • ステップ 2: Twilio アカウントを作成し、プログラム可能な音声を設定する
  • ステップ 3: Amazon Lex と Twilio Voice Stream 統合コードを構築し、Amazon ECS/Fargate にデプロイする
  • ステップ 4: デプロイしたサービスをテストする
  • 次のステップとしてオプションで、サービスをローカルで構築およびテストできます。手順については、ステップ 5 (オプション) をご参照ください。

サービスの構築とデプロイには、次の前提条件が必要です。

  1. Python (サービスの構築に使用する言語)
  2. Docker (デプロイ用サービスのパッケージに使用するツール)
  3. インストールおよび設定済み AWS CLI (必要な AWS のサービスの作成し、AWS へのサービスをデプロイする)。手順については、「AWS CLI のかんたん設定」をご参照ください。

さらに、サービスをホストするにはドメイン名が必要で、Amazon Certificate Manager を使ってドメインの SSL 証明書を登録する必要があります。  手順については、「パブリック証明書のリクエスト」をご参照ください。コンソールから証明書 ARN を記録します。

SSL 証明書は、Twilio オーディオストリームで使用する永続的な双方向通信プロトコルである wss (WebSocket Secure) を介して安全に通信するために必要です。Templates/streams.xml ファイルにある <Stream> の命令を使用すると、WebSocket を介したライブの通話からほぼリアルタイムで未加工のオーディオストリームを受信できます。接続に成功すると、サービスへの WebSocket 接続が確立され、音声のストリーミングが開始されます。

ステップ 1: Amazon Lex ボットを作成する

Amazon Lex ボットがまだない場合は、作成してデプロイします。手順については、「演習 1: 設計図を使用して Amazon Lex ボットを作成する (コンソール)」をご参照ください。

ボットを作成したら、ボットをデプロイしてエイリアスを作成します。手順については、「演習 3: バージョンを発行してエイリアスを作成する 」をご参照ください。

サービスから Amazon Lex API を呼び出すには、アクセスタイプ「Programmatic Access」で IAM ユーザーを作成し、適切なポリシーを添付する必要があります。

これには、AWS コンソールで、[IAM]->[Users]->[Add user] に移動します

ユーザー名を入力し、「Programmatic Access」アクセスタイプを選択して、[Next: Permissions] をクリックします。

「既存のポリシーを直接添付する」オプションを使用して、Amazon Lex ポリシーをフィルターし、AmazonLexReadOnly および AmazonLexRunBotsOnly ポリシーを選択します。

ユーザーを作成するために続くページで [Next: Tags]、[Next: Review]、[Create User] の順でクリックします。アクセスキー ID とシークレットアクセスキーを記録します。スタックのデプロイ中にこれらの認証情報を使用します。

ステップ 2: Twilio アカウントを作成し、プログラム可能な音声を設定する

Twilio アカウントにサインアップし、プログラム可能な音声プロジェクトを作成します。

サインアップ手順については、https://www.twilio.com/console をご参照ください

AUTH TOKEN」を記録します。この情報は、Twilio ダッシュボードの [Settings]-> [General]-> [API Credentials]にあります。

また、Twilio の番号に電話をかけるために使用している電話番号を追加して、発信者 ID を確認する必要があります。これを行うには、発信者 ID の確認ページの ボタンをクリックしてください。

ステップ 3: Amazon Lex と Twilio Stream 統合コードを構築し、Amazon ECS にデプロイする

このセクションでは、AWS Fargate を使用して統合コードをホストする新しいサービスを作成します。AWS FargateAmazon Elastic Container Service (ECS) のデプロイオプションで、プロビジョニングやサーバーのスケーリングを気にせずにコンテナをデプロイできます。このサービスでは、Python および Application Load Balancer (ALB) の後ろにある Docker コンテナの Flask を使用しています。

コアインフラストラクチャをデプロイする

インフラストラクチャ作成の最初のステップとして、CloudFormation テンプレートを使用して、VPC、サブネット、セキュリティグループ、ALB、ECS クラスター、IAM ポリシーなどのコアインフラストラクチャコンポーネントをデプロイします。

以下の [Launch Stack] ボタンをクリックすると、AWS CloudFormation スタックの作成ページが表示されます。[Next] をクリックして、パラメータを入力します。後のコアインフラストラクチャ上でサービスを起動するプロセスで、同じ「EnvironmentName」パラメータを使用することに注意してください。これで、このデプロイからのスタック出力を参照できるようになります。

スタックの作成が完了したら、[出力] タブから「ExternalUrl」キーの値を記録します。

コードをパッケージして AWS にデプロイする

コードを Amazon ECS にデプロイするには、コードを Docker コンテナにパッケージし、Docker イメージを Amazon Elastic Container Registry (ECR) にアップロードします。

サービスのコードは、以下の GitHub リポジトリから入手できます。ローカルマシンでリポジトリを複製します。

git clone https://github.com/veerathp/lex-twiliovoice.git
cd lex-twiliovoice

次に、templates/streams.xml 内の Streams 要素の URL を更新して、前提条件セクションで SSL 証明書を使って設定したサービスの DNS 名と一致させます。

<Stream url="wss://<Your DNS>/"></Stream>

次のコマンドを実行し、Dockerfile を使ってコンテナイメージを構築します。

docker build -t lex-twiliovoice .

次に、リポジトリ名の値を渡すことで、AWS CLI を使用してコンテナレジストリを作成します。出力から「repositoryUri」を記録します。

aws ecr create-repository --repository-name <repository name>

コンテナイメージをレジストリにプッシュするには、認証が必要です。次のコマンドを使用します。

aws ecr get-login --region us-west-2 --no-include-email

上記のコマンドの出力を実行して、認証プロセスを完了します。

次に、コンテナイメージにタグを付けて ECR にプッシュします。

docker tag lex-twiliovoice <repositoryUri>/lex-twiliovoice:latest
docker push <repositoryUri>/lex-twiliovoice:latest

CloudFormation テンプレートを使用して、残りのインフラストラクチャをデプロイします。このスタックの一部として、ECS サービス、ALB ターゲットグループ、HTTP/HTTPS リスナールール、Fargate タスクなどのコンポーネントをデプロイします。環境変数は、タスク定義プロパティを使ってコンテナに投入されます。

サービスでは WebSocket 接続を使用しているため、ターゲットグループ属性を使用してロードバランサーで持続性を有効にすると、同じインスタンスとの永続的な接続が可能となります。

TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      ….
      ….
      TargetGroupAttributes:
        - Key: stickiness.enabled
          Value: true
        …

以下の [Launch Stack] ボタンをクリックすると、AWS CloudFormation スタックの作成ページが表示されます。[Next] をクリックし、前の手順で収集した以下のパラメータ (IAMAccessKeyId、IAMSecretAccessKey、ImageUrl、LexBotName、LexBotAlias、TwilioAuthToken) の正しい値を入力します。他のすべてのパラメータには、デフォルト値を使用できます。必ず以前のスタックデプロイと同じ「EnvironmentName」を使用してください。これは、そのデプロイの出力を参照しているためです。

デプロイが完了したら、サービスをテストできます。ただしその前に、カスタム DNS が Application Load Balancer の URL を指すことを確認してください。

これには、Route 53、Hosted Zones の下に「A Record」を作成し、カスタム DNS がコアインフラストラクチャスタックデプロイの一部である ALB Url (出力の「ExternalUrl」キー) を指すようにします。[Create Record Set] 画面の名前フィールドで DNS 名を使用し、タイプとして「A-IPv4 アドレス」を選択し、「エイリアス」フィールドで [Yes] をクリックし、ALB Url としてエイリアスターゲットを選択してから、[Create] をクリックします。

ステップ 4: デプロイしたサービスをテストする

Amazon ECS コンソールに移動し、クラスター名をクリックすると、デプロイを確認できます。[サービス] タブで AWS Fargate サービスを、[タスク] タブで実行中のタスクを確認できます。

サービスをテストするには、まず Twilio コンソールの Voice & Fax セクションの下にある Webhook url フィールドを、AWS で実行しているサービスの URL (http://<url>/twiml) で更新します。これで、Twilio の番号に電話して Lex ボットに到達できます。Twilio コンソールを使用して、呼び出し元の番号を確認してください。接続すると、templates/streams.xml ファイルで構成されている「3、2、1、Go で Lex ボットとやり取りします」というプロンプトが聞こえます。これで Amazon Lex Bot とやり取りできるようになりました。

「CloudWatch Log Groups」を使用すると、サービスをモニタリングし、サービスの実行中に発生する可能性のある問題をトラブルシューティングできます。

ステップ 5 (オプション): サービスをローカルで構築およびテストする

サービスのデプロイとテストが完了したので、コードをローカルで構築およびテストしたいと思うかもしれません。これを行うには、ローカルマシン上のクローン GitHub リポジトリに移動し、次のコマンドを使用してすべての依存関係をインストールします。

pip install -r requirements.txt

「ngrok」をインストールすると、サービスをローカルでテストできます。詳細については、https://ngrok.com/download をご参照ください。このツールは、ローカルウェブサーバーを公開するパブリック URL を提供します。このツールを使って、Twilio webhook の統合をテストできます。

別のターミナルウィンドウで次のコマンドを使用して、ngrok プロセスを開始してください。ngrok.io の URL で外部アプリケーションからウェブサービスにアクセスできます。

ngrok http 8080

次に、templates/streams.xml ファイル内の「Stream」要素を正しい ngrok URL で設定します。

<Stream url="wss://<xxxxxxxx.ngrok.io>/"></Stream>

さらに、コードで使用する環境変数も設定する必要があります。環境変数に適切な値を指定した後、次のコマンドを実行します。

export AWS_REGION=us-west-2
export ACCESS_KEY_ID=<Your IAM User Access key ID from Step 1>
export SECRET_ACCESS_KEY=<Your IAM User Secret Access key from Step 1>
export LEX_BOT_NAME=<Bot name for the Lex Bot you created in Step 1>
export LEX_BOT_ALIAS=<Bot Alias for the Lex Bot you created in Step 1>
export TWILIO_AUTH_TOKEN=<Twilio AUTH TOKEN from Step 2>
export CONTAINER_PORT=8080
export URL=<http://xxxxxxxx.ngrok.io> (update with the appropriate url from ngrok)

変数を設定したら、次のコマンドを使用してサービスを開始できます。

python server.py

テストを行うには、以下に示すように正しい URL (http://<url>/twiml) で Twilio コンソールの「Voice & Fax」下の Webhook フィールドを設定してください。

検証済みの電話から Twilio 電話番号への通話を開始します。接続すると、templates/streams.xml ファイルで構成されている「3、2、1、Go で Lex ボットとやり取りします」というプロンプトが聞こえます。これで、ステップ 1 で作成した Amazon Lex ボットと対話できるようになりました。

このブログ投稿では、Amazon Lex を使用してチャットボットを音声アプリケーションに統合する方法をご紹介しました。Amazon Lex で構築する方法をさらに学ぶには、開発者用リソースをご参照ください。


著者について

Praveen Veerath は AWS のシニア AI ソリューションアーキテクトです。