QiitaGPT、爆誕！！ (の予感)

**みんなの大好きなQiitaがGPTになりました！**
わーい👏👏👏

となるといいですね。

Open AIのAPIを使用して、Qiitaの投稿（対象はChatGPTタグの指定があるもの）をもとに回答する仕組みを作りました。

https://qiita-gpt-git-main-moritalous.vercel.app/

![qiita-gpt.vercel.app_(1280x720) (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/bf750512-a5dd-df38-2802-204d5be012f1.png)

![qiita-gpt-git-main-moritalous.vercel.app_(1280x720).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/caf38552-a367-4cdb-f7a9-e2beb84dc7ee.png)


## 仕組み

[Supabase](https://supabase.com/)が公開している[Next.js OpenAI Doc Search Starter](https://github.com/supabase-community/nextjs-openai-doc-search)というVercel Templateを使用します。

詳細は[README.md](https://github.com/supabase-community/nextjs-openai-doc-search/blob/main/README.md#technical-details)を参照ください。


## 質問してみた

**Q:GPT4とはなんですか？**

> GPT-4とは、OpenAIが開発した自然言語処理モデルです。GPT-4は、自然言語処理タスクを自動化するための新しいツールです。GPT-4は、自然言語処理タスクを自動化するための新しいツールであり、自然言語処理タスクを自動化するための新しいツールです。GPT-4は、自然言語処理タスクを自動化するための新しいツールであり、自然言語処理タスクを自動化するための新しいツールです。GPT-4は、自然言語処理タスクを自動化するための新しいツールであり、自然言語処理タスクを自動化するための新しいツールです。

**Q:GPT4とGPT3の違いはなんですか？**

> GPT-4とGPT-3.5の違いは、トレーニングに使用されるデータ量がGPT-4の方が大きく、さらに高い性能を発揮することです。GPT-3.5のパラメーター数は1.75兆ですが、GPT-4のパラメーター数は1,750億です。また、GPT-4の回答の解像度がGPT-3.5よりも高いことも特徴です。詳細は論文参照 https://arxiv.org/abs/2005.14165

**Q:GPT4はどのような用途に使用できますか？ユースケースを5つ上げてください**

> GPT-4は以下のような用途に使用できます。 1. プログラムコードの生成 2. チャットボットの作成 3. 文章生成 4. 機械翻訳 5. 機械学習モデルの訓練

指定の通り、5つ回答してくれました。

**Q:GPT4でプログラムコードの生成を行うデモを示してください。**

> GPT-4を使用してプログラムコードを生成するデモを示すには、[ChatGPT](https://github.com/microsoft/ChatGPT)を使用します。ChatGPTは、GPT-3を使用して、自然言語からプログラムコードを生成するためのツールです。ChatGPTを使用すると、自然言語で指定したプログラムコードを生成することができます。例えば、以下のような自然言語で指定したプログラムコードを生成することができます。 ``` kintoneのコードを聞いてみます ``` 生成されたプログラムコードは以下のようになります。 ``` import kintone client = kintone.Client('https://example.cybozu.com', 'example@example.com', 'password') app = client.app('1') records = app.records.get() for record in records: print(record) ```


**GPT4の始め方を教えてください**

> GPT-4を使うには、まず[OpenAIのサイト](https://openai.com/research/gpt-4/)からモデルをダウンロードします。次に、プルダウンから「GPT-4」を選択して、GPT-4を利用できるようにします。最後に、GPT-4を使ってプロンプトを改良していきます。

**Q:プロンプトとはなんですか？**

> プロンプトとは、特定のシチュエーションに沿った文章や音声を生成するための文字列や言葉のことです。プロンプトを使用することで、日本語を自分自身で使って練習することができます。例えば、自己紹介や旅行の計画、食事の注文など、特定のシチュエーションに沿ったプロンプトを与えることで、日本語の練習ができます。また、日本語の文法や表現方法を学ぶためのプロンプトも用意されています。

**Q:GPT4を作ったのは誰ですか？**

> OpenAIがGPT-4を開発しました。詳しい情報は[OpenAIのGPT-4のページ](https://openai.com/research/gpt-4/)をご覧ください。

**Q:OpenAIについて詳しく教えてください。**

> OpenAIは、2015年にエリック・シュミット氏、イーサン・アシマー氏、ジョン・ピータース氏、ブロントン・ベンス氏、イーライ・ミスライ氏、サミ・ゼリック氏によって設立された非営利団体です。OpenAIの目的は、人工知能の技術を進展させ、人類の福祉を向上させることです。OpenAIの資金提供は、企業や個人からの寄付や、政府や非政府組織からの助成金などを通じて行われます。 OpenAI APIは、自然言語やコードを理解したり生成したりするタスクにほとんど適用できます。さまざまなタスクに適した異なる電力レベルのモデルを提供し、カスタマイズしたモデルの能力を微調整します。これらのモデルは、コンテンツ生成からセマンティック検索と分類までのすべての側面で使用できます。 OpenAIの代表的な成果の一つには、GPT（Generative Pre-trained Transformer）があります。GPTは、Chat GPTのベースとなった技術で、大量のテキストデータを学習して、自

途中で切れますね。

**Q:OpenAIの近況を教えてください。**

> OpenAIは、自然言語処理、画像処理、音声処理などの分野で最先端の技術を開発しています。代表的な成果の一つには、GPT（Generative Pre-trained Transformer）があります。GPTは、Chat GPTのベースとなった技術で、大量のテキストデータを学習して、自然言語生成タスクにおいて高い精度を発揮することができます。また、OpenAIは、画像生成や画像認識においても、最先端の技術を開発しています。

**Q:chatgptに関する日本国内の事例を教えてください。**

> ChatGPTを日本企業がどのように活用しているかについては、以下の記事が参考になります。 https://www.businessinsider.jp/post-265674?fbclid=IwAR1\_mN4vR-QHNWwXtDTIvK0GaoZzUO2DDyh8PlnzMzXZd1vSqwGRQWpYYxQ

BUSINESS INSIDERの公開日は2023/2/16です。Qiitaでは以下の投稿でリンクが紹介されていました。

https://qiita.com/nyanko5656/items/147e2f12dcb75e65b1e4

https://qiita.com/mayegg/items/569f31466a3bfcd13c88

https://qiita.com/bonjiko/items/d8d76fb3f25eea213a99

**Q:ChatGPTについてQiitaで行っているキャンペーンは？**

> キャンペーンとしては、[記事投稿キャンペーン\_ChatGPT](https://qiita.com/official-events/b80ebe828fa453edf260)があります。

同じ質問はChatGPTでは回答が得られませんでした。

![chat.openai.com_(1280x720).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/d5c9fb35-da93-c232-67bc-46ddcc638a39.png)

新しいBingでは回答がありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/367b5f03-1f8d-345d-0633-ef7e4babf9ac.png)


**Q:ChatGPTとLINEを組み合わせて活用するアイディアを示してください**

> ChatGPTとLINEを組み合わせて活用するアイディアとして以下のようなものがあります。
> 1. noteとChatGPTを組み合わせることで小説などを書いてもらい記事を投稿するサービス。
> 2. 家庭教師とChatGPTを組み合わせて受験生が問題をAIに聞き勉強を教えてもらうサービス。
> 3. 子供が気軽に質問できるようなサービス例(空はなぜ青いのか？) 
> 4. 悩み事を相談するサービス悩みを聞いてその解決策をChatGPTに答えてもらう。
> 5. 作業の効率化用のアプリをChatGPTに作ってもらうサービス。例(Excelの自動化)

以下の投稿と同じ内容ですね。

https://qiita.com/kensaka1228/items/5f4094e11caf855ecc9c

6つ目のアイディアが出るか見てみましょう。

**Q:ChatGPTとLINEを組み合わせて活用するアイディアを6つ示してください。**

> 1. チャットボットを作成して、LINE上で質問に答えてもらうサービス。 
> 2. チャットボットを作成して、LINE上で質問に答えてもらうサービス。 
> 3. チャットボットを作成して、LINE上で質問に答えてもらうサービス。 
> 4. チャットボットを作成して、LINE上で質問に答えてもらうサービス。
> 5. チャットボットを作成して、LINE上で質問に答えてもらうサービス。
> 6. チャットボットを作成して、LINE上で質問に答えてもらうサービス。

ん？全部同じこと言ってる？



## QiitaGPTの作り方

[Next.js OpenAI Doc Search Starter](https://github.com/supabase-community/nextjs-openai-doc-search)を使ってサイトを作成します。

1. Next.js OpenAI Doc Search StarterのGitHubリポジトリへアクセス
    
    https://github.com/supabase-community/nextjs-openai-doc-search

1. `Deploy`ボタンをクリック

    ![github.com_moritalous_qiita-gpt(1280x720).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/70a787da-6392-c23c-5bce-3accfe9e70e2.png)

1. `Create`ボタンをクリック

    ![vercel.com_new_clone_demo-title=Next.js%20OpenAI%20Doc%20Search%20Starter&demo-description=Template%20for%20building%20your%20own%20custom%20ChatGPT%20style%20doc%20search%20powered%20by%20Next.js%2C%20OpenAI%2C%.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/c71769ba-fdbe-32ae-3cf7-3a36f0eadfc1.png)

1. `Add`ボタンをクリック

    ![vercel.com_new_clone_demo-title=Next.js%20OpenAI%20Doc%20Search%20Starter&demo-description=Template%20for%20building%20your%20own%20custom%20ChatGPT%20style%20doc%20search%20powered%20by%20Next.js%2C%20OpenAI (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/24da3f89-bd5e-0017-fe32-c702055f1659.png)

1. Supabaseのプロジェクトを作成します。`Deploy`ボタンをクリック

    ![スクリーンショット 2023-04-15 090556.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/07412d81-42b7-18f9-d5ce-1d891eb033f2.png)

1. データベースのパスワードを入力し`Create project`ボタンをクリック

    ![スクリーンショット 2023-04-15 090655.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/b3562b8b-9c20-6e81-9e8d-c33c81918fce.png)

1. Supabaseプロジェクト作成中。`Finish`ボタンをクリック

    ![スクリーンショット 2023-04-15 091057.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/c4724385-d88e-61c5-ee22-dce18d8bb8e4.png)

1. Vercelのウィザードに戻ります。OpenAI API keyを入力し、`Deploy`ボタンをクリック
    ![vercel.com_new_clone_demo-title=Next.js%20OpenAI%20Doc%20Search%20Starter&demo-description=Template%20for%20building%20your%20own%20custom%20ChatGPT%20style%20doc%20search%20powered%20by%20Next.js%2C%20OpenAI (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/d9715071-95b8-d9ea-c014-8547fed70fd3.png)

    デプロイ中

    ![vercel.com_new_clone_demo-title=Next.js%20OpenAI%20Doc%20Search%20Starter&demo-description=Template%20for%20building%20your%20own%20custom%20ChatGPT%20style%20doc%20search%20powered%20by%20Next.js%2C%20OpenAI (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/73110dbc-9b47-b961-961c-f24e7094326e.png)

    デプロイ完了

    ![vercel.com_new_clone_demo-title=Next.js%20OpenAI%20Doc%20Search%20Starter&demo-description=Template%20for%20building%20your%20own%20custom%20ChatGPT%20style%20doc%20search%20powered%20by%20Next.js%2C%20OpenAI (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/f28aad80-5327-cd60-12d7-59d415c1e05f.png)

プロジェクトダッシュボードでURLが確認できます。

![vercel.com_new_clone_demo-title=Next.js%20OpenAI%20Doc%20Search%20Starter&demo-description=Template%20for%20building%20your%20own%20custom%20ChatGPT%20style%20doc%20search%20powered%20by%20Next.js%2C%20OpenAI (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/51842e56-eed1-ce9e-2446-536996498318.png)

デプロイした画面

![qiita-gpt.vercel.app_(1280x720).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/a008b830-6a1a-d4d7-6296-1a19ac3b5e33.png)

サンプルで登録されているドキュメントの内容を検索します。

![qiita-gpt.vercel.app_(1280x720) (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/939a590d-c70d-e803-2617-956a898c6ef4.png)

<details><summary>サンプル登録されているドキュメント</summary>

```markdown:openai_embeddings.mdx
# OpenAI Embeddings

OpenAI embeddings are pre-trained language models used for natural language processing tasks. These models are built using deep learning algorithms and can be fine-tuned for specific tasks. OpenAI provides several pre-trained embeddings, including GPT-2, GPT-3, and BERT. Each of these models has a different number of parameters and can be used for different tasks.

To use OpenAI embeddings, you can install the OpenAI API and authenticate with your API key. Then, you can load the desired OpenAI embedding model and use it for your NLP task. For example, you can generate text using the model by calling the completions method.

OpenAI embeddings are trained on large amounts of text data and are designed to capture the meaning of words and phrases in a way that is useful for downstream NLP tasks. This is achieved through a process called unsupervised learning, where the model learns from the patterns in the data without being explicitly trained on a specific task.

Once trained, OpenAI embeddings can be used for a variety of NLP tasks, such as text classification, sentiment analysis, and language translation. In addition, they can be fine-tuned for specific tasks by providing additional training data and adjusting the model's parameters.

OpenAI provides several pre-trained embedding models with varying sizes and capabilities. GPT-2 and GPT-3 are both transformer-based models that are well-suited for language generation tasks, such as text completion and question answering. BERT, on the other hand, is a bidirectional encoder that is particularly useful for tasks that require understanding the relationship between different words in a sentence, such as sentiment analysis and named entity recognition.

Overall, OpenAI embeddings are a powerful tool for NLP tasks and have been used to achieve state-of-the-art performance on a wide range of benchmarks and applications.

## Storing Embeddings in Postgres

`pgvector` is a Postgres extension that provides support for vector operations, including similarity search and nearest neighbor search. It allows you to store vectors as columns in a database table and perform vector operations on them using SQL queries.

One interesting use case of `pgvector` is to use it in conjunction with OpenAI embeddings. Since OpenAI embeddings represent words and phrases as high-dimensional vectors, you can store these vectors in a pgvector column and use the extension's similarity search capabilities to find similar words or phrases in a large dataset.

For example, let's say you have a database of customer reviews and you want to find all the reviews that mention a particular product. You could use OpenAI embeddings to represent each review as a vector and store these vectors in a pgvector column. Then, you could perform a similarity search to find all the reviews that are similar to the vector representing the product name.

This approach can be very powerful for applications that involve large amounts of text data, as it allows you to perform complex queries on the data using vector operations. However, it does require some additional setup and configuration compared to traditional SQL queries, so it may not be suitable for all use cases.
```
</details>

## Qiitaの投稿を取得

動作するところまで構築できました。独自のドキュメントとしてQiitaの投稿を使用してみようと思います。


### Qiita APIの使い方

[Qiita API v2](https://qiita.com/api/v2/docs)を使用してQiitaの投稿をクロールします。
`chatgpt`タグがついている投稿を取得する場合は、`https://qiita.com/api/v2/items?query=tag:chatgpt`へリクエストを投げるとJSONが取得できます。


### Qiitaトークンの取得

Qiita API v2には以下の制限があります。

* 認証している状態ではユーザーごとに1時間に1000回まで、認証していない状態ではIPアドレスごとに1時間に60回まで

たくさん投稿を集めたいので認証することにします。

1. [ユーザーの管理画面](https://qiita.com/settings/applications)にアクセスします。
    
    ![qiita.com_settings_applications(1280x720).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/94de7cb3-5c34-ba37-b421-d5ba14c72f32.png)

1. `個人用アクセストークン新しくトークンを発行する`をクリックします。
    
    ![qiita.com_settings_tokens_new(1280x720).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/266390fe-f9bd-47bb-23e3-39a6499b6966.png)

1. アクセストークンの説明を入力し、`read_qiita`にチェックを入れ、`発行する`ボタンをクリックします。

### クロール実行

cURLでJSONを収集します。

```shell
TOKEN=...

for i in $(seq 1 100); do \
  curl -H "Authorization: Bearer ${TOKEN}" "https://qiita.com/api/v2/items?query=tag:chatgpt&per_page=100&page=$i" -o items/$i.json ; \
  sleep 1;
done
```

### Markdownを分割してファイル化

1つのJSONに複数の投稿が含まれているので、Markdown部分だけを抽出して、個々のファイルに分割します。

<details><summary>JSONの構造</summary>

```json
[
  {
    "rendered_body": "<h1>Example</h1>",
    "body": "# Example",
    "coediting": false,
    "comments_count": 100,
    "created_at": "2000-01-01T00:00:00+00:00",
    "group": {
      "created_at": "2000-01-01T00:00:00+00:00",
      "description": "This group is for developers.",
      "name": "Dev",
      "private": false,
      "updated_at": "2000-01-01T00:00:00+00:00",
      "url_name": "dev"
    },
    "id": "c686397e4a0f4f11683d",
    "likes_count": 100,
    "private": false,
    "reactions_count": 100,
    "stocks_count": 100,
    "tags": [
      {
        "name": "Ruby",
        "versions": [
          "0.0.1"
        ]
      }
    ],
    "title": "Example title",
    "updated_at": "2000-01-01T00:00:00+00:00",
    "url": "https://qiita.com/Qiita/items/c686397e4a0f4f11683d",
    "user": {
      "description": "Hello, world.",
      "facebook_id": "qiita",
      "followees_count": 100,
      "followers_count": 200,
      "github_login_name": "qiitan",
      "id": "qiita",
      "items_count": 300,
      "linkedin_id": "qiita",
      "location": "Tokyo, Japan",
      "name": "Qiita キータ",
      "organization": "Qiita Inc.",
      "permanent_id": 1,
      "profile_image_url": "https://s3-ap-northeast-1.amazonaws.com/qiita-image-store/0/88/ccf90b557a406157dbb9d2d7e543dae384dbb561/large.png?1575443439",
      "team_only": false,
      "twitter_screen_name": "qiita",
      "website_url": "https://qiita.com"
    },
    "page_views_count": 100,
    "team_membership": {
      "name": "Qiita キータ"
    },
    "organization_url_name": "qiita-inc"
  }
]
```

</details>

以下のようなPythonスクリプトを作成しました。

```python:python
import os
import json

def main():

    for file_name in os.listdir("items"):
        if file_name.endswith(".json"):

            with open("items/" + file_name, "r") as f:
                item_json = json.load(f)

            for i, item in enumerate(item_json):
                body = item['body']

                with open(f"output/{file_name}_{i}.md", "w") as f:
                    f.write(body)

if __name__ == "__main__":
    main()
```

これでQiitaの投稿をMarkdownで取得することができました。


## 独自ドキュメントをデータベースに登録

収集した投稿をデータベースに登録します。

`npm run build`を行うと自動で`embeddings`（tsx lib/generate-embeddings.ts）が実行されるようになっており、`docs`ディレクトリ配下のMarkdownファイルがSupabaseのデータベースに登録される仕組みです。

### Gitリポジトリをクローン

Vercelでプロジェクトを生成した際にGitHubにリポジトリが作成されていますので、まずローカルにクローンします。

```
git clone https://github.com/moritalous/qiita-gpt.git
```

### embeddings処理にSleepを追加

Open AI APIのレートリミットに引っかかるので、Sleep処理を追加します。

```diff_typescript:lib/generate-embeddings.ts
+ function sleep(ms: number): Promise<void> {
+   return new Promise(resolve => setTimeout(resolve, ms));
+ }
```
```diff_typescript:lib/generate-embeddings.ts
      for (const { slug, heading, content } of sections) {
        // OpenAI recommends replacing newlines with spaces for best results (specific to embeddings)
        const input = content.replace(/\n/g, ' ')

        try {
          const configuration = new Configuration({
            apiKey: process.env.OPENAI_KEY,
          })
          const openai = new OpenAIApi(configuration)

          const embeddingResponse = await openai.createEmbedding({
            model: 'text-embedding-ada-002',
            input,
          })

          if (embeddingResponse.status !== 200) {
            throw new Error(inspect(embeddingResponse.data, false, 2))
          }

          const [responseData] = embeddingResponse.data.data

          const { error: insertPageSectionError, data: pageSection } = await supabaseClient
            .from('nods_page_section')
            .insert({
              page_id: page.id,
              slug,
              heading,
              content,
              token_count: embeddingResponse.data.usage.total_tokens,
              embedding: responseData.embedding,
            })
            .select()
            .limit(1)
            .single()

          if (insertPageSectionError) {
            throw insertPageSectionError
          }
        } catch (err) {
          // TODO: decide how to better handle failed embeddings
          console.error(
            `Failed to generate embeddings for '${path}' page section starting with '${input.slice(
              0,
              40
            )}...'`
          )

          throw err
        }

+       await sleep(500)
      }
```

変更をコミットし、GitHubへプッシュすると、Vercelのビルド処理が自動実行されます。

![vercel.com_new_clone_demo-title=Next.js%20OpenAI%20Doc%20Search%20Starter&demo-description=Template%20for%20building%20your%20own%20custom%20ChatGPT%20style%20doc%20search%20powered%20by%20Next.js%2C%20OpenAI (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/72924b45-4723-cece-07a8-2c9cb2059bc8.png)

:::note
Vercelの一度のビルド時間は45分迄の制限があります。
100投稿のembeddings処理でおおよそ10分強かかりますので、小分けにプッシュします。
:::


## まとめ

お試しで試すには十分な成果が確認できたと思います。

**Qiitaの全投稿でやったらどうなるか、なかなか夢がありますね。**