はじめに
本記事は、専門チャット検索機能の全体構想を整理した Part1 です。
現在の構成や、質問から回答までの処理フローについては Part2 専門チャット検索機能 の 構成要素と処理フロー で整理しています。
また Part3 以降は 課題一覧 に紐付けて投稿していきます。
きっかけ
- 「以前、生成AI に質問したはずなのに、どこにあるか分からない」。
- 「同じ質問を何度も 生成AI に投げている」に加え、「同じ質問をしているのに前回と回答が違う」。
- 結局「あれどこに書いたっけ?」と迷子になるアレです。(笑)
コレを解決して「生成AIを活用して人間の知識を強化」する目的で、専門チャット検索機能 の開発に着手しました。
専門チャット検索機能
目標
- 本機能では、生成AIの利用を前提としつつも、「良い知識を残す」「検索精度を保つ」ための最終判断は人間が行います。
- 導入後、検索・運用・保守の3つを継続的に回すことで、専門知識が徐々に蓄積・進化していく構造を目指しています。
ホスティング環境
- Google Cloud
- Compute Engine
- e2-micro(2個の vCPU, 1 GBメモリ) + Swap領域 4 GB
- Guest OS
- Debian 12.15
- Webサーバー
- Nginx 1.30.4
- コンテナ
- Docker 29.6.2
- Docker Compose 5.3.1
- アプリケーション実行環境
- プログラミング言語
- JavaScript (ES Modules)
- ランタイム
- Node.js 22.23.4
- パッケージ管理
- npm 10.9.9
- ライブラリ/フレームワーク
- express 5.1.0
- express-rate-limit 8.2.1
- dotenv 16.4.5
- morgan 1.10.0
- gray-matter 4.0.3
- yaml 2.8.1
-
トークナイズ(分かち書き)- kuromoji 0.1.2
- ワーカースレッド
- node:worker_threads
-
推論を実行するためのコントローラー- @xenova/transformers 2.17.2
-
推論エンジン- onnxruntime-node 1.14.0
-
生成AI連携- @google/genai 2.32.0
- プログラミング言語
-
AIモデル- 量子化された
ONNXモデルmodel_quantized.onnx
- 量子化された
- 連携する生成AIモデル
- gemini-3.5-flash-lite
- Compute Engine
要件
- システム形態は RAGアプリケーション とします。
- RAG構成は 検索型RAG とし、以下に概要を記載します。
- 言語
- 検索対象の言語は
日本語を含む多言語とします。
- 検索対象の言語は
- 検索対象
- Gemini との チャット履歴 をもとに カテゴリ別 に
カテゴリ別ナレッジベースを作成します。 -
カテゴリ別ナレッジベースからコーパスを作成して、検索対象とします。
- Gemini との チャット履歴 をもとに カテゴリ別 に
- 一般的なRAGの Augmentation に相当する部分を、検索結果に基づく ルーティング判定 とします。
-
コーパスに回答が見つからない場合は、Gemini API 連携 して回答を生成します。
-
- この設計とした理由
- 回答精度
- 生成AIの回答は仮説であり、回答 が要件を満たしているかを検証する必要があります。
- なので生成AIから得た回答を人間が検証したものを
コーパスとします。 - 人間が検証した
コーパスを検索対象とすることにより、回答精度を高めることが可能である想定です。
- 課金
- 検索対象を
コーパスとするため、Gemini API 連携 による課金を緩和することが可能である想定です。
- 検索対象を
- 回答精度
- 言語
データの種類
環境変数
-
.envファイル- APIキーを格納します。
データモデル
-
設定ファイル- 本機能 の動作を管理する制御データを保持するJSON形式のファイルです。
- カテゴリ、
しきい値、制限値、ルーティング方式 などを定義します。
-
カテゴリ別ナレッジベース- カテゴリ別 に管理されるナレッジベースです。(Markdown)
- 生成AIからの回答をもとに 運用者 が作成します。
-
代表クエリ-
評価レポートを作成するために用意します。 - 質問に対する正解 をあらかじめ設定したクエリ一覧です。
-
-
コーパス- 生成AIが回答を作成する際に外部知識として参照する、
カテゴリ別ナレッジベースをもとに作成された検索対象となる文書の集まりです。 -
カテゴリ別ナレッジベースの回答を BM25検索用 のトークナイズ(分かち書き)、ベクトル検索用 のベクトル値として保持します。
- 生成AIが回答を作成する際に外部知識として参照する、
-
評価レポート-
推奨しきい値を保持するレポートファイルです。
-
AIモデル
-
ONNXモデル- ベクトル検索に使用される
ONNXモデルと、その関連ファイルです。 - 質問に対する
ベクトル値を取得します。
- ベクトル検索に使用される
カテゴリ別ナレッジベース の構造
-
カテゴリ種別
- java
- javascript
- node
- onnx
- express
- typescript
- html
- css
- rdbms
-
構造
- カテゴリ
- 本文
- 回答
※ 現時点では、あまり準備できていません(ごめんなさいw)。
スクリプト
-
ディレクトリ構成構築スクリプト- 本機能 導入時に ディレクトリ構成 を構築します。
-
カテゴリ別ナレッジベース作成スクリプト-
カテゴリ別ナレッジベースのテンプレートを Markdown で出力します。
-
-
コーパス作成スクリプト-
カテゴリ別ナレッジベースからコーパスを作成して、カテゴリ別ナレッジベースの回答に対するトークナイズ(分かち書き)とベクトル値を埋め込みます。
-
-
評価レポート作成スクリプト-
代表クエリとコーパスに対する BM25検索 と ベクトル検索 の結果を RRF で統合し、得られた RRF統合スコア の最小値を推奨しきい値として、評価レポートに出力します。
-
-
デプロイ処理スクリプト- Compute Engine 上で動作する Docker Container のデプロイを自動化します。
全体構想 ユースケース図
- まず、本機能 の 全体構想 を ユースケース図 で示します。
専門チャット検索機能 画面
- 画面構成 は以下となります。
画面項目 説明
- カテゴリ
- java、javascript、node、onnx、express、typescript、html、css、rdbms
- サジェスト
- カテゴリに紐付く検索候補
- 質問
- 前提
- 開発環境や使用するプロダクトのバージョン
- 要件
- 実現したいこと
- 依頼
- 要約して下さいなど、生成AIに対する回答ルール指示
- Search
- 検索実行
専門チャット検索機能 概要
- 本機能 の 概要説明 を以下に記載します。
導入
ディレクトリ構成構築
-
ディレクトリ構成構築スクリプトを手動で実行して、本機能 導入時にディレクトリ構成を構築します。
検索
-
日本語で質問を入力する- 質問 に加え 前提 などを
日本語で入力して、Searchボタンをクリックします。
- 質問 に加え 前提 などを
-
検索サービス
- 検索品質評価
- Precision@5 を指標として使用します。
- BM25検索
- WebUIからリクエストされた 質問を
トークナイズ(分かち書き)します。 -
コーパス内に 質問 が存在するか BM25検索 で抽出します。 - 検索結果として BM25関連度スコア を算出します。
- WebUIからリクエストされた 質問を
- ベクトル検索
-
推論-
エンベディングによりWebUIからリクエストされた 質問 のベクトル値を取得します。
-
-
コーパス内に 質問 が存在するか ベクトル検索 で抽出します。 - 検索結果として コサイン類似度スコア を算出します。
-
- RRF統合
- BM25関連度スコア と コサイン類似度スコア を RRF により統合して順位付けをします。
- 検索品質評価
-
ルーティング判定
- 1位の RRF統合スコア >=
設定ファイルのしきい値?コーパスから回答取得: Gemini API 連携して回答取得;
- 1位の RRF統合スコア >=
-
回答表示
-回答を Markdown 形式で表示します。
運用
カテゴリ別ナレッジベース 管理
- Gemini API 連携からの回答を 運用者 が評価
- Gemini API 連携からの回答が 良回答 の場合
- 手動で
カテゴリ別ナレッジベース作成スクリプトを実行-
カテゴリ別ナレッジベースのテンプレートを Markdown で出力します。 - その後 運用者 が
出力された Markdown の内容 と Gemini からの 良回答を確認して手動で編集します。
-
- 手動で
- Gemini API 連携からの回答が 良回答 の場合
コーパス 作成
- 手動で
コーパス作成スクリプトを実行-
カテゴリ別ナレッジベースからコーパスを出力して検索対象として使用できるように準備します。
-
保守
代表クエリ 編集
- 新しく作成した
カテゴリ別ナレッジベース用に代表クエリを編集します。
検索精度の評価・調整
- 手動で
評価レポート作成スクリプトを実行-
評価レポートを出力-
代表クエリに対する BM25関連度スコア と コサイン類似度スコア を RRF で統合し、RRF統合スコア の最小値 を推奨しきい値として評価レポートに出力します。
-
-
-
評価レポート の 推奨しきい値と設定ファイル の しきい値を比較- 乖離があれば
しきい値を推奨しきい値の値に手動で書き換えます。
- 乖離があれば
デプロイメント
-
デプロイ処理スクリプトを手動で実行して Compute Engine 上で動作する Docker Container へ 本機能 を配置します。
用語解説
| 用語 | 説明 |
|---|---|
| RAG | Retrieval-Augmented Generation の略です。 生成AIに直接すべてを答えさせるのではなく 検索で取得した外部知識を根拠として回答生成に利用するシステムです。 |
コーパス |
検索対象として整形された文書です。 本機能ではカテゴリ別ナレッジベースを検索用JSONに変換したものを指し カテゴリ別ナレッジベースの回答を トークナイズ(分かち書き) した結果および ベクトル値 を埋め込みます。 |
| Precision@5 | 上位5件の検索結果のうち、正解がどれだけ含まれているかを表す評価指標です。 |
トークナイズ(分かち書き) |
文書を意味のある単位(単語・形態素)に分割します。 例: 質問が "DAO 設計 JPA SQL" の場合 "dao", "設計", "jpa", "sql" に分割。 BM25検索の入力パラメータになります。 |
| BM25検索 | キーワード一致に強い検索方式です。 トークンの出現頻度と文書長をもとに関連度を算出します。 |
| BM25関連度 | 本機能においては、「質問の トークナイズ(分かち書き)」と「コーパス に含まれる トークナイズ(分かち書き)」を比較し質問のトークンがどの程度一致しているかを数値化します。 |
| ベクトル検索 | 本機能においては、質問に対する ベクトル値 と コーパス 内の各 ベクトル値 を比較し意味の近さで検索する方式です。 表現が違っても意味が近い文書を拾いやすくします。 |
| コサイン類似度 (Cosine Similarity) | 本機能においては、「質問に対する ベクトル値」と「コーパス に埋め込まれる ベクトル値」の 向き(意味) がどの程度近いかを数値化します。 向き(意味) 近いほど、質問と コーパス の意味が近いと判断します。 |
| RRF統合 | Reciprocal Rank Fusion の略です。 BM25検索結果 と ベクトル検索結果 を順位ベースで統合し 検索方式ごとの偏りを抑え順位付けする方式です。 |
しきい値 |
本機能においては、コーパス から回答するか Gemini API 連携 するかを判定する 境界値 です。 |
| ワーカースレッド | Node.jsでCPU負荷の高い処理をメインスレッドから分離して実行する仕組みです。 |
推論 |
本機能においては、onnxruntime-node によって文書を ONNXモデル に入力し、ベクトル値 を取得することです。 |
AIモデル |
本機能における AIモデル とは「文書を ベクトル値 に変換」する「学習環境から 変換・出力 された 学習済みモデル」を指します。学習済みモデル とは、文書を意味的な数値列 (ベクトル値)に変換するシステムです。意味的な数値列 (ベクトル値)とは意味が近い文書ほど近くに配置されるように数値化されたデータを指します。 |
| 学習環境 |
AIモデル に学習データを与え、新しい AIモデル を作成するための実行環境です。 |
ONNXモデル |
Open Neural Network Exchange の略です。AIモデル を ONNXという共通形式 で 変換・出力 したものです。本機能では ONNXモデル を 推論 のために使用します。 |
エンベディング |
文書を ベクトル値 に変換する処理で、ベクトル検索の入力パラメータになります。本機能では文書の ベクトル値 を取得するために- @xenova/transformers (ライブラリ) - model_quantized.onnx (ONNX形式の量子化モデル) を使って 日本語 を含む多言語文書をベクトル検索用の ベクトル値 に変換しています。 |
| @xenova/transformers |
ONNXモデル で 推論 を実行するためのコントローラーで、以下を実行します。- 文書のトークナイズ(単語ID化)。 - onnxruntime-node 呼び出し。 - ONNXモデル が出力したトークンごとの ベクトル値 を平均化して文書に対する384次元ベクトル(384個の数値)を出力します。 |
| onnxruntime-node |
ONNXモデル を Node.js 環境 からネイティブ実行する 推論エンジン です。 |
| 量子化モデル | 精度の低下を最小限に抑えて、INT8などの 重みパラメータの精度を縮小・離散化 する技術を用いて軽量化した AIモデル です。メリットはメモリ消費量が少なく、ファイルサイズも小さいので高速に 推論 することが可能となります。推論精度は非量子化モデルに比べ、95% 〜 99%(実用上ほぼ同等) です。 |
| 非量子化モデル | 高精度(FP32)な重みパラメータを持つ精度の高い AIモデル です。メリットは推論精度が高く、モデル本来の性能を 100%(基準値として) 発揮できることです。 |
課題一覧
- 以下に目的ごとに課題を分類した、一覧を記載します。
| 課題No. | 要件区分 | 分類 | 目的 | 詳細記事 |
|---|---|---|---|---|
| 1 | 非機能要件 | 公開・運用 | プラットフォームの選定 | ホスティング環境とローカル開発環境の構成 |
| 2 | 非機能要件 | AIモデル |
ローカルAIモデルの選定 | 最小構成の プラットフォーム で 推論 するための技術スタック |
| 3 | 機能要件 | 検索品質 | 外部知識に対する検索の仕組み | 検索 から ルーティング判定 までの仕組み |
| 4 | 非機能要件 | セキュリティ | 脆弱性対応 | 未公開 |
| 5 | 非機能要件 | 課金 | Gemini API連携時の課金制御 | 未公開 |
| 6 | 非機能要件 | ボトルネック | パフォーマンス改善 | 未公開 |
| 7 | 非機能要件 | コンポーネント化 | 関心の分離と責務ごとの整理 | 未公開 |
| 8 | 非機能要件 | UX | 使いやすさのための改善 | 未公開 |
| 9 | 非機能要件 | 将来拡張 | TypeScriptとVue.jsの導入 | 未公開 |
まとめ
- 検索で即座に答えを得る。
- 良回答を人間が見極めて ナレッジベース として残す。
- 評価と調整を繰り返して 検索精度 を保つ。
この3つを回し続けることで、専門チャット検索機能 を進化させて行きます。
おわりに
Qiita に集う皆さまは、既にお分かりだと思いますが
生成AIは「魔法の杖」ではありません。
草案や思い付きを、素早く検証することを可能にしてくれることが利点で
作業効率や作業プロセスは通常のシステム開発と変わらない認識です。
この 専門チャット検索機能 は、その 利点 を生かすための個人的な回答です。
今後も試行錯誤しながら、少しずつ育てていこうと思います。

