Sépareurs de texte
Les séparateurs de texte divisent les documents en objets DocumentChunk récupérables. Le choix du séparateur a un impact sur la qualité de récupération.
Sépareurs de texte disponibles
| Séparateur | Idéal pour |
|---|---|
| Séparateur de texte par caractères | Texte simple, prototypage rapide |
| Séparateur de texte par tokens | Découpage conscient des tokens, gestion du Contexte LLM |
| Séparateur de texte Markdown | Documents Markdown, contenu structuré avec des en-têtes |
| Séparateur de texte par séparateurs | Logique de séparation personnalisée, texte hiérarchique |
| Sépareurs personnalisés | Toute stratégie de séparation |
Chaque sous-fragment hérite du type et des métadonnées de son fragment d'origine, comme numéro_page et les éventuelles clés personnalisées. Seuls son localisateur, sa position_début et sa position_fin changent. Les fragments hors contenu, comme les résumés et les annotations d'images, ne sont pas découpés.
Recommandations pour la taille des fragments
La taille des fragments a un impact sur la qualité de récupération et sur l'utilisation du contexte par le LLM. Choisissez-la en fonction de votre cas d'utilisation :
| Contexte LLM | Taille du fragment | Recouvrement | Cas d’usage |
|---|---|---|---|
| 4 k tokens | 300 à 500 caractères | 50 à 100 caractères | Contraintes mémoire, récupération rapide |
| 8 k tokens | 500 à 1 000 caractères | 100 à 200 caractères | Qualité de récupération équilibrée |
| 32 k+ tokens | 1 000 à 2 000 caractères | 200 à 500 caractères | Contexte riche, récupération complexe |
| Code/technique | 500 à 1 000 caractères | 100 à 200 caractères | Préserver les unités logiques |
| Juridique/financier | 1 000 à 2 000 caractères | 200 à 500 caractères | Contexte complet pour l’interprétation |
Règle empirique : ~400 à 600 caractères ≈ 100 à 150 tokens. Ajustez en fonction de la complexité du domaine et des besoins en précision de récupération.
Avantages du recouvrement des fragments :
- Évite que les limites sémantiques ne séparent des concepts liés
- Améliore le Contexte lorsque les fragments sont utilisés individuellement
- Augmente la taille de l’index et la latence des requêtes de manière proportionnelle
Séparateur de texte par caractères
CharacterTextSplitter divise le texte en fonction du nombre de caractères, sans recouvrement. Utilisez-le pour du texte simple et du prototypage rapide.
Exemple :
from mistralai.search.toolkit.ingestion.text_splitters import CharacterTextSplitter
splitter = CharacterTextSplitter(
chunk_size=500, # Characters per chunk
)
chunks = (await splitter.process(document)).chunksParamètres :
| Paramètre | Type | Valeur par défaut | Description |
|---|---|---|---|
taille_fragment | int | 1000 | Nombre maximal de caractères par fragment |
Séparateur de texte par tokens
TokenTextSplitter compte les tokens avec un tokenizer Mistral, pour un contrôle précis de la taille des fragments en tokens.
Exemple :
from mistral_common.tokens.tokenizers.mistral import MistralTokenizer
from mistralai.search.toolkit.ingestion.text_splitters import TokenTextSplitter
splitter = TokenTextSplitter(
chunk_size=1000, # Tokens per chunk
chunk_overlap=200, # Token overlap
tokenizer=MistralTokenizer.v1(), # Embedding tokenizer
)
chunks = (await splitter.process(document)).chunksOptions de configuration :
| Option | Type | Valeur par défaut | Objectif |
|---|---|---|---|
taille_fragment | int | 512 | Nombre de tokens cible par fragment |
recouvrement_fragment | int | 50 | Tokens de recouvrement entre les fragments |
nom_modèle | str | "mistral-embed" | Modèle dont le tokenizer est déterminé lorsque tokenizer n'est pas défini |
tokenizer | MistralTokenizer | None | None | Instance de tokenizer ; prime sur nom_modèle |
Quand l’utiliser :
- Budget précis en tokens pour les fenêtres de Contexte LLM
- Fragments cohérents quel que soit le type de texte
- Pour travailler avec des limites de tokens spécifiques
Séparateur de texte Markdown
MarkdownTextSplitter divise les documents Markdown au niveau des titres. Il découpe d'abord sur les titres, puis exécute un SeparatorTextSplitter sur chaque section. Sa configuration étend SeparatorTextSplitterConfig avec des niveaux de titre configurables.
Prérequis :
Installez l’extra text-splitter-langchain :
uv add "mistralai-search-toolkit[text-splitter-langchain]"Exemple :
from mistralai.search.toolkit.ingestion.text_splitters import MarkdownTextSplitter, MarkdownTextSplitterConfig
config = MarkdownTextSplitterConfig(
headers_to_split_on=[
("#", "h1"),
("##", "h2"),
("###", "h3"),
],
strip_headers=False, # Keep headers in chunks
chunk_size=1000, # Inherited from SeparatorTextSplitterConfig
chunk_overlap=200, # Inherited from SeparatorTextSplitterConfig
)
splitter = MarkdownTextSplitter(config=config)
chunks = (await splitter.process(document)).chunksParamètres (MarkdownTextSplitterConfig) :
MarkdownTextSplitterConfig étend SeparatorTextSplitterConfig et ajoute :
| Paramètre | Type | Valeur par défaut | Description |
|---|---|---|---|
en-têtes_à_diviser | list[tuple[str, str]] | [("#", "En-tête 1"), ("##", "En-tête 2"), ("###", "En-tête 3")] | En-têtes Markdown sur lesquels diviser — chaque tuple est (préfixe_en-tête, libellé) |
supprimer_en-têtes | bool | False | Supprimer les lignes d’en-tête du contenu des fragments |
Tous les paramètres de SeparatorTextSplitterConfig sont également disponibles (taille_fragment, taille_max_fragment, recouvrement_fragment, séparateurs_fragments, conserver_séparateur, supprimer_espaces).
Séparateur de texte par séparateurs
SeparatorTextSplitter divise le texte de manière récursive selon une liste de séparateurs. Utilisez-le pour des structures de documents personnalisées, lorsque vous devez contrôler les points de découpage.
Prérequis :
Installez l'extra text-splitter-langchain :
uv add "mistralai-search-toolkit[text-splitter-langchain]"Exemple :
from mistralai.search.toolkit.ingestion.text_splitters import SeparatorTextSplitter, SeparatorTextSplitterConfig
config = SeparatorTextSplitterConfig(
chunk_size=1000, # Target size (characters)
chunk_max_size=1500, # Maximum size (characters)
chunk_overlap=200, # Overlap (characters)
chunk_separators=[ # Tried in order
"\n\n", # Paragraphs first
"\n", # Then lines
". ", # Then sentences
" ", # Then words
"", # Finally characters
],
)
splitter = SeparatorTextSplitter(config=config)
chunks = (await splitter.process(document)).chunksParamètres (SeparatorTextSplitterConfig) :
| Paramètre | Type | Valeur par défaut | Description |
|---|---|---|---|
taille_fragment | int | 2048 | Taille cible des fragments, en caractères |
taille_max_fragment | int | None | None | Taille maximale des fragments, pour éviter de couper au milieu d'un mot. None utilise taille_fragment. |
recouvrement_fragment | int | 0 | Recouvrement entre les fragments, en caractères |
séparateurs_fragments | list[str] | ["\n\n", "\n", ".", ", ", ",", " ", "\t"] | Séparateurs, testés de gauche à droite |
conserver_séparateur | bool | "start" | "end" | "end" | Indique si les séparateurs sont conservés dans les fragments, et à quel endroit |
supprimer_espaces | bool | False | Supprime les espaces en début et en fin de chaque fragment |
Fonctionnalités :
- Essaie les séparateurs dans l’ordre
- Respecte la taille maximale même si la division échoue
- Fusionne les petits fragments lorsqu’es possible
- Retourne les positions de début/fin
Créer des sépareurs personnalisés
Implémentez le protocole TextSplitter :
from mistralai.search.toolkit.context import IngestContext
from mistralai.search.toolkit.ingestion.text_splitters import TextSplitter
from mistralai.search.toolkit.ingestion.text_splitters.models import TextFragment
class ParagraphSplitter(TextSplitter):
"""Split text into chunks by paragraphs."""
def __init__(self, max_paragraphs_per_chunk: int = 3):
self.max_paragraphs_per_chunk = max_paragraphs_per_chunk
def split_text(self, text: str, context: IngestContext = IngestContext()) -> list[TextFragment]:
paragraphs = text.split("\n\n")
fragments = []
offset = 0
for i in range(0, len(paragraphs), self.max_paragraphs_per_chunk):
chunk_paragraphs = paragraphs[i:i + self.max_paragraphs_per_chunk]
content = "\n\n".join(chunk_paragraphs)
fragments.append(TextFragment(
content=content,
start_offset=offset,
end_offset=offset + len(content),
))
offset += len(content) + 2
return fragments
splitter = ParagraphSplitter(max_paragraphs_per_chunk=3)
fragments = splitter.split_text("First paragraph.\n\nSecond paragraph.\n\nThird paragraph.")