Chunk enrichers add custom metadata to chunks during ingestion. Use them to attach information from external sources, classifications, tags, or any computed metadata.

Available chunk enrichers

Available chunk enrichers

EnricherPurpose
Summary EnricherGenerate document summaries using an LLM
Custom EnrichersAdd custom metadata from any source
Summary Enricher

Summary Enricher

SummaryEnricher generates a document summary using an LLM and optionally injects it into chunks and/or document metadata. This can improve retrieval by giving each chunk context about the full document.

By default, SummaryEnricher is non-breaking: if summary generation fails, it logs the failure and returns the original chunks unchanged.

Requirements:

  • A Mistral API key

Usage:

import os

from mistralai.client import Mistral
from mistralai.search.toolkit.ingestion.enrichment import SummaryEnricher, SummaryConfig, SummarizeRequestConfig
from mistralai.search.toolkit.llm import MistralChat, LLMConfig

# Create LLM provider
mistral_client = Mistral(api_key=os.environ.get("MISTRAL_API_KEY", "your-api-key"))
llm = MistralChat(client=mistral_client, config=LLMConfig(model="mistral-small-latest"))

# Create enricher with default settings
enricher = SummaryEnricher(llm_provider=llm)

# Or customize the summary behavior
enricher = SummaryEnricher(
    llm_provider=llm,
    summary_config=SummaryConfig(
        request_config=SummarizeRequestConfig(
            prompt="Summarize this document in 3 sentences.",
            max_tokens=256,
        ),
    ),
)

Parameters:

ParameterTypeDefaultDescription
llm_providerChatLLMProvider(required)LLM provider for summarization
summary_configSummaryConfig | NoneNoneConfiguration object (see below)

SummarizeRequestConfig:

Controls the LLM request for summary generation.

ParameterTypeDefaultDescription
modelstr"mistral-small-latest"Model to use for summarization
promptstr"Summarize the document in less than 5 lines."Summarization prompt
max_tokensint256Maximum tokens in the summary
max_chars_per_callint | None32768Char budget per LLM call; content above this is truncated or map-reduced (see overflow_strategy)
overflow_strategyOverflowStrategyOverflowStrategy.TRUNCATETRUNCATE cuts to max_chars_per_call; MAP_REDUCE splits into parts, summarizes each, then merges
map_concurrencyint10Max concurrent map-phase LLM calls (map-reduce only)
temperaturefloat | None0.6LLM temperature

SummaryRequestOptions:

Controls how the summary is injected into the pipeline output.

ParameterTypeDefaultDescription
include_summary_chunkboolTrueAdd a dedicated summary chunk to the chunk list
propagate_summary_to_chunksboolFalsePrepend the summary to every chunk's content
populate_document_metadataboolTrueStore the summary in the document's metadata
fail_on_generation_errorboolFalseRaise on summary generation failure instead of logging and continuing
Creating custom enrichers

Creating custom enrichers

Implement the ChunkEnricher interface to add custom metadata. ChunkEnricher is a DocumentProcessor: implement enrich_chunk to transform a single chunk, and process fans it out over the document's chunks:

from mistralai.search.toolkit.context import IngestContext
from mistralai.search.toolkit.ingestion.enrichment import ChunkEnricher
from mistralai.search.toolkit.document import DocumentChunk, Document

class EntityTagger(ChunkEnricher):
    """Add entity tags to chunks."""

    async def enrich_chunk(
        self,
        document: Document,
        chunk: DocumentChunk,
        context: IngestContext = IngestContext(),
    ) -> DocumentChunk:
        entities = await self._extract_entities(chunk.content)
        updated_metadata = chunk.metadata.model_copy(update={"entities": entities})
        return chunk.model_copy(update={"metadata": updated_metadata})

    async def _extract_entities(self, text: str) -> list[str]:
        entities = []
        # ... entity extraction logic ...
        return entities

enricher = EntityTagger()
enriched_document = await enricher.process(document)

for chunk in enriched_document.chunks:
    print(f"Entities: {chunk.metadata.get('entities', [])}")

Batch enrichment patterns

ChunkEnricher.process already fans enrich_chunk out over the document's chunks with a bounded worker pool (concurrency, default 10). For external API calls, keep that work inside enrich_chunk:

from mistralai.search.toolkit.context import IngestContext
from mistralai.search.toolkit.ingestion.enrichment import ChunkEnricher
from mistralai.search.toolkit.document import DocumentChunk, Document

class BatchEnricher(ChunkEnricher):
    """Batch API calls for efficiency."""

    def __init__(self) -> None:
        super().__init__(concurrency=20)  # raise the worker-pool size for external calls

    async def enrich_chunk(
        self,
        document: Document,
        chunk: DocumentChunk,
        context: IngestContext = IngestContext(),
    ) -> DocumentChunk:
        metadata = await self._fetch_metadata(chunk.content)
        return chunk.model_copy(
            update={"metadata": chunk.metadata.model_copy(update=metadata)}
        )

    async def _fetch_metadata(self, text: str) -> dict:
        # Call external API with batching/retries
        ...

Combining multiple enrichers

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

pipeline = Pipeline(
    loader=loader,
    extractor=extractor,
    text_splitter=splitter,
    embedder=embedder,
    stores=vector_store,
    processors=[
        SummaryEnricher(llm_provider=llm),
        EntityTagger(),
        CustomMetadataEnricher(),
    ],
)

Enrichers are applied sequentially in the order listed. Each enricher receives the output of the previous one.