Claude Platform Docs
MessagesCompaction

Compaction qui conserve les tours récents

Résumez les tours plus anciens d'une conversation grâce à la compaction à la demande et envoyez les tours les plus récents après le résumé, mot pour mot.

La « keep-tail compaction » (compaction avec conservation de la fin) conserve mot pour mot les derniers tours d'une conversation après le résumé. Elle modifie deux choses dans la boucle de compaction : les messages qui entrent dans la requête de compaction, et ce que vous envoyez après le bloc. Tout ce qui figure dans Poursuivre à partir du résumé s'applique sans changement.

Choisir les tours à conserver

Aucun paramètre ne définit les tours conservés. Vous choisissez un « cut point » (point de coupure) dans votre historique : les messages qui le précèdent entrent dans la requête de compaction, et les messages à partir de ce point sont conservés.

Les tours conservés sont renvoyés à Claude dans leur intégralité ; ainsi, plus vous en conservez, moins la compaction libère d'espace.

Placez la coupure à un endroit où aucun appel d'outil ne reste ouvert, chaque appel d'outil et son résultat se trouvant du même côté. Si les messages que vous envoyez se terminent par un tour assistant dont l'appel d'outil n'a pas encore de résultat, l'API rejette la requête de compaction.

Compacter les tours plus anciens et envoyer le reste après le bloc

Pour conserver mot pour mot une fin de conversation composée de tours récents, excluez ces tours de la requête de compaction. L'API résume chaque message qui lui est envoyé ; envoyez donc uniquement les tours plus anciens, puis placez le bloc devant les tours que vous avez conservés.

Envoyez les tours conservés exactement tels qu'ils figurent dans votre historique, « thinking blocks » (blocs de réflexion) compris. Les deux requêtes portent l'en-tête bêta, comme dans Demander un résumé.

Dans l'exemple suivant, l'historique contient deux tours, et la coupure conserve le second. La requête de compaction contient le premier tour :

{
  "model": "claude-opus-5-5",
  "max_tokens": 4096,
  "messages": [
    {
      "role": "user",
      "content": "I am building a recipe app. Help me name the main entities in the data model."
    },
    {
      "role": "assistant",
      "content": "Start with Recipe, Ingredient, and Step. Add a RecipeIngredient entry that holds the quantity and unit for each ingredient in a recipe."
    }
  ],
  "compaction": { "type": "summarize" }
}

La requête suivante envoie d'abord le bloc renvoyé, puis le tour conservé exactement tel qu'il était, puis le nouveau message user. Poursuivre à partir du résumé montre une requête qui commence par un bloc.

Le programme suivant est la boucle de Compacter dans une boucle, modifiée pour conserver les deux derniers tours. Les lignes mises en évidence indiquent où il diffère de la boucle.

from anthropic.types.beta import BetaMessageParam

client = anthropic.Anthropic()

# Réglez cette valeur près de votre budget d'entrée réel. Elle est basse ici pour qu'une courte conversation soit compactée.
COMPACT_AT_TOKENS = 2500
SYSTEM = "You help design a recipe app's data model. Keep answers short."
KEEP_TURNS = 2

QUESTIONS = [
    "What are the main entities in the data model?",
    "Which fields should Recipe have?",
    "Which fields should Ingredient have?",
    "Which fields should RecipeIngredient have?",
    "Which fields should Step have?",
    "Which indexes should these tables have?",
    "Which fields should be required?",
    "Which fields should have default values?",
]

history: list[BetaMessageParam] = []
for turn, question in enumerate(QUESTIONS, start=1):
    history.append({"role": "user", "content": question})
    response = client.beta.messages.create(
        model="claude-opus-5-5",
        max_tokens=8192,
        system=SYSTEM,
        betas=["compact-2026-09-04"],
        messages=history,
    )
    history.append({"role": "assistant", "content": response.content})

    # La requête suivante envoie aussi cette réponse, comptez-la donc.
    conversation_tokens = response.usage.input_tokens + response.usage.output_tokens
    if conversation_tokens > COMPACT_AT_TOKENS and KEEP_TURNS < turn < len(QUESTIONS):
        # Un tour correspond à un message utilisateur et une réponse de l'assistant,
        # donc les tours conservés commencent par un message utilisateur.
        split = -2 * KEEP_TURNS
        older, recent = history[:split], history[split:]
        summary = client.beta.messages.create(
            model="claude-opus-5-5",
            max_tokens=4096,
            system=SYSTEM,
            betas=["compact-2026-09-04"],
            messages=older,
            compaction={"type": "summarize"},
        )
        if summary.stop_reason == "compaction":
            history = [{"role": "assistant", "content": summary.content}, *recent]
            print(f"Kept {len(recent) // 2} turns after the block")
  • Choix de la coupure : Le programme conserve les deux derniers tours, un tour étant un message user et la réponse à celui-ci. Il divise l'historique à quatre messages de la fin, de sorte que les tours conservés commencent par un message user.
  • Décider quand compacter : La vérification de taille exige également que la conversation comporte plus de tours que le programme n'en conserve, afin que la partie la plus ancienne ne soit jamais vide.
  • La requête de compaction : Là où la boucle envoie l'historique complet, cette version n'envoie que les messages plus anciens.
  • Le remplacement : Là où la boucle remplace l'historique complet par le message renvoyé, le nouvel historique de cette version est le message renvoyé suivi des tours conservés.

La vérification de stop_reason et toutes les requêtes après le remplacement sont identiques à celles de la boucle.

Garder la réflexion valide dans les tours conservés

Si vous renvoyez des blocs de réflexion sur un modèle doté de la réflexion préservée, la réflexion dans les tours conservés ne reste valide que tant que les conditions de validité de la réflexion conservée sont remplies, et l'une d'elles limite l'endroit où la coupure peut se situer.

La coupure du programme, entre une réponse et le message user suivant, remplit cette condition. C'est également le cas d'une coupure à la fin d'une requête que vous avez déjà effectuée : compactez exactement les messages de cette requête, et conservez tout ce que votre historique a accumulé depuis.

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
  • Google CloudBeta
  • Microsoft FoundryBeta

Was this page helpful?