ChatGPTと協創！arXiv論文要約ツールを作ってみた

# はじめに

こんにちは。(株) 日立製作所の [Lumada Data Science Lab.](https://www.hitachi.co.jp/products/it/lumada/about/ai/ldsl/index.html) の諸橋 政幸です。

最近、AI技術の進歩により、様々なタスクが効率化されています。その中でも、**「ChatGPT」** は自然言語処理の分野で革新的な成果を上げており、大きな注目を集めています。
今回は、このChatGPTを活用してarXiv論文の要約を生成する簡易ツールを作成してみたので、そのプロセスを共有します。本記事の構成は以下のとおり。

1. ChatGPTにやりたいことを伝えてみる
2. 生成コードを修正して期待通り動くようにする
3. ツール名も考えてもらう

とにかく **「ChatGPTに積極的に頼る！」** をコンセプトにして作りました。
土日に趣味でやったのでツールのレベルや実用性については深く考えないでください！

# その前に自己紹介（＋本のアピール）

私は日立製作所で顧客課題をデータ分析を使って解決する業務を行っています。
⇒ [紹介ページ](https://social-innovation.hitachi/ja-jp/article/people-datascientist/) （[youtube動画](https://www.youtube.com/watch?v=pVVa-2mgeJ8)）
趣味は分析コンペです。書籍も書いているので良ければ読んでみてください！

- [書名] **Kaggleで磨く 機械学習の実践力** -- 実務xコンペが鍛えたプロの手順
- [https://www.amazon.co.jp/dp/4865943269](https://www.amazon.co.jp/dp/4865943269)

# 1. ChatGPTにやりたいことを伝えてみる

まずは、開発したいツールの概要をChatGPTに伝えます。今回は「arXiv論文の要約を生成するツール」を作成することにしました。背景としては、技術情報を調査する際、数多くのarXiv論文から重要そうなものを効率的に見極めたいなと思ったからです。
ということで、実現してほしいことをテキストで書き、ChatGPTに投げかけてコードを生成してもらいました。

具体的には、こんなプロンプト（＝ChatGPTに指示するテキストのこと）を投げかけました。

```
### やりたいこと ###
1. 利用者がキーワードを入力
2. 入力したキーワードに関連する論文のpdfをarxivからダウンロード
3. ダウンロードしたpdfファイルをテキストデータ化
4. ChatGPT APIを使って論文の内容を要約して箇条書きする
5. 論文のタイトル，URL，要約（箇条書き），を表でまとめて出力する

### 利用ツール ###
- python
- gradio
- ChagGPT API

これを実現するツールを作ってください。
```

こんなふんわりした日本語のテキストでも、以下のようなそれっぽいコードを生成してくれます。

```
import gradio as gr
import openai
import arxiv
import PyPDF2
from io import BytesIO
import requests

# APIキーの設定
openai.api_key = "<your_api_key>"

def summarize_paper(keyword):
    # 論文の検索とダウンロード
    search_query = f"all:{keyword}"
    results = arxiv.query(search_query, max_results=3)

    summaries = []

    for result in results:
        # PDFをダウンロード
        pdf_url = result['pdf_url']
        response = requests.get(pdf_url)
        pdf_file = BytesIO(response.content)

        # PDFをテキストに変換
        pdf_reader = PyPDF2.PdfFileReader(pdf_file)
        text = ""
        for page_num in range(pdf_reader.numPages):
            text += pdf_reader.getPage(page_num).extractText()

        # 論文の要約を生成
        prompt = f"Summarize the following paper in bullet points:\n{text}"
        response = openai.Completion.create(
            engine="text-davinci-002",
            prompt=prompt,
            max_tokens=150,
            n=1,
            stop=None,
            temperature=0.7,
        )

        summary = response.choices[0].text.strip()

        # タイトル、URL、要約を保存
        summaries.append({
            "Title": result['title'],
            "URL": pdf_url,
            "Summary": summary
        })

    return summaries

def display_summary(summaries):
    output = ""
    for summary in summaries:
        output += f"Title: {summary['Title']}\n"
        output += f"URL: {summary['URL']}\n"
        output += f"Summary:\n{summary['Summary']}\n\n"
    return output

iface = gr.Interface(
    fn=summarize_paper,
    inputs=gr.inputs.Textbox(lines=1, label="Keyword"),
    outputs=gr.outputs.Textbox(label="Summarized Papers"),
    title="Paper Summarizer",
    description="Enter a keyword to search for related papers on arXiv, and get summarized bullet points for each paper.",
)

iface.launch()
```

おおー、とりあえずそれっぽい！！

と思いましたが、残念ながらこのコードはエラーだらけで動きません。。。

# 2. 生成コードを修正して期待通り動くようにする

次に、ChatGPTから得られたコードをもとに、期待通りの動作をするように修正を加えていきます。生成したコードは「それっぽい」ですが、とにかく動きません。。。また、出力形式が表になっていないなど、一部期待した処理になってませんでした。
このあたりは私のプロンプトの書き方が悪いせいかもしれません。

そこで、期待通りに動かすために、いくつか修正しました。修正点を3つに絞って説明します。

## 2-1. ライブラリ・関数の修正（知識が若干古い）
コード実行時にエラーが出た場合、エラーメッセージをChatGPTにコピペすれば直し方まで回答してくれます。
しかし、ChatGPTの学習では2021/9までのデータしか使っていないため、適切な回答が出来ない場合があります。

たとえば、今回の例だと、```arxiv.query()```は現行バージョンでは存在しないため、```arxiv.Search()```に変える必要があります。
これは、今のChatGPTにいくら聞いても正しいやり方が返ってこないので、公式ページやGoogle検索で調べて対応しました。

ちなみに、ChatGPTは「存在しない関数」を平気な顔して回答してきたりします。
知らなくても怒らないので、素直に「分かりません」と言ってほしいです。。。

## 2-2. 要約を指示するプロンプトのブラッシュアップ

色々な箇所を修正することで、コードがエラーなく実行できるようにはなりました。しかし、私のイメージとしては短い文章でポイントだけを出力してくれるイメージだったのですが、生成される要約文が「想定していたよりも長い」という課題がありました。
これも私の最初のプロンプトが悪かったのだと思います。

そこで、以下のように細かく指示するように変えました。（{text}は論文の本文です）
どのようなプロンプトを書けば期待するような要約文が生成されるかが分からなかったので、「プロンプト作成 -> 要約文の生成 -> 期待する要約文かを確認」というサイクルを何度も繰り返して、最終的にこのようなプロンプトに到達しました。
なかなか言うことを聞かないのでちょっと（かなり？）苦労しました。
なお、このプロンプトを使っても、文字数制限を超えたり、句読点を使ってきたりして、完全には言うことを聞いてくれないです。
このあたりはノウハウが必要そうですね。

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

### 箇条書きの制約 ###
- 最大3個
- 日本語
- 箇条書き1個を20文字以内
- カンマは使用禁止
- 「。」は使用禁止
- 文章の終わりは体言止め（体言止めの例： ｘｘを許容する ⇒ ｘｘを許容）

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

### 出力形式 ###
タイトル(和名)

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

あと注意点としては、モデルによって入力できるトークン長の上限が決まっているので（gpt-3.5-turboだと4,096トークン）、それを超える文は入力できません。このため、論文の全文ではなく、冒頭のサマリ部分のみを抽出して箇条書きするように変えました。
また、モデルが```text-davinci-002```となっていたので、```gpt-3.5-turbo```に変えました。

```
# ChatGPT APIを呼び出すコード
response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[
        {"role": "system", "content": "あなたはデータサイエンティストの熟練者です。初学者向けに分かりやすく教えるのが得意なスペシャリストです。"},
        {"role": "user", "content": prompt},
        ],
    temperature=0.0,
)
```

## 2-3. 入出力画面の調整

ChatGPTに「出力を表にして」とお願いしていますが、よく見ると全然そんなコードになってません。ここについては再度そこを強調してChatGPTに依頼してコードを書いてもらいました。
方法としては、辞書型の出力結果をHTML形式に変換し、さらにGradioのoutputsをHTML形式に変更しました。Gradioを使ったことがなかったですが、使い方を含めてChatGPTと相談しながら進めました。
コードをどう書き直したらいいかを質問すれば、すぐに修正コードを提示してくれるので本当に頼りになります（動かないコードなこともありますが）。

```
# インターフェイスのレイアウトをカスタマイズ
iface = gr.Interface(
    fn=summarize_paper,
    inputs=[
        gr.components.Textbox(label="技術情報のキーワード"),
        gr.components.Textbox(label="検索論文数"),
        gr.components.Radio(choices=["gpt-3.5-turbo", "gpt-4"], value="gpt-3.5-turbo", label="利用する生成AIモデル"),
        gr.components.Slider(minimum=0, maximum=1, label="temperature"),
        ],
    outputs=gr.components.HTML(label="Summarized Papers"),
    title="arXiv論文要約AI (by Moro)", #"arXivの調査 (by Moro)",
    description="調べたい技術情報のキーワードと，ピックアップして要約する論文数を指定してください。\n - AIで関連キーワードを自動生成して検索に利用 \n - 検索でヒットした論文を要約してポイントを箇条書き",
    theme="default",
    allow_flagging='never',
)
```


作成したWebアプリの画面：
![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2323189/4ba93b44-fef5-dc00-4199-686e26a5ee0c.png)

# 3. ツール名を考えてもらう

せっかくなので、ツールの名称もChatGPTに考えてもらいました。機能の概要を入れて、「いくつかのツール名称のアイデアを出して」とお願いしてみました。

```
- GPT-IntellectWave: ArXiv Scholarly Navigator
- ArxivSage: ChatGPT-Enhanced Academic Assistant
- GPT-Cerebrum: ArXiv Wisdom Explorer
- ArxivMentor: AI-Powered Knowledge Curator
```

ん－、やっぱり日本語がいいな。

```
- Arxivキーワード&要約マスター: ChatGPT研究アシスタント
- Arxiv知の連鎖: AI搭載キーワード発見と論文要約
- Arxiv論文ピックアップ&要点整理: AI搭載研究サポーター
- Arxiv要約エキスパート: 論文ピックアップと要点整理のAIガイド
```

ん－、長い。。

```
- arXiv技術情報収集アシストAI
- arXivAI技術情報収集アシスト
- arXiv技術情報収集アシスト+: AI搭載
- arXiv技術情報収集アシストPro: AI生成
```

シンプルな方がやっぱりいい気がする。
ということで、最終的には「arXiv論文要約AI」にしました。最終判断はやはり作り手の感性ですね。

# さいごに

今回簡単なツールですが、ChatGPTと協力して1つのツールを開発してみました。
Webアプリ開発未経験でしたが、何とか動くものを作成できました。半日くらいで完成しているので、かなり効率化できてると思います。
というか、ChatGPT無しだったら動くものを作れずに挫折していた気がします。

やりたいことを抽象的なレベルで書くだけで、コード生成までしてくれるのは本当に革命です。
その上、細かい相談もできるし、力強い味方ができた気持ちです。ただ、本当に期待することを実現できるところまで持っていくには、使い手側にもある程度の知識やノウハウが必要だなとも思いました。

ChatGPTを実際に使ってみて、あんなことも出来そうだとか、こんなのも作ってみたいとか、さらに想像と期待がふくらみました。このようなAI技術を利用することで、タスクの効率化だけでなく、アイデア創出・新たな発見や革新にもつながると感じました。
最後まで読んでいただき、ありがとうございました。この記事が、ChatGPTを活用したツール開発に興味を持つ方々にとって、貴重な情報やインスピレーションを提供できていたら嬉しいです。


ちなみに、当然ながら？、この記事も原案はChatGPTに書いてもらってます。ふわっとした指示でこんな感じの文章を生成できるってホントにすごいですね。