前一篇我們把一份 PDF 拆解成 Parse、Chunk、Embedding 與 Index,讓原本只能被人閱讀的文件,變成系統可以搜尋的知識。但建立好知識庫之後,真正影響 RAG 品質的下一個問題才剛開始:當使用者提出問題時,系統究竟要怎麼從成百上千個文件片段中,把真正需要的內容找回來?
這個步驟就是 Retrieval。
搜尋看起來像是 RAG 裡的一個技術細節,實際上卻會直接決定最後的回答是否可靠。因為不論後面的 LLM 有多強,如果搜尋階段找錯資料,模型拿到的 Context 就已經錯了,最後自然很難產生正確答案。
目前最常見的兩種方式,是關鍵字搜尋(Keyword Search)與語意搜尋(Semantic Search)。兩者並不是新舊技術的替代關係,而是分別擅長處理不同類型的問題。
我們每天使用搜尋引擎時,其實已經很熟悉關鍵字搜尋的概念。它最直觀的做法,就是找出文件中是否出現與查詢相同或相近的文字。
假設企業文件裡有一個產品代碼:
ABC-2026-X15
使用者搜尋:
ABC-2026-X15
這種情境下,關鍵字搜尋通常非常可靠。因為使用者並不是想找「意思類似」的內容,而是要找到完全相同的識別資訊。
因此,像是產品編號、訂單編號、錯誤代碼、API 名稱、版本號、系統欄位名稱或正式政策名稱,都很適合使用關鍵字搜尋。
它的另一個優點是容易理解。如果搜尋結果出現某份文件,我們通常很容易解釋:
因為這份文件裡出現了你搜尋的文字。
但問題也正出在這裡:人類表達同一件事情時,不一定會使用相同的文字。
假設公司文件寫的是:
商品退貨期限為購買日起 30 天內。
使用者卻問:
「東西買了之後,幾天內可以拿回去退?」
對人來說,我們很容易理解「拿回去退」和「商品退貨」是在談同一件事情。但如果搜尋系統只依賴文字是否一致,就有可能因為使用者沒有輸入「退貨期限」這幾個字,而漏掉真正包含答案的段落。
這就是傳統關鍵字搜尋最主要的限制:它擅長找到相同的字,卻不一定理解相同的意思。
語意搜尋(Semantic Search)試圖解決的,就是這個問題。
前一篇介紹 Embedding 時,我們提到可以把一段文字轉換成一組向量。這些向量不是單純記錄文字長什麼樣子,而是試圖把文字的語意表示成可以比較的數值。
因此,當文件寫著:
「商品退貨期限為購買日起 30 天內。」
而使用者詢問:
「商品可以在幾天內退?」
系統會分別把文件與問題轉換成 Embedding,再比較它們在向量空間中的距離。
概念上可以理解成:
使用者問題
「商品可以在幾天內退?」
↓
Embedding
↓
向量表示
↓
與知識庫中的 Chunk 比較
↓
找到語意最接近的內容
即使兩邊沒有出現完全相同的句子,只要語意足夠接近,就有機會被搜尋回來。
這也是為什麼 Semantic Search 特別適合企業文件問答。真實使用者通常不會知道公司文件到底用了什麼正式用語,他們往往只會用自己習慣的方式提出問題。
例如文件寫:
「年度績效評估於每年第四季進行。」
使用者可能問:
「公司通常什麼時候做 performance review?」
又或者文件寫:
「員工應於費用發生日起 30 日內完成報銷申請。」
使用者可能問:
「出差回來多久內要把費用報掉?」
這些都是不同文字描述相同概念的情況,而語意搜尋通常比單純的文字比對更有機會找到正確內容。
看到這裡很容易產生另一個想法:既然 Semantic Search 可以理解語意,那是不是乾脆全部改用向量搜尋就好了?
問題並沒有這麼簡單。
假設使用者正在找:
ERR_CONNECTION_1024
知識庫裡同時存在:
ERR_CONNECTION_1024
ERR_CONNECTION_1025
ERR_NETWORK_1024
從語意角度來看,這些內容可能都非常接近,但使用者真正需要的是一個完全相同的錯誤代碼。這時候 Keyword Search 反而比 Semantic Search 更可靠。
產品型號也一樣。
例如:
MacBook Pro M4
MacBook Pro M4 Pro
MacBook Pro M4 Max
三者的語意幾乎一樣,但它們其實代表不同產品。如果只依賴向量距離,很可能找到「看起來非常相關,但事實上不是使用者指定版本」的資料。
這提醒我們一件很重要的事情:
語意相似,不代表事實相同。
Semantic Search 擅長回答「這兩段文字是不是在談類似的事情」,卻不一定擅長判斷產品編號、版本、日期或人名是否完全一致。
既然 Keyword Search 與 Semantic Search 都各有優缺點,實務上更常見的策略不是二選一,而是把兩者組合起來。
這就是 Hybrid Search(混合搜尋)。
可以把它理解成:Keyword Search 負責抓住那些需要精確匹配的線索,Semantic Search 則負責處理自然語言與不同說法,再把兩邊找到的結果合併或重新排序。
假設使用者問:
「ABC-2026-X15 這個產品的退貨規範是什麼?」
這個問題其實同時包含兩種類型的資訊。
ABC-2026-X15 是一個產品代碼,希望越精確越好;「退貨規範是什麼」則是一個自然語言問題,可以透過語意搜尋理解。
如果只使用 Keyword Search,系統可能很容易找到所有出現 ABC-2026-X15 的文件,卻不知道哪些段落和退貨規範最相關。反過來,如果只使用 Semantic Search,又可能找到其他產品的退貨政策。
Hybrid Search 的思維,就是不要逼單一方法完成所有事情,而是讓兩種搜尋方法各自處理自己擅長的部分。
概念上可以理解成:
使用者問題
↓
┌───────────────┐
│ │
Keyword Semantic
Search Search
│ │
└───────┬───────┘
↓
合併候選結果
↓
重新排序
↓
Relevant Chunks
Data Machi 的文件搜尋在一開始不需要立刻做到非常複雜,但現在就應該先建立這個觀念:企業資料通常同時存在精確資訊與自然語言,因此只依賴單一向量相似度,未必足以處理所有場景。
當 RAG 回答錯誤時,很多人的第一個反應是修改 Prompt,或者直接換成能力更強的模型。
但前一篇提過,一個非常重要的除錯習慣是:
先看 Retrieval,再看 Generation。
假設我們問:
「公司的國內住宿費上限是多少?」
正確答案是:
「每日 3,000 元。」
如果 Retrieval 回傳的前三個結果卻是「海外住宿標準」、「交通費規範」與「餐費補助」,那麼問題根本還沒有進到 LLM。
這時候就算把模型從原本的版本換成更大的模型,它依然沒有看到正確答案。
因此測試 RAG 時,我會建議直接把搜尋結果顯示出來,先確認最相關的幾個 Chunks 到底是什麼。
例如:
Query:
公司的國內住宿費上限是多少?
Top 1:
國內差旅住宿費每日最高補助 3,000 元。
Top 2:
海外住宿費依城市標準計算。
Top 3:
國內交通費可依實際支出報銷。
這時我們至少可以確定,正確證據已經被找回來。
如果模型最後仍然回答錯誤,才有理由往 Prompt、Context 組裝方式或 Generation 階段繼續檢查。
反過來,如果正確段落連 Top 5 都沒有出現,就應該優先檢查 Chunking、Embedding、搜尋方法或 Index,而不是急著修改 Prompt。
當 RAG 從 Demo 慢慢變成正式系統之後,我們還需要進一步回答另一個問題:
「怎麼知道搜尋真的變好了?」
最簡單的方法不是一開始就建立很複雜的 Benchmark,而是先準備一小組具有代表性的真實問題。
例如公司差旅政策知識庫,可以準備:
問題 1:
國內住宿費一天最多可以報多少?
預期文件:
Travel Policy
預期段落:
國內住宿費每日上限 3,000 元
接著分別使用 Keyword Search、Semantic Search 與 Hybrid Search,看正確段落是否出現在前幾名結果中。
這裡常會看到一個名詞叫做 Top-k。
如果我們設定:
Top-k = 3
意思就是系統會找出最相關的 3 個文件片段。
如果設定:
Top-k = 5
就是保留前 5 個結果。
因此最基本的 Retrieval 測試,可以先問:
正確答案所在的 Chunk,有沒有出現在 Top 3 或 Top 5?
如果連續測試十幾個代表性問題,就可以開始比較不同搜尋方法的差異,而不再只是依賴「我感覺這次回答比較好」。
這也是建立可靠 RAG 很重要的一個轉變:從看最終答案,進一步開始量化 Retrieval 本身的品質。
實際的企業搜尋通常還掌握比「文字內容」更多的資訊。
假設一家跨國企業的知識庫裡,同時存在台灣、日本與美國的 HR Policy。使用者詢問:
「今年的居家工作規範是什麼?」
如果只依賴 Semantic Search,系統可能會找到語意非常接近的日本政策,但使用者其實人在台灣。
這時候,我們其實已經知道幾個額外條件:
Region = Taiwan
Department = HR
Status = Active
這些資訊稱為 Metadata(中繼資料)。
與其把所有文件都交給向量搜尋,期待它自己猜出哪份才是台灣政策,更合理的做法是先透過 Metadata Filter 把搜尋範圍縮小。
概念上就像走進一間大型圖書館。
如果你知道自己要找的是「台灣、人資、目前有效版本」的文件,就不需要先把整間圖書館的書全部拿出來比較。
可以先找到正確的書架:
所有企業文件
↓
Region = Taiwan
↓
Department = HR
↓
Status = Active
↓
Keyword + Semantic Search
這就是 Metadata Filter 的價值。
而當 Keyword Search 與 Semantic Search 找回很多候選內容後,還可以再加入另一個步驟:Reranking(重新排序)。
第一階段的搜尋主要目標是快速找到「可能相關」的內容,Reranking 則再進一步比較這些候選內容與問題之間的關聯性,把最可能真正回答問題的內容排到前面。
可以把整個流程理解成:
使用者問題
↓
Metadata Filter
先縮小搜尋範圍
↓
Keyword + Semantic Search
找出候選內容
↓
Reranking
重新判斷相關程度
↓
Top-k Chunks
↓
送給 LLM
如果把它比喻成找書,Metadata Filter 是先決定「應該去哪個書架」,Keyword Search 與 Semantic Search 是從那個書架挑出可能相關的書,而 Reranking 則是在這幾本候選書中,再決定哪一本最值得先看。
不過,不論搜尋技術做到多複雜,都要記得前面提過的原則:
相似度高,只代表內容與問題很接近,不代表內容本身一定正確。
例如搜尋結果可能同時包含 2025 與 2026 年的政策,而且兩份文件內容高度相似。這時就不能只依賴 Semantic Similarity,而需要進一步考慮來源、日期、版本與有效狀態。
這也是為什麼真正的企業 RAG,最後不會只有「向量搜尋」這一層,而會逐漸加入 Metadata、版本管理、來源引用與後續的 Verification。
今天的重點:
關鍵字搜尋擅長「找到相同的字」,語意搜尋擅長「找到相近的意思」。企業搜尋真正重要的不是選邊站,而是根據資料型態與問題特性,選擇適合的搜尋方式。
下一篇,我們會處理更麻煩的文件:掃描 PDF、圖片、圖表與表格。
因為真實世界的企業文件,通常沒有我們想像中那麼乾淨。
我們下集見囉!