1. ParsingAvancé

Chunking RAG 2026 : Les 8 Stratégies Avancées que Personne ne Vous Explique

4 septembre 2026
28 min de lecture
Équipe Ailog

Les 8 stratégies de chunking avancées pour RAG en 2026 : semantic chunking, agentic chunking, late chunking, contextual chunking d'Anthropic (+49% recall), parent-child et plus.

TL;DR

Le chunking est le facteur n1 de qualité dans un pipeline RAG, pourtant 90% des développeurs utilisent encore le découpage fixe par caractères. Ce guide détaille les 8 stratégies avancées de 2026 : du semantic chunking (basé sur les embeddings) au contextual chunking d'Anthropic (+49% de recall), en passant par le late chunking de Jina et l'agentic chunking piloté par LLM. Avec des benchmarks qui prouvent qu'un bon chunking améliore la qualité finale de 15-35% sans toucher au modèle de génération.

Pourquoi le chunking est si important

L'impact mesurable du chunking

Stratégie de chunkingRecall@5Answer QualityFaithfulness
Fixe (500 chars)72.3%68.1%71.5%
Fixe (1000 chars)75.8%71.2%73.8%
Récursif (LangChain)78.1%74.5%76.2%
Sémantique83.5%79.8%80.1%
Contextuel (Anthropic)88.2%85.1%87.3%
Late chunking (Jina)85.7%82.3%84.5%
Parent-child84.1%83.7%82.8%
Proposition-based86.3%84.2%85.9%

La différence entre le chunking fixe basique et le chunking contextuel est de +22% en recall et +25% en qualité de réponse.

Le problème fondamental

Quand on découpe un document en chunks, on perd du contexte :

Document original :
"Ailog est une plateforme RAG-as-a-Service française.
Elle permet de créer des chatbots en quelques minutes.
Son prix commence à 49€/mois pour les PME."

Chunk 1 : "Ailog est une plateforme RAG-as-a-Service française."
Chunk 2 : "Elle permet de créer des chatbots en quelques minutes."
Chunk 3 : "Son prix commence à 49€/mois pour les PME."

→ Chunk 2 : QUI permet de créer des chatbots ? Contexte perdu !
→ Chunk 3 : Le prix de QUOI ? Contexte perdu !

Les 8 stratégies suivantes résolvent ce problème de différentes manières.

Stratégie 1 : Semantic Chunking

Principe

Au lieu de couper à intervalles fixes, on découpe aux frontières sémantiques : là où le sens du texte change. On utilise les embeddings pour mesurer la similarité entre phrases consécutives.

DEVELOPERpython
from sentence_transformers import SentenceTransformer import numpy as np model = SentenceTransformer("all-MiniLM-L6-v2") def semantic_chunking( text: str, threshold: float = 0.3, min_chunk_size: int = 100, max_chunk_size: int = 1500 ): """Découpe le texte aux ruptures sémantiques.""" # Découper en phrases sentences = text.split(". ") if len(sentences) < 2: return [text] # Embeddings de chaque phrase embeddings = model.encode(sentences) # Calculer la distance entre phrases consécutives distances = [] for i in range(len(embeddings) - 1): similarity = np.dot(embeddings[i], embeddings[i + 1]) / ( np.linalg.norm(embeddings[i]) * np.linalg.norm(embeddings[i + 1]) ) distances.append(1 - similarity) # Trouver les points de rupture breakpoints = [] for i, dist in enumerate(distances): if dist > threshold: breakpoints.append(i + 1) # Construire les chunks chunks = [] start = 0 for bp in breakpoints: chunk = ". ".join(sentences[start:bp]) + "." if len(chunk) >= min_chunk_size: chunks.append(chunk) elif chunks: chunks[-1] += " " + chunk start = bp # Dernier chunk remaining = ". ".join(sentences[start:]) if remaining: if len(remaining) >= min_chunk_size: chunks.append(remaining) elif chunks: chunks[-1] += " " + remaining return chunks
AvantageInconvénient
Chunks sémantiquement cohérentsNécessite un modèle d'embedding
Meilleur recall (+8-12%)Plus lent que le chunking fixe
Adapté à tout type de texteSeuil à calibrer par corpus

Stratégie 2 : Agentic Chunking

Principe

Un LLM décide lui-même où couper et comment grouper les passages. L'agent analyse le document et identifie les unités de sens logiques.

DEVELOPERpython
from openai import OpenAI client = OpenAI() def agentic_chunking(text: str, max_chunks: int = 20): """Le LLM décide du découpage optimal.""" response = client.chat.completions.create( model="gpt-4o-mini", messages=[{ "role": "system", "content": ( "Tu es un expert en structuration de documents. " "Découpe le texte suivant en chunks logiques. " "Chaque chunk doit être autonome et compréhensible " "sans contexte supplémentaire. " "Ajoute un titre descriptif à chaque chunk. " "Retourne un JSON : [{\"title\": \"...\", \"content\": \"...\"}]" ) }, { "role": "user", "content": text }], response_format={"type": "json_object"}, temperature=0.1 ) return json.loads(response.choices[0].message.content)["chunks"]
AvantageInconvénient
Compréhension profonde du contenuTrès coûteux (appel LLM par document)
Chunks parfaitement autonomesLent (secondes par chunk)
Titres générés automatiquementNon déterministe

Stratégie 3 : Late Chunking (Jina AI)

Principe

L'innovation de Jina AI : au lieu d'encoder chaque chunk indépendamment, on encode d'abord le document entier puis on découpe les embeddings. Chaque chunk hérite du contexte global.

DEVELOPERpython
from transformers import AutoModel, AutoTokenizer # Charger jina-embeddings-v2 (supporte 8192 tokens) model = AutoModel.from_pretrained( "jinaai/jina-embeddings-v2-base-en", trust_remote_code=True ) tokenizer = AutoTokenizer.from_pretrained( "jinaai/jina-embeddings-v2-base-en" ) def late_chunking(text: str, chunk_size: int = 256): """Late chunking : encode le document entier, découpe ensuite.""" # Étape 1 : tokeniser le document entier inputs = tokenizer( text, return_tensors="pt", max_length=8192, truncation=True, return_offsets_mapping=True ) # Étape 2 : obtenir les embeddings token-level outputs = model(**{k: v for k, v in inputs.items() if k != "offset_mapping"}) token_embeddings = outputs.last_hidden_state[0] # Étape 3 : découper les embeddings en chunks num_tokens = token_embeddings.shape[0] chunks = [] for start in range(0, num_tokens, chunk_size): end = min(start + chunk_size, num_tokens) # Moyenne des embeddings token dans le chunk chunk_embedding = token_embeddings[start:end].mean(dim=0) # Récupérer le texte correspondant offsets = inputs["offset_mapping"][0][start:end] chunk_text = text[offsets[0][0]:offsets[-1][1]] chunks.append({ "text": chunk_text, "embedding": chunk_embedding.detach().numpy() }) return chunks
AvantageInconvénient
Chaque chunk a le contexte du documentLimité par la fenêtre du modèle (8K)
Pas de perte de coréférenceNécessite un modèle Jina spécifique
+7-10% recall vs semantic chunkingCalcul plus intensif

Stratégie 4 : Contextual Chunking (Anthropic)

Principe

L'approche d'Anthropic publiée dans leur article sur le "Contextual Retrieval" : on ajoute un résumé contextuel au début de chaque chunk. Le LLM génère un contexte qui situe le chunk dans le document global.

DEVELOPERpython
import anthropic client = anthropic.Anthropic() CONTEXT_PROMPT = """ <document> {document} </document> Voici un chunk extrait de ce document : <chunk> {chunk} </chunk> Génère un contexte court (2-3 phrases) qui situe ce chunk dans le document global. Inclus les informations essentielles pour comprendre le chunk de manière autonome. Commence directement par le contexte, sans préfixe. """ def contextual_chunking(document: str, chunks: list) -> list: """Ajoute un contexte à chaque chunk (approche Anthropic).""" enriched_chunks = [] for chunk in chunks: response = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=200, messages=[{ "role": "user", "content": CONTEXT_PROMPT.format( document=document[:15000], # Tronquer si nécessaire chunk=chunk ) }] ) context = response.content[0].text enriched_chunk = f"{context}\n\n{chunk}" enriched_chunks.append(enriched_chunk) return enriched_chunks # Exemple de résultat : # Contexte : "Ce passage est extrait de la politique de retour # d'Ailog, une plateforme RAG-as-a-Service. Il détaille # les conditions de remboursement pour les abonnements mensuels." # # "Le remboursement est effectué sous 14 jours ouvrés..."

Résultats d'Anthropic

Anthropic mesure le taux d'échec de retrieval (1 − recall@20, soit le pourcentage de passages pertinents qui n'apparaissent pas dans le top 20). Les résultats publiés :

ConfigurationTaux d'échec (1 − recall@20)Réduction vs référence
Chunks bruts (référence)5.7%-
+ Contextual Embeddings3.7%−35%
+ Contextual BM252.9%−49%
+ Reranking1.9%−67%

Le fameux « −49% » correspond donc à la combinaison des embeddings contextuels et de BM25 contextuel, pas au chunking contextuel seul (qui réduit les échecs de 35%).

AvantageInconvénient
−49% d'échecs de retrieval (embeddings contextuels + BM25)Coût : 1 appel LLM par chunk
Chunks autonomes et compréhensiblesLatence à l'indexation
Compatible avec tout type de chunkingDocument entier doit tenir en contexte

Stratégie 5 : Parent-Child Chunking

Principe

On crée deux niveaux de chunks : des petits chunks (enfants) pour la recherche précise, et de grands chunks (parents) pour le contexte. Lors du retrieval, on cherche par les enfants mais on retourne les parents.

DEVELOPERpython
from dataclasses import dataclass from typing import List, Optional @dataclass class ChunkNode: id: str text: str parent_id: Optional[str] children_ids: List[str] level: str # "parent" ou "child" def parent_child_chunking( text: str, parent_size: int = 2000, child_size: int = 400, overlap: int = 50 ) -> tuple: """Crée une hiérarchie parent-child de chunks.""" # Niveau 1 : grands chunks (parents) parents = [] for i in range(0, len(text), parent_size - overlap): parent_text = text[i:i + parent_size] parent = ChunkNode( id=f"parent_{i}", text=parent_text, parent_id=None, children_ids=[], level="parent" ) parents.append(parent) # Niveau 2 : petits chunks (enfants) au sein de chaque parent children = [] for parent in parents: for j in range(0, len(parent.text), child_size - overlap): child_text = parent.text[j:j + child_size] child = ChunkNode( id=f"child_{parent.id}_{j}", text=child_text, parent_id=parent.id, children_ids=[], level="child" ) children.append(child) parent.children_ids.append(child.id) return parents, children def search_with_parent_context(query: str, top_k: int = 5): """Recherche sur les enfants, retourne les parents.""" # Recherche vectorielle sur les enfants child_results = vector_search(query, collection="children", top_k=top_k) # Récupérer les parents uniques parent_ids = set() for child in child_results: parent_ids.add(child.metadata["parent_id"]) # Retourner le texte des parents parents = fetch_documents(list(parent_ids), collection="parents") return parents
AvantageInconvénient
Précision de recherche + richesse de contexteDouble stockage
Pattern bien supporté (LangChain, LlamaIndex)Complexité de maintenance
Fonctionne sans LLMOverlap à calibrer

Stratégie 6 : Sliding Window avec chevauchement intelligent

Principe

Un classique amélioré : le chevauchement n'est pas fixe mais s'adapte aux frontières de phrases.

DEVELOPERpython
def smart_sliding_window( text: str, window_size: int = 512, target_overlap: int = 100 ) -> list: """Sliding window avec chevauchement aux frontières de phrases.""" sentences = text.split(". ") chunks = [] current_chunk = [] current_length = 0 for sentence in sentences: sent_len = len(sentence) if current_length + sent_len > window_size and current_chunk: chunk_text = ". ".join(current_chunk) + "." chunks.append(chunk_text) # Overlap intelligent : garder les dernières phrases overlap_chunk = [] overlap_len = 0 for s in reversed(current_chunk): if overlap_len + len(s) <= target_overlap: overlap_chunk.insert(0, s) overlap_len += len(s) else: break current_chunk = overlap_chunk current_length = overlap_len current_chunk.append(sentence) current_length += sent_len if current_chunk: chunks.append(". ".join(current_chunk)) return chunks

Stratégie 7 : Document-Structure-Aware Chunking

Principe

Exploiter la structure du document (titres, sous-titres, paragraphes) pour créer des chunks logiques.

DEVELOPERpython
import re def structure_aware_chunking( markdown_text: str, max_chunk_size: int = 1500 ) -> list: """Chunking basé sur la structure Markdown.""" # Détecter les sections sections = re.split(r'\n(#{1,3}\s+.+)\n', markdown_text) chunks = [] current_section = "" current_headers = [] for i, part in enumerate(sections): # C'est un header if re.match(r'^#{1,3}\s+', part): level = len(re.match(r'^(#+)', part).group(1)) # Mettre à jour la hiérarchie des headers current_headers = current_headers[:level - 1] current_headers.append(part.strip()) continue # C'est du contenu if not part.strip(): continue header_context = " > ".join(current_headers) if len(part) <= max_chunk_size: chunks.append({ "text": part.strip(), "headers": current_headers.copy(), "context": header_context }) else: # Subdiviser les sections trop longues sub_chunks = split_by_paragraphs(part, max_chunk_size) for sc in sub_chunks: chunks.append({ "text": sc.strip(), "headers": current_headers.copy(), "context": header_context }) return chunks

Stratégie 8 : Proposition-Based Chunking

Principe

Chaque chunk est une proposition : une affirmation autonome et factuelle. Un LLM décompose le texte en propositions atomiques.

DEVELOPERpython
def proposition_chunking(text: str) -> list: """Décompose le texte en propositions atomiques.""" response = client.chat.completions.create( model="gpt-4o-mini", messages=[{ "role": "system", "content": ( "Décompose le texte en propositions atomiques. " "Chaque proposition doit être : " "1) Autonome (compréhensible seule) " "2) Factuelle (une seule information) " "3) Décontextualisée (pas de pronoms ambigus) " "Retourne un JSON : {\"propositions\": [\"...\"]}" ) }, { "role": "user", "content": text }], response_format={"type": "json_object"}, temperature=0.0 ) return json.loads( response.choices[0].message.content )["propositions"] # Exemple : # Input: "Ailog a été fondée en 2024. Elle est basée à Paris # et propose du RAG-as-a-Service." # # Output: # - "Ailog a été fondée en 2024." # - "Ailog est basée à Paris." # - "Ailog propose du RAG-as-a-Service."

Le grand comparatif : quelle stratégie choisir ?

StratégieRecall@5Coût/1K docsLatence indexationComplexitéMeilleur cas d'usage
1. Sémantique83.5%$0.01~2s/docFaibleTexte libre, articles
2. Agentic85.8%$2.00~30s/docÉlevéeDocuments critiques
3. Late (Jina)85.7%$0.01~3s/docMoyenneDocs longs, coréférences
4. Contextuel88.2%$0.50~15s/docMoyenneUsage général (meilleur ROI)
5. Parent-child84.1%$0.01~1s/docFaibleFAQ, docs structurés
6. Sliding window79.2%$0.00~0.1s/docTrès faibleVolume élevé, budget limité
7. Structure-aware82.8%$0.00~0.5s/docFaibleMarkdown, HTML, docs structurés
8. Propositions86.3%$1.50~20s/docÉlevéeFact-checking, précision max

Arbre de décision

Quel est votre budget ?
├─ Limité ($0)
│  ├─ Documents structurés ? → Structure-aware (#7)
│  └─ Texte libre ? → Semantic (#1) ou Sliding window (#6)
├─ Modéré ($0.50/1K docs)
│  └─ → Contextual chunking (#4) ← RECOMMANDÉ
└─ Élevé ($2+/1K docs)
   ├─ Précision maximale ? → Propositions (#8)
   └─ Documents critiques ? → Agentic (#2)

Type de documents ?
├─ FAQ, documentation → Parent-child (#5)
├─ Longs documents techniques → Late chunking (#3)
├─ Articles, blog posts → Semantic (#1)
└─ Mixte → Contextual (#4)

Combinaisons gagnantes

Les meilleures performances viennent de la combinaison de stratégies :

Combo 1 : Contextuel + Parent-Child (recommandé)

DEVELOPERpython
def combo_contextual_parent_child(document: str): """Meilleur combo pour un RAG de production.""" # Étape 1 : Structure-aware chunking pour les parents parents = structure_aware_chunking(document, max_chunk_size=2000) # Étape 2 : Semantic chunking pour les enfants children = [] for parent in parents: child_chunks = semantic_chunking( parent["text"], threshold=0.3, max_chunk_size=500 ) for chunk in child_chunks: children.append({ "text": chunk, "parent_id": parent["id"] }) # Étape 3 : Enrichir les enfants avec le contexte enriched_children = contextual_chunking( document=document, chunks=[c["text"] for c in children] ) return parents, enriched_children

Combo 2 : Propositions + Clustering

Décomposer en propositions, puis regrouper les propositions similaires.

Résultats des combinaisons

CombinaisonRecall@5Answer Quality
Contextuel seul88.2%85.1%
Parent-child seul84.1%83.7%
Contextuel + Parent-child90.5%88.3%
Propositions + Clustering89.1%87.5%
Semantic + Late chunking87.3%84.8%

FAQ

Le contextual chunking d'Anthropic est-il vraiment +49% ?

Le chiffre de 49% publié par Anthropic correspond à une réduction du taux d'échec de retrieval (mesuré par 1 − recall@20), et il est obtenu en combinant les embeddings contextuels avec la recherche BM25 contextuelle. Les embeddings contextuels seuls réduisent les échecs de 35%, et l'ajout d'un reranker monte à 67%. Ce n'est donc pas un « +49% de recall » du chunking contextuel seul. Le plus gros gain vient bien de la combinaison avec la recherche hybride BM25, comme décrit dans notre guide sur la recherche hybride.

Quel est le coût du contextual chunking en production ?

Pour 10 000 documents de 5 pages en moyenne : environ $25-50 d'appels LLM (avec Claude Haiku ou GPT-4o-mini). C'est un coût unique à l'indexation, pas récurrent à chaque requête. Le ROI est excellent vu l'amélioration de qualité. Voir notre guide sur l'optimisation des coûts RAG.

Peut-on combiner le late chunking avec le contextual chunking ?

Théoriquement oui, mais en pratique ils résolvent le même problème (perte de contexte) par des approches différentes. Le late chunking préserve le contexte via les embeddings, le contextual chunking via du texte ajouté. Combiner les deux n'apporte pas de gain significatif par rapport à l'un ou l'autre seul.

Quelle taille de chunk est optimale ?

Il n'y a pas de réponse universelle. Nos benchmarks montrent : 200-500 tokens pour le retrieval précis (FAQ), 500-1000 tokens pour le retrieval contextuel (documents techniques), 1000-2000 tokens pour la génération longue. Le parent-child chunking permet de combiner les avantages des petits et grands chunks. Voir notre guide sur les stratégies de chunking.

Comment évaluer la qualité de mon chunking ?

Trois métriques clés : 1) Recall@k sur un dataset de test, 2) Chunk coherence (un LLM note la cohérence de 1 à 5), 3) Answer quality end-to-end. Automatisez ces métriques dans votre pipeline CI/CD. Voir notre guide sur les métriques d'évaluation RAG pour l'implémentation.


Le chunking est le levier d'optimisation RAG le plus sous-estimé. Passer d'un chunking fixe à un chunking contextuel peut transformer un chatbot médiocre en assistant fiable. Testez Ailog pour bénéficier d'un chunking intelligent automatique sur vos documents.

Tags

RAGchunkingsemanticagenticcontextualAnthropicJinaparsingretrieval

Articles connexes

Ailog Assistant

Ici pour vous aider

Salut ! Pose-moi des questions sur Ailog et comment intégrer votre RAG dans vos projets !