はじめに
RAG パイプラインは データ から始まります。データは PDF、Word、Web ページ、YouTube ビデオ、コード リポジトリなど任意の形式にすることができます。このレッスンでは、すべての一般的なドキュメント タイプを RAG パイプラインにロードする方法を説明します。
ルール: ガベージイン = ガベージアウト。ドキュメントの読み込み 高品質 = RAG 高品質。
1. ドキュメント ローダーの概要
1.1 一般的なデータソース
| 出典 | フォーマット | チャレンジ |
|---|---|---|
| 表、図、複数列、スキャン | ||
| 単語 | .docx、.doc | 書式設定、ヘッダー/フッター |
| ウェブページ | HTML | JavaScript レンダリング、ノイズ |
| YouTube | ビデオ/オーディオ | トランスクリプト、タイムスタンプが必要 |
| コード リポジトリ | .py、.js、.md | 構造、依存関係 |
| CSV/Excel | .csv、.xlsx | 表形式データ → テキスト |
| データベース | SQL | クエリ、スキーマの理解 |
1.2 LangChain ドキュメント ローダー
LangChain は、ドキュメント ローダーの豊富なエコシステムを提供します。
from langchain_community.document_loaders import (
PyPDFLoader, # PDF
Docx2txtLoader, # Word
WebBaseLoader, # Web pages
YoutubeLoader, # YouTube
GitLoader, # Git repos
CSVLoader, # CSV files
TextLoader, # Plain text
UnstructuredExcelLoader, # Excel
)
2. PDF — 最も一般的なドキュメントの種類
2.1 PyPDFLoader — 基本
"""Load PDF đơn giản nhất — PyPDFLoader"""
from langchain_community.document_loaders import PyPDFLoader
# Load từng trang
loader = PyPDFLoader("company_handbook.pdf")
pages = loader.load()
print(f"Số trang: {len(pages)}")
for i, page in enumerate(pages[:3]):
print(f"\n--- Trang {i+1} ---")
print(f"Nội dung: {page.page_content[:200]}...")
print(f"Metadata: {page.metadata}")
# metadata = {"source": "company.pdf", "page": 0}
2.2 高度な PDF — 表と図の処理
PyPDF はシンプルですが、表や図を扱うのが 苦手です。複雑な PDF には 非構造化 を使用します。
"""Unstructured: xử lý PDF phức tạp (bảng, hình, multi-column)"""
from langchain_community.document_loaders import UnstructuredPDFLoader
# Partition strategy: "hi_res" cho chất lượng cao
loader = UnstructuredPDFLoader(
"financial_report.pdf",
mode="elements", # Tách từng element (text, table, image)
strategy="hi_res", # OCR + layout analysis
)
elements = loader.load()
# Lọc theo loại element
for elem in elements[:10]:
elem_type = elem.metadata.get("category", "unknown")
print(f"[{elem_type}] {elem.page_content[:100]}...")
2.3 PDF ローダーの比較
| ローダー | 表 | 図 | OCR(スキャン) | スピード | 設定 |
|---|---|---|---|---|---|
| PyPDFLoader | ❌ | ❌ | ❌ | ⚡ 速い | pip install pypdf |
| PyMuPDFLoader | ⚠️ | ❌ | ❌ | ⚡ 速い | pip install pymupdf |
| 非構造化PDFLoader | ✅ | ✅ | ✅ | 🐢 遅い | pip install unstructured[pdf] |
| Amazon Textract | ✅ | ✅ | ✅ | ⚡ | AWS アカウント |
推奨事項: PyPDFLoader から始めます。 PDF に表や図がある場合は、非構造化 を使用してください。
3. Web ページ
3.1 Web サイトをロードする
"""Load nội dung từ trang web"""
from langchain_community.document_loaders import WebBaseLoader
# Load 1 trang
loader = WebBaseLoader("https://blog.xdev.asia/ai/")
docs = loader.load()
print(f"Content length: {len(docs[0].page_content)} chars")
print(docs[0].page_content[:500])
# Load nhiều trang
urls = [
"https://blog.xdev.asia/blog/post-1",
"https://blog.xdev.asia/blog/post-2",
"https://blog.xdev.asia/blog/post-3",
]
loader = WebBaseLoader(urls)
docs = loader.load()
print(f"Loaded {len(docs)} pages")
3.2 Web サイトをクロールする (サイトマップ)
"""Crawl tất cả trang từ sitemap"""
from langchain_community.document_loaders.sitemap import SitemapLoader
loader = SitemapLoader(
web_path="https://blog.xdev.asia/sitemap.xml",
filter_urls=["https://blog.xdev.asia/blog/"], # Chỉ blog
)
docs = loader.load()
print(f"Crawled {len(docs)} pages from blog")
4. YouTube トランスクリプト
"""Load transcript từ YouTube video"""
from langchain_community.document_loaders import YoutubeLoader
# Load transcript (auto-generated hoặc manual)
loader = YoutubeLoader.from_youtube_url(
"https://www.youtube.com/watch?v=dQw4w9WgXcQ",
add_video_info=True, # Thêm title, description
language=["vi", "en"], # Ưu tiên tiếng Việt
)
docs = loader.load()
print(f"Title: {docs[0].metadata.get('title')}")
print(f"Duration: {docs[0].metadata.get('length')} seconds")
print(f"Transcript: {docs[0].page_content[:300]}...")
5. コードリポジトリ
"""Load code từ Git repo"""
from langchain_community.document_loaders import GitLoader
# Clone + load tất cả files
loader = GitLoader(
clone_url="https://github.com/user/project",
repo_path="./temp_repo",
branch="main",
file_filter=lambda f: f.endswith((".py", ".md", ".yaml")),
)
docs = loader.load()
print(f"Loaded {len(docs)} files")
for doc in docs[:5]:
print(f" {doc.metadata['file_path']} ({len(doc.page_content)} chars)")
6. バッチ処理 — 複数のファイルの処理
6.1 ドキュメントフォルダーの読み込み
"""Load tất cả tài liệu trong folder"""
from langchain_community.document_loaders import DirectoryLoader, PyPDFLoader
from pathlib import Path
# Load tất cả PDF trong folder
loader = DirectoryLoader(
"./company_docs/",
glob="**/*.pdf", # Recursive, chỉ PDF
loader_cls=PyPDFLoader,
show_progress=True,
use_multithreading=True, # Parallel loading
)
docs = loader.load()
print(f"Loaded {len(docs)} pages from PDF files")
# Thêm custom metadata
for doc in docs:
filename = Path(doc.metadata["source"]).stem
doc.metadata["department"] = "HR" if "hr" in filename.lower() else "General"
doc.metadata["doc_type"] = "policy"
6.2 マルチフォーマットローダー
"""Unified loader cho nhiều format"""
from langchain_community.document_loaders import (
PyPDFLoader, Docx2txtLoader, TextLoader, CSVLoader
)
from pathlib import Path
def load_document(file_path: str):
"""Load document dựa trên extension."""
ext = Path(file_path).suffix.lower()
loaders = {
".pdf": PyPDFLoader,
".docx": Docx2txtLoader,
".txt": TextLoader,
".md": TextLoader,
".csv": CSVLoader,
}
loader_cls = loaders.get(ext)
if not loader_cls:
raise ValueError(f"Unsupported format: {ext}")
return loader_cls(file_path).load()
# Usage
all_docs = []
for f in Path("./docs/").glob("**/*"):
if f.suffix in [".pdf", ".docx", ".txt", ".md", ".csv"]:
try:
docs = load_document(str(f))
all_docs.extend(docs)
print(f"✅ {f.name}: {len(docs)} chunks")
except Exception as e:
print(f"❌ {f.name}: {e}")
print(f"\nTotal: {len(all_docs)} documents loaded")
💡 演習 6: フォルダー内のすべてのドキュメントをロードするスクリプトを作成します (PDF + DOCX + TXT を混合)。出力: ファイル名、ページ/チャンク数、総文字数。エラーを適切に処理します。
7. ヒントとベストプラクティス
| ヒント | 説明 |
|---|---|
| 積み込む前に掃除してください | ヘッダー/フッター、ページ番号、透かしを削除 |
| メタデータを追加 | ソース、日付、カテゴリ — 後でフィルタリングするために使用されます。 |
| ハンドルエンコーディング | ベトナム語: UTF-8。チェック chardet 不明な場合 |
| バッチ処理 | 大きなフォルダー (100 以上のファイル) にはマルチスレッドを使用する |
| テストの品質 | ロード後に 10% のドキュメントを抜き取りチェック |
| エラー処理 | ログ ファイルが破損しています。サイレント スキップしないでください。 |
概要
| 出典 | ローダー | メモ |
|---|---|---|
| PyPDFLoader / 非構造化 | 表/図の非構造化 | |
| ウェブ | WebBaseLoader / サイトマップローダー | サイトマップ経由でサイト全体をクロールする |
| YouTube | Youtubeローダー | 自動転写 + メタデータ |
| コード | GitLoader | 拡張子のファイルフィルター |
| フォルダー | ディレクトリローダー | マルチスレッド、再帰的 |
一般的な演習
- ✅ 小さな演習を完了する (6)
- 取り込みパイプラインの構築: 関数の書き込み
ingest(folder_path)フォルダー内のすべてのファイルをロードし、完全なメタデータを含むドキュメントのリストを返します。 - PDF ベンチマーク: 複雑な PDF (表と画像を含む) を作成します。 PyPDFLoader と非構造化の出力を比較します。品質はどう違うのでしょうか?
- Web クローラー: お気に入りの Web サイトから 10 件のブログ投稿をクロール → ChromaDB にロード → 「Chat with Blog」を作成します。
次の記事: チャンキング戦略 — 文書を取得のために最適なチャンクに分割する方法。