2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Linebot × ChatGPT × Amazon Polly が織り成す楽しい自動対話の世界

Last updated at Posted at 2023-09-30

ChatGPT使って何か作りたい

ChatGPTが出てきてからAI(人工知能)への興味や関心を抱く方が非常に増えましたね。
私も魅力にハマった一人です。ChatGPTを初めて利用した時の感動と驚き、これを使ってどんなことができるようになるんだろう!とワクワク感がたまりませんでした。

ChatGPTを使って自分も何か作りたいなぁと思い、考えたのが自動対話アプリです。
本当は、、AIアバターを使って、音声入出力できて、性格や口調なんかもカスタマイズできて、、と色々夢物語を描いてみたんですが、どうやって作れば良いか見当もつかなかった。。

なので、まずはミニマムにテキスト&音声応答する対話アプリを考えてみました。
下のイメージで作ります。(作ったやつです…)
image.png

構成

大好きなサーバーレスサービス駆使していきます。
* フロント       : Linebot
* API         : Amazon API Gateway + Lambda(python)
* 対話文生成      : ChatGPT API(openai API)
* 合成音声(音声変換) : Amazon Polly

作り方

1.準備(アカウントやトークンの準備)

1-1.Linebot利用登録

 Linebotを利用するにはLine Developersアカウント登録が必要です。
 アカウント登録 → プロバイダー作成 → チャネル作成 → チャネルアクセストークンの発行を行います。
 以下の記事を参考にさせていただきました:bow:

1-2.ChatGPT API利用登録

 ChatGPT APIを利用するにはOpenAIアカウント登録が必要です。
 アカウント登録 → APIキーの発行を行います。
 以下の記事を参考にさせていただきました:bow:

1-3.Lambdaで利用するライブラリ取得

 LINE Messaging API、openai API の利用のために以下ライブラリを取得します。
 インストール後、Lambdaレイヤーに登録するために各pythonフォルダをzip化しておきます。

ターミナル
pip install line-bot-sdk -t ./line-bot-sdk/python/
pip install openai -t ./openai/python/

2.AWS Lambda (python 3.11) 構築

2-1.Lambdaレイヤー登録

1-3でzip化したモジュールをLambdaレイヤーに登録します。(方法が分からない方はこちらを参照)
image.png
image.png

2-2.Lambda関数作成

Lambda関数をPythonで作成し、レイヤーを登録します。
image.png

1-1 と 1-2で発行した各種トークンを環境変数に登録します。
image.png

環境変数利用方法
lineAccesstoken = os.environ['LINE_ACCESS_TOKEN']
lineChannelSecret = os.environ['LINE_CHANNEL_SECRET']
openaiApikey = os.environ['OPENAI_APIKEY']

LINE Messaging API、openai APIを利用するためにLambdaレイヤーに登録したライブラリをインポートします。

import
from linebot import LineBotApi
from linebot.models import AudioSendMessage, TextSendMessage
import openai
2-3.Linebotから受信したテキストメッセージをChatGPT APIに渡す

それでは中身を作っていきましょう。
まずは、Linebotから受信したテキストメッセージをChatGPT APIに渡していきます。

Linebotから受信したメッセージを取り出す
body = json.loads(event['body'])
events = body['events'][0]
if events['type'] == 'message':
    if events['message']['type'] == 'text':
        keyword = events['message']['text']
        
        try:
            responseText = sendOpenAi(keyword)
        except Exception as e:
            logger.error(e)
ChatGPT APIに渡す
def sendOpenAi(keyword):
    logger.info(keyword)
    payload = {
        "model": "gpt-3.5-turbo",
        "messages": [
            {"role": "system",
            "content": """あなたはChatbotとして、ツンデレ女子高生のロールプレイを行います。 以下の制約条件を厳密に守ってロールプレイを行ってください。
            #制約条件
            * Chatbotの名前は、ツンデレ女子高生です
            * ツンデレ女子高生は表面上は連れない態度を取りますが、実はとてもやさしい心の持ち主です。
            * ツンデレ女性高生は強気でプライドが高いです。
            * ツンデレ女性高生の年齢は18歳です。
            * ツンデレ女性高生は語尾に「です」「ます」といった敬語表現は使いません。
            
            #ツンデレ女子高生のセリフ、口調の例
            * あんたなんかに付き合ってあげる物好き、私くらいしかいないんだからね!
            * 別に、あんたの心配なんてしてないし!
            * 寂しくなんてなかったんだから!別に少しの間会わなくたって平気だし!
            * 好きじゃないってば! 勘違いしないでよね!
            * 今回だけだから! 感謝しなさいよね
            * べ、別にあんたのことなんて好きじゃないんだからね!
            * いつでも連絡して良いよ。けど、返事は期待しないでね
            
            #ツンデレ女子高生の行動指針
            * ユーザーに対して厳しいアドバイスを2つしてください。最後は必ず一つ褒めてあげてください。
            * ユーザーからツン要素追加と言われたら、前回の回答を厳しいアドバイス3つに変更して再度返答してあげてください。
            * ユーザーからデレ要素追加と言われたら、前回の回答をツンデレのデレ要素を増やしてあげた状態で再度返答してあげてください。口調はツンデレ女子高生らしい言葉遣いにしてください。
            * 端的な、要点をまとめた内容で答えて下さい。
            """
            },
            {"role": "user", "content": keyword}
        ]
    }
    headers = {
        "Content-Type": "application/json",
        "Authorization": "Bearer " + openaiApikey
    }
    openaiApi = "https://api.openai.com/v1/chat/completions"
    try:
        response = requests.post(openaiApi, headers = headers, data = json.dumps(payload))
        jsonResponse = json.loads(response.text)
        text = jsonResponse['choices'][0]['message']['content']
        logger.info(text)
    except Exception as e:
        logger.warning(e)
    return text

ChatGPTにはロールプレイという人格設定を行う機能があります
roleに記載している制約条件、セリフ/口調、行動指針で細かく設定ができます
今回は ツンデレ女子高生を利用させていただきました

2-4.ChatGPTから返却されたメッセージをAmazon pollyで合成音声に変換→S3アップ
Amazon Polly Call
    # Amazon Polly で音声化しS3配置
    session = Session(region_name="ap-northeast-1")
    polly = session.client("polly")
    s3 = resource('s3')
    bucket = s3.Bucket("gpt-polly")
    mp3File = "polly-" + datetime.now().strftime("%Y%m%d%H%M") + ".mp3"

    response = polly.synthesize_speech(
        Text=responseText,
        Engine="neural",
        OutputFormat="mp3",
        VoiceId="Kazuha")
    with closing(response["AudioStream"]) as stream:
        bucket.put_object(Key=mp3File, Body=stream.read())

Text:ChatGPTに生成してらもったテキスト
Engine:Amazon Polly で利用するエンジン(neural:自然で人間に近い)
VoiceId:Amazon Polly で利用する音声(Kazuha:女性)

2-5.S3音声ファイルのURLを発行し、テキストデータと音声データURLをLinebotに返却します
    # S3 generate_presigned_url
    s3_client = boto3.client('s3')
    original_content_url = s3_client.generate_presigned_url(
        ClientMethod='get_object',
        Params={'Bucket':  'gpt-polly', 'Key': mp3File },
        ExpiresIn=3600)
    # response(Text & Audio)
    line_bot_api = LineBotApi(lineAccesstoken)
    line_bot_api.reply_message(events['replyToken'], [TextSendMessage(text=responseText),AudioSendMessage(original_content_url=original_content_url, duration=30000)])

LineBotApi:Lambdaレイヤーに設定したSDK
reply_message:Linebotから受領したリクエスト内にあるreplyTokenと、返却データを指定

3.API Gateway 構築

LambdaのトリガーにAPI Gatewayを指定します
image.png

4.Linebot webhook 設定

 ・webhook に API Gateway のURLを指定します
  image.png

  これで実装完了です!

動作確認

 それでは動作確認していきましょう。
 Linebotから適当にメッセージを送信します。
 image.png
 テキストメッセージと音声の2つが返却されてます。
 ちゃんと厳し目のツンデレな感じですねw

 image.png

 ちょっと厳しすぎる気もするけどw

 image.png

 これはこれで面白いw

まとめ

いかがでしたでしょうか。ワクワクが止まらないですね。
SDKが用意されているので比較的簡単に作れた印象です。
ChatGPTの人格設定を変えてみたり、Amazon Pollyの音声を変更してみたりして色々と試してみようと思います。

こんなの作ってみて!とか、こんな設定や作りにしたらもっと面白くなるんじゃない!などあればぜひご意見ください。

以上です。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?