Ingestion

L’ingestion transforme des documents bruts en fragments indexables dans un magasin vectoriel. Le processus est modulaire : vous pouvez remplacer n’importe quel composant selon vos besoins.

Un FileLoader lit les octets bruts depuis une source (système de fichiers local, stockage cloud ou toute autre source personnalisée) et retourne un objet File.

Un DocumentExtractor convertit ce File en un Document structuré. Il analyse notamment les PDF via OCR, convertit le HTML en Markdown ou lit le texte brut en fonction du type de fichier.

Un TextSplitter divise le Document en objets DocumentChunk plus petits. La stratégie et la taille des fragments influencent la qualité de la recherche.

Les étapes facultatives de DocumentProcessor (comme un ChunkEnricher ou un SummaryEnricher) ajoutent des métadonnées à chaque fragment avant l’indexation, par exemple un résumé généré par un LLM ou des tags d’entités.

Un Embedder convertit chaque fragment en un vecteur, et le magasin conserve à la fois le vecteur et le texte brut pour permettre la recherche.

Pipeline

Pipeline

Pipeline est le point d’entrée principal. Il gère le chargement des fichiers, l’extraction, la division en fragments, l’intégration (embedding) et l’indexation. Il prend en charge le traitement en batch, avec gestion de la concurrence, du suivi de progression et des points de contrôle.

from mistralai.search.toolkit.ingestion.pipelines import Pipeline
from mistralai.client import Mistral
from mistralai.search.toolkit.embedding import MistralEmbedder, MODEL_1024_EMBEDDING
from mistralai.search.toolkit.ingestion.extractors import PlainTextExtractor
from mistralai.search.toolkit.ingestion.loaders import FilesystemFileLoader
from mistralai.search.toolkit.ingestion.text_splitters import CharacterTextSplitter
from mistralai.search.toolkit.ingestion.enrichment import SummaryEnricher
from mistralai.search.toolkit.llm import MistralChat, LLMConfig
from mistralai.search.toolkit.mistral_search_index import MistralSearchIndexService

mistral_client = Mistral(api_key="...")
llm = MistralChat(client=mistral_client, config=LLMConfig(model="mistral-small-latest"))

index_name = "my_collection"
vector_store = await MistralSearchIndexService(client=mistral_client).get_search_index(index_name)

pipeline = Pipeline(
    loader=FilesystemFileLoader(),
    extractor=PlainTextExtractor(),
    text_splitter=CharacterTextSplitter(chunk_size=512),
    processors=[SummaryEnricher(llm_provider=llm)],
    embedder=MistralEmbedder(client=mistral_client, model_name=MODEL_1024_EMBEDDING),
    stores=vector_store,
)

num_chunks = await pipeline.run(documents=["doc1.txt", "doc2.txt"])
i
Information

index_name, passé à get_search_index, sélectionne le Mistral Search Index dans lequel vos fragments sont indexés. Commencez par créer l'index et utilisez le même nom pour récupérer des documents par la suite. Les autres backends fonctionnent de la même manière : passez leur store à stores.

Points de contrôle

Pour les collections de documents volumineuses, activez les points de contrôle afin de reprendre le traitement en cas d'échec. Le callback de progression nécessite tqdm, qui ne fait pas partie des dépendances principales : installez-le avec uv add tqdm.

from mistralai.search.toolkit.ingestion.progress import create_tqdm_progress_callback
from mistralai.search.toolkit.ingestion.enrichment import SummaryEnricher
from mistralai.search.toolkit.storage import FilesystemStorage

pipeline = Pipeline(
    loader=FilesystemFileLoader(),
    extractor=extractor,
    text_splitter=splitter,
    processors=[SummaryEnricher(llm_provider=llm)],
    embedder=embedder,
    stores=vector_store,
    checkpoint_store=lambda: FilesystemStorage("./checkpoints"),
)

num_chunks = await pipeline.run(
    documents=document_paths,
    use_checkpoint=True,
    progress_callback=create_tqdm_progress_callback(),
)

Au redémarrage, les documents disposant déjà d'un point de contrôle ignorent l'étape d'extraction (par exemple, OCR). Le découpage, l'enrichissement, les représentations vectorielles et l'indexation sont exécutés à nouveau.

Acheminer les fichiers par type

Acheminer les fichiers par type

RoutedPipeline achemine automatiquement les fichiers vers des pipelines spécifiques en fonction de leur extension et de leur type MIME. Utilisez-le pour ingérer des collections de documents aux formats variés : il sélectionne intelligemment l'extracteur et le pipeline de traitement adaptés à chaque type de fichier.

Protocoles

RoutedPipeline inclut 9 protocoles intégrés. Chaque protocole associe un ensemble de types de fichiers au pipeline d’extraction correspondant :

ProtocoleTypes de fichiers
ocrPDF, DOCX, PPTX, ODT, EPUB
plain_textTXT, MD, CSV, JS, PY, JSON, YAML…
htmlHTML, HTM
xlsxXLSX, XLS, XLSM, XLSB, XLTX, ODS, ODF
numbersNUMBERS
legacy_officeDOC, PPT, HWP, HWPX (uniquement si PYMUPDF_PRO_LICENSE_KEY est définie)
emailEML, MSG
imagePNG, JPEG, GIF, WebP
audioMP3, WAV, M4A, FLAC, OGG

Utiliser les protocoles par défaut

Associez chaque protocole dont vous avez besoin à un Pipeline :

from mistralai.search.toolkit.ingestion.pipelines import RoutedPipeline

router = RoutedPipeline({
    "ocr": ocr_pipeline,
    "html": html_pipeline,
    "plain_text": text_pipeline,
    "xlsx": spreadsheet_pipeline,
})

document = await router.run_file(file=file)

Paramètres

ParamètreDescription
pipelinesDictionnaire associant les noms de protocoles aux instances de Pipeline
mime_registryRegistre MIME personnalisé pour la détection des types de fichiers (optionnel)
protocol_overridesDictionnaire optionnel qui associe un type MIME (par exemple, "text/html") au protocole à utiliser à la place de celui par défaut

Exemple de remplacement

Pour envoyer un type de fichier vers un autre protocole, indexez la substitution par type MIME :

router = RoutedPipeline(
    pipelines={
        "ocr": ocr_pipeline,
        "html": html_pipeline,
        "plain_text": text_pipeline,
        "xlsx": spreadsheet_pipeline,
    },
    protocol_overrides={
        "text/html": "plain_text",  # Index raw HTML as text instead of converting it
    },
)

document = await router.run_file(file=file)
Composants

Composants

Chaque composant d'ingestion dispose de sa propre page, avec ses options de configuration et des exemples :