metadata 過濾:讓檢索先縮小範圍再比相似度
很多檢索問題不是相似度算錯,而是根本不該搜到那批文件。
使用者問「2026 年的請假規定」,卻檢索到 2023 年的舊版辦法——這不是相似度的問題,是範圍的問題。
建索引時就要帶上 metadata
{
"text": "……",
"embedding": [...],
"meta": {
"doc_id": "hr-leave-2026",
"effective_from": "2026-01-01",
"deprecated": false,
"dept": "hr",
"lang": "zh-TW"
}
}三種常用過濾
- 時效:只搜生效中的版本,
deprecated=false。 - 權限:依使用者部門或角色限制可見範圍,這是資安要求而非優化。
- 語言:避免中文問題檢索到英文原版文件。
過濾要在檢索端做
常見錯誤是先取 top-k 再用程式過濾——如果前 10 筆全被濾掉,就變成沒有結果。正確做法是把條件下推到向量資料庫,讓它在候選集合內做相似度比對。
# 錯:先搜再濾,可能全被濾光
hits = [h for h in search(q, top_k=10) if not h.meta['deprecated']]
# 對:條件下推
hits = search(q, top_k=10, filter={'deprecated': False, 'dept': user.dept})權限過濾絕對不能只靠提示告訴模型「不要回答其他部門的內容」。權限是檢索層的責任,模型看不到的資料才是真的看不到。