はじめに
Pythonのline-bot-sdkやopenaiモジュールなど使い、LINE上でGPT-4oが応答してくれる超シンプルなBotを作ってみます。
流れのイメージはこんな感じです。
- ユーザがLINEでメッセージ送信
- Webhook URL(https://xxxx.ngrok-free.app/callback)に対してPOSTリクエストが送信される
- ngrokにより、/callbackエンドポイントがローカルのPython実行環境に渡される
- Pythonのコード内で一連の処理を行い、ユーザに結果が返される
動作環境
- GPT-4o
- Python 3.8
- ubuntu 20.04(Python実行環境)
- ngrok
各種アカウント準備
以下、必要なアカウントの準備をしていきます。
- LINE Messaging API
- OpenAI API
- ngrok
LINE Messaging API
LINEのAPIを使う準備を行います。
以下を参考に、LINE公式アカウントの作成と、Messaging APIの有効化を行います。
LINE Official Account Managerからアイコンやチャンネル名など設定できるので、適当に設定しておきます。
OpenAI API
OpenAIのAPIを使う準備を行います。
OpenAIからアカウント作成orサインインします。
※ChatGPTなど使っている場合はそのままのアカウントで入れます。
サインインできたら、Billing > Add to credit balanceからAPI利用のための金額をチャージしていきます。
※デフォルトだと自動チャージが有効になっていた気がするので、注意が必要です。
ngrok
今回はローカルのPC上で動かすため、ローカルのサーバ(localhost)を一時的にインターネットに公開してくれる、ngrokというツールを使います。(便利!)
使うにはアカウント登録が必要なので、https://ngrok.com/ から登録します。
登録できたら、Your Authtokenから後々使うトークンを確認しておきます。
ちなみにngrokは、無料版だと1環境まで外部公開できるみたいです。
実装
ngrokインストール
まずは以下に従って、ローカルの実行環境にngrokをインストールします。
インストールできたら、手順にある通り、tokenを設定します。
登録した際に確認した、Your Authtokenを<token>に入れます。
ngrok config add-authtoken <token>
Python実行環境準備
次にPythonの実行環境を用意していきます。
※当方Python初心者のため、このあたりはChatGPTの力を借りて進めていきました。間違いがあったらすみません・・・m(__)m
一時的な作業なので、仮想環境を作成して実施します。
mkdir line-gpt-bot ; cd line-gpt-bot
# 仮想環境作成
python3 -m venv venv
# 有効化
source venv/bin/activate
続いて、今回必要なライブラリをインストールしていきます。
pip install flask line-bot-sdk openai==0.28 python-dotenv
ライブラリをインストールできたら、ファイルを作成していきます。
line-gpt-bot/
├── .env
├── app.py
変数定義ファイル
まず、.env
ファイルで環境変数を定義します。
LINE_CHANNEL_SECRET=チャネルシークレット
LINE_CHANNEL_ACCESS_TOKEN=チャネルアクセストークン
OPENAI_API_KEY=OpenAIのAPIキー(sk-から始まるもの)
上2つはLINE Developersのコンソール > チャネル基本設定、Messaging API設定から確認可能です。
OpenAIのAPIキーは、OpenAIのPlatform > Create new secret keyから作成したものを指定します。
app.py
続いて、動作の大元となるPythonファイルを作成します。
from flask import Flask, request, abort
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextMessage, TextSendMessage
from dotenv import load_dotenv
import os
import openai
# .envからキーを読み込む
load_dotenv()
line_bot_api = LineBotApi(os.getenv("LINE_CHANNEL_ACCESS_TOKEN"))
handler = WebhookHandler(os.getenv("LINE_CHANNEL_SECRET"))
openai.api_key = os.getenv("OPENAI_API_KEY")
# Flaskアプリ作成
app = Flask(__name__)
# Webhookを受けるルート
@app.route("/callback", methods=["POST"])
def callback():
signature = request.headers["X-Line-Signature"]
body = request.get_data(as_text=True)
try:
handler.handle(body, signature)
except InvalidSignatureError:
abort(400)
return "OK"
# メッセージイベントの処理
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
user_message = event.message.text
# OpenAI GPT-4oで返答を生成
response = openai.ChatCompletion.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "あなたは丁寧なAIアシスタントです。"},
{"role": "user", "content": user_message}
]
)
ai_reply = response["choices"][0]["message"]["content"]
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=ai_reply)
)
if __name__ == "__main__":
app.run()
今回使っているライブラリが何者なのか、自分なりの理解は以下の通りです。
※ふわっと理解
- flask
- Python製の軽量Webアプリケーションフレームワーク。
- 今回は、Webhookから受け取ったhttpリクエストを「/callback」という受け口でさばいてくれる。
- line-bot-sdk
- LINE公式から提供されている、PythonでLINE Messaging APIを使用してBotを開発するためのパッケージ。
- 今回は、Webhookから受け取ったリクエストのパース処理※をしている。
※リクエストの中身を取り出して扱いやすい形にする処理 - https://github.com/line/line-bot-sdk-python
- openai==0.28
- OpenAI公式から提供されている、PythonでOpenAIのAPIを呼び出すためのパッケージ。
- 今回は、GPT-4oへのメッセージ送信と応答取得の処理をしている。
- ※0.28は古いバージョンらしく、1.0以降になるとコードの書き方が大きく変わるとのことなので、0.28をバージョン指定してインストールしました。
- https://github.com/openai/openai-python
- python-dotenv
-
.env
ファイルに記載したAPIキーやトークンなどの環境変数を、Python内で自動的に読み込めるようにするためのパッケージ。 -
.env
に書いた内容をos.getenv("KEY名")
で取得できるようになる。 - https://github.com/theskumar/python-dotenv
-
動作確認
ngrokで公開
以下コマンドでlocalhostの5000ポートを外部公開します。
ngrok http 5000
実行すると、以下のように出力されます。
https\://xxx.ngrok-free.app
が、localhost:5000へアクセスするURLになります。
ngrok (Ctrl+C to quit)
?? ngrok? We're hiring https://ngrok.com/careers
Session Status online
Account <メールアドレス> (Plan: Free)
Version 3.22.1
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding https://xxx.ngrok-free.app -> http://localhost:5000
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
Webhook設定
上記で公開されたhttps\://xxx.ngrok-free.app
に、flaskの受け口である/callback
を付けて、Webhook URLに設定します。
LINE Developersのコンソール > Messaging API設定から、Webhook設定という項目があるので、Webhook URLを入れ、Webhookの利用をオンにします。
Python実行
ngrokとは別のターミナルを開き、先ほど作成したapp.py
を実行します。
python app.py
(venv) root@MyVM:~/Test/line-openai-bot# python app.py
app.py:12: LineBotSdkDeprecatedIn30: Call to deprecated class LineBotApi. (Use v3 class; linebot.v3.<feature>. See https://github.com/line/line-bot-sdk-python/blob/master/README.rst for more details.) -- Deprecated since version 3.0.0.
line_bot_api = LineBotApi(os.getenv("LINE_CHANNEL_ACCESS_TOKEN"))
app.py:13: LineBotSdkDeprecatedIn30: Call to deprecated class WebhookHandler. (Use 'from linebot.v3.webhook import WebhookHandler' instead. See https://github.com/line/line-bot-sdk-python/blob/master/README.rst for more details.) -- Deprecated since version 3.0.0.
handler = WebhookHandler(os.getenv("LINE_CHANNEL_SECRET"))
* Serving Flask app 'app'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
LINEからメッセージを送ってみる
これで準備は整ったので、いよいよメッセージを送ってみます。
返ってきました!
おまけ
今回はgpt-4oを使いましたが、他のバージョンだとどうなのか、旧モデルのgpt-4との回答を比較してみました。
gpt-4の回答
gpt-4oの回答
面白いかは置いておいて、gpt-4oの方がスマートになってますね!笑
感想
ChatGPTはずっと使っていましたが、APIを使って何かやるのは初めてだったので、良い勉強になりました。
今回はシンプルBotでしたが、今後はさらに、会話履歴を保持したり、webに検索しにいく処理を入れたり、画像処理を入れたり…等々、拡張の幅は広がるなと思いました!