返回文章列表
程式2026年7月10日 19:31

淺談 RAG

RAG 是什麼?

RAG (Retrieval-Augmented Generation 檢索增強生成)。

是一種讓 LLM 基於外部知識庫來回答問題的架構。每次提問時,都會從知識庫中檢索相關的資料,將這些資料與提問一起送給 LLM,讓它可以看著資料回答,而不是憑空想像。

由於 LLM 的一個根本限制是:它的知識量會停留在模型訓練完成的那個時間點。所以它不會知道今天的新聞、今天上市的新產品、新技術的發表等等。

LLM 擁有的大多是公開知識,因此無法直接回答像是企業內部文件、客戶資料等私有資訊的問題,容易會產生幻覺硬湊一個答案。

RAG 就是一種在 LLM 不需要重新微調的前提下,讓它擁有在生成答案時,可以即時查資料、引用資料、使用私有資料的架構。

就像是一位正在考試的學生,考試的內容都是課本裡沒出現過的考題,但是桌上有放一本參考書,那他就可以即時翻閱參考書,引用書裡的內容來寫考題。

什麼時候需要 RAG?

1. 需要處理企業專屬資料或私有資料時

當問題跟企業或私有資料相關時,就必須依賴外部知識庫來讓 LLM 補足這些相關知識,解決 LLM 無法處理公開知識以外的問題。例如:公司內部文件、API 規格、客戶資料等等。

2. 知識需要頻繁更新時

只需要將文件內容更新進知識庫,LLM 就能即時反映最新內容,不用另外微調 LLM。

3. 需要極力避免 AI 幻覺,且答案必須可追溯

讓 LLM 看著知識庫裡的資料來回答問題,並且每個回答都能對應回原始的資料來源,以減少幻覺的發生。

RAG 的基本流程

RAG 主要可以分為準備期回答期兩個流程。

準備期負責處理原始文件,建立可以檢索的知識庫。回答期則是將使用者提問與知識庫進行比對,找出最相關的資料一起送給 LLM 生成回答。

準備期:Indexing (建索引)

首先,系統要先從各種格式的文件中,抽取裡面的文字。然後把這些文字切割成片段 (Chunking),接著將片段向量化 (Embedding),最後存入向量資料庫 (Vector DB)。

這個步驟是一開始的準備階段,需要把所有原始文件轉成可以被搜尋的形式。通常只會跑一次,直到知識庫需要更新才會需要重跑 Indexing。

Chunking 是什麼?

Chunking 是將原始文件切成較小,且具備完整語意的片段的過程,是決定 RAG 檢索品質上限的關鍵步驟。

那我們不能一開始把整份文件直接丟進資料庫就好了嗎?如果直接將整份文件 Embedding 會發生什麼事呢?

1. 語意稀釋

當一個片段包含太多不同主題的內容時,向量的特徵會變得模糊,會影響檢索的精準度,導致搜尋結果不準確。

2. 長 Context 問題

LLM 會有注意力偏差的問題,當 Context 過長時,通常中段的內容很容易會被 LLM 忽略,只取前面和後面的內容。

3. 更新成本

如果只是某一頁文件的文字有更新,每一次 Embedding 時,就要整份重跑,時間與成本大幅增加。

4. Token 上限

text-embedding-3-small 這個模型的 Token 上限大概只有 8k,如果將整份大概五千字的文件直接丟進去的話,就容易會超出 Token 上限,那麼就會遺失掉文件裡面的部分內容。

Embedding 是什麼?

處理好片段的文字之後,還要將這些文字向量化。前面有多次提到 Embedding 是什麼呢?

Embedding 是將每一段文字轉換成一組固定長度的數字的過程,也就是文字向量化。

電腦本身看不懂文字,它沒辦法直接比較語意相近的文字,但是它可以計算兩組數字的向量距離。

透過 Embedding,把具有相似語意的文字放在向量空間中彼此接近的位置,電腦就有辦法判斷文字之間的相似度。

回答期:Retrieval(檢索)

當使用者提出問題時,就會進入 RAG 的回答期。目標是將使用者提問轉為向量後,從資料庫中找出語意相關的片段,讓 LLM 生成答案。

主要分成 Recall、Reranking、Generation 三個階段。

1. Recall 階段

初步檢索相關的資料,先從大量的資料中,用快速的方法找出一些可能相關的 Chunks。

依據相似度結果由高到低排序,取出前 k 個最相關的 Chunks,像是一個搜尋排行榜。這就是 Top-K,會作為 Prompt 的一部分給 LLM 參考。

關鍵字相似度

傳統的搜尋方法。判斷提問內容的詞是否有出現在文件中、出現了多少次、是否是稀有的詞等。

向量相似度

知識庫文件切成 Chunk 後,透過 Embedding 存進了 Vector DB 中,我們就可以使用向量比對的方式找出語意相關的片段。

  • 餘弦相似度 (Cosine Similarity):計算兩個向量的夾角,夾角越小表示方向越一致、語意越相似;反之夾角越大,表示語意越不相關。通常會看到數字是 -1 ~ 1 之間。

  • 點積相似度 (Dot Product):直接計算兩個向量的內積,兩個向量的對應數字相乘後加總。

由於許多 Embedding 模型都會做 L2 正規化,點積結果和餘弦相似度數值上會很接近,所以實務上會直接使用點積相似度,因為它算起來最快、最省伺服器資源。

那電腦是怎麼判斷兩組文字之間的相似度?

舉個例子,我們假設這個 Embedding 模型只有 3 個維度,設計三組詞彙透過 Embedding 變成的向量會是這樣:

詞彙第一維度 (水果)第二維度 (科技)第三維度 (食物)
香蕉0.950.020.98
微軟0.000.990.01
蘋果0.650.700.60

註1:實際的 text-embedding-3-small 模型有 1536 個維度

註2:這個範例只是簡單的示意用來方便理解,實際維度並不是人類看得懂的語意標籤

可以看到香蕉微軟,在任何維度的數字上都有很大的差異,這兩個向量在空間中的夾角非常大,電腦就會認為這兩個詞彙毫無關係。

蘋果香蕉在水果與食物的維度上數字比較接近,電腦就會認為這兩個詞彙比較相似。

有趣的是,蘋果微軟在電腦眼中,也會被認為是相似的詞彙,因為它們在科技的維度上很接近 (Apple 公司)。

所以像是蘋果這種多義詞的這種情況,就需要靠著 Chunk 的上下文來判斷最終的語意。例如:

  • 「今天吃了一顆蘋果」,算出來的向量會就會比較接近香蕉
  • 「今天蘋果發表了最新的產品」,算出來的向量會就會比較接近微軟

2. Reranking 階段

在 Recall 階段的時候,通常是從大量資料中先快速找出可能相關的 Chunks。這個階段的 Top-K 並不一定非常精準,因此會需要重新評分,把最有相關的資料排序在最前面。

要注意的是,Reranking 是在 Advanced RAG 才加入的階段。傳統 RAG 在取得 Top-K 就會直接送給 LLM 了

3. Generation 階段

最後,把使用者提問以及最終結果的 Top Chunks 一起打包進 Prompt 裡,送給 LLM 生成最終答案。

結構會類似以下例子:

{
  "system": "你是一個專業的電商客服助理,請根據下方提供的參考資料回答使用者問題。若參考資料中沒有相關資訊,請明確告知「目前查無相關資料」,不要編造答案。回答時請註明引用的來源編號。",
  // 最終篩選出的 Top Chunks
  "context": [
    {
      "chunk_id": "doc_012_chunk_3",
      "source": "退換貨政策.pdf",
      "score": 0.89,
      "content": "商品若有瑕疵,可於收到商品後 7 天內申請退換貨,運費由賣家負擔。"
    },
    {
      "chunk_id": "doc_045_chunk_1",
      "source": "常見問題FAQ.md",
      "score": 0.82,
      "content": "退換貨需保持商品全新未使用狀態,並附上原始包裝與發票。"
    },
    {
      "chunk_id": "doc_012_chunk_5",
      "source": "退換貨政策.pdf",
      "score": 0.71,
      "content": "客製化商品、拆封後的食品類商品不適用退換貨規定。"
    }
  ],
  // 使用者提問
  "user_query": "我收到的衣服有瑕疵,可以退貨嗎?運費要自己出嗎?",
  "generation_config": {
    "model": "claude-sonnet-5",
    "max_tokens": 1000,
    "temperature": 0.3
  }
}

從範例可以看到 source 是這段內容出自於某一份文件裡。這樣 LLM 生成答案時,就可以一起附上引用的資料來源。

RAG 發展至今

從 RAG 的誕生、ChatGPT 的出現造成需求的爆發,到後來社群開始意識到傳統 RAG 能力的限制,已經開始發展成各種改良 RAG 技術,簡單介紹這幾種不同的 RAG。

Naive RAG

本篇主要介紹的傳統 RAG,只做一次檢索與單次答案生成,適合用在 FAQ、單一文件問答。

Advanced RAG

當知識庫越來越多,Naive RAG 可能會找錯資料或是漏掉真正的內容,像是前面提到的:Naive RAG 快速取得的 Top-K 並不一定是最精準相關的內容。

Advanced RAG 增加了 Query Rewriting、Reranking、HyDE 等技術,改善了 Retrieval 品質。

Graph RAG

Naive RAG 的思路是找最相似的 Chunk 來直接回答,缺點就會是永遠只找的到語意最接近的片段。

Graph RAG 會建立知識圖譜,將人物、事件等關係建立成圖表,再透過圖中的關聯性找到相關的資料。

Agentic RAG

目前較新的發展方向。當進入了 Agent 的時代,RAG 變成是一個會主動規劃步驟、挑選工具、自我反思的智能體,它可以根據第一次的查詢結果判斷是否要再查詢。整體上由 Agent 來決定要怎麼查資料、要查幾次、要不要合併多個來源資料。

總結

從整個流程看下來,RAG 做的事情其實就是把「搜尋」與「生成」結合在一起。就如開頭所提到的,把考生翻參考書作答這個比喻具體的實作出來。

RAG 的品質常常不是只取決於 LLM,重要的是前面 Chunking、Retrieval 這些是否做的夠好,LLM 才有機會產生正確的答案。

RAG 之所以會發展出多種形式,是因為當知識庫變大、問題變得複雜的時候,傳統 RAG 就會容易找錯資料或是漏掉真正相關的資料,因此才需要不同的技術去改善這些限制。

也並不是最新的 Agentic RAG 就會取代前面的所有 RAG。如果只是單純的 FAQ 或是文件查詢,那就只需要最傳統的 RAG 就足夠。只有問題需要多次推理或規劃,才會考慮使用 Agentic RAG。

因此選擇哪一種 RAG 並不是看誰最新最強,而是取決於想要解決什麼樣的問題。