LangChain 教學:文檔載入 Loader(PDF / Word / Markdown / Web)
簡介
在使用 LLM(大型語言模型)進行問答、摘要或知識檢索時,資料的載入與前處理是關鍵第一步。LangChain 作為一套串接 LLM、工具與資料的框架,提供了多種 Document Loader,讓開發者可以輕鬆把 PDF、Word、Markdown 甚至網頁內容轉換成 Document 物件,直接餵給向量資料庫或聊天機器人使用。
本單元將說明如何使用 LangChain 內建的 loader 讀取四種常見格式,並示範搭配文字分段、向量化的完整流程。即使你是第一次接觸 LangChain,也能在閱讀完本篇後,快速將各式文件納入自己的 LLM 應用中。
核心概念
1. Document 與 Loader 的基本概念
- Document:LangChain 中的核心資料結構,包含
page_content(文字內容)與metadata(檔名、頁碼、來源 URL 等)。 - Loader:負責把外部檔案或網路資源讀取成
Document陣列的類別。每種檔案格式都有對應的 loader,例如PyPDFLoader、DocxLoader、MarkdownLoader、WebBaseLoader。
簡單來說:Loader = 「把檔案搬進記憶體」,Document = 「搬進來的每一塊資料」。
2. 為什麼要分段(Chunking)?
LLM 的一次輸入長度有限(如 OpenAI 的 gpt‑3.5‑turbo 約 4,096 tokens),直接把整本 PDF 丟進去會超過上限,且檢索效能會下降。
分段(Chunking)將長文件切成適當大小的片段,配合向量化後能更精準地匹配使用者問題。
3. 常見的 Loader 與安裝需求
| 格式 | Loader 類別 | 主要套件 |
|---|---|---|
PyPDFLoader |
pypdf |
|
| Word | DocxLoader |
python-docx |
| Markdown | MarkdownLoader |
markdown(可選) |
| Web | WebBaseLoader |
requests、beautifulsoup4 |
安裝指令(一次安裝所有需求)
pip install langchain[all] pypdf python-docx markdown beautifulsoup4 requests
4. 程式碼範例
以下範例均以 Python 為例,展示四種 loader 的基本使用方式、分段與向量化(以 OpenAI Embedding 為例)。每段程式碼皆附上說明註解,方便初學者快速上手。
4.1 讀取 PDF 並分段
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import FAISS
# 1. 載入 PDF(會自動把每一頁轉成 Document)
loader = PyPDFLoader("data/sample.pdf")
documents = loader.load()
# 2. 使用遞迴字元切分器,每段 1000 個字元,重疊 200 個字元
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
separators=["\n\n", "\n", " "]
)
chunks = text_splitter.split_documents(documents)
# 3. 產生向量並存入 FAISS
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(chunks, embeddings)
print(f"已建立 {len(chunks)} 個向量,總檔案大小 {loader.file_path}")
4.2 讀取 Word(.docx)
from langchain.document_loaders import DocxLoader
loader = DocxLoader("data/report.docx")
documents = loader.load() # 每段落為一個 Document
# 同樣使用文字切分器
chunks = text_splitter.split_documents(documents)
vectorstore.add_documents(chunks) # 直接加入先前的 FAISS
print(f"Word 檔案共 {len(documents)} 個段落,已加入向量庫")
4.3 讀取 Markdown
from langchain.document_loaders import MarkdownLoader
loader = MarkdownLoader("data/README.md")
documents = loader.load() # 會保留 markdown 標記,可視需求自行移除
# 若想去除 markdown 標記,可在切分前使用 markdown2html 或正則表達式
chunks = text_splitter.split_documents(documents)
vectorstore.add_documents(chunks)
print("Markdown 內容已成功向量化")
4.4 從網頁抓取內容
from langchain.document_loaders import WebBaseLoader
# 以 Wikipedia 為例
loader = WebBaseLoader("https://zh.wikipedia.org/wiki/LangChain")
documents = loader.load() # 每個 <p> 會成為一個 Document
# 針對網頁內容做分段
chunks = text_splitter.split_documents(documents)
vectorstore.add_documents(chunks)
print(f"網頁載入完成,共 {len(documents)} 個段落")
4.5 使用向量庫進行檢索
from langchain.chains import RetrievalQA
from langchain.llms import OpenAI
qa = RetrievalQA.from_chain_type(
llm=OpenAI(),
retriever=vectorstore.as_retriever(search_kwargs={"k": 4}),
)
question = "LangChain 的核心概念是什麼?"
answer = qa.run(question)
print("問答結果:", answer)
小技巧:
search_kwargs={"k": 4}表示一次取回最相似的 4 個 chunk,通常能取得較完整的上下文。
常見陷阱與最佳實踐
| 陷阱 | 說明 | 解決方案 |
|---|---|---|
| 文字編碼錯誤 | PDF/Word 內部可能使用非 UTF‑8 編碼,導致讀取時出現亂碼。 | 確認 loader 支援的編碼;若仍有問題,可使用 pdfplumber 或 docx2txt 手動轉成純文字。 |
| 分段過大 | chunk_size 設定過大會超過 LLM token 上限,導致 API 錯誤。 |
建議以 800‑1000 tokens 為上限,並使用 chunk_overlap 防止斷句資訊遺失。 |
| metadata 缺失 | 直接使用 loader.load() 時,metadata 可能只有 source,缺少頁碼或標題。 |
自訂 metadata:在載入後遍歷 documents,加入 {'page': i+1} 或 {'title': ...}。 |
| 重複資料 | 多次跑同一個 loader 會產生重複向量,影響檢索精度。 | 在向量庫插入前,使用 FAISS 的 index.is_trained 或自行檢查 doc_id 去重。 |
| 網頁動態內容 | WebBaseLoader 只能抓取靜態 HTML,無法取得 JavaScript 渲染的文字。 |
需要使用 Playwright、Selenium 等 headless 瀏覽器先渲染,再把結果傳給 loader。 |
最佳實踐
- 先檢視原始 Document:使用
print(documents[:2])確認內容與 metadata 是否正確。 - 分段前先清理:移除多餘的空行、HTML 標籤或 Markdown 語法,以提升向量品質。
- 批次上傳:FAISS、Pinecone 等向量資料庫支援一次批次寫入,能大幅降低 API 呼叫成本。
- 持續監控 token 使用量:使用
tiktoken或 OpenAI 官方工具,確保每次查詢不會超出配額。
實際應用場景
| 場景 | 使用的 Loader | 為何選擇 |
|---|---|---|
| 企業內部文件搜尋 | DocxLoader + PdfLoader |
大多數公司文件以 Word、PDF 為主,載入後可直接建立內部知識庫。 |
| 開源專案說明文件 | MarkdownLoader |
GitHub README、CONTRIBUTING 等多為 Markdown,直接索引可快速回答開發者問題。 |
| 法規或政策查詢平台 | PdfLoader(結合 OCR) |
法律條文常以 PDF 發布,結合 pdfplumber + OCR 可支援掃描檔。 |
| 即時客服聊天機器人 | WebBaseLoader + RecursiveCharacterTextSplitter |
從公司官網抓取 FAQ、產品說明,實時更新知識庫。 |
| 學術研究輔助 | PdfLoader + LangChain 的 RetrievalQA |
讀取期刊 PDF,提供文獻摘要與關鍵句搜尋。 |
案例簡述:某金融公司利用
PyPDFLoader把 2,000 份投資說明書轉成向量,結合OpenAIEmbeddings與FAISS,在內部聊天機器人中即時回答「這份基金的風險等級?」等問題,成功降低客服工時 30%。
總結
- Loader 是 LangChain 與各類文件之間的橋樑,支援 PDF、Word、Markdown、Web 等常見格式。
- 分段(Chunking) 與 向量化 是讓 LLM 能夠有效檢索的關鍵步驟,務必根據 token 限制調整
chunk_size。 - 常見的錯誤多與編碼、重複資料、分段過大有關,透過前置檢查與適當的 metadata 設定即可避免。
- 只要把文件載入、切分、向量化三個步驟串好,就能在 聊天機器人、文件搜尋、即時問答 等多種應用場景中快速部署 LangChain 解決方案。
掌握了本單元的技巧後,你就能把任何文字資源變成可被 LLM 理解與回應的「知識」——從此開發 AI 助手不再受限於資料來源的格式。祝你玩得開心,打造出更智慧的應用!