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.
L’utilisation varie selon le produit
compact_20260112 ; la compaction démarre par défaut à 150 000 tokens d’entrée.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 :
- Détecte le moment où les tokens d’entrée atteignent le seuil de déclenchement que vous avez spécifié.
- Génère un résumé de la conversation en cours.
- Crée un bloc
compactioncontenant le résumé. - 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é.
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ètre | Type | Valeur par défaut | Description |
|---|---|---|---|
type | string | Obligatoire | Doit être "compact_20260112" |
trigger | object | {"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_compaction | boolean | false | Indique s’il faut faire une pause après la génération du résumé de compaction |
instructions | string | null | Prompt 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"}]},
)L’API se met en pause même si aucun résumé n’est généré. Le content du bloc compaction est alors null ; conservez donc les messages d’origine lorsque vous poursuivez. Si les garde-fous bloquent le résumé, content est également null et la raison d’arrêt est refusal au lieu de compaction. stop_details indique la catégorie de politique, le cas échéant. Poursuivez de la même manière dans les deux cas : recherchez le bloc compaction au lieu de tester stop_reason, comme le fait l’exemple qui conserve les messages récents.
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 proprement la tâche 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é.
{
"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.
Si aucun résumé n’est généré, le content du bloc est null et l’API ignore le bloc. Rien n’est compacté ; conservez donc les messages d’origine.
Sur les modèles Claude 5.1 et ultérieurs, 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 :
{
"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("Briefly, help me build a Python web scraper"))
print(chat("Briefly, add support for JavaScript-rendered pages"))
print(chat("Briefly, add rate limiting and error handling"))
# Continuer d'appeler chat() aussi longtemps que la conversation l'exige.Sur les modèles Claude 5.1 et ultérieurs, les blocs de réflexion présents dans tout tour de l’assistant que vous réinsérez après le bloc de compaction échouent à la vérification de préfixe, car ils ont été produits lorsque l’historique complet était présent. Supprimez les blocs thinking et redacted_thinking de ces tours. Vous pouvez également envoyer thinking.block_binding.prefix_mismatch_behavior: "drop_block" avec l’en-tête bêta thinking-binding-controls-2026-08-01. 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. Sur Claude Sonnet 5.5 et Claude Haiku 5.5, block_binding fonctionne uniquement avec thinking: {"type": "adaptive"}. Avec tout autre paramètre de réflexion sur ces modèles, supprimez les blocs.
Voici un exemple qui utilise pause_after_compaction pour conserver l’échange précédent et le message utilisateur actuel (trois messages au total) au lieu de les résumer. Il conserve leurs blocs de texte et d’outils inchangés, supprime les blocs thinking et redacted_thinking du tour de l’assistant conservé, et supprime ce tour s’il ne reste rien d’autre :
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,
}
]
},
)
# Rechercher le bloc de compaction, et non la raison d'arrêt :
# stop_reason vaut "refusal", et non "compaction", si le résumé a été bloqué
compaction_block = next(
(block for block in response.content if block.type == "compaction"), None
)
# Ne remplacer l'historique que si un résumé a été généré
if compaction_block is not None and compaction_block.content is not None:
# Conserver l'échange précédent + le message utilisateur actuel (3 messages)
# en les incluant après le bloc de compaction, sans les blocs de réflexion ;
# un tour assistant laissé sans contenu est supprimé
preserved_messages = [
{
**message,
"content": [
block
for block in message["content"]
if block.type not in ("thinking", "redacted_thinking")
],
}
if message["role"] == "assistant"
else message
for message in messages[-3:]
]
preserved_messages = [m for m in preserved_messages if m["content"]]
# 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
# Mettre à jour la liste de messages pour refléter la compaction
messages.clear()
messages.extend(messages_after_compaction)
if compaction_block is not None:
# Poursuivre la requête, avec l'historique complet s'il n'y a pas de résumé
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"}]},
)
# 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("Briefly, help me build a Python web scraper"))
print(chat("Briefly, add support for JavaScript-rendered pages"))
print(chat("Briefly, add rate limiting and error handling"))
# Continuer d'appeler chat() aussi longtemps que la conversation l'exigeLimitations 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 bloccompactionaveccontent: null. Pour éviter cela, définissezinstructionssur 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.
Disponibilité
Compaction par seuil est en bêta sur certains modèles et éligible aux dispositifs suivants : zéro conservation des données.
Prise en charge de l’API
Utilisation
Activez-la avec une modification compact_20260112 dans context_management.edits. La compaction démarre lorsque les tokens d’entrée atteignent le déclencheur, 150 000 par défaut et au moins 50 000.
- Claude API
- Claude Platform on AWS
- Amazon Bedrock
- Amazon BedrockInvokeModel
- Claude Models on Google CloudGoogle managed
- Microsoft Foundry
- Claude Haiku 4.5Non pris en charge
- Claude Opus 4.5Non pris en charge
- Claude Sonnet 4.5Non pris en charge
- Tous les autres modèles
Utilisation
Toujours activé
Elle compacte l’historique de conversation de la session pour qu’il tienne dans la fenêtre de contexte, et chaque compaction émet un événement agent.thread_context_compacted.
- Claude API
- Claude Platform on AWS
- Claude Haiku 4.5Non pris en charge
- Claude Opus 4.5Non pris en charge
- Claude Sonnet 4.5Non pris en charge
- Tous les autres modèles
En-têtes bêta requis
Présentation des en-têtes bêtaLes en-têtes bêta vous permettent d’accéder à des fonctionnalités expérimentales et à de nouvelles capacités des modèles avant qu’elles ne fassent partie de l’API standard.
compact-2026-01-12
Traitement des données
Présentation du traitement des donnéesPoints de terminaison concernés
/v1/messagesaveccontext_management
Exclut Modèles couverts
Les résultats de la compaction côté serveur sont renvoyés et transmis aller-retour sans état via la réponse de l’API.
Cette page vous a-t-elle été utile ?