TL;DR
流行りに乗ってChatGPT(本当はOPENAIのgpt-3.5-turboエンジン)のWebAPIをたたくLineBotを作る
ほぼ、下記記事の劣化焼き直し
https://zenn.dev/umi_mori/articles/chatgpt-api-python
https://chatgpt-lab.com/n/n55257c082a9d
OPENAIキーの発行方法
下記の通り。ただし、https://openai.com/api/はproductのページへリダイレクトされてしまう
https://platform.openai.com/account/api-keys などにアクセスする
https://zenn.dev/umi_mori/books/chatbot-chatgpt/viewer/how_to_use_openai_api#api%E3%81%AE%E7%99%BA%E8%A1%8C%E6%96%B9%E6%B3%95
LineDeveloper登録
下記などを参考にする。
https://chatgpt-lab.com/n/n55257c082a9d#f877eef2-6a5f-4061-8558-d57d2f91e868
- 応答設定からWebhookを有効、応答メッセージは無効にする
実装
今回はWebhookのバックエンドをAWS Lambdaとして、関数URL設定にて作成した。
おおむね下記手順
- AWSコンソールから「関数の作成」を押下
- 一から作成を選択し、ランタイムを選択(今回は使用するLayerの関係でPython3.7にしたが、Python3.9がいいと思う)
- 設定タブから「一般設定」を選択し、「変数」を押下、タイムアウト時間を30秒ほどに設定する
- 設定タブから「関数URL」を選択し、「関数URLの作成」を押下、認証は「NONE」を選択してURLを作成する
- 設定タブから「環境変数」を選択し、「LINE_ACCESS_TOKEN」、「OPENAI_KEY」を設定する
- 後述のコードを関数に張り付ける
- 基本的にはPythonのrequestsモジュールと一緒にzip化したものをアップロードする
コード
大分雑だが、下記でいけた。
import json
import requests
import os
OPENAI_KEY = os.environ["OPENAI_KEY"]
LINE_ACCESS_TOKEN = os.environ["CH_ACCESS_TOKEN"]
reply_url = 'https://api.line.me/v2/bot/message/reply'
openai_url = 'https://api.openai.com/v1/chat/completions'
def lambda_handler(event, context):
# requst情報取得
body_dict = json.loads(event["body"])
events = body_dict["events"][0]
reply_token = events["replyToken"]
text = events["message"]["text"]
if text == "":
#メッセージ以外(スタンプや画像など)が送られてきた場合
text = '???'
# OPENAIのAPI実行
prompt = text
headers_openai = {"Content-Type": "application/json", "Authorization": "Bearer {}".format(OPENAI_KEY)}
payload = {"model": "gpt-3.5-turbo","messages": [{"role": "user", "content": prompt}]}
resp_openai = requests.post(openai_url, headers=headers_openai, data=json.dumps(payload))
openai_replytext = json.loads(resp_openai.content)['choices'][0]['message']['content']
# LINE replyのAPI実行
headers = {'Content-Type': 'application/json; charset=UTF-8', 'Authorization': 'Bearer {}'.format(LINE_ACCESS_TOKEN)}
body = {
'replyToken': reply_token,
'messages': [{
'type': 'text',
'text': openai_replytext,
}]
}
resp = requests.post(reply_url, headers=headers, data=json.dumps(body))
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
感想
- 思ったより簡単にできた
- 参考記事ではPython/node.jsなのmoduleを利用するものが多かったがrequestsで簡単にできた
- Lambdaだとタイムアウト時間の設定が必須。3秒でレスポンスは返ってこない
- "role": "system"のプロンプト回りはまだトライしてないので、続きでやる