企業RAGで最初に問うべきはモデル品質よりデータ境界
企業RAGで問うべきなのは、どのモデルが最も流暢に答えるかだけではありません。テナント境界、権限、検索、運用証跡を検証可能にする必要があります。
モデル品質は回答の上限を決めますが、データ分離、監査可能性、安全な進化の仕組みが、検証環境を本番サービスへ移せるかを決めます。
Headless RAGアーキテクチャは何を接続するのか
Headlessアーキテクチャは、client experienceを再利用可能なknowledgeとAI serviceから分離しつつ、identity、authorization、audit、data scopeを一つのgovernance layerで統制します。
PROCESS MAP
Headless RAGのマルチテナント全体アーキテクチャ
複数の利用チャネルが共通の認証・テナント統制層を通り、企業知識とモデルサービスへ接続します。
- 01STEP
利用チャネル
企業Webサイト、モバイルアプリ、メッセージングBot、社内システム
- 02STEP
Headless API
JWTまたはAPI Keyの検証、tenant_id、RBAC、監査
- 03STEP
データと検索
オブジェクトストレージ、Queue、PostgreSQL RLS、pgvector、ハイブリッド検索
- 04STEP
生成と応答
LLM生成、出典、Request ID、SSEストリーミング
どのマルチテナント・データアーキテクチャを選ぶべきか
分離強度が高いほど、インフラ、アップグレード、運用のコストは通常増加します。
DECISION TABLE
マルチテナント・データアーキテクチャ比較
分離強度が高いほど、インフラ、アップグレード、運用のコストは通常増加します。
| 評価項目 | Shared Schema + RLS | Schema-per-tenant | Database-per-tenant |
|---|---|---|---|
| 実装方式 | tenant_idで分ける共有テーブル | 1 DB内でテナントごとのSchema | テナントごとの独立DB |
| 分離強度 | RLS設計により中から高 | 高い | 最も高い |
| 一括アップグレード | 最も容易 | テナント増加で複雑化 | 最も複雑 |
| インフラコスト | 低い | 中程度 | 高い |
| 多数テナントへの拡張 | 最適 | 中程度 | 高コスト |
| テナント単位の復元 | 複雑 | 中程度 | 最も明確 |
| 適用例 | SaaS、SMB、標準サービス | 企業カスタマイズ | 高規制、データ主権、大企業 |
分離モデルはどのように選ぶべきか
分離レベルは、機密性、カスタマイズ、バックアップと復元、データ所在地、運用コストから選びます。唯一の正解を前提にしません。
PostgreSQL RLSでテナント分離をどう実現するか
PostgreSQL Row-Level Securityは、現在のDB Transactionにあるテナント条件で読み書きを制限できます。アプリケーションがtenant filterを漏らした場合のDB側の追加防御になります。
1CREATE EXTENSION IF NOT EXISTS vector;23CREATE TABLE knowledge_chunks (4 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),5 tenant_id UUID NOT NULL,6 document_id UUID NOT NULL,7 content TEXT NOT NULL,8 embedding vector(1536),9 created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()10);1112ALTER TABLE knowledge_chunks ENABLE ROW LEVEL SECURITY;13ALTER TABLE knowledge_chunks FORCE ROW LEVEL SECURITY;1415CREATE POLICY tenant_select_policy16ON knowledge_chunks FOR SELECT17USING (tenant_id = NULLIF(current_setting('app.current_tenant_id', true), '')::uuid);1819CREATE POLICY tenant_insert_policy20ON knowledge_chunks FOR INSERT21WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant_id', true), '')::uuid);
RLSで守れるものと、置き換えられないもの
DECISION TABLE
PostgreSQL RLSの統制境界
PostgreSQL Row-Level Securityは、現在のDB Transactionにあるテナント条件で読み書きを制限できます。アプリケーションがtenant filterを漏らした場合のDB側の追加防御になります。
| 統制項目 | RLSで扱えること | 別の仕組みが必要なこと |
|---|---|---|
| 行レベルのアクセス制限 | 可能 | Policyテストと最小権限 |
| アプリ側tenant_id filterの漏れ | リスクを低減可能 | 各リクエストTransactionでSET LOCAL |
| コネクションプールとsession変数 | 自動では扱えない | 実際のpool modeと明示的Transactionをテスト |
| BYPASSRLSまたはsuperuser | 不可能 | Runtime roleをNOSUPERUSER、NOBYPASSRLSにする |
| ownerの既定回避 | 条件付き | non-owner roleと必要に応じたFORCE RLS |
| JWT検証 | 不可能 | API Gatewayまたはbackendで検証 |
| Storage、Queue、Cache、Prompt | 不可能 | エンドツーエンドでtenant-awareなPolicyとkeyを使用 |
connection poolとroleでRLSを有効に保つには
RLS Policyだけでは信頼できるテナント境界は作れません。各リクエストでtenant contextを設定し、同じ明示的Transaction内で、RLSを回避できないruntime roleにより検索・読み書きを実行します。
1BEGIN;2SET LOCAL app.current_tenant_id = 'tenant-uuid';34SELECT id, content5FROM knowledge_chunks6ORDER BY embedding <=> :query_embedding7LIMIT 8;89COMMIT;
SET LOCALは現在のTransaction内だけで有効です。Transaction poolingはBEGIN、SET LOCAL、全クエリを同じTransactionに保持する場合に利用できますが、statement poolingは利用できません。superuserとBYPASSRLSロールは常にRLSを回避し、table ownerもFORCE ROW LEVEL SECURITYがない限り既定で回避します。
Headless RAG APIはどのように設計するべきか
Headless APIはstatelessに保ち、信頼できるcredentialsからtenantとpermission scopeを導出します。clientがtenant_idを選択または上書きしてはいけません。
文書アップロードAPI
1POST /api/v1/documents2Authorization: Bearer <access_token>3Content-Type: multipart/form-data
1{2 "document_id": "d3b07384-d113-4956-a5cc-9c60012443d3",3 "status": "processing",4 "message": "文書は解析とindexingのqueueに登録されました"5}
会話と検索API
1POST /api/v1/chat/completions2Authorization: Bearer <access_token>3Content-Type: application/json
1{2 "messages": [{ "role": "user", "content": "年次有給休暇はどのように計算されますか?" }],3 "stream": true4}
企業向け応答には、source document、version、updated time、Request ID、根拠なしまたは権限不足時の明確なstateを含めます。
文書はどのようにRAGナレッジベースへ入るのか
解析、OCR、chunking、embeddingが元のHTTP requestを占有しないよう、ingestionは非同期にします。
PROCESS MAP
ナレッジベース登録フロー
アップロード要求と、解析、分割、Embeddingの長時間処理を分離し、利用者を待たせません。
- 01STEP
アップロードと検証
形式、サイズ、身元、tenant_id、権限を確認します。
- 02STEP
安全な保存とスケジュール
原本をテナント分離ストレージへ保存し、作業をQueueへ送ります。
- 03STEP
解析と分割
WorkerがOCRとレイアウト解析を実行し、文書構造から追跡可能なchunkを作ります。
- 04STEP
ベクトル化
Embeddingサービスを呼び、モデルバージョンと出典Metadataを保持します。
- 05STEP
RLS経由の書き込み
tenant contextを設定し、本文とvectorを書き、処理状態を更新します。
Chunkingは固定文字数ではなく文書構造に従う
heading、clause、semantic boundary、文書種別を使い、sourceとversionの追跡性を保つchunkを作ります。
DECISION TABLE
文書種別ごとのChunking戦略
Chunkingでは元の構造と追跡可能なMetadataを保持します。
| 文書種別 | Chunkingの基準 | 必須Metadata |
|---|---|---|
| FAQ | 1つの質問と回答 | Category、product、version |
| 規程 | Article、paragraph、clause、heading | effective date、version、owner |
| 契約 | clauseとattachment | version、party、term |
| 製品manual | chapter、function、step | model、software version、page |
| 会議記録 | topic、decision、action | date、attendee、owner |
Embeddingモデル変更時に次元をどう進化させるか
vector(1536)は固定次元のデータ契約であり、将来の任意モデル向けの仮置きではありません。新モデルは意味空間と出力次元の両方を変えるため、model nameとversionの記録だけでは移行計画になりません。
DECISION TABLE
Embedding次元とモデル移行
vector(1536)は固定次元のデータ契約であり、将来の任意モデル向けの仮置きではありません。新モデルは意味空間と出力次元の両方を変えるため、model nameとversionの記録だけでは移行計画になりません。
| 戦略 | 適用条件 | 必要な統制 |
|---|---|---|
| 新しいembeddings table | モデルまたは次元が変わる | dual-write、再ベクトル化、新index作成後にreadを切替 |
| 新しいvector column | 同一chunk tableで短期の二重運用 | 次元、index、rollback期間を個別に管理 |
| 次元未固定のvector column | 複数モデルを長期共存 | model filterと次元別partial/expression indexを使用 |
| 既存columnの上書き | 旧検索が不要または停止を許容 | 全量再ベクトル化、index再構築、rollback backupを先に完了 |
1-- Example: a v2 model outputs 1024 dimensions2CREATE TABLE knowledge_chunk_embeddings_v2 (3 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),4 tenant_id UUID NOT NULL,5 chunk_id UUID NOT NULL,6 embedding_model TEXT NOT NULL,7 embedding vector(1024) NOT NULL,8 created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()9);1011CREATE INDEX CONCURRENTLY knowledge_chunk_embeddings_v2_hnsw12ON knowledge_chunk_embeddings_v213USING hnsw (embedding vector_cosine_ops);
RAGはどのように検索し回答を生成するのか
各queryでは、hybrid retrieval、reranking、model generation、citation、audit loggingの前にidentityとtenant scopeを確立します。
PROCESS MAP
ユーザー質問とRAG検索フロー
各queryはretrieval、generation、auditの前にidentityとtenant scopeを確立します。
- 01STEP
requestを検証
信頼できるTokenからtenant_id、user_id、scopeを読みます。
- 02STEP
data scopeを制限
Transactionでtenant contextを設定し、PostgreSQL RLSで行を分離します。
- 03STEP
検索と順位付け
vector、keyword、metadata filter、rerankingを組み合わせます。
- 04STEP
組み立てと生成
policy、企業knowledge、質問をLLMへ渡します。
- 05STEP
streamとaudit
SSEで回答とcitationを返し、model、latency、Request IDを記録します。
企業知識にハイブリッド検索が適する理由
企業知識には意味的な質問だけでなく、製品型番、規制、条項番号、正確な数値が混在します。ハイブリッド検索はvector、keyword、metadata filter、rerankingを組み合わせます。
DECISION TABLE
企業知識検索能力の比較
企業知識には意味的な質問だけでなく、製品型番、規制、条項番号、正確な数値が混在します。ハイブリッド検索はvector、keyword、metadata filter、rerankingを組み合わせます。
| 能力 | vectorのみ | keywordのみ | ハイブリッド検索 |
|---|---|---|---|
| 意味的な近さ | 強い | 弱いから中程度 | 強い |
| 製品型番 | 不安定な場合がある | 強い | 強い |
| 規制の条項番号 | 不安定な場合がある | 強い | 強い |
| 同義語 | 強い | 辞書が必要 | 強い |
| 正確な数値 | 弱め | 強い | 強い |
| Metadata権限 | 対応可能 | 対応可能 | 必須 |
テナント削除後にvector indexをどう維持するか
テナントデータの完全削除はコンプライアンス要件ですが、高頻度の削除はindex workloadも変えます。特にHNSWでは、行の削除確認だけでなく、index size、latency、recall、maintenance timeを監視します。
DECISION TABLE
Vector Index運用チェック
テナントデータの完全削除はコンプライアンス要件ですが、高頻度の削除はindex workloadも変えます。特にHNSWでは、行の削除確認だけでなく、index size、latency、recall、maintenance timeを監視します。
| イベントまたは兆候 | 運用アクション | 検証指標 |
|---|---|---|
| テナント退去または大量削除 | 分割削除とindex/統計情報の保守を計画 | table/index size、完了率、query latency |
| HNSW VACUUMの長時間化 | REINDEX INDEX CONCURRENTLY後にVACUUM (ANALYZE) | 保守window、disk余裕、書き込み影響 |
| recallまたはlatencyの悪化 | 近似検索を正確検索と抽出比較 | Recall、p95 latency、ef_searchまたはprobes |
| 高頻度更新テナント | partitionまたは独立table/indexを評価 | hot tenantが他テナントへ与える影響 |
1REINDEX INDEX CONCURRENTLY knowledge_chunks_embedding_hnsw;2VACUUM (ANALYZE) knowledge_chunks;
企業RAGの本番稼働前に何を確認するべきか
もっともらしいDemoだけでは本番受入試験になりません。稼働前に次の統制の証跡を残します。
よくある質問
1. 企業RAGのマルチテナント・アーキテクチャとは何ですか?
複数組織が一つのRAGアプリケーションを使いながら、文書、vector、権限、検索結果をDB、storage、queue、cache、log、model inputまで分離する設計です。
2. PostgreSQLは企業RAGに適していますか?
多くの中小から大規模のRAG workloadに適しています。関係データ、metadata、全文検索、transaction、pgvectorを一緒に扱えるためです。最終判断は規模、latency、運用複雑性によります。
3. PostgreSQL RLSは何を守りますか?
RLSはTransaction scopedのtenant contextにより行を制限できます。application filter漏れのリスクを減らしますが、明示的Transaction、最小権限role、connection pool testと組み合わせる必要があります。
4. Shared Schemaは必ずデータ漏えいを起こしますか?
いいえ。主なリスクは誤ったrole、tenant contextの欠落、negative test不足です。RLS、least privilege、cross-tenant testがリスクを下げます。
5. Shared Schemaが適さないのはどのような場合ですか?
独立したbackupとrestore、data residency、異なるschema、高度なcustomization、厳格なcomplianceが必要な場合は、より強い分離を評価します。
6. なぜingestionを非同期にする必要がありますか?
解析、OCR、chunking、embeddingには数秒から数分かかることがあります。QueueとWorkerによりrequest timeoutを避け、retry、recovery、status trackingを改善できます。
7. RAGのchunk sizeはどの程度にすべきですか?
万能の固定サイズはありません。文書構造、意味境界、条項、実際の質問を使い、retrievalとanswer quality testで調整します。
8. ハイブリッド検索とは何ですか?
vector search、keyword search、metadata filtering、rerankingを組み合わせ、意味的質問と、正確な用語、型番、条項、数値の両方に対応する方法です。
9. RAGはhallucinationを完全になくせますか?
できません。検索はgroundingを改善しますが、retrieval failure、古い文書、prompt design、generation errorは残ります。citation、refusal condition、review controlが必要です。
10. Headless RAGの事業価値は何ですか?
検索と生成を統制されたAPIへ変え、Webサイト、アプリ、Bot、社内システムが同じdataとpermission modelを再利用できることです。
11. Embedding modelの変更では再ベクトル化が必要ですか?
通常は必要です。モデルにより意味空間と次元が変わるため、新しいtableまたはcolumn、parallel index、re-embedding、controlled read cutoverを計画します。
12. 企業RAGが本番準備完了だとどう判断しますか?
tenant isolation、pool transaction scope、role bypass、文書version、実問集合、citation、refusal behavior、performance、dimension migration、deletion-index operationの証跡を確認します。
結論:アーキテクチャは唯一の技術回答を選ぶことではない
多くのSaaS RAG製品では、Headless API、Shared Schema、PostgreSQL RLS、pgvector、非同期Workerが費用対効果の高い出発点になります。
重要なのは単一の技術を選ぶことではありません。システム全体が安全に分離され、安定運用され、隠れたデータリスクなしに進化し、各回答の根拠を提示できるかです。