← 文章列表
LLM

📚 RAG + HuggingFace Embeddings 實戰:讓 LLM 認真讀 PDF!🧠🔍

2025-06-10 · — views

如果你曾經想過:

「我能不能把整份 PDF 丟給模型,讓它幫我找重點、回答問題?」

那你來對地方啦 👏
這篇文章要帶你體驗 RAG(Retrieval-Augmented Generation) 的魅力,並且搭配 HuggingFace 的超強嵌入模型,把你手上的文件變成超級知識庫 📖⚡️

🤔 RAG 是什麼?

📌 Retrieval-Augmented Generation,簡稱 RAG,是一種讓 LLM 先去「找資料」,再用「找到的資料」來生成回答的方法。

你可以想像成:

👦 你問模型:「投資計畫書內容是什麼?」
🤖 模型心裡想:「我先去文件裡翻翻看~找到再回答你」

🧰 我們這次用到的工具組合

元件用途
LangChain串接整個 RAG 流程
HuggingFaceEmbeddings把文件轉成向量,方便比對相似度
Chroma本地的向量資料庫
AzureChatOpenAI當然要靠 GPT 幫忙產出回應啦 🤖
PyPDFLoader把 PDF 拆成文字

🔨 動手做:打造一條 RAG Chain!

來看我們的核心實作 👇

from langchain_core.prompts import ChatPromptTemplate
from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.chat_models import AzureChatOpenAI
from rich import print as pprint
from langchain_core.runnables import (RunnablePassthrough, RunnableLambda)

# This code initializes a Retrieval Augmented Generation (RAG) chain using LangChain components.
# Use HuggingFaceEmbeddings for document embeddings

def build_rag_chain():
    # Load the PDF document
    # PyPDFLoader is used to load the content of the PDF file into a format suitable for processing
    loader = PyPDFLoader("./data/investiment.pdf")
    documents = loader.load()

    # Split the documents into chunks
    # RecursiveCharacterTextSplitter splits the document into smaller chunks for better processing
    text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
    texts = text_splitter.split_documents(documents)

    # Initialize the embedding function
    # HuggingFaceEmbeddings generates vector embeddings for the document chunks
    embedding_function = HuggingFaceEmbeddings(
        model_name="sentence-transformers/all-MiniLM-L6-v2"  # Pre-trained embedding model
    )

    # Create a vector store from the texts
    # Chroma is used to store the document embeddings and perform similarity searches
    vector_store = Chroma.from_documents(
        texts,  # List of document chunks
        embedding=embedding_function,  # Embedding function to generate vector representations
        persist_directory="./chroma_db"  # Directory to persist the vector store
    )

    # Define the prompt template for RAG
    # This template combines the user input and retrieved documents to generate a response
    rag_prompt_template = ChatPromptTemplate.from_template(
        "請回答問題:{input}\n 以下為相關文件{result}"
    )

    # Create the RAG chain
    # The chain retrieves relevant documents, formats the prompt, and generates a response
    rag_chain = (
        {
            "result": RunnableLambda(lambda input: vector_store.similarity_search(input, k=5)),  # Retrieve top 5 similar documents
            "input": RunnablePassthrough()  # Pass the user input directly
        }
        | rag_prompt_template  # Format the prompt with the retrieved documents and user input
        | chat_model  # Generate a response using the AzureChatOpenAI model
    )

    return rag_chain

✨ 這裡是重點!

  • 先用 query 去向量資料庫找最像的段落(top 5)

  • 然後把這些段落塞進 Prompt

  • 最後交給 GPT 回答

這就是一條完整的「先查資料再回答」RAG 流程!

🧪 實際測試一下!

這次測試使用的檔案是 investiment.pdf, 也是由ChatGPT 產生的pdf檔案

Investing is the process of allocating money with the expectation of generating an income or profit.
It plays a key role in achieving long-term financial goals such as retirement, education, and home
ownership.
There are several common investment vehicles including stocks, bonds, mutual funds, ETFs, and
real estate.
Each carries a different level of risk and potential return. Diversification-spreading your investments
across
different asset types-helps manage risk.
......
# Execute the RAG chain
# This invokes the RAG chain with a sample query and prints the response
rag_chain = build_rag_chain()
response = rag_chain.invoke("investiment.pdf的內容是什麼?")
pprint(response)

##resutlt
'檔案 `investiment.pdf` 的內容主要是介紹投資和財富管理的基本概念。以下是其主要內容摘要:\n\n1. 
**投資的定義**:投資是將資金分配以期望產生收入或利潤的過程,對於實現長期財務目標(如退休、教育和擁有房產)至關重要。\n\n2. 
**投資工具**:文中提到了幾種常見的投資工具,包括股票、債券、共同基金、交易所交易基金(ETFs)及房地產等。這些投資工具具有不同的風險和潛在回報。\n\n3
. **分散投資**:通過將投資分散到不同的資產類型,可以有效地管理風險。\n\n4. 
**財富管理**:財富管理不僅涉及投資,還包括財務規劃、稅務優化、風險管理和遺產規劃。目的是在與個人財務目標一致的前提下,增長和保護財富。\n\n5. 
**基本原則**:對於初學者來說,文中強調了幾個關鍵原則,包括:儘早開始、一致性投資、了解自己的風險承受能力,以及避免情緒化決策。建議諮詢持牌的財務顧
問以獲得量身定制的指導。\n\n總的來說,此文件旨在幫助讀者理解投資的基本概念及其在財富管理中的重要性。',

🔍 小技巧與延伸應用

技巧 ✨說明
chunk_overlap 調整可避免段落斷裂問題,回答更自然
換其他 embedding 模型可選更大型的如 bge-m3, e5-large
支援多語言文件HuggingFace 模型支援英文、中文都 OK
可以上傳多份 PDF把多份文件 merge 成大的 document list

🎯 結語:讓 LLM 擁有「資料存取力」

這次我們示範了如何把 LLM + 文件結合,用的是最經典的 RAG 架構,加上 HuggingFace 的超香 embedding 模型 🤩

現在你就能打造一個會「讀文件回答問題」的 AI 助理啦!🚀

📁 未來可以應用在:

  • 公司內部知識庫查詢

  • 技術白皮書 Q&A

  • 法律合約分析

  • 投資說明書解析

  • 教材內容問答