[ChatGPT × Amazon Connect] ホームページに埋め込めるチャットボットシステムを構築してみた

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、AWS事業本部の荒平(@0Air)です。

ChatGPTの登場以来、ずっとワクワクが止まらないので、Amazon Connectの標準機能であるチャット機能を用いて、多種多様なホームページに埋め込むことが可能なチャットボットシステムを作成してみました。

基本的な構成・設定値は以下の記事と同様ですが、音声入力とチャット入力では若干設定方法が異なっていたため、 そのあたりを重点的に解説します。

作ったもの

構成図

参考記事と同様で、使用しているAWSサービスはAmazon Connect、Lex、Lambdaとなります。

本エントリで紹介するチャットボットでは、以下のメリット・デメリットがあります。

メリット

  • 手軽
    • 使用するチャットウィジェットは、Amazon Connectコンソールからスクリプトをコピー&ペーストするだけで利用できるので、手軽に始めることができます
  • 多言語対応
    • ChatGPTが学習している範囲であれば、どんな言語でも可
  • 様々なサイトに適用可能
    • JavaScriptが動作すれば適用できるため、PC用サイト・スマホ用サイト問わず利用できます

デメリット

  • 曖昧な回答をする可能性がある
    • 現時点では、特定サイトのチャットサポートとしては力不足と思われますが、今後の学習により使えるレベルになる可能性は秘めていると考えます
  • 目的外の質問に対しても返答してしまう
    • 製品のチャットサポートとして置き換えたい場合は、事前に回答を縛るようなプロンプトを渡す必要があります
  • チャットウィザードのカスタマイズ性がない
    • Amazon Connectの基本機能を利用しているだけなので、色やタイトル以外は編集できません。

構築方法

(1) OpenAIアカウントの作成、APIの発行

既に準備されている方は不要です。
以下の記事を参考に、OpenAIアカウントを作成し、APIキーを発行します。
また、Lambda LayerにOpenAIライブラリのアップロードを行います。

(2) Lambda関数の作成

参考記事(再掲)のコードをベースに、チャット用に少し変更を加えました。
(チャットボットは会話を継続的に行いたいため、切断フローを入れない、など)

import json
from decimal import Decimal
import os
import openai

openai.api_key = os.environ['API_Key']

API_ENDPOINT = 'https://api.openai.com/v1/engine/davinci-codex/completions'

SLOT_DUMMY = {
    "question_slot": {
        "shape": "Scalar",
        "value": {
            "originalValue": "default",
            "resolvedValues": [
                "default"
            ],
            "interpretedValue": "default"
        }
    }
}

def decimal_to_int(obj):
    if isinstance(obj, Decimal):
        return int(obj)

def confirm_intent(message_content, intent_name, slots):
    return {
        'messages': [{'contentType': 'PlainText', 'content': message_content}],
        'sessionState': {
            'dialogAction': {
                'type': 'ConfirmIntent',
            },
            'intent': {
                'name': intent_name,
                'slots': slots,
                'state': 'Fulfilled'
            }
        }
    }

def get_openai_response(input_text):
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "user", "content": input_text}, 
        ]
    )
    print("Received response:" + json.dumps(response,default=decimal_to_int, ensure_ascii=False))
    return response["choices"][0]["message"]["content"].replace('n', '')

def ChatGPT_intent(event):
    intent_name = event['sessionState']['intent']['name']
    slots = event['sessionState']['intent']['slots']
    input_text = event['inputTranscript']

    response_text = get_openai_response(input_text)
    print("Received response_text:" + response_text)
    
    return confirm_intent(
        f'ChatGPTの出力:{response_text}',
        intent_name, slots)

def lambda_handler(event, context):
    print("Received event:" + json.dumps(event, default=decimal_to_int, ensure_ascii=False))
    intent_name = event['sessionState']['intent']['name']

    if intent_name == 'chatgpt':
        return ChatGPT_intent(event)

Lambdaの環境変数にキー「API_Key」を作成し、値にOpenAIから取得したAPIキーを入力します。

(3) Amazon Lexの構築

参考記事に記載があるため画像は省略しますが、以下のようにボットを作成します。

  • 「空のボットを作成します」を選択
  • ボット名は任意
  • IAMアクセスロールは作成、および選択
  • 言語は「日本語」を選択
  • (2)で作成したLambdaを紐付け

カスタムスロットタイプまで作成したら、続いてインテントを作成します。

今回設定したチャットボットでは、ユーザーにChatGPTへ接続することを同意してもらうため、
一番始めに「ChatGPTに接続します。問題なければ、Yesを入力してください」と案内し、「Yes」以外であればチャットを切断するようにしました。

このため、画面例では「Yes」以外の入力はFallbackIntentに転送され、チャットが終了します。

最後に、「初期化と検証にLambda関数を使用」を有効にし、Buildします。

(4) Amazon Connectの構築

Amazon LexおよびAWS Lambdaとの紐付け

AWSコンソールにて、[Amazon Connect] - [問い合わせフロー]を選択し、前手順までのAmazon LexおよびAWS Lambdaの紐付けを行います。

コンタクトフローの作成

Amazon Connectのコンタクトフローを作成します。全容は下図の通りです。

[コンタクト属性の設定]にて、以下の設定を行います。

  • 名前空間:システム
  • 値:言語
  • 手動で設定 - 値:ja-JP

※ 余談ですが、この設定値を見落としていたため半日ほどトラブルシュートに費やしました *1。詳細は以下のドキュメントに記載があります。(翻訳して引用)
Amazon Lexの設定画面で指定した言語モデルと一致する必要があります。なお、ここで日本語を選択したとしても、チャットボット動作時は日本語以外でもレスポンスが返ります。

Set contact attributeブロックを使用して、Amazon Lex V2 ボットに必要な言語属性を設定できます。(Amazon Connect の言語属性は、Amazon Lex V2 ボットの構築に使用された言語モデルと一致する必要があります。)

[顧客の入力を取得する]のフローでは、以下の設定を行います。

  • テキスト読み上げまたはチャットテキスト
    • ChatGPTに接続します。問題なければ、「Yes」を入力してください。
  • Amazon Lexボットを選択
    • 前手順で作成したボットとエイリアスを指定します。

フローを作成できたら、保存して公開します。

チャットウィジェットの作成

Amazon Connectの左カラムから、[チャットウィジェット]をクリックします。

チャットウィジェットをカスタマイズします。ここでは、テーマカラーとフォント、タイトルの変更が可能です。


最後に、前手順で作成したコンタクトフローを選択し、[次へ]をクリックします。

チャットウィジェットを埋め込むドメインを入力して、保存します。
入力したドメイン以外からチャットボットへリクエストを送ることはできません。

チャットウィジェットのスクリプトが出力されるので、これをコピーして任意のWEBページのソースに貼り付けます。
(今回の環境では、S3に静的ページを用意して検証しました)

静的ウェブサイトホスティングについては、こちらの記事が参考になるかと思います。

冒頭で解説した通り、チャットが表示されていれば完成です!

さいごに

Amazon Connectのチャット機能を用いて、ChatGPTと対話する手法を紹介しました。
カスタマイズ次第では、チャットサポートなどの業務負担を減らせると思います!

このエントリが誰かの助けになれば幸いです。
それでは、AWS事業本部 コンサルティング部の荒平(@0Air)がお送りしました!

参考

脚注

  1. 【追記】 社内でも同様の事象に遭遇した方が居ましたので、こちらもご参考ください: https://dev.classmethod.jp/articles/amazon-lex-contactflow/