うみがめのオセロ以外

オセロ以外の雑多なことを書きます。

arXivの最新論文を要約してSlackに自動投稿

表題のものを作ってみた。それなりに躓いた&未解決の問題があるので備忘録。

などが初めて触ったもので、それぞれに詰まったので、ざっくりとまとめる。

背景

環境の変化に伴ってよく知らん分野の論文も広く浅く読んだりしなくてはいけない感じになってきた。

最近の動向を掴むためにもarXiv*1に投稿されている最新論文の雰囲気を掴みたいが、よく知らん分野のよく知らん専門用語が多くアブストをざっと読むのもしんどいし、大半は興味ない。

そこで以前見かけたGPT-3.5-turboの新機能を使ってCVPRの論文を良い感じに検索・推薦・要約するシステムを思い出して、3行で要約して興味があればちゃんと読むというスタイルに移行しようと思った。

作ったもの

  • Slackの個人ワークスペースに、arXivの興味があるカテゴリごとにチャンネルを作成
  • arXiv APIのPythonラッパーを用いて最新の論文情報を取得
  • OpenAI APIを用いて論文のAbstractを3行で要約
    • アブストをさらに要約しているので情報がだいぶ落ちるが、興味のあるなしだけ判定できればよしとする
  • Slack APIのPythonラッパーを用いて論文情報と3行要約をチャンネルに投稿
    • crontabに設定して平日の午前11時に自動的に投稿

最終的に以下のようなものができた*2

見た目は改善の余地が多いし、機能的にもちょっとサボっている点もあるのだが、いったんは動くものができたのでよしとした。

使ったものと躓いたところ

Slack APIを用いたチャンネルへの投稿

  • 参考にした記事
  • 躓いたところ
    • workspace上でそれぞれのchannelのintegrationなどから、事前に作成したappをchannelに追加する必要があった
    • 環境変数に認証Tokenを置いておいたが、Jupyter Notebookでは環境変数を取得するのが大変だった
      • .ipynbで実験するときにはTokenをベタ書きして対応した
        • gitで管理するときには.gitignoreに.envを作ってそこに書くらしい?
      • .pyでは普通にos.environで取得できる

arXiv APIを用いた論文情報の取得

  • 参考にした記事
  • 躓いたところ
    • 未解決:SubmittedDateで検索できない?
      • ソートはできるんだけど...現状は少しサボって取得できる最新の論文と同じSubmittedDateのものを取っており、これだと論文の投稿がない日に困る
    • 未解決:statみたいな大きなカテゴリで検索できない?
      • これはできても使わないかもだけど

OpenAI APIの利用

プロンプトに関しては現状は以下のような処理になっている。

def summarize_abstract(abst):
    content = '''論文のAbstractを要約してください。3つの観点で、それぞれ1行ずつ箇条書きで要約してください。キーワードは取りこぼさないでください。箇条書き以外の内容を出力に含めないでください。
## 観点
- この研究が解決したい課題
- どのような方法で課題に取り組んだか
- 結果何が得られたか
## 入力例
It was raining. I went out with an umbrella. I didn't get wet.
## 出力例
- 課題:雨が降っていた。
- 方法:傘を持って出かけた。
- 結果:濡れなかった。
## 入力
{}
## 出力
'''.format(abst)
    
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "user", "content": content},
        ],
    )
    return response

この関数にarxiv.Searchで得た論文のAbstractを与えることで、「課題、方法、結果」の3行で要約した出力がresponse.choices[0]["message"]["content"]に入る。

簡単な指示+具体例を1セット与えているだけだが、現状はきちんとフォーマット通りの出力になっている。出力がブレるようならFunction Callingとかを使うことになりそう。

APIは月の利用額に制限をかけることができて、デフォルトの120ドルはちょっと怖かったので20ドルにしておいた。 たぶん実際は数ドル程度しかかからないはず*3

crontabを用いて定期的に実行

上記の組み合わせでarXivの最新論文の一覧を取得して、3行要約を添えてSlackに投稿するPythonスクリプトができた。

これを毎日手動で実行するのも面倒なのでcrontabに設定したのだが、cronも環境変数を取得するのに一苦労あるようだった。

結論として、必要な環境変数をcrontab内にベタ書きした。

OPENAI_APIKEY=sk-xxx
SLACK_API_TOKEN_ARXIV_SUMMARY=xoxb-xxx
00 11 * * 1-5 {pythonの絶対path} {Pythonスクリプトの絶対path}

あまりスマートな解決方法ではなさそうだが、他の方法もめんどくさそうなのしか見つからなかったので、とりあえずこれで...

実は完成して記事を書いている時点では土日なので平日の自動投稿は起きてないのだが、テスト用の投稿がcronから成功したので大丈夫でしょう(楽観)。

まとめ

予想外に色々と詰まって数日かかってしまったが、とりあえずはイメージに近いものができて満足。

OpenAI APIには最初につかえる無料枠があるらしいが、期間が過ぎていたのかなぜか使えなかったことだけが残念。

arXivの検索条件やGPTに投げるプロンプト、Slackでの良い運用や追加の機能、データベースを活用していない点などは今後改善していきたい。

その後

続きを書いた。

*1:数学や物理学などいくつかの分野の論文のプレプリントサーバー

*2:スクショは手動で実行した時のものなので投稿時刻は11時ではない

*3:gpt-4もAPI版が使えるようになるっぽいが、用途とコスパを考えるとgpt-3.5-turboで十分に思える