gpt-3.5-turboを使ったslack bot を作ってみた
ファインディ株式会社、アルゴリズム企画開発チームの山家です。
OpenAIが出しているAPI(gpt-3.5-turbo)を使用してslack bot を作成しました。
作ったもの
スレッドの内容を理解しながら返信してくれるChatGPTライクなslack botを作成しました。
pythonで書いてる方が少なかったので、記事にしてみました。
OpenAIのkey取得
OpenAIのAPI keysを開く
+ create new secret key を押してkeyを発行する。
Slack Botを作成する
Basic InformationのApp-Level Tokensでwriteを追加し、xapp~~から始まるtokenをコピーしておきます。(後で使います。)
https://api.slack.com/apps へアクセスしてAppを作成する
Bolt for PythonでSocketModeを使用するため、slack app ページでSocket Mode をenableにする
Event Subscriptionsをenableにして、トリガーを作成する。
今回は、app_mentionとmessage.imを設定しています。
参考記事)
コード
Boltフレームワークを使用します。(Bolt 入門ガイド)
以下を環境変数でexportしておきます
export SLACK_BOT_TOKEN=xoxb-hogehoge
export SLACK_APP_TOKEN=xapp-fugafuga()
export SLACK_BOT_ID=@PIYOPIYO
export OPENAI_DEFAULT_MESSAGE=Let's think step by step.
export OPENAI_API_KEY=foofoo
以下のコードをmain.pyに保存する
import os
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
import openai
# 環境変数からトークンを読み込む
app = App(token=os.environ["SLACK_BOT_TOKEN"])
openai.api_key = os.environ["OPENAI_API_KEY"]
system_message = os.environ["OPENAI_DEFAULT_MESSAGE"]
slack_bot_id = os.environ["SLACK_BOT_ID"]
# direct messageを送付した場合のイベントはmessage、チャンネルでメンションした場合はapp_mentionをトリガーしている。
@app.event("message")
@app.event("app_mention")
def gpt_reply(event, say):
# ecent[text]には、メンションが含まれているので、メンションを削除する
input_message = remove_slack_id_from_text(event["text"], slack_bot_id)
channel = event["channel"]
user_slack_id = event["user"]
# メッセージを取得する
messages = [
{"role": "system", "content": system_message},
{"role": "user", "content": input_message},
]
thread_ts = event["ts"]
# スレッドにメッセージがある場合は、メッセージを取得する
if "thread_ts" in event:
thread_ts = event["thread_ts"]
thread_messages_response = app.client.conversations_replies(
channel=channel, ts=thread_ts
)
for i in thread_messages_response["messages"]:
# メッセージがBotの場合は、Botの発言をmessagesに追加する
if i["user"] == slack_bot_id:
messages.append(
{
"role": "assistant",
"content": remove_slack_id_from_text(i["text"], slack_bot_id),
}
)
# メッセージがユーザーの場合は、ユーザーの発言をmessagesに追加する
elif i["user"] == user_slack_id:
messages.append(
{
"role": "user",
"content": remove_slack_id_from_text(i["text"], user_slack_id),
}
)
print("User:" + input_message)
# OpenAIのChat APIを使用してChatGPTからの返答を取得する
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=messages,
)
text = response["choices"][0]["message"]["content"]
if text != "":
print("ChatGPT:" + text)
say(text=text, thread_ts=thread_ts, channel=channel)
else:
print("ChatGPT:" + "No response from OpenAI API")
say(text="No response from OpenAI API", thread_ts=thread_ts, channel=channel)
thread_ts = app.client.conversations_replies(channel=channel, ts=thread_ts)[
"messages"
][0]["thread_ts"]
def remove_slack_id_from_text(text, slack_id):
return text.replace(f"<@{slack_id}>", "")
# Socket Modeハンドラーを作成し、Slack APIを起動する
if __name__ == "__main__":
handler = SocketModeHandler(
app,
os.environ["SLACK_APP_TOKEN"],
)
handler.start()
python main.py
を実行する
社内では、GKEを使用して常時起動するようにしています。
のびしろ
tokenが上限を超える際にエラーが出ないです。(気が向いたら修正します)
スレッドの内容を全て渡している為、gpt_botとのやり取り以外のメッセージも考慮されてしまいます。
まとめ
社内でslackbotを展開したところ、わからない単語を調べたり、slackのコミュニケーション活性化に繋がっているようでうれしかったです。
現在、事業領域的にもセンシティブな情報を扱うので、OpenAIのAPIにはセンシティブな情報をいれないようにしており、LLMの内製化を進めてます。(内製の知見ある人いたら教えて下さいw)
宣伝
一緒に働く人も募集してます!ぜひ!