ChatGPT APIでConfluenceの内容を利用してみる

これは、[GO Inc. Advent Calendar 2023](https://adventar.org/calendars/8633)の21日目の記事です。

皆さんの会社では、仕事にまつわるドキュメントは何で管理をしていますか？GO株式会社の『DRIVE CHART』の開発プロジェクトではConfluenceを活用しています。

Confluenceは便利ですが、さらに便利に活用するためにChatGPT APIにその内容を読み込ませて内容の要約をしてもらったり、必要な情報の入手に役立てることができると思います。この記事では、ConfluenceのAPIとChatGPT APIを併せて活用するための方法を紹介します。

# 1. Confluenceに関する各種情報の入手

### Confluenceのtoken
公式マニュアルの「API トークンの作成」を参考にConfluence APIを利用するために、API トークンを作成して入手してください。
https://support.atlassian.com/ja/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/


### スペースキーの確認
各スペースにはスペースキーと呼ばれる識別子が設定されています。利用しているページのURLを確認してみると
```
https://<your-confluence-domain>/wiki/spaces/<スペースキー>
```

のようになっているかと思いますが、この`<スペースキー>`と表示されている位置にある値がスペースキーです。

# 2. APIを使ってConfluenceの情報を入手する

まずはConfluence APIをPythonから呼び出すためのライブラリをインストールします。

```sh
pip install atlassian-python-api
```

### 事前準備
準備として利用しているConfluenceのドメイン、ユーザ名、tokenをセットしてください。

```python
from atlassian import Confluence
from bs4 import BeautifulSoup
from tqdm import tqdm

confluence_url = 'https://<your-confluence-domain>'
username = 'your-username@email-domain'
token = 'your-api-token'
space_key = 'target-space-key'

# Confluence インスタンスを初期化
confluence = Confluence(url=confluence_url, username=username, password=token)
```

### Confluenceを検索してインプットにする情報を得る
ここではタイトルから検索、本文から検索、の2種類の検索の仕方を紹介します。

#### タイトルから検索

```python
# 例：機械学習をタイトルに含むページ
search_text = "機械学習"
cql = f'type=page AND space={space_key} AND title~"{search_text}"'
response = confluence.cql(cql=cql, limit=100)
search_result_title = [{"id":c["content"]["id"],"title": c["content"]["title"]} for c in response["results"]]
```

#### 本文から検索

```python
# 例：機械学習を本文に含むページ
search_text = "機械学習"
cql = f'type=page AND space={space_key} AND text~"{search_text}"'
response = confluence.cql(cql=cql, limit=100)
search_result_page = [{"id":c["content"]["id"],"title": c["content"]["title"]} for c in response["results"]]
```

`search_result_title`や`search_result_page`の中身は下記のようなフォーマットになっています。

```
[{'id': 1, 'title': 'AAAAA'},
 {'id': 2, 'title': 'BBBBB'},
 {'id': 3, 'title': 'CCCCC'},
 {'id': 4, 'title': 'DDDDD'},
 {'id': 5, 'title': 'EEEEE'}]
 ```

### 検索した結果から1つ目のページの本文を取得する例
タイトル検索した結果の中から1つ目のページを読み込んで文字列にするコードはこちらです。

```python
def read_confluence_page(page_id):
    contents = confluence.get_page_by_id(page_id=search_result_title[0]["id"], expand='body.storage')
    soup = BeautifulSoup(contents["body"]["storage"]["value"], 'html.parser')
    return soup.text
```


### 複数ページの読み込み
前述のページ本文を取得する例を繰り返し適用し、文字列結合することで複数ページの情報をChatGPTに読み込ませる準備ができます。

```python
search_result_ids = [c["id"] for c in search_result_page]

contents = ""
for page_id in tqdm(search_result_ids):
    contents += read_confluence_page(page_id)
```

# 3. 入手したConfluenceのデータをChatGPTに投げて回答をもらう

### 事前準備
[**ここ**](https://help.openai.com/en/articles/4936850-where-do-i-find-my-api-key)を参考にOpenAIのAPI keyを入手してここにセットしてください。

```python
import os
import openai
from langchain.chat_models import ChatOpenAI
from langchain.schema import AIMessage, HumanMessage, SystemMessage

os.environ['OPENAI_API_KEY'] = 'openai-api_key'
openai.api_key = os.getenv("OPENAI_API_KEY")
```

### ChatGPTに問い合わせる
問い合わせ内容と入手した情報を関数に渡して回答を得るための関数です。

```python
def confluence_inquiry(inqury, contents, model='gpt-4-1106-preview'):
    chat = ChatOpenAI(model=model)
    query = "confluence contentsを読み込んで問い合わせに回答してください。"
    query += "[問い合わせ]\n"
    query += f"{inqury}\n"
    query += "[confluence contents]\n"
    query += contents
    messages = [
        SystemMessage(content="あなたはシステムの開発者です。顧客からの問い合わせに対して回答してください。"),
        HumanMessage(content=query)
    ]
    return chat(messages).content
```

この関数を使って実際に問い合わせを実行してみます。

```python
inquiry = "このサービスで利用されている機械学習モデルはどのようなものがありますか？"
message = confluence_inquiry(inquiry, contents)
```

これで、問い合わせに対してConfluenceの内容を参考にした回答を入手することができます！
このブログでは簡単のためにエラー処理等々のコードは省略していますので、本記事で紹介した処理を参考に皆さんもぜひChatGPT APIを活用してみてください！