Claude Platform Docs
MessagesCompaction

Compaction à un seuil de tokens

Demandez à l'API de résumer automatiquement le contexte plus ancien, au sein d'une requête ordinaire, lorsque la conversation atteint un seuil de tokens que vous définissez.

La « threshold compaction » (compaction par seuil) est la forme automatique de la compaction : vous définissez un « token threshold » (seuil de tokens) sur vos requêtes ordinaires, et l'API résume le contexte plus ancien en cours de requête une fois le seuil atteint. Elle est prise en charge parallèlement à la compaction à la demande, où c'est vous qui décidez quand le résumé est rédigé (consultez Compaction à la demande). Pour choisir entre les deux, consultez Choisir comment compacter.

La compaction étend la longueur de contexte effective pour les conversations et les tâches de longue durée en résumant automatiquement le contexte plus ancien à l'approche de la limite de la « context window » (fenêtre de contexte). Elle permet également de garder le contexte actif réduit : à mesure qu'une conversation s'allonge, la qualité des réponses se dégrade, c'est pourquoi la compaction remplace le contenu plus ancien par un résumé concis.

Cette fonctionnalité est idéale pour :

  • Les conversations multi-tours de type chat, où vous souhaitez que les utilisateurs utilisent un même chat pendant une longue période
  • Les prompts orientés tâches qui nécessitent beaucoup de travail de suivi (souvent de l'utilisation d'outils) susceptible de dépasser la fenêtre de contexte

Fonctionnement de la compaction

Lorsque la compaction est activée, Claude résume automatiquement votre conversation lorsqu'elle atteint le seuil de tokens configuré. L'API :

  1. Détecte le moment où les tokens d'entrée atteignent le seuil de déclenchement que vous avez spécifié.
  2. Génère un résumé de la conversation en cours.
  3. Crée un bloc compaction contenant le résumé.
  4. Poursuit la réponse avec le contexte compacté.

Lors des requêtes suivantes, ajoutez la réponse à vos messages. L'API supprime automatiquement tous les blocs de contenu antérieurs au bloc compaction et poursuit la conversation à partir du résumé.

ServerInput tokens exceed trigger thresholdConversation is summarizedCompaction block created with summaryResponse continues with compacted contextnext requestClientAppend response to messagesMessages before the compaction block are dropped on next request

Utilisation de base

Activez la compaction en ajoutant la stratégie compact_20260112 à context_management.edits dans votre requête à l'API Messages.

client = anthropic.Anthropic()

messages = [{"role": "user", "content": "Help me build a website"}]

response = client.beta.messages.create(
    betas=["compact-2026-01-12"],
    model="claude-opus-5-5",
    max_tokens=4096,
    messages=messages,
    context_management={"edits": [{"type": "compact_20260112"}]},
)

# Ajoutez la réponse (y compris tout bloc de compaction) pour poursuivre la conversation.
messages.append({"role": "assistant", "content": response.content})

Paramètres

ParamètreTypeValeur par défautDescription
typestringObligatoireDoit être "compact_20260112"
triggerobject{"type": "input_tokens", "value": 150000}Moment où déclencher la compaction. input_tokens est le seul type de déclencheur pris en charge. value doit être d'au moins 50 000 tokens.
pause_after_compactionbooleanfalseIndique s'il faut faire une pause après la génération du résumé de compaction
instructionsstringnullPrompt de résumé personnalisé. Remplace entièrement le prompt par défaut lorsqu'il est fourni.

Configuration du déclencheur

Configurez le moment où la compaction se déclenche à l'aide du paramètre trigger :

client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
response = client.beta.messages.create(
    betas=["compact-2026-01-12"],
    model="claude-opus-5-5",
    max_tokens=4096,
    messages=messages,
    context_management={
        "edits": [
            {
                "type": "compact_20260112",
                "trigger": {"type": "input_tokens", "value": 150000},
            }
        ]
    },
)

Instructions de résumé personnalisées

Le prompt de résumé par défaut varie selon le modèle. Chaque prompt par défaut demande à Claude de rédiger un résumé entre des balises <summary></summary> contenant les informations nécessaires pour poursuivre la tâche dans une future fenêtre de contexte. Par exemple, certains modèles utilisent le prompt suivant :

You have written a partial transcript for the initial task above. Please write a summary of the transcript. The purpose of this summary is to provide continuity so you can continue to make progress towards solving the task in a future context, where the raw history above may not be accessible and will be replaced with this summary. Write down anything that would be helpful, including the state, next steps, learnings etc. You must wrap your summary in a <summary></summary> block.

Vous pouvez fournir des instructions personnalisées via le paramètre instructions. Les instructions personnalisées ne complètent pas le prompt par défaut. Elles le remplacent entièrement :

client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
response = client.beta.messages.create(
    betas=["compact-2026-01-12"],
    model="claude-opus-5-5",
    max_tokens=4096,
    messages=messages,
    context_management={
        "edits": [
            {
                "type": "compact_20260112",
                "instructions": "Focus on preserving code snippets, variable names, and technical decisions.",
            }
        ]
    },
)

Sur Claude 5.1 et les modèles ultérieurs, une requête comportant des instructions personnalisées produit un résumé à partir de la seule conversation visible : les blocs de réflexion antérieurs ne font pas partie de l'entrée du résumeur.

Pause après la compaction

Utilisez pause_after_compaction pour mettre l'API en pause après la génération du résumé de compaction. Cela vous permet d'ajouter des blocs de contenu supplémentaires (par exemple pour conserver des messages récents ou des messages spécifiques orientés instructions) avant que l'API ne poursuive la réponse.

Lorsque cette option est activée, l'API renvoie un message avec la raison d'arrêt compaction après avoir généré le bloc de compaction :

client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
response = client.beta.messages.create(
    betas=["compact-2026-01-12"],
    model="claude-opus-5-5",
    max_tokens=4096,
    messages=messages,
    context_management={
        "edits": [{"type": "compact_20260112", "pause_after_compaction": True}]
    },
)

# Vérifier si la compaction a déclenché une pause.
if response.stop_reason == "compaction":
    # La réponse ne contient que le bloc de compaction.
    messages.append({"role": "assistant", "content": response.content})

    # Poursuivre la requête.
    response = client.beta.messages.create(
        betas=["compact-2026-01-12"],
        model="claude-opus-5-5",
        max_tokens=4096,
        messages=messages,
        context_management={"edits": [{"type": "compact_20260112"}]},
    )

Appliquer un budget total de tokens

Lorsqu'un modèle travaille sur des tâches longues comportant de nombreuses itérations d'utilisation d'outils, la consommation totale de tokens peut augmenter considérablement. Vous pouvez combiner pause_after_compaction avec un compteur de compactions pour estimer l'utilisation cumulée et conclure la tâche proprement une fois un budget atteint.

Cet exemple n'apparaît que dans les langages des SDK : son intérêt réside dans la logique de suivi du budget autour de la requête. La requête brute combine le trigger de Configuration du déclencheur avec pause_after_compaction de Pause après la compaction.

client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
TRIGGER_THRESHOLD = 100_000
TOTAL_TOKEN_BUDGET = 3_000_000
n_compactions = 0

response = client.beta.messages.create(
    betas=["compact-2026-01-12"],
    model="claude-opus-5-5",
    max_tokens=4096,
    messages=messages,
    context_management={
        "edits": [
            {
                "type": "compact_20260112",
                "trigger": {"type": "input_tokens", "value": TRIGGER_THRESHOLD},
                "pause_after_compaction": True,
            }
        ]
    },
)

if response.stop_reason == "compaction":
    n_compactions += 1
    messages.append({"role": "assistant", "content": response.content})

    # Estimer le total des tokens consommés ; inviter à conclure si le budget est dépassé.
    if n_compactions * TRIGGER_THRESHOLD >= TOTAL_TOKEN_BUDGET:
        messages.append(
            {
                "role": "user",
                "content": "Please wrap up your current work and summarize the final state.",
            }
        )

Travailler avec les blocs de compaction

Lorsque la compaction est déclenchée, l'API renvoie un bloc compaction au début de la réponse de l'assistant.

Une conversation de longue durée peut donner lieu à plusieurs compactions. Le dernier bloc de compaction reflète l'état final du prompt et remplace le contenu qui le précède par le résumé généré.

Output
{
  "content": [
    {
      "type": "compaction",
      "content": "Summary of the conversation: The user requested help building a web scraper..."
    },
    {
      "type": "text",
      "text": "Based on our conversation so far..."
    }
  ]
}

Renvoyer les blocs de compaction

Vous devez renvoyer le bloc compaction à l'API lors des requêtes suivantes pour poursuivre la conversation avec le prompt raccourci. L'approche la plus simple consiste à ajouter l'intégralité du contenu de la réponse à vos messages :

client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
response = client.beta.messages.create(
    betas=["compact-2026-01-12"],
    model="claude-opus-5-5",
    max_tokens=4096,
    messages=messages,
    context_management={"edits": [{"type": "compact_20260112"}]},
)
# Après avoir reçu une réponse contenant un bloc de compaction
messages.append({"role": "assistant", "content": response.content})

# Poursuivre la conversation
messages.append({"role": "user", "content": "Now add error handling"})

response = client.beta.messages.create(
    betas=["compact-2026-01-12"],
    model="claude-opus-5-5",
    max_tokens=4096,
    messages=messages,
    context_management={"edits": [{"type": "compact_20260112"}]},
)

En Python, utilisez client.beta.messages, comme le font les exemples de cette page. Si vous appelez client.messages et sérialisez vous-même les blocs, un simple model_dump() ajoute text: null et citations: null au bloc compaction. L'API rejette alors la requête avec une erreur 400 (Extra inputs are not permitted). Utilisez plutôt to_dict() ou model_dump(exclude_none=True). Poursuivre à partir du résumé donne le même conseil pour la compaction à la demande.

Lorsque l'API reçoit un bloc compaction, tous les blocs de contenu qui le précèdent sont ignorés. Vous pouvez soit :

  • Conserver les messages d'origine dans votre liste et laisser l'API se charger de supprimer le contenu compacté
  • Supprimer manuellement les messages compactés et n'inclure que les éléments à partir du bloc de compaction

Sur Claude Fable 5.1, Claude Mythos 5.1 et Claude Opus 5.5, les blocs de réflexion antérieurs à un bloc compaction ne sont pas reportés, de sorte que le résumé est tout ce dont le modèle dispose de ce travail antérieur. Si vous rédigez vos propres instructions, indiquez au modèle ce que le résumé doit conserver ; consultez Indiquez au modèle ce qu'il doit préserver dans les résumés de compaction.

Streaming

Le bloc de compaction est transmis en streaming différemment des blocs de texte. Vous recevez un événement content_block_start, suivi d'un unique content_block_delta contenant l'intégralité du résumé (sans streaming intermédiaire), puis d'un événement content_block_stop.

client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]

with client.beta.messages.stream(
    betas=["compact-2026-01-12"],
    model="claude-opus-5-5",
    max_tokens=4096,
    messages=messages,
    context_management={"edits": [{"type": "compact_20260112"}]},
) as stream:
    for event in stream:
        match event.type:
            case "content_block_start":
                block = event.content_block
                match block.type:
                    case "compaction":
                        print("Compaction started...")
                    case "text":
                        print("Text response started...")

            case "content_block_delta":
                delta = event.delta
                match delta.type:
                    case "compaction_delta":
                        print(f"Compaction complete: {len(delta.content or '')} chars")
                    case "text_delta":
                        print(delta.text, end="", flush=True)

    # Obtenir le message final accumulé
    message = stream.get_final_message()
    messages.append({"role": "assistant", "content": message.content})

Mise en cache des prompts

La compaction fonctionne bien avec le « prompt caching » (mise en cache des prompts). Vous pouvez ajouter un point d'arrêt cache_control sur les blocs de compaction pour mettre en cache le contenu résumé.

{
  "role": "assistant",
  "content": [
    {
      "type": "compaction",
      "content": "[summary text]",
      "cache_control": { "type": "ephemeral" }
    },
    {
      "type": "text",
      "text": "Based on our conversation..."
    }
  ]
}

Maximiser les accès au cache avec les invites système

Lorsqu'une compaction se produit, le résumé devient un nouveau contenu qui doit être écrit dans le cache. Sans points d'arrêt de cache supplémentaires, cela invaliderait également toute « system prompt » (invite système) mise en cache, qui devrait alors être remise en cache en même temps que le résumé de compaction.

Pour maximiser les taux d'accès au cache, ajoutez un point d'arrêt cache_control à la fin de votre invite système. Cela permet de mettre en cache l'invite système séparément de la conversation, de sorte que lorsqu'une compaction se produit :

  • Le cache de l'invite système reste valide et est lu depuis le cache
  • Seul le résumé de compaction doit être écrit en tant que nouvelle entrée de cache
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
response = client.beta.messages.create(
    betas=["compact-2026-01-12"],
    model="claude-opus-5-5",
    max_tokens=4096,
    system=[
        {
            "type": "text",
            "text": "You are a helpful coding assistant...",
            "cache_control": {
                "type": "ephemeral"
            },  # Cache the system prompt separately
        }
    ],
    messages=messages,
    context_management={"edits": [{"type": "compact_20260112"}]},
)

Cela permet de conserver en cache les longues invites système au fil de plusieurs événements de compaction tout au long d'une conversation.

Comprendre l'utilisation

La compaction nécessite une étape d'échantillonnage supplémentaire, qui est prise en compte dans les « rate limits » (limites de débit) et la facturation. L'API renvoie des informations d'utilisation détaillées dans la réponse :

Output
{
  "usage": {
    "input_tokens": 23000,
    "output_tokens": 1000,
    "iterations": [
      {
        "type": "compaction",
        "input_tokens": 180000,
        "output_tokens": 3500
      },
      {
        "type": "message",
        "input_tokens": 23000,
        "output_tokens": 1000
      }
    ]
  }
}

Le tableau iterations indique l'utilisation pour chaque itération d'échantillonnage. Lorsqu'une compaction se produit, vous verrez une itération compaction suivie de l'itération principale message. Dans cet exemple, les valeurs de premier niveau input_tokens et output_tokens correspondent exactement à l'itération message, car il n'y a qu'une seule itération hors compaction. Le nombre de tokens de la dernière itération reflète la taille effective du contexte après la compaction.

Combinaison avec d'autres fonctionnalités

Outils serveur

Lorsque vous utilisez des outils serveur (comme la recherche web), le déclencheur de compaction est vérifié au début de chaque itération d'échantillonnage. La compaction peut se produire plusieurs fois au cours d'une même requête, en fonction de votre seuil de déclenchement et de la quantité de sortie générée.

Comptage des tokens

Le point de terminaison de comptage des tokens (/v1/messages/count_tokens) applique les blocs compaction existants dans votre prompt, mais ne déclenche pas de nouvelles compactions. Utilisez-le pour vérifier votre nombre effectif de tokens après des compactions précédentes :

client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
count_response = client.beta.messages.count_tokens(
    betas=["compact-2026-01-12"],
    model="claude-opus-5-5",
    messages=messages,
    context_management={"edits": [{"type": "compact_20260112"}]},
)

print(f"Current tokens: {count_response.input_tokens}")
print(f"Original tokens: {count_response.context_management.original_input_tokens}")

Exemples

Voici un exemple complet d'une conversation de longue durée avec compaction :

client = anthropic.Anthropic()

messages: list[dict] = []


def chat(user_message: str) -> str:
    messages.append({"role": "user", "content": user_message})

    response = client.beta.messages.create(
        betas=["compact-2026-01-12"],
        model="claude-opus-5-5",
        max_tokens=4096,
        messages=messages,
        context_management={
            "edits": [
                {
                    "type": "compact_20260112",
                    "trigger": {"type": "input_tokens", "value": 100000},
                }
            ]
        },
    )

    # Ajouter la réponse (les blocs de compaction sont inclus automatiquement).
    messages.append({"role": "assistant", "content": response.content})

    # Renvoyer le contenu textuel.
    return next(block.text for block in response.content if block.type == "text")


# Exécuter une longue conversation.
print(chat("Help me build a Python web scraper"))
print(chat("Add support for JavaScript-rendered pages"))
print(chat("Now add rate limiting and error handling"))
# Continuer d'appeler chat() aussi longtemps que la conversation l'exige.

Sur Claude Fable 5.1 et Claude Opus 5.5, supprimez les blocs thinking et redacted_thinking de tout tour de l'assistant que vous réinsérez après le bloc de compaction, ou envoyez thinking.block_binding.prefix_mismatch_behavior: "drop_block" avec l'en-tête bêta thinking-binding-controls-2026-08-01. Ces blocs ont été produits alors que l'historique complet était présent ; ils ne passent donc plus la vérification de conversation. Là où cette vérification est appliquée, la requête de poursuite est rejetée avec une erreur 400. Les blocs de texte et d'outils conservés peuvent rester tels quels. Laisser l'API tout résumer, sans réinsérer les tours précédents, permet d'éviter ce problème.

Voici un exemple qui utilise pause_after_compaction pour conserver mot pour mot l'échange précédent et le message actuel de l'utilisateur (trois messages au total) au lieu de les résumer :

from typing import Any

client = anthropic.Anthropic()

messages: list[dict[str, Any]] = []


def chat(user_message: str) -> str:
    messages.append({"role": "user", "content": user_message})

    response = client.beta.messages.create(
        betas=["compact-2026-01-12"],
        model="claude-opus-5-5",
        max_tokens=4096,
        messages=messages,
        context_management={
            "edits": [
                {
                    "type": "compact_20260112",
                    "trigger": {"type": "input_tokens", "value": 100000},
                    "pause_after_compaction": True,
                }
            ]
        },
    )

    # Vérifier si une compaction a eu lieu et a mis en pause
    if response.stop_reason == "compaction":
        # Récupérer le bloc de compaction depuis la réponse
        compaction_block = response.content[0]

        # Conserver l'échange précédent + le message utilisateur actuel (3 messages)
        # en les incluant après le bloc de compaction
        preserved_messages = messages[-3:] if len(messages) >= 3 else messages

        # Construire la nouvelle liste de messages : compaction + messages conservés
        new_assistant_content = [compaction_block]
        messages_after_compaction = [
            {"role": "assistant", "content": new_assistant_content}
        ] + preserved_messages

        # Poursuivre la requête avec le contexte compacté + les messages conservés
        response = client.beta.messages.create(
            betas=["compact-2026-01-12"],
            model="claude-opus-5-5",
            max_tokens=4096,
            messages=messages_after_compaction,
            context_management={"edits": [{"type": "compact_20260112"}]},
        )

        # Mettre à jour la liste de messages pour refléter la compaction
        messages.clear()
        messages.extend(messages_after_compaction)

    # Ajouter la réponse finale
    messages.append({"role": "assistant", "content": response.content})

    # Renvoyer le contenu textuel
    return next(block.text for block in response.content if block.type == "text")


# Exécuter une longue conversation
print(chat("Help me build a Python web scraper"))
print(chat("Add support for JavaScript-rendered pages"))
print(chat("Now add rate limiting and error handling"))
# Continuer d'appeler chat() aussi longtemps que la conversation l'exige

Limitations actuelles

  • Même modèle pour le résumé : le modèle spécifié dans votre requête est utilisé pour le résumé. Il n'existe aucune option permettant d'utiliser un modèle différent (par exemple, moins coûteux) pour le résumé.

  • La compaction peut échouer lorsque des outils sont définis : lorsque votre requête inclut tools, le modèle appelle parfois un outil pendant l'étape interne de résumé au lieu de rédiger un résumé. Dans ce cas, la réponse contient un bloc compaction avec content: null. Pour éviter cela, définissez instructions sur un prompt qui indique explicitement au modèle de ne pas appeler d'outils, par exemple :

    Summarize the transcript inside <summary></summary> tags. Include relevant information in the summary for continuing the task in the next context window. Do not call any tools while writing this summary; respond with text only.

Étapes suivantes

Gérez automatiquement le contexte de la conversation à mesure qu'il s'agrandit grâce à l'édition du contexte.

Découvrez les tailles de fenêtre de contexte et les stratégies de gestion.

Explorez une implémentation pratique qui gère les conversations de longue durée grâce à une compaction instantanée de la mémoire de session, à l'aide de threads en arrière-plan et de la mise en cache des prompts.

Compatibility

Supported models
  • Fable 5 and 5.1
  • Mythos 5, 5.1, and Preview
  • Opus 4.6, 4.7, 4.8, 5, and 5.5
  • Sonnet 4.6 and 5
Supported platforms
  • Claude APIBeta
  • Claude Platform on AWSBeta
  • Amazon BedrockBeta
  • Google CloudBeta
  • Microsoft FoundryBeta

Was this page helpful?