本文 AI 產出,尚未審核

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,例如 PyPDFLoaderDocxLoaderMarkdownLoaderWebBaseLoader

簡單來說:Loader = 「把檔案搬進記憶體」,Document = 「搬進來的每一塊資料」。

2. 為什麼要分段(Chunking)?

LLM 的一次輸入長度有限(如 OpenAI 的 gpt‑3.5‑turbo 約 4,096 tokens),直接把整本 PDF 丟進去會超過上限,且檢索效能會下降。
分段(Chunking)將長文件切成適當大小的片段,配合向量化後能更精準地匹配使用者問題。

3. 常見的 Loader 與安裝需求

格式 Loader 類別 主要套件
PDF PyPDFLoader pypdf
Word DocxLoader python-docx
Markdown MarkdownLoader markdown(可選)
Web WebBaseLoader requestsbeautifulsoup4

安裝指令(一次安裝所有需求)

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 支援的編碼;若仍有問題,可使用 pdfplumberdocx2txt 手動轉成純文字。
分段過大 chunk_size 設定過大會超過 LLM token 上限,導致 API 錯誤。 建議以 800‑1000 tokens 為上限,並使用 chunk_overlap 防止斷句資訊遺失。
metadata 缺失 直接使用 loader.load() 時,metadata 可能只有 source,缺少頁碼或標題。 自訂 metadata:在載入後遍歷 documents,加入 {'page': i+1}{'title': ...}
重複資料 多次跑同一個 loader 會產生重複向量,影響檢索精度。 在向量庫插入前,使用 FAISSindex.is_trained 或自行檢查 doc_id 去重。
網頁動態內容 WebBaseLoader 只能抓取靜態 HTML,無法取得 JavaScript 渲染的文字。 需要使用 PlaywrightSelenium 等 headless 瀏覽器先渲染,再把結果傳給 loader。

最佳實踐

  1. 先檢視原始 Document:使用 print(documents[:2]) 確認內容與 metadata 是否正確。
  2. 分段前先清理:移除多餘的空行、HTML 標籤或 Markdown 語法,以提升向量品質。
  3. 批次上傳:FAISS、Pinecone 等向量資料庫支援一次批次寫入,能大幅降低 API 呼叫成本。
  4. 持續監控 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 份投資說明書轉成向量,結合 OpenAIEmbeddingsFAISS,在內部聊天機器人中即時回答「這份基金的風險等級?」等問題,成功降低客服工時 30%。

總結

  • Loader 是 LangChain 與各類文件之間的橋樑,支援 PDF、Word、Markdown、Web 等常見格式。
  • 分段(Chunking)向量化 是讓 LLM 能夠有效檢索的關鍵步驟,務必根據 token 限制調整 chunk_size
  • 常見的錯誤多與編碼、重複資料、分段過大有關,透過前置檢查與適當的 metadata 設定即可避免。
  • 只要把文件載入、切分、向量化三個步驟串好,就能在 聊天機器人、文件搜尋、即時問答 等多種應用場景中快速部署 LangChain 解決方案。

掌握了本單元的技巧後,你就能把任何文字資源變成可被 LLM 理解與回應的「知識」——從此開發 AI 助手不再受限於資料來源的格式。祝你玩得開心,打造出更智慧的應用!