📖

【Python】ChatGPT+Slack APIでチャットボットを作成する

2023/10/05に公開

はじめに

初めまして。
都内IT企業で、データアルゴリズムチームのエンジニアをしております、Noraです。

今回は、SlackAPIとOpenAI APIを活用して、チャットボットを構築します。
今回はPythonを利用した実装です。

社内Slackにチャットボットを構築することで、メンバーの質問内容を把握できるようになります。
また、スレッドの内容を記憶した返答をできるようになると、満足度も向上し、様々なチャット内容を蓄積・展開できます。

(OpenAI APIは従量課金制なので、使い過ぎには気をつけましょう)

利用ツール・言語

Python

今回の実装はPythonを使用します。
OpenAI APIや、Slack BoltのPython用ドキュメントが充実していたこと、私が普段から使い慣れている言語であったことから、採用しています。
JavaScriptのドキュメントも充実しているので、JavaScriptを使うのも良いかもしれません。

OpenAI API

今回は、ChatGPT(モデルはgpt-3.5-turboを使用)からの返答を、SlackBotに組み込みたいので、OpenAI APIを活用しています。
OpenAI APIを使うことで、チャットボットのような返答だけでなく、Embedding(ベクトル生成)や、Fine-tuningもできるようになっています。(今回はChatのみの使用です)
https://openai.com/product

Slack API

Slackチャンネルとのやりとりを行うために、公式が公開しているSlack APIを利用します。
Slack APIを発行することで、パブリックチャンネルやDM、スレッドの情報取得や、メッセージの送信が可能になります。
https://api.slack.com/lang/ja-jp

Slack Bolt

BoltはSlackを使ったアプリ開発のために、Slack公式が出しているフレームワークです。
Pythonだけでなく、JavaScriptなど様々な言語に対応したドキュメントが公開されています。
https://slack.dev/bolt-python/ja-jp/tutorial/getting-started

ソケットモード

また今回は、ソケットモードを使うことでより簡易的なアプリケーションを作成します。
公式ドキュメントに書いている通り、バブリックなHTTPリクエストURLがなくとも、EventAPIとのやり取りが可能になります。

Socket Mode allows your app to use the Events API and interactive features—without exposing a public HTTP Request URL.

https://api.slack.com/apis/connections/socket

実装手順(15分ほどで完了!)

  1. OpenAI APIとSlack APIを取得
  2. Boltを使った実装(Python)
  3. 実際に動かしてみる & 完成!

1. OpenAI APIとSlack APIを取得

OpenAI APIとSlack APIを取得

まずは、OpenAI APIから取得します。
こちらからAPI取得画面に移動します。
【OpenAI APIの取得 4step】
1.ログイン
2.アカウントから、View API Keyに移動
3.Create New Scret Keyで取得する
4.表示されたキー(sk-から始まる)は後ほど使うので、保存しておいてください。

この4ステップで、Open AI APIを取得できたかと思います。

次に、Slack APIの取得を行います。
1.こちらからサイトへアクセス

2.「Your App」を押す

3.「Create New App」を押す

4.App Nameは自由に記述し、ワークスペースを選択

5.「Basic Information」から、「Bots」を選択

6. 「Review Scopes to add」を選択

7.「Add OAuth Scope」を選択し、以下のスコープを追加
Bot Token Scopes

  • app_mentions:read(メンションされているメッセージを読む)
  • chat:write(メッセージをチャンネルに書き込む)

8.「Socket Mode」に移動し、Enable Socket ModeをONに設定する

9.「Event Subscriptions」に移動し、Enable EventsをONに設定する
加えて、Subscribe to bot eventsにapp mention権限を付与する。最後に画面右下にある「Save Changes」を忘れずに!

10.「Install App」からInstall to WorkSpaceを押す。
飛んだ先のページで、ワークスペースへのアクセス権限を許可する。

こちらで、API周りの取得を設定は完了です。

具体的実装

今回は以下のようなリポジトリ構成にしています。

root/
  ├ .venv/
  ├ app/
    ├ app.py
  ├ .env
  ├ .gitignore
  ├ README.md
  ├ requirements.txt

では実装していきます。

1.まずは、今回使用するライブラリをrequirements.txtに記載していきます。

requirements.txt
python-dotenv==1.0.0
slack-bolt==1.18.0
requests==2.31.0
openai==0.28.1

2.次にrequirements.txtを使用して、Python仮想環境をアクティベートします

$ python3 -m venv .venv
$ source .venv/bin/activate
$ pip install -r requirements.txt

3.envファイルに APIキーを記載します。
それらのAPIキーを間違えてリリースしないよう、.gitignoreファイルに.envを追加します。
.gitignoreファイルに記述することで、gitの管理から除外され、コミットやプッシュされないようになります。

.gitignore
#.venvもgit管理しないようにする
.venv/
.env
.env
SLACK_BOT_TOKEN = xoxb-hogehoge
SLACK_APP_TOKEN = xapp-hogehoge

OPENAI_API_KEY = sk-hogehoge

SLACK_BOT_TOKEN(xoxb-から始まる)や、SLACK_APP_TOKEN(xoxb-から始まる)は、先ほどのSlackAPIページから取得できます。

3-1.SLACK_BOT_TOKENの取得
「OAuth & Permissions」から取得できます。

3-2.SLACK_APP_TOKENの取得
「Basic Information」に移動し、App-Level Tokensまでスクロールしたら、登録したtoken名をタップ。
「xapp-」から始まるtokenをコピー

4.チャットボットのメイン処理を実装

app.py
import os

import openai
from dotenv import load_dotenv
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler

load_dotenv(verbose=True)
# トークン設定
app = App(token=os.environ.get("SLACK_BOT_TOKEN_2"))
openai.api_key = os.environ.get("OPENAI_API_KEY")


def respond_gpt(user, content):
    # GPTで内容を生成
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "user", "content": personality},
            {"role": "user", "content": "{}".format(content)},
        ],
    )

    res = response.choices[0]["message"]["content"].strip()
    return res


# メンションが飛んできたときのイベント「app_mention」に対する実行ハンドラ
@app.event("app_mention")
def response(event, say):
    input_text = event["text"]
    thread_ts = event.get("thread_ts")
    channel = event["channel"]

    personality = """
    あなたはプログラムミングに関して、周辺知識とともに教えてくれるプログラマー先生です。
    プログラミング以外の話題に関しては、普通に回答してください。
    プログラミングに関するの話題は、次を意識して回答してください。
    
    【意識する点】
    ・プログラムに関する話題を答える
    ・プログラムに関して知っておくべき知識があれば、教える
    ・もし必要であれば、公式ドキュメントや、公式に近い情報源を教える
    ・公式ドキュメントだけで不十分な場合は、サンプルコードとともに解説する
    ・回答は次のように伝える
    
    以下が回答方法です。
    【質問に対する回答】
    hogehoge
    【回答に関する解説や周辺知識】
    hogehoge
    【参考にすべきドキュメントやサンプルコード】
    hogehoge
    """

    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "user", "content": personality},
            {"role": "user", "content": input_text},
        ],
    )

    res_text = response["choices"][0]["message"]["content"].strip()

    if thread_ts is not None:
        parent_thread_ts = event["thread_ts"]
        say(text=res_text, thread_ts=parent_thread_ts, channel=channel)
    else:
        say(text=res_text, channel=channel)


# アプリ起動
if __name__ == "__main__":
    SocketModeHandler(app, os.environ.get("SLACK_APP_TOKEN_2")).start()

動作確認

ここまで実装できたら、最後に動作確認を行います。
Bolt app is runnning!となれば、アプリケーションが動いている確認ができます。

$ cd app
$ python app.py
⚡️ Bolt app is running!

では、Slackで、botをチャンネルに招待して、メンションを飛ばしてみましょう。

ボットをメンションすると、正しく返答してくれることが確認できました!
今記事での実装は以上です!

あと書き

記事をお読みいただき、ありがとうございました。
今回は簡単なbot作成になりましたが、スレッドへの返信や過去会話の記憶ができると更に体験が向上するかと思います。
また、今回はソケットモードを使用しましたが、WebアプリケーションフレームワークのFlaskを利用することでより良いアプリケーションを構築できるのではと考えています。

もし補足点・修正等ございましたら、ご気軽にコメントいただけますと幸いです。

引き続き、ハマったポイントや、タメになる情報を発信できればと思います。

Discussion