RAGOps Studioとは
RAGOps Studioは、Azure AI Searchの検索実験とRAG検証をブラウザ内で行うための統合開発ツールです。検索リクエストの構築、Search Parameter AutoTuning、スキルパイプライン編集、評価データセット生成、インデックス可視化などを1つのUIにまとめています。
v0.1.2 の新機能である Index Cluster Visualizer は、Azure AI Search の既存インデックスに保存されているベクトルフィールドを取得し、ドキュメント群をクラスタリングして、インデックス全体の意味構造を散布図・階層ビュー・クラスター関係グラフとして可視化する機能です。
さらに、クラスターのラベル、要約、検索用テキストをAzure AI Search上のメタインデックスとして保存し、Global(意味領域)→Local(元ドキュメント) の2段階検索に再利用できます。
1. Index Cluster Visualizer ~ EFLC によるインデックス構造の可視化
1.1. なぜインデックス全体の可視化が必要なのか
RAGシステムでは、検索インデックスに数千〜数十万件のチャンクやドキュメントが格納されます。通常の検索UIでは「このクエリに対して何が返るか」は確認できますが、次のような質問には答えにくいです。
| 質問 | 通常の検索 UI で難しい理由 |
|---|---|
| このインデックスは何についての集合か | 個別クエリの結果しか見えず、全体の主題分布が見えない |
| チャンクが特定のPDFやWebページに偏っていないか | 先頭取得や単発検索では親文書単位の偏りを見落としやすい |
| 大きすぎるクラスターの内部構造は何か | 検索結果リストだけでは意味領域の階層が見えない |
| 似たクラスター同士はどこで接続しているか | 境界文書や共有ファセットを横断的に確認しにくい |
| LLMが作ったクラスター要約の根拠は何か | 要約、根拠文書、使用フィールド、トークン使用量を追跡しにくい |
| 検索時にどの意味領域を通ったか | GlobalノードからLocalドキュメントへの経路が見えない |
Index Cluster Visualizerは、検索インデックスを単なる検索結果を返す箱ではなく、観測可能な意味空間として扱うための機能です。散布図で全体像を見て、階層クラスターで粒度を調整し、クラスター関係グラフで境界や近接領域を確認し、その構造をメタインデックス検索へ戻します。
さらにこの機能が重要なのは、インデックスの構造を観測し、その構造を検索、評価、改善の入口として再利用できる (= RAGOps)点にあります。
1.2. EFLC とは
本機能の中核となる考え方を、この記事ではEFLC (Embedding-First Lightweight Clustering)と呼びます。
EFLC は、Azure AI Search にすでに存在するベクトルフィールドを起点に、軽量なクラスタリングで意味領域を発見し、LLM はクラスターの説明に限定して使う設計です。
GraphRAG のような技術は強力ですが、全ドキュメントからエンティティとリレーションを抽出してグラフを構築するため、初期構築コストが大きくなります。一方、EFLC は最初に LLM で全件を読むのではなく、既存の埋め込み空間から主題のまとまりを発見します。
| 観点 | GraphRAG | EFLC |
|---|---|---|
| 初期入力 | 生テキスト全体 | 既存ベクトルフィールド |
| 主な前処理 | LLM によるエンティティ抽出、リレーション抽出 | ベクトル取得、クラスタリング、次元削減 |
| LLMコスト | 全ドキュメント規模になりやすい | クラスター代表文書に限定 |
| 保存先 | 独自成果物、グラフストレージ、複数ファイル | Azure AI Search のメタインデックス |
| 得意領域 | 関係推論、知識グラフ化 | インデックス全体像の把握、低コストな意味領域検索 |
特に、以前私が解説した Microsoft GraphRAG は重厚長大で、使用するトークン数も莫大でした。サクッと全体像を把握したいのであれば、既存の手法でクラスタリングして、そのクラスターに対して要約処理を行うことで大幅にコストを削減できます。EFLC では Microsoft GraphRAG から学んだ多様なテクニックを実験的に実装しています。
EFLCの設計原則は次の5つです。
1. 既存ベクトルを再利用する
追加の埋め込み生成を既定では行わない。
2. 重い数値計算はブラウザ内の Web Worker で実行する
K-Means++、階層 K-Means、グラフ構築、次元削減を UI スレッドから分離する。
3. LLM は全件処理ではなくクラスター説明に使う
ラベル、要約、意味プロファイル、検索用クエリ候補の生成に限定する。
4. ソースインデックスを壊さない
元のインデックスは変更せず、クラスター情報は別のメタインデックスに保存する。
5. 可視化と検索を分けない
画面で見えた意味構造を、Global→Local 検索の入口として再利用する。
2. アーキテクチャ概要
Index Cluster Visualizer は、UI、可視化パイプライン、メタインデックス生成、2 段階検索の 4 つの層で構成されています。
各モジュールの役割は以下です。
| モジュール | 役割 |
|---|---|
IndexVisualizer.tsx |
設定フォーム、散布図、階層ビュー、クラスター関係グラフ、メタインデックス操作、Trace表示を統合するUI |
useIndexVisualization.ts |
インデックス定義取得、ベクトルフィールド検出、表示タイトルフィールド解決、サンプリング、Worker実行を管理 |
vectorSampling.ts |
detectIndexStructure()を再利用し、Chunked / Independent / Unknownに応じてベクトル取得戦略を切り替える |
visualizationWorker.ts |
K-Means++、階層K-Means、クラスター関係グラフ、次元削減をメインスレッド外で実行 |
clustering.ts |
K-Means++、階層K-Means、コサイン類似度、Silhouetteスコア、Elbow法を提供 |
dimensionReduction.ts |
PCA、UMAP、t-SNE、PCA→UMAPの2D射影を提供 |
clusterGraph.ts |
セントロイド類似度、Bridge Document、共有ファセット、共有キーワードから説明可能なエッジを構築 |
clusterEvidence.ts |
Prototype / Diverse / Boundary / OutlierのRole-aware evidenceを選定 |
embeddingTopology.ts |
KNNグラフから凝集度、分離度、境界率、外れ値率、曖昧度を算出するETAを提供 |
metaIndex.ts |
EFLC v1/v2要約、HSA、RAPTOR-liteノード生成、メタインデックス作成、2段階検索を提供 |
persistedVisualization.ts |
.ragvis.jsonと.ragmeta.jsonの保存・復元を提供 |
2.1. 現在の全体フロー
現行実装のパイプラインは、可視化、要約、検索まで含めると次のようになります。
2.2. EFLCパイプライン各ステップ一覧
| # | ステップ | 何をするか | 主な実装 |
|---|---|---|---|
| 0 | Index Definition | キーフィールド、ベクトルフィールド、表示タイトル候補を取得 | getIndexDefinition() |
| 1 | Structure Detection | インデックスをChunked / Independent / Unknownに分類 | detectIndexStructure() |
| 2 | Adaptive Sampling | 構造に応じて偏りを抑えたベクトル取得を行う | scanVectorsAdaptive() |
| 3 | Worker Transfer | ベクトルをFloat32Arrayに詰めて Worker へ転送 |
visualizationWorker.ts |
| 4 | Flat Clustering | K-Means++ で大まかなクラスターを作る | kMeans() |
| 5 | Hierarchical Clustering | Macro→Micro の2段階クラスターを作る | hierarchicalKMeans() |
| 6 | Cluster Graph | クラスター間の近接関係と Bridge Document を計算する | buildClusterGraph() |
| 7 | Dimension Reduction | 高次元ベクトルを 2D 座標へ射影する | reduce2D() |
| 8 | Visualization | 散布図、階層ビュー、グラフ、凡例を表示する | IndexVisualizer.tsx |
| 9 | Evidence Selection | 要約に使う代表文書を役割別に選ぶ | selectRoleAwareEvidence() |
| 10 | Cluster Summary | EFLC v1 または v2 でクラスター説明を生成する | summarizeClustersV2() |
| 11 | HSA | Micro プロファイルから Macro プロファイルをボトムアップに集約する | summarizeClustersHierarchicalV2() |
| 12 | Meta-Index | クラスター要約と Retrieval Tree を Azure AI Search に保存する |
createMetaIndex() / uploadMetaDocuments()
|
| 13 | Two-stage Search | メタインデックスで意味領域を探し、元インデックスで根拠文書を探す | twoStageSearch() |
| 14 | Overview Answer | Global ノードと Local 文書を使って回答概要を生成する | synthesizeTwoStageOverviewAnswer() |
このパイプラインを通すことで、インデックスは単なる文書集合から、意味領域、境界、階層、検索経路を持つ抽象レイヤーとして利用可能になります。
3. なぜ EFLC か
3.1. 既存ベクトルを再利用して初期コストを抑える
Azure AI Searchのベクトル検索用インデックスには、すでに埋め込みベクトルが保存されています。EFLCはこのベクトルフィールドを再利用します。
つまり、可視化のために全文書を再度埋め込み生成する必要はありません。既存インデックスからCollection(Edm.Single)などのベクトルフィールドを検出し、取得可能なベクトルだけをサンプリングしてクラスタリングします。
実装では、ベクトルフィールドが retrievable: false または stored: false の場合は取得できないため利用することはできません。
3.2. チャンクインデックスの偏りを Adaptive Sampling で抑える
RAG 用インデックスでは、1つの PDF や Web ページが複数チャンクに分割されることがよくあります。この場合、単純に先頭から topN 件を取得すると、同じ親文書由来のチャンクばかりが散布図に並ぶことがあります。
Index Cluster Visualizer は、Eval Dataset Generator と同じ detectIndexStructure() を再利用して、インデックス構造を推定します。
| 構造 | サンプリング戦略 | 狙い |
|---|---|---|
| Chunked | 親フィールドをファセットで列挙し、親ソースごとにチャンクを分散取得 | 同一PDFや同一ページへの偏りを抑える |
| Independent | 総件数に対して分散した$skipオフセットから取得 |
インデックス先頭への偏りを抑える |
| Unknown | Simple Scanにフォールバック | 判定できない場合も最低限の可視化を可能にする |
現行値では、最大サンプル数は 10,000 件、Simple / Independent の並行度は6、Chunked Sampling の並行度は5です。Azure AI Search の $skip 上限を踏まえ、実装側では 100,000 を上限として扱います。
3.3. ブラウザ内計算で素早く探索できる
クラスタリングと次元削減は重い処理ですが、RAGOps Studio では Web Worker に移譲しています。UI スレッドを止めずに、次の処理を実行します。
| 処理 | 実装 | 特徴 |
|---|---|---|
| K-Means++ | kMeans() |
seeded PRNGにより再現性を確保 |
| 階層K-Means | hierarchicalKMeans() |
Macro→Microの2段階クラスタリング |
| PCA | pcaReduce2D() |
高速で全体傾向を見やすい |
| UMAP | umapReduce2D() |
局所構造と大域構造のバランスを見やすい |
| t-SNE | tsneReduce2D() |
局所的なクラスター分離を確認しやすい |
| クラスター関係グラフ | buildClusterGraph() |
セントロイド類似度とBridge Documentからエッジを作る |
K-Means++ は、クラスター数kをユーザーが指定する前提ではありますが、ブラウザ内で動かしやすく、クラスターの大まかな主題領域を掴むには十分軽量です。
3.4. 階層クラスターで「粗く見る」と「細かく見る」を切り替える
単一のkだけでは、クラスターが粗すぎたり細かすぎたりします。そこで階層モードでは、全体をMacroクラスターに分けたあと、各Macroの内部をMicroクラスターに分けます。
散布図ではフラット/階層を切り替えられます。フラットでは通常のクラスターを見て、階層ではマクロに属するマイクロの分布を見ます。クラスター関係グラフもマクロ全体像から、特定マクロに属するマイクログラフへドリルダウンできます。
3.5. 「近いクラスター」を説明可能なエッジとして扱う(開発中)
クラスター関係グラフは、単に近いクラスターを線で結ぶだけではありません。まずセントロイド類似度で候補エッジを作り、追加の根拠がある場合に説明付きエッジとして扱います。
| 根拠 | 内容 |
|---|---|
| Centroid similarity | クラスター重心同士のコサイン類似度 |
| Bridge Document | 自クラスターだけでなく隣接クラスターにも近い境界文書 |
| Shared Facet | EFLC v2の意味プロファイルで共有される観点 |
| Shared Keyword | 要約やcriteriaから抽出される共有語 |
| Signature overlap | 意味プロファイルの重なりを統合した補助スコア |
エッジにはlow / medium / highの confidence が付きます。low はセントロイドが近いだけの候補、medium は Bridge Document または意味プロファイルの重なりがある関係、high は複数の根拠が揃った関係です。
4. EFLC v1 / v2— クラスターを検索可能な意味プロファイルへ変換する
クラスタリング結果は数値上のグループです。そのままでは「クラスター3が何を意味するのか」は人間にも検索 API にも分かりません。そこで、選択した LLM 設定を使ってクラスター説明を生成します。
各クラスターに要約テキストを付加
ユーザーの多様なモデル利用を想定して、OpenAI, Azure OpenAI, Foundry Local, LMStudio でそれぞれホスティングしているモデルを簡単に切り替え可能です。
クラスター要約の実験用には Foundry Local 上でホスティングしている gpt-oss-20b を使ってコストを削減するといった利用法も考えられます。
4.1. v1: 軽量クラスター要約
v1 は、クラスター単位で代表文書を集め、短いラベル、要約、キーワードを JSON で生成します。まず全体像をサクッと掴むためのモードです。
セントロイド最近傍だけに偏らないよう、Role-aware evidence を併用しています。典型的な文書だけでなく、少し離れた文書や境界文書も混ぜることで、クラスターラベルが一部の代表文書だけに引っ張られることを抑えます。
4.2. v2: 高カーディナリティ向け意味プロファイル
v2は、高分散・高カーディナリティなインデックスでもクラスター説明が雑にならないよう、より構造化されたClusterSemanticSignatureを生成します。
| 要素 | 説明 |
|---|---|
primaryLabel |
兄弟クラスターと区別できる主要ラベル |
shortSummary |
クラスター全体を説明する短い要約 |
facets |
クラスター内の主要観点。ラベル、要約、キーワード、代表文書IDを持つ |
inclusionCriteria |
このクラスターに含める条件 |
exclusionCriteria |
似ているが除外すべき条件 |
evidenceDocIds |
根拠として使った文書ID |
splitCandidate |
混合クラスターとして分割候補かどうか |
v2のポイントは、クラスターを単一ラベルに潰すのではなく、検索に使える意味プロファイルとして保存することです。後段のメタインデックス検索では、ラベルや要約だけでなく、ファセット、包含条件、除外条件、生成質問も検索対象になります。
4.3. v2 の実験的機能
ETA と HSA
ETA(Embedding Topology Analysis)は、クラスタがどれだけ凝集しているか、隣接クラスタとどれだけ混ざっているか、外れ値がどの程度あるかを測る補助分析です。EFLC v2 の要約では、曖昧なクラスタを単一ラベルへ無理に圧縮しないよう、ETA をプロンプトと Trace に含めます。
HSA(Hierarchical Signature Aggregation)は、Micro の意味プロファイルを Macro へ集約する手法です。大きなクラスタを一度に要約するより、細かい意味プロファイルをボトムアップに統合する方が、混在した主題を説明しやすくなります。
RAPTOR-lite
RAPTOR は、抽象度の違う要約ノードを木構造にして検索する手法です。Index Cluster Visualizer では、フル RAPTOR を移植するのではなく、EFLC の Macro / Micro / 生成質問 / ファセットを Azure AI Search のメタインデックスに保存する RAPTOR-lite として実装しています。
これにより、検索時に「どの抽象度のノードがヒットし、どの親子関係をたどって候補文書に到達したか」をトレースできます。
5. Global→Local 2段階検索
2段階検索は、メタインデックスで意味領域を先に探し、その候補文書 ID を使って Source Index を検索する流れです。このアプローチはまさに Microsoft GraphRAG の検索手法を参考にしています。
5.1. Overview Answer ― 概要回答生成
Local ドキュメントが見つかった場合、選択済み LLM 設定を使って Overview Answer を1件生成します。
ここで大事なのは、Global ノードは「検索スコープと意図の説明」に使い、事実主張は Local ドキュメントを主根拠にすることです。これにより、クラスター要約だけから回答を作るのではなく、元ドキュメントへ戻ったうえで回答概要を合成できます。
「このデータセット全体の概要は?」
検索アプローチはまだまだ改善の余地があります。
6. Traceability(追跡可能性)がビルトイン
Index Cluster Visualizer ではトレーサビリティを重要視しており、クラスター要約と 2 段階検索の両方でトレースを持ちます。
MetaClusterTrace
クラスター要約では、以下の情報をクラスターごとに保持します。
| 項目 | 内容 |
|---|---|
summaryMode |
v1またはv2
|
traceLevel |
flat / micro / macro
|
systemPrompt / userPrompt
|
LLMに渡したプロンプト |
response / error
|
LLM 応答またはエラー |
promptTokens / completionTokens / totalTokens
|
トークン使用量 |
representativeDocIds |
根拠として使った文書 ID |
evidenceStats |
evidence role の分布 |
indexFields |
どの Source Index フィールドを要約に使ったか |
pipelineSteps |
EFLC v2 の段階別処理記録 |
output |
最終的な意味プロファイル、ETA、HSA 情報 |
2段階検索のトレース
2 段階検索では、Global Search のリクエスト、Local Search のリクエスト、検索に使ったフィールド、Node Decision、候補文書 ID、Score Gate の結果がトレースに残ります。
これにより、次のような確認ができます。
- どの Global ノードがヒットしたか
- なぜそのノードから候補文書が選ばれたか
- Local Search に
search.in()フィルターが適用されたか - どの候補文書 ID が Source Index に渡されたか
- Overview Answer がどの Global ノードと Local ドキュメントを参照したか
合成データ生成と同じく、RAG の改善で重要なのは「結果が良いか悪いか」だけではありません。なぜその結果になったのかを後から追えることが、改善サイクルを回すうえで重要です。
7. 制約と緩和策
Index Cluster Visualizerは強力ですが、ブラウザ内計算とAzure AI Search REST APIを前提にしているため、いくつかの制約があります。
| 制約 | 内容 | 緩和策 |
|---|---|---|
$skip上限 |
Azure AI Searchの$skipは大きなオフセットに制限がある |
Adaptive Samplingで分散取得し、最大件数を明示的に制御する |
| ブラウザメモリ | ベクトルをFloat32Arrayとして保持するため、大規模データではメモリを消費する |
まず500〜1,000件で試し、必要に応じて増やす |
k依存 |
クラスター数が不適切だと、混合クラスターや細かすぎるクラスターが生じる | 階層モード、ETA、Traceを併用して調整する |
| 2D射影の誤読 | 散布図上の距離は元の高次元距離を完全には表さない | 散布図は概観、グラフやTraceは根拠確認として併用する |
| LLM要約の品質 | 専門用語、短すぎる本文、混在クラスターで要約精度が落ちる | EFLC v2、Role-aware evidence、ETA、HSA、Trace で確認する |
| Content Filter | 代表文書本文が Azure OpenAI の Content Filter に該当する場合がある | 本文を省略した再試行プロンプトに段階的に降級する |
| メタインデックスのコスト |
{sourceIndex}-metaはAzure AI Search上の実体として作成される |
不要になったら明示的に削除する |
使い分けの目安
| 目的 | 推奨操作 |
|---|---|
| インデックス全体の概観把握 | PCA + Flat view + v1要約 |
| 混合クラスターの分解 | Hierarchy view + Micro graph |
| 境界トピックの確認 | Cluster graph + Bridge Document |
| 高精度なクラスター名付け | EFLC v2 + Trace確認 |
| LLMコストを抑えた再検証 |
.ragmeta.jsonを読み込む |
| 可視化結果だけ共有 |
.ragvis.jsonを共有 |
| 大規模インデックスの検索空間削減 | メタインデックス生成 + Global→Local 2段階検索 |
GitHub
多種多様なインデックスの軽量・高精度な要約は難しいので開発中です。











