Redmineに埋もれたナレッジをChatGPT APIで問い合わせて再利用する方法

# はじめに

複数のデータベースに埋もれてしまっているナレッジをChatGPTを利用していつでも取り出して再利用できる環境を整えたい。まずはRedmineのプラグインである[Knowledgebase](https://github.com/alexbevi/redmine_knowledgebase)の内容をOpenAIのGPTで扱うことを試みる。

# 結論
ナレッジを取り出して再利用するために、RedmineのKnowledgebaseを利用し、OpenAIのGPTを使用して質問と回答の実験を行った。質問に対応したナレッジを検索しGPTに与えることでGTPが適切な回答を出力できることを確認した。

|  | 質問 | 回答 |
|:-:|:-|:-|
| 1  | ラズパイでスクリーンショットを撮りたい  |  以下の手順でラズパイでスクリーンショットを撮ることができます。1\. ラズパイにログインし、ターミナルを開きます。...
| 2  |  ナレッジDBをexportしたい | この場合、30分で作成されたエクスポートスクリプトを使用することができます。手順は以下の通りです。...  |


# 用意するもの
本記事では実行環境としてGoogle Colabを利用する
* Google Colab アカウント　: https://colab.research.google.com/?hl=ja
* OpenAI API キー : https://openai.com/blog/openai-api


# 前提
下記のページに記載している内容は省く

https://qiita.com/rairaii/items/5e4ad7e66730c50dd7c6


# Knowledgebaseのデータを取り込む

Redmineのプラグインである[Knowledgebase](https://github.com/alexbevi/redmine_knowledgebase)のデータをRedmineのIssueチケットのようにCSV形式で一括ダウンロードしたい。

### データをExportする仕組みがない
驚いたことにKnowledgebaseのデータをExportするための仕組みが用意されていないようだ。

### ブラウザ経由で力技でデータを取り込む
Webブラウザの操作を自動化するフレームワークである[Selenium](https://qiita.com/Chanmoro/items/9a3c86bb465c1cce738a)を使って力技でKnowledgebaseのデータをCSV形式で保存することにした。 M1 MacBook で動作確認したプログラムを示しておく。

:::note
取り込んだデータを下記のようにCSV形式で`knowledge_db.csv`ファイルに保存しGoogle Colabへアップロードする
| subject | description | source |
|:-:|:-:|:-:|
| タイトル 1  | 記事の内容 1  | 元データのURL 1  |
| タイトル 2  |  記事の内容 2 | 元データのURL 2  |
| ...  | ...  | ...  |
:::


https://github.com/aRaikoFunakami/scraping_knowledgebase


# GPTを利用して埋もれたナレッジを取り出す

### 必要なライブラリをGoogle Colabの環境にインストールする

```python: Google Colab　commands
%%writefile requirements.txt
openai
tiktoken
chromadb
langchain
%pip install -U requests
%pip install -r requirements.txt
```

### ソースコード
CharacterTextSplitterのセパレータがデフォルト値 `"\n\n"` だとchunk_sizeが大きくなりgptの許容値を頻繁に越えるため `"\n"` に変更した。
```python: source code
import os
import platform

import openai
import chromadb
import langchain

from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationalRetrievalChain
from langchain.document_loaders.csv_loader import CSVLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.text_splitter import RecursiveCharacterTextSplitter

# load 
loader = CSVLoader(file_path='./knowledge_db.csv',  source_column='source')
data = loader.load()

text_splitter = CharacterTextSplitter(
    separator = "\n",  # セパレータ
    chunk_size = 1000,   # チャンクの文字数
    chunk_overlap  = 0,  # チャンクオーバーラップの文字数
)

docs = text_splitter.split_documents(data)

# Preprocessing for using Open　AI
os.environ["OPENAI_API_KEY"] = '<Your API Key>' 
openai.api_key = os.getenv("OPENAI_API_KEY")
llm = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo")
embeddings = OpenAIEmbeddings()

# Stores information about the split text in a vector store
vectorstore = Chroma.from_documents(docs, embedding=embeddings, persist_directory=".")
vectorstore.persist()

# IF for asking OpenAI
csv_qa = ConversationalRetrievalChain.from_llm(llm, vectorstore.as_retriever(), return_source_documents=True)
```

## 質問1と回答
```python: 質問1　ラズパイでスクリーンショットを撮りたい
# Question
query = 'ラズパイでスクリーンショットを撮りたい'
chat_history = []

result = csv_qa({"question": query, "chat_history": chat_history})
print(result["answer"])
```


:::note info
[GPTが作成した回答]
以下の手順でラズパイでスクリーンショットを撮ることができます。
1\. ラズパイにログインし、ターミナルを開きます。
2\. 以下のコマンドを入力して、scrotをインストールします。
```
sudo apt install scrot
```
3\. 以下のコマンドを入力して、スクリーンショットを撮影します。
```
scrot
```
4\. スクリーンショットが保存されます。
:::

```python: 回答に利用した元データを確認する
# Review the original set of texts related to the above responses.
for doc in result['source_documents']:
  print(doc.page_content.split('\n', 1)[0])
  print(doc.metadata)
```

GPTは主に`RaspberryPi3 でのスクリーンショット取得方法` というタイトルを持つ記事を利用して回答を作成していた。記事内に`ラズパイ`や`スクリーンショット`というキーワードが含まれておりGPTに必要な記事を渡せたようだ。

## 質問2と回答
```python: 質問2 ナレッジDBをexportしたい
# Question
query = 'ナレッジDBをexportしたい'
chat_history = []

result = csv_qa({"question": query, "chat_history": chat_history})
print(result["answer"])
```

:::note info
[GPTが作成した回答]
この場合、30分で作成されたエクスポートスクリプトを使用することができます。手順は以下の通りです。
1. カテゴリのtableのHTMLをdevtoolsでコピーする。 https://省略/knowledgebase/categories/124
2. ChatGPTにHTMLを送信して、「このHTMLからURLのリストを取得してください」とリクエストします。
3. URLのリストをChatGPTに送信して、「これらのURLのリストからPDFをダウンロードして、devtoolsで実行してください」とリクエストします。
4. DevToolsにJSを送信して、PDFをダウンロードします。
この手順に従うことで、ナレッジDBをPDF形式でエクスポートすることができます。ただし、この手順はChatGPTによって作成されたものであり、実際に使用する場合は注意が必要です。
:::

GPTは`Knowledgebase の PDF 一括エクスポート方法（を ChatGPT に30分で作ってもらった）`というタイトルの記事を利用して回答を作成していた。