Strategies de decoupage de texte
Le decoupage (chunking) est l’une des etapes les plus critiques d’un pipeline RAG. La maniere dont vous divisez vos documents impacte directement la qualite de tout le systeme. Une mauvaise strategie de decoupage peut mener a l’insertion de contexte non pertinent dans vos prompts, ce qui fait repondre le modele de maniere completement erronee.
Prenons un exemple concret : vous avez un document avec des sections sur la recherche medicale et l’ingenierie logicielle. Si le decoupage est mal fait, un utilisateur qui demande “Combien de bugs les ingenieurs ont-ils corriges cette annee ?” pourrait obtenir des informations sur la recherche medicale au lieu du genie logiciel, simplement parce que la section medicale contenait le mot “bug” dans un contexte different.
C’est pourquoi le choix de la bonne strategie de decoupage est si important. Voyons les principales approches.
Decoupage par taille fixe
C’est l’approche la plus simple : on divise le texte en chaines de longueur egale. Par exemple, un document de 325 caracteres serait coupe en trois chunks d’environ 108 caracteres.
Cette methode est facile a implementer et fonctionne avec n’importe quel type de document, mais elle a des inconvenients clairs :
- Les mots sont coupes en plein milieu
- Les chunks perdent le contexte du texte environnant
- Les titres de section peuvent etre separes de leur contenu
Pour attenuer ces problemes, on peut ajouter un chevauchement (overlap) entre les chunks. Chaque chunk inclut alors quelques caracteres des chunks voisins, ce qui ameliore le contexte et garantit des mots et phrases complets.
Voici une implementation basique :
def chunk_by_char(text, chunk_size=150, chunk_overlap=20):
# Decoupe le texte en morceaux de taille fixe avec chevauchement
chunks = []
start_idx = 0
while start_idx < len(text):
end_idx = min(start_idx + chunk_size, len(text))
chunk_text = text[start_idx:end_idx]
chunks.append(chunk_text)
start_idx = (
end_idx - chunk_overlap if end_idx < len(text) else len(text)
)
return chunks
Decoupage par structure
Le decoupage structurel divise le texte selon la structure naturelle du document : titres, paragraphes, sections. Il fonctionne tres bien quand on dispose de documents bien formtes, comme des fichiers Markdown.
Pour un document Markdown, on peut simplement couper sur les marqueurs de titre :
def chunk_by_section(document_text):
# Decoupe le document a chaque titre de niveau 2
pattern = r"\n## "
return re.split(pattern, document_text)
Cette approche produit les chunks les plus propres et les plus significatifs, car chacun represente une section complete. En revanche, elle ne fonctionne que lorsqu’on a des garanties sur la structure du document. Beaucoup de documents reels sont du texte brut ou des PDF sans marqueurs structurels clairs.
Decoupage semantique
Le decoupage semantique est l’approche la plus sophistiquee. On divise le texte en phrases, puis on utilise le traitement du langage naturel pour determiner a quel point les phrases consecutives sont liees entre elles. On construit ensuite les chunks a partir de groupes de phrases apparentees.
Cette methode est couteuse en calcul mais produit les chunks les plus pertinents. Elle necessite de comprendre le sens de chaque phrase et est plus complexe a implementer.
Decoupage par phrases
Un bon compromis pratique consiste a decouper par phrases. On separe le texte en phrases individuelles avec des expressions regulieres, puis on les regroupe en chunks avec un chevauchement optionnel :
def chunk_by_sentence(text, max_sentences_per_chunk=5, overlap_sentences=1):
# Decoupe le texte en groupes de phrases avec chevauchement
sentences = re.split(r"(?<=[.!?])\s+", text)
chunks = []
start_idx = 0
while start_idx < len(sentences):
end_idx = min(start_idx + max_sentences_per_chunk, len(sentences))
current_chunk = sentences[start_idx:end_idx]
chunks.append(" ".join(current_chunk))
start_idx += max_sentences_per_chunk - overlap_sentences
if start_idx < 0:
start_idx = 0
return chunks
Comment choisir sa strategie ?
Le choix depend entierement de votre cas d’usage et de vos garanties sur les documents :
| Strategie | Cas d’usage ideal |
|---|---|
| Structure | Meilleurs resultats quand vous controlez le format (ex. rapports internes) |
| Phrases | Bon compromis pour la plupart des documents textuels |
| Taille fixe | Solution de repli fiable qui fonctionne avec tout type de contenu, y compris le code |
Le decoupage par taille fixe avec chevauchement est souvent le choix par defaut en production car il est simple, fiable et fonctionne avec n’importe quel type de document. Meme s’il ne donne pas des resultats parfaits, il produit systematiquement des chunks raisonnables.
Il n’existe pas de strategie “universellement meilleure”. La bonne approche depend de vos documents, de vos cas d’usage, et des compromis que vous acceptez entre complexite d’implementation et qualite des chunks.
Exercice : Testez les strategies
Prenez un document Markdown que vous avez sous la main et implementez les trois strategies de decoupage. Comparez les resultats :
- Decoupez-le par taille fixe (150 caracteres, 20 de chevauchement)
- Decoupez-le par sections (titres H2)
- Decoupez-le par phrases (5 phrases par chunk, 1 phrase de chevauchement)
Questions :
- Quelle strategie produit les chunks les plus coherents ?
- Quelle strategie perd le plus de contexte ?
- Pour votre cas d’usage, quelle strategie choisiriez-vous ?