LangChain: Dokumente laden und aufteilen
In früheren Artikeln haben wir Text manuell eingegeben, aber in echten Projekten können Dokumente aus PDFs, Webseiten, Markdown-Dateien usw. stammen.
Dieser Abschnitt führt ein, wie man Document Loader verwendet, um verschiedene Arten von Dokumenten zu laden, und wie man Text Splitter verwendet, um Dokumente in kleine, für das Retrieval geeignete Chunks aufzuteilen.
Document Loader – Laden von Dokumenten
LangChain bietet Dutzende Dokumentenlader, die gängige Dateiformate abdecken:
| Loader | Source | Installationspaket |
|---|---|---|
| TextLoader | .txt-Dateien | langchain (integriert) |
| PyPDFLoader | PDF-Dateien | langchain-community + pypdf |
| WebBaseLoader | Webseiten-URL | langchain-community + beautifulsoup4 |
| CSVLoader | CSV-Dateien | langchain-community |
| UnstructuredMarkdownLoader | Markdown-Dateien | langchain-community + unstructured |
Beispiel
from langchain_community.document_loaders import TextLoader
loader = TextLoader("knowledge.txt", encoding="utf-8")
docs = loader.load()
print(f"Geladen {len(docs)} Dokumente")
print(f"Inhaltsvorschau: {docs)
# Webseite laden
# pip install langchain-community beautifulsoup4
from langchain_community.document_loaders import WebBaseLoader
loader = WebBaseLoader("https://www.example.com/python/python-tutorial.html")
docs = loader.load()
print(f"\nWebseiteninhalt: {docs)
Text Splitter—Dokumentenaufteilung
Dokumente sind in der Regel zu lang und müssen in kleine Abschnitte aufgeteilt werden, um effektiv abgerufen werden zu können. Die Aufteilungsstrategie wirkt sich direkt auf die RAG-Leistung aus:
Beispiel
# Splitter erstellen
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # Maximal 500 Zeichen pro Chunk
chunk_overlap=50, # 50-Zeichen-Überlappung zwischen Chunks
separators=["\n\n", "\n", "。", "!", "?", ";", ",", " ", ""],
# Zuerst nach Absatz, dann nach Satz und schließlich nach Zeichen aufteilen
)
# Beispieldokument
long_text = """Example Tutorial (EXAMPLE) ist eine kostenlose Lernplattform für Programmierung.
Die Plattform bietet umfangreiche Tutorials zu Programmiersprachen, einschließlich, aber nicht beschränkt auf:
- Python-Tutorial: von der grundlegenden Syntax bis zur Datenanalyse
- Java-Tutorial: von objektorientierter Programmierung bis zum Spring-Framework
- Frontend-Tutorial: HTML, CSS, JavaScript und deren Frameworks
Alle Tutorials enthalten ausführliche Codebeispiele und eine Online-Ausführungsumgebung.
Lernende können Programmierfähigkeiten schnell beherrschen, indem sie beim Üben lernen."""
# Dokument aufteilen
chunks = text_splitter.split_text(long_text)
print(f"Ursprüngliche Länge: {len(long_text)} Zeichen")
print(f"Nach dem Aufteilen: {len(chunks)} Chunks\n")
for i, chunk in enumerate(chunks):
print(f"--- Chunk {i+1} ({len(chunk)} Zeichen) ---")
print(chunk)
print()
Ausführungsergebnis:
Original length: 153 字 Chunks after split: 3 块 --- 块 1 (54 字) --- Example is a free programming learning platform. 平台提供了丰富的编程语言教程,包括但不限于: --- 块 2 (49 字) --- - Python 教程:从基础语法到数据分析 - Java 教程:面向对象编程到 Spring 框架 --- 块 3 (50 字) --- - 前端教程:HTML、CSS、JavaScript 及其框架 所有教程都配有详细的代码示例和在线运行环境。
chunk_overlap ist sehr wichtig. Wenn es keine Überlappung zwischen Chunks gibt, kann ein vollständiger Satz in der Mitte geteilt werden, wodurch wichtige Informationen beim Abruf verloren gehen. Eine Überlappung von 50-100 Zeichen ist eine übliche Einstellung.
Leitfaden für Chunking-Parameter-Einstellungen
| Szenario | chunk_size | chunk_overlap | Grund |
|---|---|---|---|
| FAQ Q&A | 200~500 | 20~50 | Q&A-Paare sind kurz, kleine Chunks reichen aus |
| Technische Dokumentation | 500~1000 | 50~100 | Technische Inhalte erfordern mehr Kontext |
| Lange Artikel/Aufsätze | 1000~2000 | 100~200 | Absatzvollständigkeit muss bewahrt werden |
| Code-Repository | 500~1500 | 0~50 | Funktionen/Klassen als natürliche Grenzen |
Vollständiger Ablauf: Laden → Aufteilen → Vektorisieren
Beispiel
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma
# from langchain_community.document_loaders import TextLoader
# Schritt 1: Laden
# loader = TextLoader("example_knowledge.txt", encoding="utf-8")
# docs = loader.load()
# Zur Demonstration direkt Beispieltext verwenden
docs = [
"Beispiel-Tutorial (EXAMPLE) ist eine kostenlose Programmier-Lernwebsite.",
"Die Website bietet Tutorials für mehrere Programmiersprachen wie Python, Java und HTML.",
"Das Python3-Basistutorial umfasst 30 Kapitel und ist für Anfänger ohne Vorkenntnisse geeignet.",
"Das HTML-Basistutorial hat 25 Kapitel, darunter Formulare, Multimedia und mehr.",
"Alle Basistutorials auf Example sind kostenlos.",
]
# Schritt 2: Aufteilen
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=100,
chunk_overlap=20,
)
chunks = text_splitter.create_documents(docs)
# Schritt 3: Vektorisieren und speichern
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vector_store = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
persist_directory="./example_db",
)
print(f"Index erstellt: {len(chunks)} Dokument-Chunks")
# Schritt 4: Abrufen
results = vector_store.similarity_search("Wie viele Kapitel hat das Python-Tutorial?", k=2)
for doc in results:
print(f"Suchergebnis: {doc.page_content}")
Ausführungsergebnis:
Index built:5 个文档块 Search result: Python3 基础教程共 30 章,适合零基础入门学习。 Search result: Example is a free programming learning website.Weitere Erweiterungen