La « compaction » (compaction) étend la longueur de contexte effective pour les conversations et tâches de longue durée en résumant automatiquement le contexte plus ancien à l'approche de la limite de la fenêtre de contexte. Elle maintient également le contexte actif réduit : à mesure qu'une conversation s'allonge, la qualité des réponses se dégrade, donc la compaction remplace le contenu plus ancien par un résumé concis.
Ceci est idéal pour :
La compaction est prise en charge sur les modèles suivants :
Lorsque la compaction est activée, Claude résume automatiquement votre conversation lorsqu'elle atteint le seuil de tokens configuré. L'API :
compaction contenant le résumé.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, poursuivant la conversation à partir du résumé.
Activez la compaction en ajoutant la stratégie compact_20260112 à context_management.edits dans votre requête de 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",
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ètre | Type | Valeur par défaut | Description |
|---|---|---|---|
type | string | Requis | Doit être "compact_20260112" |
trigger | object | {"type": "input_tokens", "value": 150000} | Quand 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 mettre en pause après la génération du résumé de compaction |
instructions | string | null | Prompt de résumé personnalisé. Remplace complètement le prompt par défaut lorsqu'il est fourni. |
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",
max_tokens=4096,
messages=messages,
context_management={
"edits": [
{
"type": "compact_20260112",
"trigger": {"type": "input_tokens", "value": 150000},
}
]
},
)Le prompt de résumé par défaut varie selon le modèle. Chaque prompt par défaut demande à Claude d'écrire un résumé à l'intérieur de balises <summary></summary> avec 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 complètement :
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-5",
max_tokens=4096,
messages=messages,
context_management={
"edits": [
{
"type": "compact_20260112",
"instructions": "Focus on preserving code snippets, variable names, and technical decisions.",
}
]
},
)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 (comme la préservation de messages récents ou de messages spécifiques orientés instructions) avant que l'API ne poursuive avec 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",
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 contient uniquement 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",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
)Lorsqu'un modèle travaille sur de longues tâches avec 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 compaction pour estimer l'utilisation cumulée et conclure la tâche en douceur une fois qu'un budget est atteint.
Cet exemple n'apparaît que dans les langages du SDK : sa valeur 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 Mise en 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",
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 de 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.",
}
)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 entraîner plusieurs compactions. Le dernier bloc de compaction reflète l'état final du prompt, remplaçant 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..."
}
]
}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",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
)
# Après avoir reçu une réponse avec 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",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
)Lorsque l'API reçoit un bloc compaction, tous les blocs de contenu qui le précèdent sont ignorés. Vous pouvez soit :
Le bloc de compaction est diffusé en streaming différemment des blocs de texte. Vous recevez un événement content_block_start, suivi d'un unique content_block_delta avec le contenu complet du résumé (pas de streaming intermédiaire), puis 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",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
) as stream:
for event in stream:
if event.type == "content_block_start":
if event.content_block.type == "compaction":
print("Compaction started...")
elif event.content_block.type == "text":
print("Text response started...")
elif event.type == "content_block_delta":
if event.delta.type == "compaction_delta":
print(f"Compaction complete: {len(event.delta.content or '')} chars")
elif event.delta.type == "text_delta":
print(event.delta.text, end="", flush=True)
# Obtenir le message final accumulé
message = stream.get_final_message()
messages.append({"role": "assistant", "content": message.content})La compaction fonctionne bien avec la mise en cache des prompts. Vous pouvez ajouter un point de rupture 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..."
}
]
}Lorsque la compaction se produit, le résumé devient un nouveau contenu qui doit être écrit dans le cache. Sans points de rupture de cache supplémentaires, cela invaliderait également toute invite système mise en cache, nécessitant sa remise en cache avec le résumé de compaction.
Pour maximiser les taux d'accès au cache, ajoutez un point de rupture cache_control à la fin de votre invite système. Cela maintient l'invite système mise en cache séparément de la conversation, de sorte que lorsque la compaction se produit :
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-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 les longues invites système en cache à travers plusieurs événements de compaction tout au long d'une conversation.
La compaction nécessite une étape d'échantillonnage supplémentaire, qui contribue aux 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 montre l'utilisation pour chaque itération d'échantillonnage. Lorsque la compaction se produit, vous verrez une itération compaction suivie de l'itération message principale. Les input_tokens et output_tokens de niveau supérieur correspondent exactement à l'itération message dans cet exemple car il n'y a qu'une seule itération non liée à la compaction. Les comptes de tokens de la dernière itération reflètent la taille effective du contexte après la compaction.
Lors de l'utilisation d'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 sein d'une même requête selon votre seuil de déclenchement et la quantité de sortie générée.
Le point de terminaison de comptage de 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 les 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",
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}")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",
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 automatiquement inclus)
messages.append({"role": "assistant", "content": response.content})
# Retourner 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 à appeler chat() aussi longtemps que la conversation le nécessiteVoici un exemple qui utilise pause_after_compaction pour préserver textuellement l'échange précédent et le message utilisateur actuel (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",
max_tokens=4096,
messages=messages,
context_management={
"edits": [
{
"type": "compact_20260112",
"trigger": {"type": "input_tokens", "value": 100000},
"pause_after_compaction": True,
}
]
},
)
# Vérifier si la compaction a eu lieu et s'est mise en pause
if response.stop_reason == "compaction":
# Récupérer le bloc de compaction depuis la réponse
compaction_block = response.content[0]
# Préserver 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 préservé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 préservés
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-5",
max_tokens=4096,
messages=messages_after_compaction,
context_management={"edits": [{"type": "compact_20260112"}]},
)
# Mettre à jour notre 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})
# Retourner 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 à appeler chat() aussi longtemps que la conversation le nécessiteMê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 pour utiliser un modèle différent (par exemple, moins cher) pour le résumé.
La compaction peut échouer lorsque des outils sont définis : Lorsque votre requête inclut tools, le modèle appelle occasionnellement un outil pendant l'étape interne de résumé au lieu d'écrire un résumé. Lorsque cela se produit, 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.Gérez automatiquement le contexte de la conversation à mesure qu'il s'allonge grâce à l'édition de contexte.
Découvrez les tailles de fenêtres de contexte et les stratégies de gestion.
Explorez une implémentation pratique qui gère les conversations de longue durée avec une compaction instantanée de la mémoire de session en utilisant le threading en arrière-plan et la mise en cache des prompts.
Was this page helpful?