LangChain RAG進階教學,結合 Ollama 和 Chroma 持久化向量資料庫,讓LLM讀取PDF文件,並分析產生回應
日期:2024-12-02
實現一個基於 LangChain 的檢索增強生成(RAG,Retrieval-Augmented Generation)模型,讓你可以對 PDF 文檔進行智能問答,並支援動態更新數據庫
需要知識
- LangChain RAG實作教學,結合Llama3讓LLM可以讀取PDF和DOC文件,並產生回應
- 全面解析 RAG(Retrieval-Augmented Generation)
- RAG 中文本分割:chunk_size 和 chunk_overlap 實踐指南)
需要文件下載
- Github Repository — weitsung50110/Huggingface Langchain kit
本文是使用到裡面的langchain_rag_pdf_chroma_advanced.py檔案。
教學目標
實現功能
- 載入 PDF 文檔。
- 將 PDF 文檔分割為小段進行嵌入生成。
- 構建向量數據庫(Vector Database)來支持快速檢索。
- 使用檢索增強生成(RAG)模型回答用戶問題。
- 動態檢測 PDF 更新,自動重建數據庫,保證查詢內容的準確性。
技術架構
使用工具與框架
- LangChain:構建檢索與生成的核心框架。
- Chroma 向量數據庫:用於存儲和檢索嵌入向量。
- Ollama LLM:生成自然語言回應。
- PDF 處理與文本分割:提取 PDF 文件中的文本並分段存儲。
成果展示
root@4be643ba6a94:/app# python3 langchain_rag_pdf_chroma_advanced.py
---PDF 文件已更新,正在重新生成數據庫...
---正在刪除舊的向量數據庫...
---正在載入文件,請稍候...
---PDF 加載完成,共 3 頁
第 1 頁內容(部分):
崴寶 Weibert Weiberson - AI 軟體工程師
關於崴寶
🎓 崴寶,資訊科
第 2 頁內容(部分):
Instagram : @weibert_coding
YouTube : Well崴寶
第 3 頁內容(部分):
工具與技術
Git 版本控制
Docker
Linux / Ubuntu
---正在分割文本...
---分割後的文檔數量: 3
第一段內容(部分):
崴寶 Weibert Weiberson - AI 軟體工程師
關於崴寶
🎓 崴寶,資訊科
---正在生成向量數據庫...
/app/langchain_agents_React-docstore.py:87: LangChainDeprecationWarning: Since Chroma 0.4.x the manual persistence method is no longer supported as docs are automatically persisted.
vectorstore.persist()
---向量數據庫已保存!
請輸入查詢內容(輸入 'bye' 退出):崴寶的Threads帳號是?
Number of requested results 4 is greater than number of elements in index 3, updating n_results = 3
@weibert_coding
請輸入查詢內容(輸入 'bye' 退出):崴寶的專長?
Number of requested results 4 is greater than number of elements in index 3, updating n_results = 3
崴寶的專長包括:
1. NLP(自然語言處理):熟悉 LangChain、RAG、HuggingFace、BERT 等技術。
2. CV(電腦視覺):精通 OpenCV、PyTorch、YOLOR / YOLOv7、PRB-FPN 和
Attention Mechanism 等工具和技術。
請輸入查詢內容(輸入 'bye' 退出):介紹一下崴寶
Number of requested results 4 is greater than number of elements in index 3, updating n_results = 3
崴寶(Weibert Weiberson)是一位 AI 軟體工程師,目前在台灣某上市公司擔任。
他具有資訊科學碩士學歷,並涉足多個領域,如電腦視覺、機器學習、大型語言模型、手機遊戲開發、
網站架設和 APP 開發等。崴寶的使命是攜手程式設計愛好者一起學習、成長,實現他們的程式夢想。
他在社群媒體上提供各種工具與技術,如 Git 版本控制、Docker、Linux / Ubuntu、
SQLite, MySQL, Firebase, NoSQL 等。他也是一位活躍的 YouTuber,
在頻道「Weibert好崴寶程式」分享更多程式教學影片。
崴寶擅長 NLP(自然語言處理)和 CV(電腦視覺),
使用了 LangChain、RAG、HuggingFace、BERT 等工具。
他是一位多才多藝的程式設計師,對於想要學習程式的人來說,是個很好的夥伴。
前置條件
- 確保本地環境已安裝 Ollama。
- 下載所需的 LLM 模型,例如:
kenneth85/llama-3-taiwan:8b-instruct
。 - 準備 PDF 測試文檔,將其命名為
pdf_test.pdf
並放置於程式的根目錄。
本文有在GitHub放了我寫的PDF測試檔案叫做pdf_test.pdf,大家也可以拿來測試用。
1. 初始化環境
首先,我們需要初始化 LangChain 中的主要組件:
Ollama:作為生成模型(LLM)。
OllamaEmbeddings:生成向量嵌入,用於文本檢索匹配。
Chroma:用於存儲和檢索嵌入向量。
from langchain_community.llms import Ollama from langchain_community.embeddings import OllamaEmbeddings from langchain.vectorstores import Chroma from langchain.callbacks.manager import CallbackManager from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler # 初始化 Callback Manager callback_manager = CallbackManager([StreamingStdOutCallbackHandler()]) # 初始化 Ollama LLM llm = Ollama( model="kenneth85/llama-3-taiwan:8b-instruct", callback_manager=callback_manager ) # 初始化 Ollama Embeddings embeddings = OllamaEmbeddings(model="kenneth85/llama-3-taiwan:8b-instruct")
2. 設置文件與向量數據庫存儲路徑
我們需要指定 PDF 文件的路徑和向量數據庫的存儲目錄,並設置一個哈希文件用於檢測 PDF 文件的變更。
指定 PDF 文件的路徑和向量數據庫的存儲目錄。
import hashlib import os # PDF 文件路徑 pdf_path = "pdf_test.pdf" # 向量資料庫存儲目錄 persist_directory = "chroma_vectorstore" # 哈希文件存儲路徑 hash_file_path = os.path.join(persist_directory, "pdf_hash.txt")
為了檢測文件是否發生變更,我們計算 PDF 文件的 MD5 哈希值。
設置哈希文件,用於檢測 PDF 文件的變更。
def calculate_file_hash(file_path): hasher = hashlib.md5() with open(file_path, "rb") as f: buf = f.read() hasher.update(buf) return hasher.hexdigest()
3. 檢測 PDF 文件變更
通過比對當前 PDF 文件的哈希值和之前保存的哈希值,來確定是否需要更新向量數據庫。
計算 PDF 文件的 MD5 哈希值。
若哈希值與記錄不符,表示文件內容已更改,需要更新數據庫。
# 檢查是否需要更新數據庫 def needs_update(pdf_path, hash_file_path): new_hash = calculate_file_hash(pdf_path) if not os.path.exists(hash_file_path): return True, new_hash with open(hash_file_path, "r") as f: existing_hash = f.read().strip() return new_hash != existing_hash, new_hash update_required, new_hash = needs_update(pdf_path, hash_file_path)
4:生成向量數據庫
文件變更檢測與數據庫更新
- 如果檢測到 PDF 文件有變更,則重新生成向量數據庫。
- 如果文件無變更,則直接加載現有的數據庫。
清理舊數據庫
若 PDF 文件有更新,需要刪除舊數據庫以保證內容一致性。
刪除舊數據庫後,重新生成新的向量數據庫。
if os.path.exists(persist_directory) and not update_required: print("---正在加載現有的向量數據庫...") vectorstore = Chroma(persist_directory=persist_directory, embedding_function=embeddings) else: print("---PDF 文件已更新,正在重新生成數據庫...") # 清理舊數據庫 if os.path.exists(persist_directory): print("---正在刪除舊的向量數據庫...") import shutil shutil.rmtree(persist_directory)
載入 PDF 並分割文本
提取 PDF 文本:
使用 PyPDFLoader 從 PDF 文件中提取文本。分割文本:
使用 RecursiveCharacterTextSplitter 按指定大小和重疊率分割文本:chunk_size=500
chunk_overlap=50
完成後,記錄分割的段數以供後續使用。
from langchain.document_loaders import PyPDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter # 步驟 1:載入 PDF loader = PyPDFLoader(pdf_path) documents = loader.load() # 步驟 2:分割文本 text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50) docs = text_splitter.split_documents(documents) print(f"---PDF 分割完成,共 {len(docs)} 段")
生成並持久化向量數據庫
將分割後的文本轉換為向量。
使用 Chroma 持久化數據庫,存儲生成的向量。
保存新的 PDF 哈希值,以便下次對比文件變更。
from langchain.vectorstores import Chroma # 步驟 3:生成向量數據庫 vectorstore = Chroma.from_documents(docs, embeddings, persist_directory=persist_directory) vectorstore.persist() # 保存新的 PDF 哈希值 with open(hash_file_path, "w") as f: f.write(new_hash)
5:構建檢索問答鏈
利用生成模型(LLM)和檢索數據庫構建檢索問答鏈:
將數據庫設為檢索器。
通過 RetrievalQA 模組,實現檢索增強生成(RAG)的功能。
from langchain.chains import RetrievalQA retriever = vectorstore.as_retriever() qa_chain = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=retriever)
6:提供查詢功能
- 提供一個互動式查詢介面,讓用戶輸入問題進行查詢。
- 功能描述:
用戶輸入查詢內容。
系統檢索相關內容並生成答案。
當用戶輸入
bye
,系統退出。# 提供查詢功能 while True: query = input("請輸入查詢內容(輸入 'bye' 退出):") if query.lower() == "bye": print("已退出查詢系統。") break result = qa_chain.invoke(query) print(f"查詢結果:\n{result}")
完整流程
1. 檢測 PDF 文件變更
- 若文件有更新,刪除舊數據庫並重新生成。
- 若無變更,直接加載現有數據庫。
2. 生成向量數據庫
- 分割 PDF 文本。
- 生成嵌入向量並存儲於數據庫。
3. 檢索與生成
- 基於用戶查詢,檢索相關內容並生成答案。
崴寶結語
之前崴寶教導大家的基礎 RAG 是使用 Faiss 向量數據庫(詳見:LangChain RAG實作教學,結合Llama3讓LLM可以讀取PDF和DOC文件,並產生回應)。
本次進階教學則使用 Chroma 向量數據庫,並藉由哈希值來達成動態檢測 PDF 文件更新,自動重建Vector Database。
喜歡 好崴寶 Weibert Weiberson 的文章嗎?在這裡留下你的評論!本留言區支援 Markdown 語法。