PVL AI
開啟選單

PVL.AI Tech Blog

企業 RAG 真正難的不是模型:多租戶架構怎麼設計?

企業 RAG 多租戶架構完整指南,比較 Shared Schema、Schema-per-tenant 與獨立資料庫,解析 PostgreSQL RLS、pgvector、Headless API、文件向量化、混合檢索、租戶資料隔離及正式上線檢核流程。

BenChen

企業導入 RAG,真正困難的往往不是模型

企業 RAG 多租戶架構的核心,是建立可驗證的租戶隔離、權限控制與資料處理流程。模型能力決定回答上限,但資料邊界、稽核能力與營運可靠性,才決定系統能否進入正式環境。

當系統從概念驗證走向正式營運,企業必須回答幾個更務實的問題:不同客戶的資料如何安全隔離?大型文件如何避免拖慢前端?模型或前端載具更換時,是否需要重建整套系統?權限控制是否只依賴應用程式碼?

Headless 架構將後端定位為可重複使用的資料與 AI 服務。不同前端透過標準 API 使用相同的知識庫、權限與檢索能力,使企業能在不重建後端的情況下擴充新的使用介面。

Headless RAG 的整體架構是什麼?

Headless RAG 是以統一 API 連接多種前端、租戶驗證、企業資料與模型服務的架構。它把前端體驗與後端知識能力分離,但仍由共用治理層控制身分、權限、稽核與資料範圍。

PROCESS MAP

Headless RAG 多租戶整體架構

多種前端透過統一 API 進入身分驗證與租戶治理層,再由 RLS 與混合檢索連接企業知識及模型服務。

  1. 01STEP

    前端載具

    企業網站、App、LINE 機器人與企業內部系統

  2. 02STEP

    Headless API

    JWT/API Key 驗證、tenant_id、RBAC 與稽核

  3. 03STEP

    資料與檢索

    物件儲存、Queue、PostgreSQL RLS、pgvector 與混合檢索

  4. 04STEP

    生成與回應

    LLM 生成、引用來源、Request ID 與 SSE 串流

Headless RAG 架構流程:前端載具經由無狀態 API 完成租戶驗證,進入 PostgreSQL RLS 與混合檢索,再由模型生成附引用的串流答案。

多租戶資料架構有哪些選擇?

多租戶架構主要分為 Shared Schema、Schema-per-tenant 與 Database-per-tenant。企業應依資料敏感度、客製化程度、租戶規模、備份需求與營運成本選擇隔離層級。

DECISION TABLE

多租戶資料架構比較

隔離強度越高,通常也會增加升級、維運與基礎設施成本。

評估項目Shared Schema + RLSSchema-per-tenantDatabase-per-tenant
實作方式共用資料表,以 tenant_id 區分同一資料庫,每租戶一個 Schema每租戶一個獨立資料庫
隔離程度中至高,取決於 RLS最高
統一升級最容易租戶增加後較複雜最複雜
基礎設施成本
大量租戶擴展最適合中等成本較高
單租戶備份還原較複雜中等最清楚
適用情境SaaS、SMB、標準化服務中大型企業、欄位客製化高法遵、資料主權、大型企業
Shared Schema、Schema-per-tenant 與 Database-per-tenant 的隔離、升級、成本、擴展及備份比較。

如何選擇隔離模式?

DECISION TABLE

隔離模式選擇指南

先從商業與法遵條件判斷,再決定資料隔離層級。

企業最重視的條件優先評估方案主要原因
快速推出 SaaS MVPShared Schema + RLS結構統一、成本較低、容易擴展
支援大量 SMBShared Schema + RLS避免每個租戶建立獨立基礎設施
每家客戶有不同欄位Schema-per-tenant保留較高的結構彈性
獨立備份與還原Database-per-tenant資料生命週期邊界最清楚
跨國資料落地獨立資料庫或獨立部署較容易配合區域資料主權政策
依 SaaS 規模、客製欄位、備份還原與資料主權需求選擇多租戶隔離模式。

PostgreSQL RLS 如何建立租戶隔離?

PostgreSQL Row-Level Security 可依目前資料庫 Session 的租戶條件,自動限制可讀寫的資料列。即使應用程式漏寫 tenant_id 過濾條件,資料庫仍能提供額外防線。

SQL
1CREATE EXTENSION IF NOT EXISTS vector;
2
3CREATE 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);
11
12ALTER TABLE knowledge_chunks ENABLE ROW LEVEL SECURITY;
13ALTER TABLE knowledge_chunks FORCE ROW LEVEL SECURITY;
14
15CREATE POLICY tenant_select_policy
16ON knowledge_chunks FOR SELECT
17USING (
18 tenant_id = NULLIF(
19 current_setting('app.current_tenant_id', true), ''
20 )::uuid
21);
22
23CREATE POLICY tenant_insert_policy
24ON knowledge_chunks FOR INSERT
25WITH CHECK (
26 tenant_id = NULLIF(
27 current_setting('app.current_tenant_id', true), ''
28 )::uuid
29);

後端完成身分驗證後,應在同一筆 Transaction 中執行 SET LOCAL app.current_tenant_id = '租戶 UUID';。SET LOCAL 的作用範圍只存在於目前 Transaction,可降低連線池重複使用時殘留租戶設定的風險。

RLS 能防止什麼?不能取代什麼?

DECISION TABLE

PostgreSQL RLS 的能力邊界

RLS 提供資料列級防線,但它依賴正確的 Transaction 範圍與資料庫角色設計。

控制項目RLS 可處理仍需其他機制
資料列存取限制可以Policy 測試與最小權限
應用程式漏寫 tenant_id可降低風險每筆請求在同一 Transaction 設定 SET LOCAL
連線池與 Session 變數不可以自動處理明確 Transaction、SET LOCAL 與實際 pool 模式測試
BYPASSRLS/superuser不可以Runtime role 必須為 NOSUPERUSER、NOBYPASSRLS
表擁有者預設繞過不一定Runtime role 非 owner;必要時 FORCE ROW LEVEL SECURITY
JWT 真偽驗證不可以API Gateway/後端驗證
檔案儲存隔離不可以Bucket Path 與 Storage Policy
Queue 工作隔離不可以Job Payload 與 Worker 權限
Cache Key 隔離不可以租戶化 Cache Key
LLM Prompt 外洩不可以Prompt 組裝與輸出治理
PostgreSQL RLS 可處理與不可取代的多租戶安全控制項目。

RLS 上線時,連線池與角色權限要如何避免失效?

RLS Policy 不會自行建立可信任的租戶範圍。每個請求都必須在同一筆資料庫 Transaction 中設定 tenant_id,並以不具繞過權限的 runtime role 執行後續讀寫與檢索。

SQL
1BEGIN;
2SET LOCAL app.current_tenant_id = 'tenant-uuid';
3
4-- 所有 tenant-scoped 讀寫與向量檢索都在同一筆 Transaction 中
5SELECT id, content
6FROM knowledge_chunks
7ORDER BY embedding <=> :query_embedding
8LIMIT 8;
9
10COMMIT;

SET LOCAL 僅在目前 Transaction 有效;在 Transaction 外執行會產生警告且不生效。因此不能用跨請求的 session SET 取代這個界線,也不能把設定 tenant_id 與實際查詢拆到不同的 Transaction。

PgBouncer 的 transaction pooling 並非必然不安全,但應用程式必須以明確 Transaction 包住 SET LOCAL 與所有查詢。statement pooling 禁止多敘述 Transaction,不能承載此模式;驗證時必須以正式環境相同的 pool mode 進行跨租戶負向測試。

superuser 與具有 BYPASSRLS 的角色會繞過 RLS;表擁有者預設也會繞過,除非啟用 FORCE ROW LEVEL SECURITY。實務上應讓 application runtime 使用非 owner、NOSUPERUSER、NOBYPASSRLS 的獨立角色,並僅授與必要的資料表權限。

Headless RAG API 應如何設計?

Headless API 應保持無狀態,並由伺服器根據可信任憑證解析租戶與權限。tenant_id 不應由前端自行指定或覆寫。

文件上傳 API

HTTP
1POST /api/v1/documents
2Authorization: Bearer <access_token>
3Content-Type: multipart/form-data
JSON
1{
2 "document_id": "d3b07384-d113-4956-a5cc-9c60012443d3",
3 "status": "processing",
4 "message": "文件已排入解析與索引流程"
5}

對話與檢索 API

HTTP
1POST /api/v1/chat/completions
2Authorization: Bearer <access_token>
3Content-Type: application/json
JSON
1{
2 "messages": [
3 {
4 "role": "user",
5 "content": "公司的特休制度如何計算?"
6 }
7 ],
8 "stream": true
9}

企業應用不應只回傳模型答案,也應提供引用文件、文件版本、更新時間、Request ID,以及找不到依據或權限不足時的明確狀態。

文件如何進入 RAG 知識庫?

文件建立流程應採非同步設計,避免解析、OCR、切片與向量化占用原始 HTTP Request。

PROCESS MAP

知識庫文件建立流程

上傳請求與耗時的解析、切片及向量化工作解耦,避免前端等待。

  1. 01STEP

    上傳與驗證

    檢查格式、大小、身分、tenant_id 與權限。

  2. 02STEP

    安全儲存與排程

    原始文件寫入租戶隔離儲存,工作送入 Queue。

  3. 03STEP

    解析與切片

    Worker 執行 OCR、版面解析,依文件結構建立可追溯片段。

  4. 04STEP

    向量化

    呼叫 Embedding 服務,保留模型版本與來源 Metadata。

  5. 05STEP

    RLS 安全寫入

    設定租戶 Session,寫入文字、向量並更新處理狀態。

企業 RAG 文件建立流程:上傳與租戶驗證後,經安全儲存、Queue 排程、解析切片、Embedding,再以 RLS 寫入知識庫。

文件切片不能只設定每段500字

DECISION TABLE

不同文件類型的切片策略

切片應沿用文件原有結構,並保存可追溯的版本與來源資訊。

文件類型建議切片依據必須保留的 Metadata
FAQ一組問題與答案類別、產品、版本
規章制度條、項、款及標題層級生效日、版本、權責部門
合約條款與附件結構版本、當事人、有效期間
產品手冊章節、功能與操作步驟型號、軟體版本、頁碼
會議紀錄議題、決議與待辦日期、出席者、負責人
FAQ、規章、合約、產品手冊與會議紀錄的建議切片方式及必要 Metadata。

Embedding 模型更換時,向量維度要如何演進?

vector(1536) 是固定維度的資料契約,不是可任意替換模型的預設值。若新版模型輸出不同維度,現有欄位與其近似索引無法直接相容;只記錄 model name 或 version 並不足以完成遷移。

DECISION TABLE

向量維度與模型遷移策略

模型版本、向量維度、索引與查詢切換必須一起設計。

策略適用情境必要控制
新版 embeddings table維度或模型語意空間改變平行寫入、重新向量化、建立新版索引後再切換讀取
新版 vector 欄位同一 chunk 表需要短期雙軌新舊欄位各自維護維度、索引與回滾時間窗
未限制維度的 vector 欄位多模型長期共存每個維度以 model filter 搭配 partial/expression index;不可混用比較
直接覆寫既有欄位沒有舊版查詢或可接受停機先完成全量 re-embedding、索引重建與回滾備份
不同向量維度的模型不可直接共用同一個近似索引;應採新版表、欄位或模型專屬索引策略。
SQL
1-- 範例:新版模型輸出 1024 維,採獨立的 v2 embeddings table
2CREATE 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);
10
11CREATE INDEX CONCURRENTLY knowledge_chunk_embeddings_v2_hnsw
12ON knowledge_chunk_embeddings_v2
13USING hnsw (embedding vector_cosine_ops);

使用者提問時,RAG 如何完成檢索?

一次完整查詢會經過身分驗證、租戶限制、混合檢索、內容排序、模型生成與引用回傳。

PROCESS MAP

使用者提問與 RAG 檢索流程

每次查詢都先確立身分與租戶邊界,再進行檢索、生成與稽核。

  1. 01STEP

    驗證請求

    解析 Token 中的 tenant_id、user_id 與 scope。

  2. 02STEP

    限制資料範圍

    Transaction 內設定租戶 Session,由 PostgreSQL RLS 隔離。

  3. 03STEP

    混合檢索與排序

    結合向量、關鍵字、Metadata Filter 與 Reranking。

  4. 04STEP

    組裝與生成

    合併系統規則、企業知識與問題後交由 LLM 生成。

  5. 05STEP

    串流與稽核

    透過 SSE 回傳答案和引用,記錄模型、延遲與 Request ID。

企業 RAG 查詢流程:身分驗證、租戶限制、混合檢索、Reranking、LLM 生成、SSE 引用回傳與稽核。

為什麼繁體中文企業知識庫適合混合檢索?

繁體中文企業資料同時包含語意、專有名詞、型號、法規條號與精確數字,因此通常比純向量搜尋更需要混合檢索。

DECISION TABLE

企業知識檢索能力比較

混合檢索同時處理語意相近與必須精準命中的企業詞彙。

能力純向量搜尋關鍵字搜尋混合檢索
理解語意近似弱至中
產品型號可能不穩定
法規條號可能不穩定
同義詞需建立字典
精確數字較弱
Metadata 權限可搭配可搭配必須搭配
純向量、關鍵字與混合檢索對語意、型號、條號、數字及權限條件的能力比較。

大量刪除與租戶下線後,如何維護向量索引?

完整刪除租戶資料是合規與資料生命週期的必要能力,但大量刪除也會改變向量索引的工作負載。特別是 HNSW,在高頻刪除後應把索引大小、查詢延遲、召回率與 VACUUM 時間納入營運監控,而不是只確認資料列已刪除。

DECISION TABLE

向量索引維運檢核

大量刪除、模型遷移與高頻更新都應有可排程的索引維運流程。

事件或訊號維運動作驗證指標
租戶下線或大量刪除分批刪除並安排索引與統計資訊維護table/index size、刪除完成率、查詢延遲
HNSW VACUUM 時間拉長先 REINDEX INDEX CONCURRENTLY,再 VACUUM (ANALYZE)維護窗口、磁碟餘裕、寫入影響
召回率或延遲惡化以精確搜尋抽樣比對近似搜尋Recall、p95 latency、hnsw.ef_search 或 ivfflat.probes
高頻增刪的租戶評估分區或獨立 table/index熱租戶對其他租戶的召回與速度影響
刪除大量向量後,應以索引大小、召回率、延遲與維護時間共同判斷是否重建索引。
SQL
1-- 依維護窗口與容量計畫執行;先重建 HNSW,再清理 dead tuples
2REINDEX INDEX CONCURRENTLY knowledge_chunks_embedding_hnsw;
3VACUUM (ANALYZE) knowledge_chunks;

企業 RAG 上線前應檢查什麼?

企業不能只用 Demo 回答看起來合理作為上線標準。至少應完成以下檢查:

常見問題 FAQ

1. 什麼是企業 RAG 多租戶架構?

企業 RAG 多租戶架構,是讓多家企業共用同一套 RAG 應用,同時隔離各自文件、向量、權限與查詢結果的系統設計。隔離範圍應涵蓋資料庫、物件儲存、Queue、快取、日誌與模型輸入。

2. PostgreSQL 適合建立 RAG 應用嗎?

PostgreSQL 適合許多中小型至中大型 RAG 應用,因為它能同時管理結構化資料、Metadata、全文搜尋、交易一致性與 pgvector。是否需要專用向量資料庫,仍應依向量規模、查詢延遲與營運複雜度評估。

3. PostgreSQL RLS 是什麼?

PostgreSQL RLS 是資料列級安全性機制,可依目前資料庫 Transaction 內的租戶條件限制可讀寫資料列。它能降低應用程式漏寫租戶過濾條件的風險,但必須搭配明確 Transaction、最小權限 runtime role 與連線池模式測試,不能單靠 Policy 視為完整隔離。

4. Shared Schema 會造成資料外洩嗎?

Shared Schema 本身不必然造成資料外洩。主要風險來自錯誤的權限設定、過高的資料庫角色、未設定租戶範圍或缺乏負向測試。RLS、最小權限與跨租戶測試可降低風險。

5. 什麼情況不適合使用 Shared Schema?

當客戶需要獨立備份、區域資料落地、不同 Schema、高度客製化或嚴格法遵時,應評估 Schema-per-tenant、Database-per-tenant 或完全獨立部署。

6. 為什麼文件向量化需要非同步處理?

文件解析、OCR、切片與 Embedding 可能需要數秒至數分鐘。採用 Queue 與背景 Worker,可避免 API 逾時,也更容易處理重試、失敗復原及狀態追蹤。

7. RAG 文件應該切成多大?

沒有適用所有文件的固定切片大小。切片應依標題層級、段落語意、條款結構及實際問題設計,再透過召回率與答案正確率測試調整。

8. 什麼是混合檢索?

混合檢索結合向量搜尋、關鍵字搜尋、Metadata Filter 與 Reranking,同時處理語意問題與產品型號、法規名稱、條號及精確數值。

9. RAG 可以完全避免 AI 幻覺嗎?

不可以。RAG 能提供較可靠的企業知識依據,但仍可能受到檢索失敗、文件過期、Prompt 設計與模型生成錯誤影響。正式系統應提供引用來源、拒答條件與人工覆核機制。

10. Headless RAG 的商業價值是什麼?

Headless RAG 將知識檢索與生成能力轉成標準 API,讓網站、App、通訊機器人與內部系統共用相同的資料、權限與治理機制。

11. Embedding 模型更換後需要重新向量化嗎?

通常需要。不同 Embedding 模型可能同時改變語意空間與向量維度;固定維度欄位例如 vector(1536) 無法直接寫入不同維度的向量。除了記錄模型名稱與版本,還應規劃新版欄位或新版 embeddings table、平行索引、重新向量化及讀取切換。

12. 如何判斷企業 RAG 可以正式上線?

至少應完成租戶隔離、連線池 Transaction 範圍、BYPASSRLS/owner 權限、文件版本、真實問題集、引用正確率、拒答、效能、向量維度遷移與大量刪除後索引維運測試,不能只依 Demo 的回答觀感判斷。

結論:架構決策不是選出唯一技術答案

對多數 SaaS 型 RAG 產品而言,Headless API、Shared Schema、PostgreSQL RLS、pgvector 與非同步工作流程,可以形成具成本效率的起始架構。但當企業具有資料主權、獨立備份、客製 Schema、區域部署或高法遵需求時,系統仍可能需要升級隔離層級。

企業 RAG 從技術展示走向商業產品,關鍵不只是模型回答得多流暢,而是整套系統能否安全隔離、穩定營運、持續演進,並為每一個答案提供可信任的資料依據。