---
# System prepended metadata

title: RAG Tutorial 2 (逐字稿)

---

# RAG Tutorial 2 (逐字稿)
## P1
各位好，歡迎回到國立清華大學自然語言處理課程，今天由助教負責接續講解 Retrieval Augmented Generation (通常被縮寫成 RAG) 的相關教學。

## P2
在今天的課程中，我會講解在沒有使用到上次介紹到的專案下，如何自己建立一個 RAG 系統的各個部件，並將各個部件串連起來的步驟

## P3
在開始課程前，先幫大家快速地複習在上次教學中提到的 RAG 的架構創建以及執行流程。在使用LangChain時，我們會將 Retriever、Knowledge Base 以及 LLM 都包裝到一個 Chain 內部，我們可以直接使用 invoke() 方法，將要詢問的問題輸入 Chain，而這個 Chain 就會遵循包裝好的邏輯，從知識庫中檢索相關資料用以輔助 LLM 生成更好的內容，最後變成 Reponse。

但其中 Retriever、Knowledge Base 或是 Generator Prompt 格式都是經由套件呼叫進行設置，詳細的步驟是不容易了解的。而當我們在面對現實任務需要對內部任一架構進行調整，所要進行的更改會較為複雜，因此這次課程會帶大家如何在沒有使用套件包裝下，完成一個自製的RAG系統。

## P4
就如前一頁所介紹，我們要在沒有使用LangChain架構的情況下，完成RAG系統，我們會更加的了解Database, Retriever 和模型生成的詳細過程。 

## P5
首現我們需要引入一個資料集，因為我們是使用 colab，資料的上船會較為複雜，所以在這邊我們使用 WebBaseLoader 直接從網站上面爬下資料，我們設定好要爬下的資料所屬 class，並將text內容存取下來。

當然根據任務不同，會需要使用 PDF 或是 X(Twitter) 論壇，因此可以先根據需求先進行 survey，處理你所需要的資料。

## P6
照圖講

## P7
在從網站上爬下資料之後，我們需要對髒亂的資料先進行一部前處理，將資料轉換為較為乾淨的形式。
照圖講各個步驟

## P8
接著我們必須對資料進行切割，將大規模的文件拆分成大小適中的段落或片段（例如，根據字數、句子數量或自然段落進行分割）。確保每個 chunk 都能適配檢索系統的輸入長度限制。

每個 chunk 被單獨索引和檢索，提升了檢索結果的相關性和準確性。避免檢索過於冗長的段落，減少無關內容對生成結果的干擾。

當然也可以為了維持語義完整性，在切分時需考量語義邊界，避免破壞上下文邏輯，確保每個 chunk 仍具有可讀性，像是以句子或段落為單位切分，在 chunker 這部分也是一個研究領域，我們在這便只使用簡單的 Token 為單位進行處理。

## P9
在現實情況中，我們需要處理成千上萬的資料，所以當建立 Dense, Sparse Index 資料庫後，我們需要將這些耗費大量計算資源的結果存取下來。

## P10
照圖講。建立text_db、vector_db

## P11
照圖講。前處理、Rank-BM25 建立BM25 index資料庫、建立bm25_db

## P12
照圖講。query轉embedding、計算cos_sim、排名

## P13
照圖講。query前處理、計算bm25 score、透過ID取得分數並進行排序

## P14
Dense Retriever 和 Sparse Retriever 各有其優勢。Dense Retriever 更側重於語義相似度的計算，而 Sparse Retriever 則專注於重要字詞的重複性匹配。當我們希望結合兩者的優點，就需要採用某些方法將它們的排名進行合併或參考。

合併排名的方法多種多樣。部分方法基於兩者的分數進行調整，然後計算綜合評分；另一些方法則僅考慮排名本身，透過排名位置計算最終的總體排名。在這裡，我們採用 RRF（Reciprocal Rank Fusion）演算法來合併兩者的排名。該方法根據排名位置 𝑟 和一個可調整的常數 𝑘 來計算分數，從而控制排名對最終結果的影響。

此外，我們還可以為不同的 Retriever 分配不同的權重，根據任務需求靈活調整對語義相似度或字詞重複度的側重程度，從而更好地滿足具體應用場景的需求。

## P15
照圖講。照著排序結果給予 rank 值、處理結果可能有不包含所有 docs 的情況、RRF、next() 在這裡的主要功能是高效地從兩個文檔集合中查找匹配的文檔，並提取其 "text"

## P16
在所有設置都完成的情況下，我們將所有系統(dense ranker, sparse ranker, and hybrid ranker )串接在一起，型成一個完整的 Retriever ranking workflow。

## P17
完成 Retriever 後，現在我們只需要輸入 query，就能得到指定 top-k 的相關文檔

## P18
再來我們會需要設置 LLM 模型來做為 Reader(Generator)，在上次教學中，有先讓大家去申請 HF llama-3-1B-instruct，在這次教學中，我們不會使用 Ollama，而是透過 Access Token，用來登入 Hugging Face、存取受限制llama模型。如果忘記存取 Access Token，可以直接刷新取得新的 token 來使用就可以了。

## P19
將 LLM 模型存取後，我們要開始設定好我們的 prompt 形式，在這邊我們參考 langchain rlm/rag-prompt 的形式，將從知識庫中檢索相關資料放到輸入中用以輔助 LLM ，當然可以根據各自的任務，對 prompt 進行任何修改皆可。

照圖講。system, user prompt、Retriever docs 設置、input 轉 model input 的形式

## P20
將 input, model 放到相同 device，直接使用 HF generation function 進行生成，其中可以設置 max_new_tokens 或是更多參數來調整 LLM 生成。

接著將生成 tokens 轉換回可閱讀文字內容，這樣就算完成一個簡易的 RAG 系統了。

在提供程式碼中，也有實際給予一個沒有使用 RAG 時的情境，各位也可以實做看看專業領域問題在有無使用RAG系統的差別。

以上，就成功地使用手動設置 Database, Retriever, Generator 建立一個基礎的 RAG 系統了。
那我們今天的 Lab 課程就講到這邊，如果有任何問題的話，歡迎大家到 Slido 或寄信到助教信箱詢問，謝謝大家。
