0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

生成AIの良回答を 育てる ための 専門チャット検索機能 を作った話

0
Last updated at Posted at 2026-01-23

はじめに

本記事は、専門チャット検索機能の全体構想を整理した第一段の記事です。
現在の構成や、質問から回答までの処理フローについては、第二段の記事で整理しています。
第二段の記事: 専門チャット検索機能 の 構成要素と処理フロー
第三段以降の記事は 課題一覧 に紐付けて投稿していきます。

きっかけ

  • 「以前、生成AI に質問したはずなのに、どこにあるか分からない」。
  • 「同じ質問を何度も 生成AI に投げている」に加え、「同じ質問をしているのに前回と回答が違う」。
  • 結局「あれどこに書いたっけ?」と迷子になるアレです。(笑)

コレを解決して「生成AIを活用して人間の知識を強化」する目的で、専門チャット検索機能 の開発に着手しました。

専門チャット検索機能

目標

  • 本機能では、生成AIの利用を前提としつつも、「良い知識を残す」「検索精度を保つ」ための最終判断は人間が行います。
  • 導入後、検索・運用・保守の3つを継続的に回すことで、専門知識が徐々に蓄積・進化していく構造を目指しています。

ホスティング環境

  • GCP
    • GCE
      • e2-micro(2個の vCPU, 1GBメモリ) + Swap領域 4GB
    • 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.1
      • パッケージ管理
        • npm 10.9.8
      • ライブラリ/フレームワーク
        • Express 5.2.1
        • Express-rate-limit 8.5.2
        • dotenv 16.4.5
        • morgan 1.10.0
        • gray-matter 4.0.3
        • yaml 2.8.1
        • ワーカースレッド
          • node:worker_threads
        • 推論
          • onnxruntime-node 1.14.0
        • エンベディング
          • @xenova/transformers 2.17.2
        • 生成AI連携
          • @google/genai 2.17.1
    • AIモデル
      • 量子化された ONNXモデル model_quantized.onnx
    • 連携する生成AIモデル
      • gemini-2.5-flash

要件

  • システム形態は RAGアプリケーション とします。
  • RAG構成は 検索型RAG とし、以下に概要を記載します。
    • 検索対象
      • Gemini との チャット履歴 を元に カテゴリ別 に カテゴリ別ナレッジベース を作成します。
      • カテゴリ別ナレッジベース から コーパス を作成して、検索対象とします。
    • 一般的なRAGの Augmentation に相当する部分を、検索結果に基づく ルーティング判定 とします。
      • コーパス に 回答 が見つからない場合は、Gemini API 連携 して 回答 を生成します。
        • こうした理由
          • 回答精度
            • 生成AIの回答は仮説であり、回答が要件を満たしているかを検証する必要が有ります。
            • なので生成AIから得た回答を人間が検証したものを コーパス とします。
            • 人間が検証した コーパス を検索対象とすることにより、回答精度を高めることが可能である想定です。
          • 課金
            • 検索対象を コーパス とするため、Gemini API 連携 による課金を緩和することが可能である想定です。

データの種類

データモデル

  • 設定ファイル

    • 本機能 の動作を管理する制御データを保持するJSON形式のファイルです。
    • カテゴリ、しきい値、制限値、ルーティング方式 などを定義します。
  • カテゴリ別ナレッジベース

    • カテゴリ別 に管理されるナレッジベースです。(Markdown)
    • 生成AIからの回答を元に 運用者 が作成します。
  • 代表クエリ

    • 評価レポート を作成するために用意します。
    • 質問に対する正解 を予め設定したクエリ一覧です。
  • コーパス

    • 生成AIが回答を作成する際に外部知識として参照する、カテゴリ別ナレッジベース を元に作成された検索対象です。
    • BM25検索用の トークナイズ(分かち書き) と、ベクトル検索用の ベクトル値 を保持します。
  • 評価レポート

    • 推奨しきい値 を保持するレポートファイルです。

AIモデル

  • ONNXモデル
    • ベクトル検索に使用される ONNXモデル と、その関連ファイルです。
    • 質問に対する ベクトル値 を取得します。

カテゴリ別ナレッジベース の構造

  • カテゴリ種別

    • java
    • javascript
    • node
    • onnx
    • express
    • typescript
    • html
    • css
    • rdbms
  • 構造

    • カテゴリ
    • 質問
    • 前提 (開発環境や使用するプロダクトのバージョン)
    • 要件 (実現したいこと)
    • 回答

※ 現時点では、あまり準備できていません(ごめんなさいw)。

スクリプト

  • ディレクトリ構成構築スクリプト

    • 本機能 導入時に ディレクトリ構成 を構築します。
  • カテゴリ別ナレッジベース作成スクリプト

    • カテゴリ別ナレッジベース のテンプレートを Markdown で出力します。
  • コーパス作成スクリプト

    • カテゴリ別ナレッジベース から コーパス を作成して、カテゴリ別ナレッジベース の タイトル + 本文 に対する トークナイズ(分かち書き) と ベクトル値 を埋め込みます。
  • 評価レポート作成スクリプト

    • 代表クエリコーパス にどの程度 的中 したのか、推奨しきい値 を埋め込んで 評価レポート を出力します。
  • デプロイ処理スクリプト

    • GCE 上で動作する Docker コンテナのデプロイを自動化します。

全体構想 ユースケース図

  • まず、本機能 の 全体構想 を ユースケース図 で示します。

Qiita-01-01-全体構想 ユースケース図.png

専門チャット検索機能 画面

  • 画面構成 は以下となります。

Qiita-01-02-専門チャット検索機能 画面専門チャット検索機能 画面.png

画面項目 説明

  • カテゴリ
    • java、javascript、node、onnx、express、typescript、html、css、rdbms
  • サジェスト
    • カテゴリに紐付く検索候補
  • 質問
  • 前提
    • 開発環境や使用するプロダクトのバージョン
  • 要件
    • 実現したいこと
  • 依頼
    • 要約してくださいなど、生成AIに対する回答ルール指示
  • Search
    • 検索実行

専門チャット検索機能 概要

  • 本機能 の 概要説明 を以下に記載します。

導入

ディレクトリ構成構築

  • ディレクトリ構成構築スクリプト を手動で実行して、本機能 導入時にディレクトリ構成を構築します。

検索

  • 質問を入力する

    • 質問 に加え 前提 などを入力して、Searchボタンクリックします。
  • 検索サービス

    • 検索品質評価
      • Precision@5 を指標として使用します。
    • BM25検索
      • WebUIからリクエストされた 質問を トークナイズ(分かち書き) します。
      • コーパス 内に 質問 が存在するか BM25検索 で抽出します。
      • 検索結果としてスコアを算出します。
    • ベクトル検索
      • 推論
        • エンベディング によりWebUIからリクエストされた 質問 のベクトル値を取得します。
      • コーパス 内に 質問 が存在するか ベクトル検索 で抽出します。
      • 検索結果としてスコアを算出します。
    • RRF統合
      • BM25検索結果(スコア) と ベクトル検索結果(スコア) を RRF統合 により統合して順位付けをします。
  • ルーティング判定

    • RRF統合スコア >= 設定ファイル の しきい値 ? コーパス から回答取得: Gemini API 連携して回答取得;
  • 回答表示

    • 回答を Markdown 形式で表示します。

運用

カテゴリ別ナレッジベース 管理

  • Gemini API 連携からの回答を 運用者 が評価
    • Gemini API 連携からの回答が 良回答 の場合
      • 手動で カテゴリ別ナレッジベース作成スクリプト を実行
        • カテゴリ別ナレッジベース のテンプレートを Markdown で出力します。
        • その後 運用者 が 出力された Markdown の内容 と Gemini からの 良回答 を確認して手動で編集します。

コーパス 作成

  • 手動で コーパス作成スクリプト を実行
    • カテゴリ別ナレッジベース から コーパス を出力して検索対象として使用できるように準備します。

保守

代表クエリ 編集

  • 新しく作成した カテゴリ別ナレッジベース 用に 代表クエリ を編集します。

検索精度の評価・調整

  • 手動で 評価レポート作成スクリプト を実行
    • 評価レポート を出力
      • 代表クエリコーパス にどの程度 的中 したのか(Precision@5 を指標として使用) を元に 推奨しきい値評価レポート に埋め込んで出力します。
  • 評価レポート の 推奨しきい値設定ファイル の しきい値 を比較
    • 乖離があれば しきい値推奨しきい値 の値に手動で書き換えます。

デプロイメント

  • デプロイ処理スクリプト を手動で実行して GCE 上で動作する Docker コンテナへ 本機能 を配置します。

用語解説

用語 説明
RAG Retrieval-Augmented Generation の略です。
生成AIに直接すべてを答えさせるのではなく
検索で取得した外部知識を根拠として回答生成に利用する仕組みです。
コーパス 検索対象として整形された文書集合です。
本機能ではカテゴリ別ナレッジベースを検索用JSONに変換したものを指します。
Precision@5 上位5件の検索結果のうち、正解がどれだけ含まれているかを表す評価指標です。
トークナイズ(分かち書き) 文章を意味のある単位(単語・形態素)に分割します。
例: 質問が "DAO 設計 JPA SQL" の場合 "dao", "設計", "jpa", "sql" に分割。
BM25検索の入力パラメータになります。
BM25検索 キーワード一致に強い検索方式です。
単語の出現頻度と文書長をもとに関連度を計算します。
ベクトル検索 文章のベクトルに対して、意味の近さで検索する方式です。
表現が違っても意味が近い文書を拾いやすくします。
RRF統合 Reciprocal Rank Fusion の略です。
複数の検索結果を順位ベースで統合し、検索方式ごとの偏りを抑え順位付けする方式です。
しきい値 コーパスから回答 するか Gemini API 連携 するかを判定する 最小の境界値 です。
ワーカースレッド Node.jsでCPU負荷の高い処理をメインスレッドから分離して実行する仕組みです。
AIモデル 文章をベクトルに変換するモデルです。
ONNXモデル Open Neural Network Exchange の略です。
AIモデルONNXという共通形式 で保存したものです。
本機能では ONNXモデル推論 のために使用します。
onnxruntime-node ONNXモデル を Node.js環境 からネイティブ実行する 推論基盤 です。
@xenova/transformers ONNXモデルエンベディング するためのコントローラーで、以下を実行します。
- 文章のトークナイズ(単語ID化)。
- onnxruntime-node 呼び出し。
- ONNXモデル が出力した単語ごとのベクトルを平均化して、文章に対する384次元の数値配列を出力します。
推論 onnxruntime-node によって文章を ONNXモデル に入力し、ベクトル値を取得することです。
エンベディング 文章をベクトルに変換する処理で、ベクトル検索の入力パラメータになります。
本機能では文章をベクトル化するために
- @xenova/transformers
- model_quantized.onnx
を使って、日本語を含む多言語文章を検索用のベクトルに変換しています。
量子化モデル 精度の低下を最小限に抑えて、INT8などの 重みパラメータの精度を縮小・離散化 する技術を用いて軽量化した AIモデル です。
メリットはメモリ消費量が少なく、ファイルサイズも小さいので高速に 推論 する事が可能となります。
推論精度は非量子化モデルに比べ、95% 〜 99%(実用上ほぼ同等) です。
非量子化モデル 高精度(FP32)な重みパラメータを持つ精度の高い AIモデル です。
メリットは推論精度が高く、モデル本来の性能を 100%(基準値として) 発揮できる事です。

課題一覧

  • 以下に目的ごとに課題を分類した、一覧を記載します。
課題No. 要件区分 分類 目的 詳細記事
1 非機能要件 公開・運用 プラットフォームの選定 ホスティング環境とローカル開発環境の構成
2 非機能要件 AIモデル ローカルAIモデルの選定 未公開
3 機能要件 検索品質 外部知識に対する検索方法 未公開
4 非機能要件 コンポーネント化 関心の分離と責務ごとの整理 未公開
5 非機能要件 ベクトル検索 パフォーマンス改善 未公開
6 非機能要件 課金 Gemini API連携時の課金制御 未公開
7 非機能要件 セキュリティ 脆弱性対応 未公開
8 非機能要件 UX 使いやすさのための改善 未公開
9 非機能要件 将来拡張 TypeScriptとVue.jsの導入 未公開

まとめ

  1. 検索で即座に答えを得る。
  2. 良回答を人間が見極めて ナレッジベース として残す。
  3. 評価と調整を繰り返して 検索精度 を保つ。

この3つを回し続けることで、専門チャット検索機能 を進化させて行きます。


おわりに

Qiita に集う皆さまは、既にお分かりだと思いますが
生成AIは「魔法の杖」ではありません。

草案や思い付きを、素早く検証することを可能にしてくれることが利点で
作業効率や作業プロセスは通常のシステム開発と変わらない認識です。

この 専門チャット検索機能 は、その 利点 を生かすための個人的な回答です。

今後も試行錯誤しながら、少しずつ育てていこうと思います。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?