從零建一套可上線的 RAG:完整流程與關鍵決策點
把前面的零件組起來。這篇是一條端到端的實作路線,含每個決策點的判斷依據。
單獨看每個 RAG 元件都不難,難的是組起來之後的整體行為。這篇按實際建置順序走一遍,每一步都標出「這裡要做什麼決定」。
假設情境:一家公司要為內部三千份文件(PDF、Word、網頁)建立問答系統,使用者約兩百人,需要權限控制與可追溯的引用。
階段一:資料盤點(最容易被跳過)
- 統計文件型別分布——原生 PDF、掃描件、網頁各佔多少,決定前處理的投入。
- 確認權限模型——哪些文件哪些人能看,這會決定 metadata 設計。
- 確認更新頻率——每天變動的文件與五年沒改的文件,同步策略不同。
- 抽樣 20 份人工閱讀,找出格式陷阱(雙欄、表格、頁首頁尾)。
階段二:擷取與清洗
def ingest(path):
kind = detect_kind(path) # native_pdf | scanned | docx | html
if kind == 'native_pdf':
blocks = extract_pdf_blocks(path) # 保留座標與頁碼
elif kind == 'scanned':
blocks = ocr_with_layout(path)
else:
blocks = extract_generic(path)
blocks = strip_running_heads(blocks)
blocks = fix_reading_order(blocks) # 雙欄處理
return blocks決策點:掃描件的比例若低於一成,可以先跳過 OCR 只處理原生文件,讓系統早點上線。完美的擷取流程可以之後再補。
階段三:切塊與索引
- 結構感知切塊,標題路徑附在片段開頭。
- 父子結構:子片段 250 字用於檢索,父片段為整個小節。
- metadata 必含:doc_id、page、acl(權限標籤)、effective_date、deprecated、source_url。
{
"id": "hr-leave-2026#c018",
"parent_id": "hr-leave-2026#s03",
"text": "[人事規章 > 請假 > 特休] 到職滿一年者……",
"embedding": [...],
"meta": {"doc_id": "hr-leave-2026", "page": 4,
"acl": ["all_staff"], "deprecated": false,
"effective_date": "2026-01-01"}
}階段四:檢索管線
def retrieve(q, user, k=5):
q2 = rewrite(q, history=user.history) # 查詢改寫
flt = {'acl': {'$in': user.roles}, 'deprecated': False}
vec = vector_search(q2, top_k=40, filter=flt)
kw = bm25_search(q2, top_k=40, filter=flt)
cands = rrf([vec, kw])[:20] # 混合檢索
ranked = rerank(q2, cands)[:k] # 重排
parents = dedupe_parents(ranked) # 取父片段並去重
return parents, {'rewritten': q2, 'n_cand': len(cands)}決策點:權限過濾一定要在檢索層(filter),不能在取回後過濾。這是資安要求,沒有折衷空間。
階段五:生成與引用
片段編號、強制引用、程式驗證引用有效性、驗證失敗則降級為「僅顯示相關段落」。這一段前面的免費教程已詳細講過,直接沿用。
階段六:上線前的量測
- Recall@5 ≥ 0.85(用 100 題金標評測集)。
- 引用有效率 = 100%(無效引用一律攔截)。
- p95 延遲符合體驗要求。
- 權限測試:用低權限帳號跑一遍高權限文件的問題,必須全部查無資料。
階段七:上線後的維運節奏
- 每日:同步變更文件、檢查同步失敗清單。
- 每週:抽查 20 筆真實問答,補進評測集。
- 每月:重跑完整評測、檢視棄答率與零結果率趨勢。
- 每季:檢視切塊與嵌入模型是否該升級(需重建索引,要排期)。
第一版刻意縮小範圍:挑一個部門、五百份文件、一種文件格式。範圍小的系統能真正上線並收到回饋,範圍大的系統通常會卡在資料清洗階段。
訂閱後繼續閱讀全文
本篇為訂閱者專屬內容。訂閱後可取得下列權限:
- 解鎖全部內容權限
- 閱讀不限篇數
- 全站移除廣告
月卡
NT$240
開通 30 天
一次付清,開通 30 天
季卡
NT$620
開通 90 天
一次付清,開通 90 天,每天約 NT$7
年卡
NT$2,160
開通 365 天
一次付清,開通 365 天,每天約 NT$6
一次性付款,付款成功後立即開通,到期自動結束,不會再次扣款,也不需要取消訂閱。
立即訂閱
金額均為新臺幣(TWD),即實際扣款金額,不另收手續費
支援信用卡 · Apple Pay · Google Pay · WebATM · ATM 轉帳
購買須知與退款政策