Amazon Connect Wisdom を触ってみた

December 10, 2021

Amazon Connect Wisdom とは

Amazon Connect Wisdom とは Amazon Connect で構築されたコンタクトセンターでエージェントが顧客対応を行っている際に、会話の内容を Contact Lens の Real-time speech analisys により解析し、自社が保有するナレッジベースから自動的に顧客の課題解決に役立ちそうな記事をサジェストしてくれるという、なんともインテリジェントな機能です。
今回、2021 年 9 月 に Contact Lens が日本語をサポート し、さらに Wisdom が GA になった ので、色々遊んでみようと思います。

今回やること

Amazon Connect Wisdom は、コンソールから設定を行った場合 Salesforce もしくは ServiceOne の統合が必須になりますが、API を利用した場合はカスタムナレッジベースを利用することが可能であり、コンテンツの内容としては HTML 及びテキストがサポートされます。今回は、本ブログをナレッジベースのコンテンツとして登録し、Amazon Connect Wisdom が自動で適切な記事をサジェストしてくれるのか、試してみたいと思います。

準備

今回の構成としては Ingesting content to power real-time recommendations and search with Amazon Connect Wisdom に倣い、S3 バケットでバージョニングを有効化して、そのバケットにオブジェクトが作成・削除された際のイベントをトリガーとして Lambda 関数が起動、Amazon Connect Wisdom 側のナレッジベースを更新する、というものになります。
なので、まずは S3 バケット及び Lambda 関数の作成をします。ただ、Lambda 関数については サンプル がそのまま使えそうなので、これを流用します。おかげさまで、リソースの作成自体には手間がかかりません。

次にやるのは S3 バケットにおけるバージョニングの有効化及びオブジェクトの作成・削除に対する Lambda 関数のイベントトリガーの作成ですが、前者については ここ を、後者については ここ を参照すれば問題ないでしょう。

Amazon Connect Wisdom のセットアップ

ここからは全て AWS CLI で操作を行います。なお Amazon Connect Wisdom が AWS CLI に追加されたのは割と最近なので、最新版にアップデートしておきましょう。

1. アシスタントの作成

まずはアシスタントを作成します。assistantIdassistantArn の値はメモしておきましょう。

$ aws wisdom create-assistant --name DealingWithAmbituityAssistant --type AGENT
{
    "assistant": {
        "assistantArn": "arn:aws:wisdom:us-west-2:xxxxxxxxxxxx:assistant/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "assistantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "name": "DealingWithAmbituityAssistant",
        "status": "ACTIVE",
        "tags": {},
        "type": "AGENT"
    }
}

2. カスタムナレッジベースの作成

次に、CUSTOM を指定したナレッジベースを作成します。返却される knowledgeBaseIdknowledgeBaseArn の値をメモしておきます。

$ aws wisdom create-knowledge-base --name DealingWithAmbiguityKnowledgeBase --knowledge-base-type CUSTOM 
{
    "knowledgeBase": {
        "knowledgeBaseArn": "arn:aws:wisdom:us-west-2:xxxxxxxxxxxx:knowledge-base/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
        "knowledgeBaseId": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
        "knowledgeBaseType": "CUSTOM",
        "name": "DealingWithAmbiguityKnowledgeBase",
        "status": "ACTIVE",
        "tags": {}
    }
}

3. ナレッジベースとアシスタントを関連付ける

以下のコマンドで、アシスタントとナレッジベースを関連付けます。

$ aws wisdom create-assistant-association --assistant-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
    --association knowledgeBaseId=yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy \ 
    --association-type KNOWLEDGE_BASE
{
    "assistantAssociation": {
        "assistantArn": "arn:aws:wisdom:us-west-2:xxxxxxxxxxxx:assistant/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "assistantAssociationArn": "arn:aws:wisdom:us-west-2:xxxxxxxxxxxx:association/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz",
        "assistantAssociationId": "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz",
        "assistantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "associationData": {
            "knowledgeBaseAssociation": {
                "knowledgeBaseArn": "arn:aws:wisdom:us-west-2:xxxxxxxxxxxx:knowledge-base/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
                "knowledgeBaseId": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"
            }
        },
        "associationType": "KNOWLEDGE_BASE",
        "tags": {}
    }
}

4. アシスタント及びナレッジベースを Amazon Connect インスタンスに関連付ける

作成したアシスタントとナレッジベースをそれぞれインスタンスに関連付けます。

アシスタントの関連付け

$ aws connect create-integration-association --instance-id [Instance ID] 
    --integration-type WISDOM_ASSISTANT 
    --integration-arn arn:aws:wisdom:us-west-2:xxxxxxxxxxxx:assistant/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

ナレッジベースの関連付け

$ aws connect create-integration-association --instance-id [Instance ID] 
    --integration-type WISDOM_KNOWLEDGE_BASE
    --integration-arn arn:aws:wisdom:us-west-2:xxxxxxxxxxxx:knowledge-base/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy

これで Amazon Connect Wisdom 側の設定は完了です。

5. Lambda 関数の環境変数を設定する

サンプルで提供される Lambda 関数は、KnowledgeBaseId を環境変数から取得することを想定しています。そのため、環境変数 KNOWLEDGE_BASE_ID に対して、2. で作成した際に取得した knowledgeBaseId の値を指定してあげましょう。

Lambda 関数のテスト

適当なサンプルを S3 バケットに保存して、それがナレッジベースに登録されるかをテストしておきます。サンプルとしては ここ で提供されているものを用います。

sample.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Wisdom Content</title>
  </head>
  <body>
    <table>
      <tr>
        <th>Question</th>
        <th>Answer</th>
      </tr>
      <tr>
        <td>How do I share my pickup location?</td>
        <td>When you request a ride, your driver will see where you've place your pickup location pin. For improved pickups, you can enable sharing your physical GPS location. This helps drivers know if you are coming towards them, or where to look for you if your pin is not in your exact location.</td>
      </tr>
      <tr>
        <td>Can I ride with dog?</td>
        <td>In accordance with state and federal laws, as well as our policies, service animals are permitted to accompany riders at all times. If you're traveling with a pet that's not a service animal, drivers may choose whether or not to allow the pet in their vehicle.</td>
      </tr>
    </table>
  </body>
</html>

以下のように S3 バケットにアップロードします。

$ aws s3 cp sample.html s3://[Your S3 Bucket]/

あとは list-contents コマンドで登録されたか確認してあげましょう。以下のように表示されれば OK です。

$ aws wisdom list-contents --knowledge-base-id [Knowledge Base ID]
{
    "contentSummaries": [
        {
            "contentArn": "arn:aws:wisdom:us-west-2:xxxxxxxxxxxx:content/yyyyyyyy-yyyy-yyyy-yyyyyyyyyyyy/cccccccc-cccc-cccc-cccccccccccc",
            "contentId": "cccccccc-cccc-cccc-cccccccccccc",
            "contentType": "text/html",
            "knowledgeBaseArn": "arn:aws:wisdom:us-west-2:967951649083:knowledge-base/yyyyyyyy-yyyy-yyyy-yyyyyyyyyyyy",
            "knowledgeBaseId": "yyyyyyyy-yyyy-yyyy-yyyyyyyyyyyy",
            "metadata": {
                "sourceS3Version": "Lh28JU2kg1235MTEf4ccI6TgLXTo0Gy2"
            },
            "name": "sample.html",
            "revisionId": "NjY4ODY3ODE0YTJjYzIxMzE0OTNlYjUwMTY2N2U0NzMxMWQxMjg4NDg4ZTdlNWM3NjUxZjIzM2EzMTE4M2MzOA==",
            "status": "ACTIVE",
            "tags": {},
            "title": "sample.html"
        }
    ]
}

では削除してみます。

$ aws s3 rm s3://[Your S3 Bucket]/sample.html

再度 list-contents コマンドを実行し、リストが空であれば OK です。

$ aws wisdom list-contents --knowledge-base-id [Knowledge Base ID]
{
    "contentSummaries": []
}

ブログ記事の静的 HTML ファイルを生成する

ナレッジベースの更新が正常に実施されることを確認したので、いよいよ本ブログ記事を突っ込んでみたいと思います。といってもまずは静的 HTML ファイルを生成するところからなので、その辺から S3 へのアップロードまでを自動化してしまいます。どうせ本ブログは GitHub のリポジトリで管理されてるので、そもそも S3 に一旦上げなくてもブログ更新時に自動で Wisdom にも追加する程度であればいくらでもやりようがあるとは思いますが、それは後々暇があったらやります。

今回は以下のようなスクリプトで全ブログ記事をナレッジベースに移行しました。移行ができているかの確認は先ほどと同様に aws wisdom list-contents で確認ができます。

import boto3
import os
import urllib

s3 = boto3.client("s3")
bucket = "Bucket Name"

def get_content_path_list(base_dir):
  content_path_list = os.listdir(base_dir)
  return content_path_list


def get_static_html(content_url):
  response = urllib.request.urlopen(content_url)
  html = response.read()
  return(html.decode("utf-8"))


def upload_html_to_s3(content, static_html):
  s3.put_object(
    Bucket=bucket,
    Key=content + ".html",
    Body=static_html,
    ContentType="text/html",
  )


def main():
  base_dir = "/Path/To/Contents/"
  base_url = "https://blog.longest-road.com/"
  print("Start extracting contents")
  content_list = get_content_path_list(base_dir)

  for content in content_list:
    static_html = get_static_html(base_url + content)
    upload_html_to_s3(content=content, static_html=static_html)


if __name__ == "__main__":
  main()

Contact Flow / Security Profile の準備

最後に Contact Flow に Wisdom ブロックの追加及び Set recording and analytics behavior ブロックを追加し、Real-time and post-call analytics を有効化します。
また、Security Profile 側でも Wisdom の権限をエージェントに渡しておきます。

試してみる

実際に /agent-app-v2/ からアクセスして、右上からサーチを行うと記事一覧が取得できました。ただ、React との兼ね合いなのか、うまくコンテンツがレンダリングされず…。

agent-app-v2

また、実際に通話もしてみたのですがサジェストを得られることはできませんでした。もう少し調査が必要そうです。

おわりに

最後は残念な結果になってしまいましたが、一から Amazon Connect Wisdom を設定する方法について学べたのは良かったです。いずれまたちゃんとサジェストが得られるように色々調べていきたいと思います。


 © 2023, Dealing with Ambiguity