Strategien für Chunking RAG 2025: Optimale Größen & Techniken
Beherrschen Sie Chunking für RAG: optimale Größen (512–1024 tokens), Überlappungsstrategien, semantische vs. feste Segmentierung. +25% Retrieval-Genauigkeit.
Auf einen Blick
- Die Chunk-Größe zählt: 500-1000 Tokens balancieren Kontext und Genauigkeit
- Semantisches Chunking (Aufteilung nach Bedeutung) übertrifft feste Größenaufteilung in der Qualität (+15-30% Retrieval-Genauigkeit)
- Überlappung (10-20%) verhindert Kontextverlust an den Grenzen
- Beste Wahl für die meisten Fälle: Recursive text splitter mit 512 Tokens, 50 Tokens Überlappung
- Jetzt ausprobieren: Testen Sie verschiedene Strategien auf der Ailog-Plattform
Das Chunking-Problem
Die meisten Dokumente sind zu lang, um:
- Als einzelner Vektor eingebettet zu werden (Kontextfenster-Grenzen)
- Vollständig als LLM-Kontext verwendet zu werden (Token-Grenzen)
- Präzise abgerufen zu werden (zu viele irrelevante Informationen)
Chunking teilt Dokumente in kleinere, handhabbare Stücke auf und bewahrt dabei die semantische Bedeutung.
Warum Chunking wichtig ist
Schlechtes Chunking führt zu:
- Fragmentiertem Kontext: Wichtige Informationen auf mehrere Chunks verteilt
- Irrelevantem Retrieval: Chunks enthalten eine Mischung aus relevanten und irrelevanten Inhalten
- Kontextverlust: Chunk-Grenzen schneiden kritische Informationen ab
- Schlechte Generierung: Dem LLM fehlt der vollständige Kontext für eine präzise Antwort
Gutes Chunking ermöglicht:
- Präzises Retrieval: Genau die relevanten Informationen finden
- Vollständiger Kontext: Chunks enthalten vollständige Gedanken oder Konzepte
- Effiziente Token-Nutzung: Kein Kontextverschwendung für irrelevanten Text
- Bessere Antworten: Das LLM hat genau das, was es braucht, nicht mehr
Chunking mit fester Größe
Zeichenbasiert
Den Text alle N Zeichen aufteilen.
DEVELOPERpythondef chunk_by_chars(text, chunk_size=1000, overlap=200): chunks = [] start = 0 while start < len(text): end = start + chunk_size chunks.append(text[start:end]) start += chunk_size - overlap return chunks
Vorteile:
- Einfache Implementierung
- Vorhersehbare Chunk-Größen
- Schnelle Verarbeitung
Nachteile:
- Schneidet mitten in Wörtern oder Sätzen
- Ignoriert semantische Grenzen
- Zerstört Code, Tabellen, Listen
Verwenden, wenn:
- Ein schneller Prototyp benötigt wird
- Die Textstruktur homogen ist
- Präzision nicht kritisch ist
Tokenbasiert
Nach Anzahl der Tokens aufteilen (entspricht der Tokenisierung des Modells).
DEVELOPERpythonimport tiktoken def chunk_by_tokens(text, chunk_size=512, overlap=50): encoding = tiktoken.get_encoding("cl100k_base") tokens = encoding.encode(text) chunks = [] start = 0 while start < len(tokens): end = start + chunk_size chunk_tokens = tokens[start:end] chunks.append(encoding.decode(chunk_tokens)) start += chunk_size - overlap return chunks
Vorteile:
- Respektiert Token-Grenzen präzise
- Funktioniert mit jedem Embedding-Modell
- Vorhersehbare Embedding-Kosten
Nachteile:
- Ignoriert weiterhin semantische Grenzen
- Tokenisierungs-Overhead
- Kann einen wichtigen Kontext zerschneiden
Verwenden, wenn:
- Ein striktes Token-Budget besteht
- Die Token-Anzahl kritisch ist (API-Kosten)
- Das Embedding-Modell strikte Token-Grenzen hat
Empfohlene feste Größen
| Anwendungsfall | Chunk-Größe | Überlappung | Begründung |
|---|---|---|---|
| Kurze FAQs | 128-256 Tokens | 0-20 | Minimaler Kontext erforderlich |
| Allgemeine Dokumentation | 512-1024 Tokens | 50-100 | Balance zwischen Präzision und Kontext |
| Technische Dokumentation | 1024-2048 Tokens | 100-200 | Mehr Kontext für komplexe Themen |
| Code | 256-512 Tokens | 50-100 | Funktions-/Klassenkontext erhalten |
Semantisches Chunking
An natürlichen semantischen Grenzen aufteilen.
Satzbasiert
An Satzgrenzen aufteilen.
DEVELOPERpythonimport nltk nltk.download('punkt') def chunk_by_sentences(text, sentences_per_chunk=5): sentences = nltk.sent_tokenize(text) chunks = [] for i in range(0, len(sentences), sentences_per_chunk): chunk = ' '.join(sentences[i:i + sentences_per_chunk]) chunks.append(chunk) return chunks
Vorteile:
- Respektiert Satzgrenzen
- Besser lesbare Chunks
- Bewahrt vollständige Gedanken
Nachteile:
- Variable Chunk-Größen
- Satzerkennung kann fehlschlagen
- Gruppiert möglicherweise keine zusammengehörigen Sätze
Verwenden, wenn:
- Lesbarkeit wichtig ist
- Sätze eigenständig sind
- Es sich um allgemeinen narrativen Text handelt
Absatzbasiert
An Absatzumbrüchen aufteilen.
DEVELOPERpythondef chunk_by_paragraphs(text, paragraphs_per_chunk=2): paragraphs = text.split('\n\n') chunks = [] for i in range(0, len(paragraphs), paragraphs_per_chunk): chunk = '\n\n'.join(paragraphs[i:i + paragraphs_per_chunk]) chunks.append(chunk) return chunks
Vorteile:
- Respektiert die Dokumentstruktur
- Hält zusammengehörige Inhalte beisammen
- Natürliche Leseeinheiten
Nachteile:
- Sehr variable Größen
- Abhängig von der Formatierung
- Lange Absätze bleiben problematisch
Verwenden, wenn:
- Dokumente gut formatiert sind
- Absätze vollständige Ideen darstellen
- Blogbeiträge, Artikel
Recursive Character Splitting
LangChain-Ansatz: Aufteilungen in Präferenzreihenfolge ausprobieren.
DEVELOPERpythonfrom langchain_text_splitters import RecursiveCharacterTextSplitter splitter = RecursiveCharacterTextSplitter( chunk_size=1000, chunk_overlap=200, separators=["\n\n", "\n", ". ", " ", ""] ) chunks = splitter.split_text(text)
Trennhierarchie:
- Doppelter Zeilenumbruch (Absätze)
- Einfacher Zeilenumbruch (Zeilen)
- Punkt + Leerzeichen (Sätze)
- Leerzeichen (Wörter)
- Zeichen
Vorteile:
- Respektiert die Dokumentstruktur, wo möglich
- Elegante Rückfalllösung
- Balance zwischen Semantik und Größe
Nachteile:
- Bleibt etwas willkürlich
- Erfasst möglicherweise nicht die wahren semantischen Einheiten
- Konfiguration erforderlich
Verwenden, wenn:
- Allgemeines Chunking benötigt wird
- Gemischte Dokumenttypen vorliegen
- Eine gute Standardwahl gesucht wird
Metadaten-bewusstes Chunking
Die Dokumentstruktur für das Chunking nutzen.
Markdown-Chunking
Nach Überschriften aufteilen und die Hierarchie beibehalten.
DEVELOPERpythondef chunk_markdown(text): chunks = [] current_h1 = "" current_h2 = "" current_chunk = [] for line in text.split('\n'): if line.startswith('# '): if current_chunk: chunks.append({ 'content': '\n'.join(current_chunk), 'h1': current_h1, 'h2': current_h2 }) current_chunk = [] current_h1 = line[2:] elif line.startswith('## '): if current_chunk: chunks.append({ 'content': '\n'.join(current_chunk), 'h1': current_h1, 'h2': current_h2 }) current_chunk = [] current_h2 = line[3:] current_chunk.append(line) if current_chunk: chunks.append({ 'content': '\n'.join(current_chunk), 'h1': current_h1, 'h2': current_h2 }) return chunks
Vorteile der Metadaten:
- Überschriften liefern Kontext für die Suche
- Filterung nach Abschnitt möglich
- Besseres Relevanz-Scoring
HTML/XML-Chunking
Nach semantischen HTML-Tags aufteilen.
DEVELOPERpythonfrom bs4 import BeautifulSoup def chunk_html(html): soup = BeautifulSoup(html, 'html.parser') chunks = [] # Nach Abschnitten aufteilen for section in soup.find_all(['section', 'article', 'div']): if section.get('class') in ['content', 'main']: chunks.append({ 'content': section.get_text(), 'tag': section.name, 'class': section.get('class') }) return chunks
Code-Chunking
Nach Funktions-/Klassengrenzen aufteilen.
DEVELOPERpythonimport ast def chunk_python_code(code): tree = ast.parse(code) chunks = [] for node in ast.walk(tree): if isinstance(node, (ast.FunctionDef, ast.ClassDef)): chunk_lines = code.split('\n')[node.lineno-1:node.end_lineno] chunks.append({ 'content': '\n'.join(chunk_lines), 'type': type(node).__name__, 'name': node.name }) return chunks
Vorteile:
- Bewahrt logische Einheiten (Funktionen, Klassen)
- Metadaten erleichtern das Auffinden
- Natürliche Code-Grenzen
Nachteile:
- Sprachspezifische Analyse
- Komplexe Implementierung
- Kontext zwischen Funktionen kann verloren gehen
Fortgeschrittene Chunking-Techniken
Basierend auf semantischer Ähnlichkeit
Sätze nach semantischer Ähnlichkeit gruppieren.
DEVELOPERpythonfrom sentence_transformers import SentenceTransformer from sklearn.cluster import AgglomerativeClustering def semantic_chunking(text, model, max_chunk_size=512): sentences = nltk.sent_tokenize(text) embeddings = model.encode(sentences) # Ähnliche Sätze gruppieren clustering = AgglomerativeClustering( n_clusters=None, distance_threshold=0.5 ) labels = clustering.fit_predict(embeddings) # Sätze nach Cluster gruppieren chunks = {} for sent, label in zip(sentences, labels): chunks.setdefault(label, []).append(sent) return [' '.join(sents) for sents in chunks.values()]
Vorteile:
- Echte semantische Gruppierung
- Bewältigt Themenwechsel
- Optimale Informationsdichte
Nachteile:
- Rechenintensiv
- Erfordert ein Embedding-Modell
- Komplex zu justieren
Gleitendes Fenster mit kontextuellem Überlappung
Jedem Chunk umgebenden Kontext hinzufügen.
DEVELOPERpythondef sliding_window_chunk(text, window_size=512, context_size=128): tokens = tokenize(text) chunks = [] for i in range(0, len(tokens), window_size): # Hauptfenster start = max(0, i - context_size) end = min(len(tokens), i + window_size + context_size) chunk = { 'content': detokenize(tokens[i:i+window_size]), 'context': detokenize(tokens[start:end]), 'position': i } chunks.append(chunk) return chunks
Vorteile:
- Jeder Chunk hat umgebenden Kontext
- Reduziert Informationsverlust
- Besser für Anfragen an Grenzen
Nachteile:
- Höherer Speicherbedarf
- Mehr Embeddings erforderlich
- Mögliche Redundanz
Hybrides hierarchisches Chunking
Auf mehreren Granularitätsebenen aufteilen.
DEVELOPERpythondef hierarchical_chunk(document): # Ebene 1: Dokument doc_embedding = embed(document['content']) # Ebene 2: Abschnitte sections = split_by_headers(document['content']) section_embeddings = [embed(s) for s in sections] # Ebene 3: Absätze paragraph_chunks = [] for section in sections: paragraphs = section.split('\n\n') paragraph_chunks.extend([ {'content': p, 'section': section} for p in paragraphs ]) para_embeddings = [embed(p['content']) for p in paragraph_chunks] return { 'document': {'embedding': doc_embedding, 'content': document}, 'sections': [{'embedding': e, 'content': s} for e, s in zip(section_embeddings, sections)], 'paragraphs': [{'embedding': e, **p} for e, p in zip(para_embeddings, paragraph_chunks)] }
Retrieval-Strategie:
- Auf Dokumentebene suchen
- Bei Übereinstimmung in den Abschnitten suchen
- Schließlich die spezifischen Absätze abrufen
Vorteile:
- Mehrere Granularitätsebenen
- Retrieval vom Allgemeinen zum Spezifischen
- Bessere Kontexterhaltung
Nachteile:
- Komplexe Implementierung
- Mehr Speicher erforderlich
- Langsamere Indexierung
Chunk-Überlappung
Warum Überlappung?
Ohne Überlappung:
Chunk 1: "...das Datenbankschema umfasst Benutzertabellen"
Chunk 2: "mit Spalten für E-Mail und Passwort..."
Anfrage: "Benutzerdatenbank E-Mail" könnte beide Chunks verpassen
Mit Überlappung:
Chunk 1: "...das Datenbankschema umfasst Benutzertabellen mit Spalten für..."
Chunk 2: "...Benutzertabellen mit Spalten für E-Mail und Passwort..."
Jetzt erscheint "Benutzertabellen mit Spalten" in beiden Chunks, was den Recall verbessert.
Optimale Überlappung
| Chunk-Größe | Empfohlene Überlappung | Verhältnis |
|---|---|---|
| 128 Tokens | 10-20 Tokens | 8-15% |
| 512 Tokens | 50-100 Tokens | 10-20% |
| 1024 Tokens | 100-200 Tokens | 10-20% |
| 2048 Tokens | 200-400 Tokens | 10-20% |
Kompromisse:
- Mehr Überlappung: Besserer Recall, mehr Speicherbedarf, langsamere Suche
- Weniger Überlappung: Weniger Speicherbedarf, schnellere Suche, kann Kontext verpassen
Chunking für verschiedene Inhaltstypen
Technische Dokumentation
DEVELOPERpython# Empfohlen: Markdown-bewusst, Code-Blöcke erhalten chunk_size = 1024 # Chunk-Größe overlap = 150 # Überlappung preserve_code_blocks = True # Code-Blöcke erhalten preserve_tables = True # Tabellen erhalten
Kundenservice-Tickets
DEVELOPERpython# Empfohlen: Feste Größe mit moderatem Überlappung chunk_size = 512 overlap = 100 split_by_turns = True # Jede Frage-/Antwort-Runde
Forschungsartikel
DEVELOPERpython# Empfohlen: Auf Abschnitte basierend, Zitate bewahren split_by_sections = True preserve_citations = True chunk_size = 1024
Code-Repositories
DEVELOPERpython# Empfohlen: Syntaxbewusste Aufteilung split_by_functions = True include_docstrings = True chunk_size = 512
Chat-Protokolle
DEVELOPERpython# Empfohlen: Nach Nachrichten aufteilen chunk_by_messages = True messages_per_chunk = 10 preserve_threading = True
Chunking-Strategien evaluieren
Retrieval-Metriken
Mit einer Reihe von Anfragen testen:
DEVELOPERpythondef evaluate_chunking(queries, ground_truth, chunking_fn): chunks = chunking_fn(documents) embeddings = embed(chunks) precision_scores = [] recall_scores = [] for query, expected_docs in zip(queries, ground_truth): retrieved = search(embed(query), embeddings, k=5) precision = len(set(retrieved) & set(expected_docs)) / len(retrieved) recall = len(set(retrieved) & set(expected_docs)) / len(expected_docs) precision_scores.append(precision) recall_scores.append(recall) return { 'precision': np.mean(precision_scores), 'recall': np.mean(recall_scores) }
End-to-End-Metriken
Die vollständige RAG-Pipeline testen:
- Antwortgenauigkeit
- Kontextnutzung (wie viel des abgerufenen Kontexts genutzt wird)
- Antwortverankerung (Treue zu den Chunks)
Praktische Empfehlungen
Entscheidungsrahmen
- Einfach beginnen: Feste Größe mit Überlappung (512 Tokens, 100 Überlappung)
- Leistung messen: Evaluierungsmetriken verwenden
- Fehler identifizieren: Wo scheitert das Retrieval?
- Iterieren: Semantisches oder metadaten-bewusstes Chunking ausprobieren
- A/B-Tests: Strategien mit echten Anfragen vergleichen
Häufige Muster
90% der Anwendungsfälle:
- Recursive Character Splitting
- Chunks von 512-1024 Tokens
- Überlappung von 10-20%
Strukturierte Dokumente:
- Markdown-/HTML-bewusstes Chunking
- Metadaten erhalten (Überschriften, Abschnitte)
- Variable Größen akzeptabel
Code:
- Syntaxbewusste Aufteilung
- Docstrings zusammen mit Funktionen einbeziehen
- Kleinere Chunks (256-512)
Hybride Suche:
- Mehrere Chunk-Größen
- Hierarchisches Retrieval
- Der Komplexitätsaufwand lohnt sich für hochwertige Anwendungen
Häufige Fallstricke
- Zu kleine Chunks: Kontextverlust, fragmentiertes Retrieval
- Zu große Chunks: Irrelevante Informationen, Token-Verschwendung
- Keine Überlappung: Verpasst Anfragen an Grenzen
- Struktur ignorieren: Willkürliche Aufteilungen in Tabellen, Code, Listen
- Einheitsgröße: Verschiedene Inhalte erfordern verschiedene Strategien
- Keine Evaluierung: Raten statt messen
Ailog-Expertentipp: In Produktivumgebungen mit mehr als 10 Mio. Dokumenten haben wir festgestellt, dass der Start mit Chunks von 512 Tokens und 10% Überlappung in 80% der Fälle funktioniert. Optimieren Sie erst weiter, wenn Sie in Ihren Evaluierungsmetriken Retrieval-Fehler feststellen. Der größte Fehler besteht darin, das Chunking zu über-ingenieren, bevor die tatsächliche Leistung gemessen wurde. Einfach beginnen, messen, iterieren.
Chunking-Strategien auf Ailog testen
Möchten Sie verschiedene Chunking-Ansätze ohne Programmierung testen?
Die Ailog-Plattform ermöglicht Ihnen:
- Dokumente hochladen und Chunking-Strategien nebeneinander vergleichen
- Semantisches Chunking vs. feste Größe sofort testen
- Chunk-Grenzen und Überlappungen visualisieren
- Retrieval-Qualität mit echten Anfragen evaluieren
- Die beste Strategie mit einem Klick in Produktion deployen
Kostenlos ausprobieren → Keine Kreditkarte erforderlich.
Nächste Schritte
Mit korrekt aufgeteilten Dokumenten ist der nächste Schritt die Auswahl und Konfiguration einer Vektordatenbank, um Embeddings effizient zu speichern und zu durchsuchen. Dies wird im folgenden Leitfaden über Vektordatenbanken behandelt.
Tags
Verwandte Artikel
Chunking mit fester Größe: Schnell und zuverlässig
Beherrschen Sie die Grundlagen: Implementieren Sie Chunking mit fester Größe und Überlappungen für konsistente und vorhersehbare RAG-Leistung.
Semantische Aufteilung für besseren Abruf
Teilen Sie Dokumente intelligent nach Bedeutung, nicht nur nach Länge. Lernen Sie Techniken der semantischen Aufteilung für RAG.
Hierarchische Aufteilung: Die Struktur Ihrer Dokumente bewahren
Die hierarchische Aufteilung erhält die Eltern-Kind-Beziehungen in Ihren Dokumenten. Lernen Sie, wie Sie diese fortgeschrittene Technik implementieren, um die Retrieval-Qualität von RAG zu verbessern.