企業向けRAG構築の五層フレームワーク
企業向けRAG構築の五層フレームワーク
以前のRAGに関する記事では、ゼロからRAGシステムを構築した話をした。あの時はとりあえず「動いた!」という興奮が大きかった。しかし数ヶ月の実践、失敗、そしてインターンで企業シナリオに触れた経験を経て、もっと本質的な問いを考えるようになった:RAGを企業で本当に落とし込むにはどうすればいいのか?
デモレベルの「質問して回答が返ってくる」ではなく、安定稼働し、定量評価でき、問題発生時に優雅にフォールバックできる完全なシステムのことだ。
この記事では、現時点での思考フレームワークを五つの層に整理した。すべてのケースに当てはまるわけではないが、実践と思索を重ねた上での整理だ。
第一層:トップレベル設計 — シナリオ定義
多くのRAGプロジェクトが失敗するのは技術力不足ではなく、最初にシナリオを明確にしなかったからだ。コードを書く前に、三つの問いに答える必要がある。
ユーザーは誰か?
社内スタッフと社外顧客ではシステムへの要求がまったく異なる。社内スタッフはある程度のハルシネーションを許容できる — 彼らにはドメイン知識があるからだ。一方、社外顧客はゼロトレランス — 一つの誤回答がクレームにつながりかねない。これがシステム全体の品質基準を決定づける。
データはどんな状態か?
想像以上に複雑な問いだ。構造化されたテーブルなのか、半構造化ドキュメントなのか、スキャン文書のOCR結果なのか。データクレンジングの難度がRAGの天井を直接決める — 自分のプロジェクトでも痛感した。ブログのMarkdownパースとRustドキュメントのHTML処理はまったく別の課題だった。
リアルタイム性の要件は?
ナレッジベースはリアルタイム更新が必要か、日次バッチ同期で足りるか。これがデータパイプライン全体のアーキテクチャ設計に影響する。
第二層:コアパイプライン — データとアーキテクチャ
シナリオが決まったら、RAGパイプラインの構築に入る。三つのサブレイヤーに分けて考える。
データ層:クレンジングSOP + セマンティックチャンキング + メタデータ付与
「ゴミを入れたらゴミが出る」 — RAGの世界ではこれが特に残酷だ。データクレンジングは一回きりの作業ではなく、標準化されたSOPが必要だ。
- クレンジングルール:ノイズ除去(ヘッダー・フッター、透かし)、フォーマット統一、エンコーディング修正
- セマンティックチャンキング:文字数で機械的に切るのではなく、意味の境界で分割する。shinBlogのRAGサービスではLangChainのRecursiveCharacterTextSplitterを使っているが、企業シナリオではドキュメント種類ごとのカスタム戦略が必要になるだろう
- メタデータ付与:チャンクがコンテキストを失ってはならない。各チャンクにソース、タイトル、セクション、日付などのメタ情報を付与することが、検索と引用追跡の鍵となる
検索層:ハイブリッド検索 → リランキング → Top K
純粋なベクトル検索には明確な限界がある — 製品番号やエラーコードのような精密一致クエリのパフォーマンスが悪い。成熟した方法はハイブリッド検索だ:
- Vector + BM25:セマンティック類似度とキーワードマッチングの相互補完
- Rerank:クロスエンコーダで一次検索結果を再順位付けし、関連性を大幅に向上
- Top K制御:多ければ良いわけではない。通常Top 3〜5が最適なバランス — 多すぎるとノイズが増え、少なすぎると重要情報を見落とす
Kokoronの記憶システムでも同様のアプローチを適用した — ChromaDBでベクトル検索し、importanceスコアでリランキング。
生成層:System Prompt制約 + 引用追跡
検索は手段であり、生成が目的だ。この層では二つの重要な課題を解決する:
- System Prompt制約:精緻に設計したプロンプトでモデルを検索ドキュメントに基づいた回答に限定し、ハルシネーションを低減する
- 引用追跡(Citation):すべての回答にソースを明記する。信頼性を高めるだけでなく、ユーザーが情報を検証しやすくなる。企業シナリオでは引用追跡はほぼ必須だ
第三層:品質防御線 — 評価ループ
パイプラインを構築するだけでは不十分だ。評価なしではシステムの良し悪しも劣化も分からない。
オフライン評価
- Golden Dataset:人手でアノテーションした標準Q&Aセット。ベースラインとして機能する
- Recall@K:上位K件の検索結果に正解が含まれる割合 — 検索品質の指標
- Faithfulness:生成された回答が検索ドキュメントに忠実かどうか — 生成品質の指標
これらの指標がバージョンイテレーションのベースラインを構成する。
オンライン監視
リリース後はオフライン指標だけでは不十分だ:
- Bad評価率:ユーザーが「悪い」と明示的に評価した割合
- 引用クリック率:ユーザーが引用元を実際に確認するか — 高クリック率は検証の意思を示す
- 無回答率:「わかりません」と回答した割合 — 高すぎればナレッジ不足、低すぎれば無理な回答の疑い
第四層:安定性保障 — パフォーマンス最適化
企業シナリオはデモではない。実際の同時接続とコスト圧力に向き合う必要がある。
セマンティックキャッシュ
1000人が同じような質問をしているなら、なぜLLMを1000回呼ぶ必要があるのか?
セマンティックキャッシュの核心は、意味的に類似したクエリにはキャッシュ結果を返すこと。従来のキャッシュと違い、ここでの「同じ」はベクトル空間での類似度だ。効果は驚異的 — QPSを10倍に、LLM呼び出しコストを90%削減できる。
実装時の注意点:
- キャッシュ無効化戦略(ナレッジベース更新時に関連キャッシュをクリア)
- 類似度閾値の調整(低すぎると無関係な回答、高すぎるとキャッシュ無意味)
- パーソナライズシナリオでは慎用(ユーザーごとに異なるコンテキスト)
非同期ストリーミング
最初の一文字が表示されるまでの遅延がUXの鍵だ。空白画面を5秒間見つめたい人はいない。
SSE(Server-Sent Events)が現在最も主流のアプローチだ。shinBlogのRAGサービスでもFastAPI + SSEで実装している。目標は初字遅延200ms以内。
第五層:フォールバック — セーフティネット
最後の層は最も軽視されがちだが、最も重要だ — システムが不確実な時やトラブル発生時に、いかに優雅に対処するか。
回答拒否メカニズム
検索結果の類似度が閾値(例:0.6)を下回った場合、無理に回答せず直接拒否する。「わかりません」と言う方が、間違った答えを返すよりずっと良い。
Koclawの記憶システムでも、importance < 2の記憶は自動注入しないルールを設けている — 低品質な情報は提供しない方がマシだ。
ルール介入
特定の高感度クエリはLLMを通すべきではない:
- 個人プライバシーを含むクエリ
- 法律・医療などの専門分野の質問
- 特定のセンシティブキーワードを含むクエリ
これらはルールエンジンまたは人手対応にルーティングすべきだ。
降格戦略
ベクトルDBが障害を起こした場合、システムは落ちるのではなく、BM25純キーワード検索にフォールバックする。品質は落ちるが、最低限の可用性は維持できる。
個人的な所感
RAG構築は一見シンプルに見える — チャンキング、エンベディング、検索、生成の四ステップで完了。しかし本番環境で信頼性高く運用するには、この四ステップをはるかに超える考慮が必要だ。
shinBlogのRAGアシスタントから、Koclawの記憶検索システム、そしてインターンで触れた企業RAGまで — 実践を重ねるたびに痛感する:技術ソリューションは30%に過ぎず、残りの70%はエンジニアリング、可観測性、エッジケースの処理だ。
RAG関連の仕事をしている方にとって、何かの参考になれば幸いだ。
質問やディスカッションは GitHub からどうぞ。