【Amazon Connect+LexV2】Lambdaを使用した動的な自動応答実装例

記事タイトルとURLをコピーする

はじめに

お客様が企業へ電話を掛ける場面では、その先に対応する人間(オペレータさん)がいる、というイメージになるかと思います。
いつでも柔軟にリソースを増減できれば良いですが、電話対応する人員を増やすことは容易ではありませんし、電話機などのハードウェアや、勤務場所の確保、オペレータのトレーニング等、時間とコストがかかりますね。

そんな状況を少しでも解決するツールとして、Amazon ConnectとAmazon Lex (v2) を組み合わせて、音声による自動応答の仕組みを試してみたいと思います。
(最後にデモ動画あります。)

概要

今回は、電話を受けて無人で自動応答、完結することをターゲットにします。
実際の動作をイメージできるよう、人とのインターフェイスにAmazon Connect、データ処理はAWS Lambdaを用いて、完結した動作例を作成します。

会話シナリオ

ショッピングサイトの注文状況を確認するシンプルなシナリオを実現してみます。
下記のような会話を想定します。

動作・発話
顧客 (電話をかける)
自動応答(Connect) はい、サバワショッピングです。どのようなご用件でしょうか?
顧客 注文の状態を教えてください
自動応答(LexBot) <顧客名>様、ご注文の <商品名> は、<配送予定日> お届けの予定です
自動応答(Connect) 他にもご用件はありますか?
顧客 大丈夫です
自動応答(Connect) ご利用いただき、ありがとうございました(切断)

顧客体験としては自動応答発話は同じようになりますが、実装側視点ではConnectでの発話とLexの発話の組み合わせとします。
また、「動的」と言いつつ、今回はハードコーディングした内容を応答しますが、実際はCRMや注文等のバックエンド管理システムとAPI連携する想定になります。

構築手順

Amazon Lex V2

Bot作成(ステップ1)

マネジメントコンソール:Amazon Lex V2画面から[ボットを作成]をクリックし、下記のように指定し、[次へ]をクリックします。

項目 設定
作成方法 空のボットを作成します
ボット名 SabawaShopSupportBot
IAMアクセス許可 → ランタイムロール 基本的な Amazon Lex 権限を持つロールを作成します。
児童オンラインプライバシー保護法 いいえ

f:id:swx-shinsaka:20220201181428p:plain

Bot作成(ステップ2)

言語は 「日本語(JP)」を選択、音声による対話へ「Takumi(ニューラル)」を指定し、[完了]をクリックします。

f:id:swx-shinsaka:20220201182039p:plain

インテントの設定(インテントの詳細)

Botが作成されるとインテント作成ページへ遷移します。
注文のステータスを受け答えする機能として CheckOrder インテントを作成指示します。

f:id:swx-shinsaka:20220201182347p:plain

インテントの設定(サンプル発話)

サンプル発話を指定します。
顧客が、「注文の状態を教えてください」 と発話したら CheckOrder インテント機能が開始することになります。

f:id:swx-shinsaka:20220201191254p:plain

インテントの設定(スロット、確認プロンプトと応答拒否)

スロットは、インテントに必要な情報を指定します。
商品注文であれば、商品名、数量などの必要な情報を「スロット」という表現で示します。
今回のシナリオでは使わないため、指定しません。

インテントの設定(フルフィルメント)

フルフィルメントは情報がすべて揃った時点で実行される設定です。
今回はスロットを指定しないため、インテント実行=フルフィルメント動作となります。
[フルフィルメントが成功した場合] の三角をクリックし、展開し、 [詳細オプション] をクリックします。
詳細オプション→[フルフィルメントに Lambda 関数を使用] をチェック、 [更新オプション] をクリックします。 (設定方法が少し分かりにくいかもしれません)

f:id:swx-shinsaka:20220201192504p:plain

f:id:swx-shinsaka:20220201192001p:plain

インテントの設定(応答を閉じる、コードフック)

今回は指定しません。

ここまで設定したら [インテントを保存] します。

AWS Lambda

LexBotから呼び出されるLambda関数を作成します

関数の作成

マネジメントコンソール:AWS Lambda画面から[関数の作成]をクリックし、下記のように指定し、[関数の作成]をクリックします。

項目 設定
作成方法 一から作成
関数名 SabawaShopSupport
ランタイム Python 3.9

f:id:swx-shinsaka:20220202123235p:plain

コード作成

コードを実装します。ここでは下記のソースを記述しました。
コード記述後、 [Deploy] を実施します。

import json

def lambda_handler(event, context):
    return invoke(event)

def invoke(request):
    # インテントによって分岐する
    intent_name = request['sessionState']['intent']['name']
    if intent_name == 'CheckOrder':
        return check_order(request)

def check_order(request):
    # Lambda実行の目的によって分岐する
    # 今回はフルフィルメントのみ実装
    if request['invocationSource'] == 'FulfillmentCodeHook':
        (customer_name, order_item, delivery_date) = get_order(request)
        return fulfilled_close(request, {
            'contentType': 'PlainText',
            'content': (
                f'{customer_name}様、'
                f'ご注文の {order_item} は、'
                f'{delivery_date}、お届けの予定です')})

def fulfilled_close(request, message=None):
    intent = request['sessionState']['intent']
    intent['state'] = 'Fulfilled'
    return {
        'sessionState': {
            'sessionAttributes': request['sessionState'].get('sessionAttributes') or {},
            'dialogAction': {
                'type': 'Close'
            },
            'intent': intent},
        'messages': [message] if message else None,
        'sessionId': request['sessionId'],
        'requestAttributes': request.get('requestAttributes') or {}
    }

def get_order(request):
    # バックエンドシステムとの連携を実装(今回はダミー)
    return (
        '鈴木',
        'ミネラルウォーター1ケース',
        '明日')

f:id:swx-shinsaka:20220202123650p:plain

Amazon Lex V2

Lexの画面へ戻り、上記手順で作成したLambda関数を利用するための設定を行います。
まず、(自動的に作成される) TestBotへ設定し、動作テストします。
最後に本番用バージョンをデプロイします。

TestBotへLambda設定

サイドメニューツリーから [エイリアス] を選択し、 [TestBotAlias] をクリックします。

f:id:swx-shinsaka:20220202124818p:plain

設定ページの [言語] セクションから [Japanese{Japan)] リンクをクリックします。

f:id:swx-shinsaka:20220202125427p:plain

[Lambda関数] セクションの [ソース] へ、上記手順で作成したLambda関数を指定し [保存] をクリックします。

f:id:swx-shinsaka:20220202125618p:plain

ドラフトバージョンでのテスト

サイドメニューツリーから [ドラフトバージョン] → [日本語(JP)] を選択し、右下の [構築] をクリックします。
数十秒程度で構築が完了します。

f:id:swx-shinsaka:20220202125937p:plain

構築完了後、[テスト] をクリック、メッセージフィールドへ 注文の状態を教えてください と入力し、Enterキーを押下します。
応答メッセージとして、Lambda関数で実装した通りのメッセージが表示されればOKです。

f:id:swx-shinsaka:20220202130440p:plain

本番バージョンをデプロイ

サイドメニューツリーから [ボットのバージョン] を選択し、 [バージョンを作成] をクリックします。

f:id:swx-shinsaka:20220202154952p:plain

内容を確認し、 [作成] をクリックします。

f:id:swx-shinsaka:20220202155159p:plain

バージョン1が作成されました。

f:id:swx-shinsaka:20220202155506p:plain

サイドメニューツリーから [エイリアス] を選択し、 [エイリアスを作成] をクリックします。

f:id:swx-shinsaka:20220202154640p:plain

本番バージョン用のエイリアス名を Production と指定、既存のバージョンとして上記で作成した [バージョン1] を指定します。
内容を確認し、 [作成] をクリックします。

f:id:swx-shinsaka:20220202161133p:plain

作成された Production エイリアスリンクをクリックします。

f:id:swx-shinsaka:20220202161251p:plain

設定ページの [言語] セクションから [Japanese{Japan)] リンクをクリックします。

f:id:swx-shinsaka:20220202161450p:plain

[Lambda関数] セクションの [ソース] へ、上記手順で作成したLambda関数を指定し [保存] をクリックします。
(テストバージョンの TestBotAlias エイリアスへの設定手順と同じです)

f:id:swx-shinsaka:20220202161815p:plain

Amazon Connect

Amazon Lex使用設定

対象とするConnectインスタンスへLexBotを使用できるよう設定します。
マネジメントコンソール:Amazon Connect画面、サイドメニュー [Contact flows] をクリックし、Amazon Lexセクションへ上記手順で作成したLexBotを指定、 [Amazon Lex ボットを追加] をクリックします。

項目 設定
リージョン アジアパシフィック:東京
ボット SabawaShopSupportBot
エイリアス Production

f:id:swx-shinsaka:20220202162248p:plain

問い合わせフロー作成

Amazon Connectへ、Lex botを利用した問い合わせフローを新規作成します。

完成形

7つのブロックで構成されたフローとしました。
接続順に設定内容を示します。

f:id:swx-shinsaka:20220202180731p:plain

(1)ログ記録動作の設定

動作確認時に有用であるため、ログ記録を設定しています

(2)音声の設定

発話音声と言語属性を指示します。
音声はTakumi ニューラルを指定しました。
また、必ず [言語属性を設定] をチェックします。この設定はLexの言語指示にもなります。

f:id:swx-shinsaka:20220202181057p:plain

(3)プロンプトの再生(冒頭発話)

受電冒頭の発話文言です。シナリオに従って、 はい、サバワショッピングです。どのようなご用件でしょうか? と指定します。

f:id:swx-shinsaka:20220202181609p:plain

(4)顧客の入力を取得する

Lexとの連携を指示するブロックです。
ブロック冒頭で発話できるのですが、シナリオに従うとここで発話する内容は無いので、SSMLで無音指示しています。
分岐は Amazon Lex とし、Lexbotへ SabawaShopSupportBot 、エイリアスへ Production をそれぞれ指定します。ここまでの手順で作成したLexBotとエイリアスです。
最後にインテントとして、Lexで実装した CheckOrder インテントを指定します。

f:id:swx-shinsaka:20220202181921p:plain

(5)プロンプトの再生(CheckOrderからの分岐)

CheckOrder インテントが正常に完了したあとの発話です。
他にもご用件はありますか? と発話し、(4)のLex入力へ戻ります

f:id:swx-shinsaka:20220202182339p:plain

(6)プロンプトの再生(対応終了)

Lexブロックの デフォルトエラー から分岐します。
終了、エラー、および、発話内容からインテント判断できない場合に実行されます。
電話切断の前のブロックですので ご利用いただき、ありがとうございました と発話します。

(7)切断

電話を切断します。

電話番号と問い合わせフローの設定

着信電話番号と、上記作成した問い合わせフローを関連付けます。

f:id:swx-shinsaka:20220202190947p:plain

動作確認

手元の電話から設定した電話番号へ発信し、自動応答をテストします。
デモ動画をご覧ください。

youtu.be

まとめ

簡単な内容や定型的なやり取りだけでもBotとの会話で解決できれば、オペレータさんの負荷も下がりますし、お客様としても、待たずに解決できるなら満足度も上がるのではないでしょうか。

もちろん、自動応答で対応できない内容の場合はオペレータ呼び出しするフローを構築することも可能ですので、定型的な問い合わせは自動応答、複雑で高度な内容はオペレータさんが柔軟に対応する、といったフォーメーションで、効率的なオペレーションを設計できそうです。

手順は長くなってしまいましたが、トレースすれば動作するように記述しました。
ご参考になれば幸いです。