🍣

最新の論文をChatGPTで要約して毎朝Slackに共有してくれるbotを作る!

2023/03/12に公開

研究室のSlackチャンネルに最新の論文を共有してくれるbotがあれば、議論をもっと活発化できるのでは?と思ったので試しに作ってみました!

目標

こんな感じで、時間通りにarxiv論文を要約したものをシェアしてくれるSlackbotを作ります。

手順

  1. SlackBotのためのAPIトークンを生成
  2. OpenAIのAPIを取得
  3. Pythonコードを作成
  4. Google Cloud Platform(GCP)で実行を自動化
  5. 完成!

1. SlackBotのためのAPIトークンを生成

Slack APIのページからbotを作成する必要があります。

この方の記事で詳しいやり方が紹介されているので、参考にしながらアプリ作成、APIトークン生成、ワークスペースにアプリをインストール、メッセージ送信のテストまでやってみてください。
https://zenn.dev/kou_pg_0131/articles/slack-api-post-message

2. OpenAIのAPIを取得

今回は取得した論文を要約するために、ChatGPTのAPIを使います。

ChatGPTのAPIを使用するためには、まずOpen AIのAPIキーを取得する必要があります。

以下のページからOpenAIのアカウント作成、APIキーの取得までを行いましょう。
https://platform.openai.com/account/api-keys

このような画面が出てきたら、+ Create new secret keyをクリックするとAPIキーを取得することができます。

コピーはキーを発行した時にしかできないので、コピーして、どこかに保存しておきましょう。

ただ、コピーし忘れてしまっても、もう一度ボタンを押すことで再発行することができます。

3. Pythonコードを作成

次にコードを作成していきます。

ライブラリにはopenai,slack-sdk,arxivの三つを使用します

Google Cloud Platform(GCP)のCloud Functionsでpyファイルを実行するので、main関数にはeventcontextの二つの引数を渡します。

コードはこちらの方が書いた記事を参考にしています。

https://qiita.com/GleamingCake/items/e8c53fb0c1508ba1449e

main.py
import os
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
import arxiv
import openai
import random

#OpenAIのapiキー
openai.api_key = 'OpenAIのAPIキー'
# Slack APIトークン
SLACK_API_TOKEN = 'SlackbotのAPIトークン'
# Slackに投稿するチャンネル名を指定する
SLACK_CHANNEL = "#general"

def get_summary(result):
    system = """与えられた論文の要点を3点のみでまとめ、以下のフォーマットで日本語で出力してください。```
    タイトルの日本語訳
    ・要点1
    ・要点2
    ・要点3
    ```"""

    text = f"title: {result.title}\nbody: {result.summary}"
    response = openai.ChatCompletion.create(
                model="gpt-3.5-turbo",
                messages=[
                    {'role': 'system', 'content': system},
                    {'role': 'user', 'content': text}
                ],
                temperature=0.25,
            )
    summary = response['choices'][0]['message']['content']
    title_en = result.title
    title, *body = summary.split('\n')
    body = '\n'.join(body)
    date_str = result.published.strftime("%Y-%m-%d %H:%M:%S")
    message = f"発行日: {date_str}\n{result.entry_id}\n{title_en}\n{title}\n{body}\n"
    
    return message

def main(event, context):
    # Slack APIクライアントを初期化する
    client = WebClient(token=SLACK_API_TOKEN)
    #queryを用意、今回は、三種類のqueryを用意
    query ='ti:%22 Deep Learning %22'

    # arxiv APIで最新の論文情報を取得する
    search = arxiv.Search(
        query=query,  # 検索クエリ(
        max_results=100,  # 取得する論文数
        sort_by=arxiv.SortCriterion.SubmittedDate,  # 論文を投稿された日付でソートする
        sort_order=arxiv.SortOrder.Descending,  # 新しい論文から順に取得する
    )
    #searchの結果をリストに格納
    result_list = []
    for result in search.results():
        result_list.append(result)
    #ランダムにnum_papersの数だけ選ぶ
    num_papers = 3
    results = random.sample(result_list, k=num_papers)
    
    # 論文情報をSlackに投稿する
    for i,result in enumerate(results):
        try:
            # Slackに投稿するメッセージを組み立てる
            message = "今日の論文です! " + str(i+1) + "本目\n" + get_summary(result)
            # Slackにメッセージを投稿する
            response = client.chat_postMessage(
                channel=SLACK_CHANNEL,
                text=message
            )
            print(f"Message posted: {response['ts']}")
        except SlackApiError as e:
            print(f"Error posting message: {e}")

工夫として、処理に時間は掛かりますが、最新論文を100件取得し、リストにした後randomを使うことで、新しい論文を何度も取得することが無いようにしています。

ここらへんの値は好きに調整して頂いて結構ですが、あまり大きくしすぎると処理が大きくなり、OpenAI API、GCPで料金を払う必要性が出てくるので注意です。

また、今回は、queryDeep Learningを指定していますが、自分の興味のある、もしくは研究室内でテーマとして扱っているものに変更すると良いでしょう。

queryの指定方法はこちらの方が書いた記事に詳しく載っていますので、参考にしてください。

https://qiita.com/KMD/items/bd59f2db778dd4bf6ed2

requirement.txtやローカルで試す用のpyファイルなどはこちらのリポジトリにありますのでこちらからクローンしてください。

https://github.com/zushi0516/arxiv_paper2slack

4. Google Cloud Platform(GCP)で実行を自動化

最後に、作成したpyファイルをGoogle Functionsというツールを使って実行を自動化します。

設定の仕方はこちらの方の記事を参考にしてください。

https://gammasoft.jp/blog/schdule-running-python-script-by-serverless/

注意点として、ランタイムにはPython3.10を選択、main.pyとrequirement.txtは私のgithubリポジトリからクローンしてきたものを使ってください。

論文の取得頻度はCloud Schedulerで調整してください。

例えば0 7 1 * *とすることで毎朝7時に論文を取得してくれるようになります。

5. 完成!

これで完成!思ったより簡単にできました!

毎朝論文をチェックして、気になる論文については別のチャンネルで共有して研究室メンバーと議論、なんてこともできそうですね!研究が捗りそうで嬉しいです。

次はIEEEのAPIを使って特に注目されている論文を引っ張ってくる、みたいなことがしたい!

参考文献

偉大な先人達の知恵とChatGPT様のお陰で作成できました。ここに感謝の意を表します。

https://zenn.dev/kou_pg_0131/articles/slack-api-post-message

https://qiita.com/GleamingCake/items/e8c53fb0c1508ba1449e

https://qiita.com/KMD/items/bd59f2db778dd4bf6ed2

https://gammasoft.jp/blog/schdule-running-python-script-by-serverless/

Discussion