arXivの新着をSlackに通知する

★注意★
この記事のスクリプトは下記の古いパッケージで動作確認しており,最新のパッケージでは動作しないことをご留意ください.

arxiv==1.4.7
openai==0.27.4

arxiv APIを用いた論文検索

arxivに投稿された論文を自動でSlackへ通知するbotを作成する.
概ね 参考1 を参考にした.

arxivのAPIを用いると,以下のように新規投稿された論文を取得できる.

import datetime as dt
import arxiv

# パラメータ
MAX_RESULT = 10
N_DAYS = 7

# テンプレートを用意
QUERY_TEMPLATE = '%28 ti:%22{}%22 OR abs:%22{}%22 %29 AND submittedDate: [{} TO {}]'

keyword = "Information Theory"

today = dt.datetime.today()
base_date = today - dt.timedelta(days=N_DAYS)
query = QUERY_TEMPLATE.format(keyword, keyword, base_date.strftime("%Y%m%d%H%M%S"), today.strftime("%Y%m%d%H%M%S"))

search = arxiv.Search(
    query=query,  # 検索クエリ
    max_results=MAX_RESULT * 3,  # 取得する論文数の上限
    sort_by=arxiv.SortCriterion.SubmittedDate,  # 論文を投稿された日付でソートする
    sort_order=arxiv.SortOrder.Descending,  # 新しい論文から順に取得する
)

# 興味があるカテゴリー群
CATEGORIES = {
    "math.IT",
    "cs.IT",
}
# searchの結果をリストに格納
result_list = []
for result in search.results():
    # カテゴリーに含まれない論文は除く
    if len((set(result.categories) & CATEGORIES)) == 0:
      continue
    result_list.append(result)

# 結果を表示
for res in result_list:
    print(res)

# 出力 2023-11-24 17時現在
# http://arxiv.org/abs/2311.12624v1

GPTを使った要約

続いて,GPTを用いて論文の要約を取得する.
openaiのAPIキーは .env ファイルに記入しておき,load_dotenv() で読み込むようにすると,コードの中にAPIキーを書かなくて済む.
load_dotenv()pip install python-dotenv でインストールできる.
.env ファイルに以下のように記述する.

OPENAI_API_KEY="openaiのAPIキー"

以下のコードで先に取得したarxivの検索結果をGPTに投げ,論文のポイントを要約してもらう.

from dotenv import load_dotenv
import os
import time
import openai

# .envファイルを読み込む
load_dotenv()
# OpenAIのAPIキーを設定
openai.api_key = os.getenv("OPENAI_API_KEY")

MODEL_NAME = "gpt-3.5-turbo"
TEMPERATURE = 0.25

SYSTEM = """
### 指示 ###
論文の内容を理解した上で,重要なポイントを箇条書きで3点書いてください。

### 箇条書きの制約 ###
- 最大3個
- 日本語
- 箇条書き1個を50文字以内

### 対象とする論文の内容 ###
{text}

### 出力形式 ###
タイトルを日本語に翻訳したタイトル

- 箇条書き1
- 箇条書き2
- 箇条書き3
"""

def get_summary(result: arxiv.Result) -> str:
    """
    論文の要約を取得
    Args:
        result: arXivの検索結果
    Returns:
        message: 要約
    """
    text = f"title: {result.title}\nbody: {result.summary}"
    cnt = 0
    while True:
        try:
            response = openai.ChatCompletion.create(
                model=MODEL_NAME,
                messages=[{"role": "system", "content": SYSTEM}, {"role": "user", "content": text}],
                temperature=TEMPERATURE,
            )
            break
        except Exception as e:
            time.sleep(20)
            cnt += 1
            # 3回失敗したらエラーを吐く
            if cnt == 3:
                raise e

    time.sleep(5)
    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

print(get_summary(result_list[0]))
# 出力
# 発行日: 2023-11-21 14:18:28
# http://arxiv.org/abs/2311.12624v1
# Bridging Algorithmic Information Theory and Machine Learning: A New Approach to Kernel Learning
# アルゴリズム情報理論と機械学習を結びつける:カーネル学習への新しいアプローチ

# - 機械学習とアルゴリズム情報理論は、異なる視点から複雑さを考えている
# - Sparse Kernel Flowsは、データからカーネルを学習するための自然なアプローチであることが証明されている
# - 統計的な手法を使わずに、コード長や複雑性といったアルゴリズム情報理論の概念を直接扱うことができる

Slack APIを用いた要約の投稿

取得した要約をSlackに投稿する.
SlackのAPIキーは ここ から取得できる.
APIキーを使った投稿は 参考2 を参考にした.
openaiのAPIキーと同様,SlackのAPIキーも .env に記載し,以下のコードを実行した.

from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
from dotenv import load_dotenv
import os

# .envファイルを読み込む
load_dotenv()
# Slack APIトークン
SLACK_API_TOKEN = os.getenv("SLACK_API_TOKEN")

# Slackに投稿するチャンネル名を指定する
SLACK_CHANNEL = "#arxiv"

# Slack APIクライアントを初期化する
client = WebClient(token=SLACK_API_TOKEN)

# Slackにメッセージを投稿する
message = get_summary(result_list[0])
response = client.chat_postMessage(
    channel=SLACK_CHANNEL,
    text=message
)

Slackに投稿された様子は以下の通り.

あとは,毎日定時にこの一連のコードを実行するようにすれば,毎日論文の要約がSlackに投稿される.

参考

  1. 毎日の論文サーベイを手軽に!ChatGPTを活用したSlackへの3行要約通知とNotionデータベース連携
  2. Slack API を使用してメッセージを投稿する

Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *