kintone開発者コミュニティに生成AIを導入してみた

本記事は、「kintone Advent Calendar 2024」の10日目の記事です。

この度、kintone技術者が集う「**cybozu developer network community**」に対して生成AIの導入を試してみました。
私は、サイボウズでこのコミュニティ運営を担当しているチームの1人です。

:::note info
まだ検証段階で、実際に導入はしていません。
コミュニティサイトを開いても反映されていませんのでご注意ください。

追記
①関連トピックをAIで表示する → 実際にコミュニティサイトに導入しました:clap:
:::

# はじめに
kintoneを使っていて困ったとき、
**解決策に辿り着く時間をもっと短縮したいと思ったことはありませんか？**

「コミュニティを使ったことはあるけど、うまく回答を探し出せない:weary::droplet:」

そんな方のために、生成AIを有効活用できないだろうか？
と考え、コミュニティへの生成AI導入を検討しています。
この記事では、その取り組み内容をご紹介します。

また、Discourseを使ってコミュニティサイトを運営している方の参考にもなるように、サイトの設定方法も詳しく書いておこうと思います。

# cybozu developer network communityとは
cybozu developer network communityは、kintoneやGaroonを使って開発を行なっている技術者同士で、困りごとや悩みを相談できるオンラインコミュニティです:speech_balloon:

https://community.cybozu.dev/

kintoneなどサイボウズ製品についてわからないことを質問すると、有識者から回答をもらうことができます。

kintoneのカスタマイズ開発をしている方なら、一度はこのサイトをご覧になったことがあるかと思いますが、このサイトの裏側は実は、[Discourse](https://www.discourse.org/)というオンラインコミュニティのオープンソースプラットフォーム上で動いています。

https://www.discourse.org/

# DiscourseのAI

Discourseには、自分たちのコミュニティサイトに生成AIを導入できる便利なプラグインが色々あります。

https://www.discourse.org/ai

しかし、日本語の情報はほぼなく、日本語のコミュニティサイトでどれだけ実用性があるかわかりませんでした。
そこで、今回は、**コミュニティの検索性の向上**を目的に2つの検証を行います。

- 関連トピックをAIで表示する
- サイト内検索にAI検索を追加する

それでは、実際に試した内容について詳しく書いていきます！

# 検証① 関連トピックをAIで表示する

まずは、関連性の高いトピックをAIが提案してくれる機能を検証しました。

## 設定方法

Discourse管理者の設定画面を開き、AIの設定タブを開きます。
以下の項目を設定します。

| 設定項目 | 説明 | 設定した内容 |
|:-----------|:------------|:------------|
| ai embeddings enabled      | エンベディングを有効にするか  | 有効         |
| ai embeddings models     | エンベディングの生成に使用するモデルを選択する | multilingual-e5-large|
| ai embeddings semantic related topics enabled    | 関連トピックを有効にするか | 有効|
| ai embeddings semantic related topics    | 関連トピックに表示する最大トピック数 | 5|
| ai embeddings generate for pms    | プライベートメッセージの埋め込みを生成するかどうか | 無効|
| ai embeddings semantic related include closed topics  | クローズ済みトピックを含むか | 有効|

ポイントは、`ai embeddings models` の指定です。
このモデルを何にするかによって、計算方法が変わるので、表示される関連トピックの精度も変わってきます。Discourseでの関連トピックは、トピックのタイトル、カテゴリ、タグ、投稿内容を含むembeddings（埋め込み）に基づいて計算され、表示されます。

`ai embeddings generate for pms`は、AIがプライベートメッセージ（DM）の内容を理解し、メッセージの内容や意図を解析する対象に含むかという設定です。これは本来、プライベートなやり取りのため、AIがこれらの内容を解析することにはプライバシーへの懸念が伴いますので無効にしています。

`ai embeddings semantic related include closed topics`は、解決済みにされてクローズ済みになったトピックをAIが解析する対象に含むかという設定です。私達の場合、開発者コミュニティという特色上、解決済みのトピックも役に立つので有効にしましたが、コミュニティによってはスレッドがオープンなトピックのみにするのが適しているケースもありそうです。

### Embedding（埋め込み）とは
設定項目に並んでいた耳慣れない「embeddings」について、簡単に解説します。

Embeddingについて、3行でまとめると

- Embeddingは、自然言語処理や機械学習の分野において重要な概念で、単語や文章といった自然言語の情報を、数値ベクトルに変換する方法のこと
- コンピュータは、テキストを理解する際に、テキストデータを数値ベクトルに変換する
- このベクトル変換により、そのベクトルの位置関係から要素同士の関係性を数値で扱える様になり、検索エンジンやレコメンド機能、チャットボットなど様々なものに利用できる

🔽イメージ
文章だとわかりにくいので、[Embedding Projector](https://projector.tensorflow.org/?hl=ja)という埋め込みを可視化するツールをみてみるとわかりやすいです。ここでは「fruits」を入力してみました。

![エンべディング動画.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266675/80f743c0-a7e6-4669-f195-da554fd3c7db.gif)

「fruits」に近い単語が表示されていて、ここではfruit、vegetables、flowersが最も近い単語と確認ができます。

![スクリーンショット 2024-12-10 8.57.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266675/300263e7-603c-9803-e9c1-b3f37e8fac9e.png)

このように、Embeddingの技術によって、キーワードが一致しているものだけでなく、**キーワードに近接する意味の単語を含むものも検索して表示できる**というわけです:point_up:
</details>


## 動作確認

何かしらの理由で「関連レコードの件数を取得したい」というシナリオを前提として検索フローを試してみます。
私がググって始めに辿り着いたトピックページはこちらでした。

![検索でヒットしたトピック.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266675/86740765-7c10-61b4-b6ad-38bd0d3d3629.png)


このトピックの画面下部を確認してみます。
左側が従来で、右側が生成AIによる関連トピックの表示が有効になっているときです。

![BeforeAfter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266675/f3ebf789-4b99-2ece-4096-4038aeafb483.png)

いかがでしょうか…？
今まで何の関連性もないトピックが並んでいたBeforeに比べて、Afterでは過去の似たトピックを探す手間なく見つけることができます。地味な変更にはなりますが、再検索するまでもなく、スクロールするだけで他の参考にできそうなトピックを簡単に見つけることができるようになりそうですね。

### 今回選択した multilingual-e5-large の特徴
ちなみに、今回設定した生成AIのモデルの特徴は次の通りです。
- オープンソースのため、無料で使える
- 英語以外の言語のサイトに適している
  - 多言語データで事前学習されており、英語以外の言語で高い性能を発揮する
- 特定の自然言語処理タスク（検索、分類、質問応答など）に最適化されており、それぞれのタスクに関連する意味を捉えやすい設計になっている

:::note info
Discourseの公式ドキュメントで、「英語以外の言語を使ったサイトの場合は`multilingual-e5-large`の利用が推奨」と記載もされていました。
:::

### コスト:moneybag:
気になるコスト感ですが、今回、関連トピックを表示させるためのエンべディングモデルにはオープンソースのものを選んだので、コストは発生しておらず、0円です。

# 検証② サイト内検索にAI検索を追加する
次に、サイト検索にAI検索を導入する検証をしてみました。
従来のコミュニティの検索画面は、以下の通りです。

![スクリーンショット 2024-12-02 14.21.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266675/348f2548-676d-2285-dd95-09f0beefca39.png)

従来の検索では、キーワード一致で検索結果が表示されています。
ここに、キーワード一致だけでなく、AI検索（LLMによるセマンティック検索）を追加したいと思います。

<details><summary>LLM によるセマンティック検索とは</summary>
セマンティック検索は、Embeddingと検索アルゴリズムや類似性評価などベクトル検索技術の組み合わせです。組み合わせることで、意味を深く理解したセマンティック検索（意味による検索）を高速に実行でき、曖昧な表現の違いや表記揺れに強い、検索結果を提供してくれます。
</details>

## 設定方法

こちらは、まずはどのLLMを使用するか設定が必須になります。
Discourseの設定画面で、LLMの設定を行います。
私は、OpenAIのGPT-4oを利用する設定にしました。OpenAIのAPIキーの発行方法などは他のサイトに載っているのでここでは割愛します。

![AIの設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266675/3045b373-277d-392f-c9ba-08fe903f5eb0.png)

次に、設定画面に戻り、以下の通り設定します。

| 設定項目 | 説明 | 設定した内容 |
|:-|:-|:-|
| ai embeddings semantic search enabled |サイト全体のセマンティック検索を有効にするか|有効|
| ai embeddings semantic search hyde model  |セマンティック検索中に得られる結果を改善するためにキーワードの拡張に使用されるモデルを選択する|GPT-4 Omni|

`ai embeddings semantic search hyde model` には、設定画面で先ほど追加したLLMを指定します。私の場合は、OpenAIのGPT-4oとGPT-4o miniを追加していたので、以下の2つから選択が可能でした。

![スクリーンショット 2024-12-10 9.45.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266675/687a8f08-e55e-7fb0-6d9f-c8ffe89540bd.png)

## 動作確認

設定後、検索画面を開くと、生成AIによる検索結果を含むことができるように変わりました。

![スクリーンショット 2024-12-02 14.23.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266675/29e279d0-e755-c634-e178-bff116572a17.png)

設定がシンプルで、とても簡単に実現できました。
スイッチで、AIの検索結果を含むかどうかをユーザー自身が切り替えられるのは地味に良いですね:thumbsup:

しかし、確認した限り、大外れしているようなトピックが検索結果に含まれてしまうといったことはなさそうでしたが、こちらはあまり期待していた結果にはならなくて現段階では正直なんともいえない結果になりました。以下は、GPT-4oとその小型モデルGPT-4o miniの検索結果を比較した画像です。赤枠がAIによる検索でヒットしたトピックです。

![AI検索.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266675/950635d0-bcc6-9df6-d176-709f0b61a633.png)

こちらに関しては、現段階で導入してもそこまでメリットがなさそうに感じたので、もう少し精度を上げられないか引き続き検討が必要そうです。

### コスト:moneybag:
OpenAIのAPIの料金は、入力トークン（input tokens）の数に基づいて計算されます。

- GPT-4oは、$2.5 / 1M input tokens
- 1,000,000（100万）トークンあたり$2.5(375円)の料金が発生する

https://openai.com/api/pricing/

今回、GPT-4oのLLMを利用した際、1回の検索で $0.03かかっていました。
1回検索するだけで、**約4.5円**。
つまり、今回検証した1回の検索では、サイト内のデータを20万トークン入力したと考えられます。この感覚は、人によるのかもしれませんが、結構高いなと感じました。

GPT-4o miniも同じ条件で検証してみると、こちらは、1回の検索で **$0.01(約1.5円)** でした。
1/3のコストに抑えられそうなことがわかりました。OpenAI以外の生成AIモデルと比較したサイトなどをみても、GPT-4o miniの安さは際立っていました。

どのモデルを選択するかでかなり費用は変わってくるので、精度とコストのバランスを取って検討を続けていきたいと思います。

# おわりに

kintoneの開発者コミュニティサイトに生成AIの導入を検討してみました。

- 導入すると、検索性が向上し、利用者が自分の興味関心のあるトピックに行き着きやすくなるメリットが生まれる
- コミュニティサイトには、質問と回答データが大量に日々蓄積され続けるという特色上、コストを抑えつつ精度を上げられる方法に課題が残る

ということがわかりました。

最後になりましたが、kintoneやGaroonなどサイボウズ製品をご利用いただいている皆さん、いつもご利用いただきありがとうございます。
ここで検証した生成AI機能が実際に導入されているか、来年楽しみにしていてください！:sparkles:
（どうなるかまだ全く未定ですが…:pray:）

最後まで読んでいただきありがとうございました。