Claude Platform Docs
MessagesCompattazione

Compattazione su richiesta

Chiedi a Claude di riassumere una conversazione quando lo decide la tua applicazione, quindi continua a partire dal riepilogo.

Con la "on-demand compaction" (compattazione su richiesta), è la tua applicazione a decidere quando una conversazione viene riassunta: invii una richiesta con il parametro compaction e Claude restituisce un riepilogo al posto di una risposta.

Come funziona la compattazione su richiesta

Una richiesta di compattazione è separata dai turni della tua conversazione. Invii la conversazione così com'è con il parametro compaction, e la risposta contiene un singolo blocco compaction. Il blocco contiene il riepilogo sotto forma di testo leggibile e una firma. Invialo nelle richieste successive esattamente come è arrivato.

Da quel momento in poi il blocco prende il posto dei messaggi che riassume. Va per primo in messages, i messaggi riassunti vengono rimossi e il tuo turno successivo lo segue. Claude vede il riepilogo dove si trovavano quei messaggi.

Compaction requestfour messagesuser 1asst 1user 2asst 2Responseone block, no replycompaction blockNext requestblock firstcompaction blockuser 3

Richiedi un riepilogo

Invia l'header beta compact-2026-09-04 nella richiesta che chiede il riepilogo e in ogni richiesta successiva che contiene il blocco firmato. Per verificare se un modello supporta la compattazione su richiesta, chiama la Models API con l'header beta e leggi capabilities.compaction di ciascun modello. Non puoi combinare compaction con context_management in una stessa richiesta.

Invia la conversazione così com'è con "compaction": {"type": "summarize"}. L'API riassume una sola volta tutti i messaggi della richiesta, non genera alcuna risposta dopo di essi e restituisce solo il blocco con stop_reason "compaction". Invia lo stesso prompt system e gli stessi tools che usi per il resto della conversazione. Il processo di riepilogo li legge e, se mantieni dei turni dopo il blocco su un modello con "preserved thinking" (pensiero preservato), il pensiero in quei turni resta valido solo se system e tools corrispondono. La conversazione in questo esempio non ha né un prompt system né strumenti, quindi la richiesta non invia nessuno dei due:

from anthropic.types.beta import BetaMessageParam

client = anthropic.Anthropic()

history: list[BetaMessageParam] = [
    {
        "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.",
    },
    {"role": "user", "content": "Good. Now suggest field names for Recipe."},
]

response = client.beta.messages.create(
    model="claude-opus-5-5",
    # max_tokens limita l'intera chiamata, incluso l'eventuale pensiero, quindi prevedi diverse migliaia di token.
    max_tokens=4096,
    betas=["compact-2026-09-04"],
    messages=history,
    compaction={"type": "summarize"},
)
print(f"Stop reason: {response.stop_reason}")
Response
{
  "id": "msg_013Zva2CMHLNnXjNJJKqJ2EF",
  "type": "message",
  "role": "assistant",
  "model": "claude-opus-5-5",
  "content": [
    {
      "type": "compaction",
      "content": "Summary of the conversation: the user is designing the data model for a recipe app. The entities agreed so far are Recipe, Ingredient, Step, and RecipeIngredient, which holds the quantity and unit. The user then asked for field names for Recipe.",
      "signature": "EuYBCkQY..."
    }
  ],
  "stop_reason": "compaction",
  "usage": {
    "input_tokens": 0,
    "output_tokens": 0,
    "iterations": [{ "type": "compaction", "input_tokens": 144, "output_tokens": 276 }]
  }
}

La chiamata di riepilogo usa il modello, system, tools, le impostazioni di pensiero e max_tokens della richiesta. Il processo di riepilogo legge le definizioni degli strumenti ma non esegue mai uno strumento, e la risposta non contiene alcun pensiero. max_tokens limita l'intera chiamata, incluso qualsiasi pensiero che il modello svolge prima di scrivere il riepilogo, quindi prevedi diverse migliaia di token. Conteggia l'utilizzo della compattazione mostra come viene fatturata la chiamata.

Se l'ultimo turno assistant termina con una chiamata a uno strumento ancora priva di risultato, l'API rifiuta la richiesta. Invia prima i risultati degli strumenti di quel turno. Ometti inoltre stop_sequences, output_config.format per l'output strutturato e un tool_choice di tipo any o tool. Non avrebbero alcun effetto in una chiamata di riepilogo, e l'API li rifiuta. La conversazione deve comunque rientrare nella "context window" (finestra di contesto) del modello, quindi compatta prima di superarla, non dopo.

Quando esegui lo streaming della risposta, il blocco arriva intero. Ricevi un evento content_block_start che contiene il blocco completo, poi content_block_stop, senza eventi content_block_delta. Gli eventi ping possono arrivare prima o tra di essi.

Continua dal riepilogo

Nella tua cronologia, sostituisci i messaggi che hai inviato con il messaggio assistant restituito. Mantieni il blocco compaction esattamente come l'API lo ha restituito, inclusa la sua signature. Eventuali turni svolti dopo l'invio della richiesta di compattazione seguono il blocco invariati, ed è su questo che si basa Compattazione in background. Invia il blocco per primo in ogni richiesta successiva, con l'header beta:

{
  "model": "claude-opus-5-5",
  "max_tokens": 2048,
  "messages": [
    {
      "role": "assistant",
      "content": [
        {
          "type": "compaction",
          "content": "Summary of the conversation: the user is designing the data model for a recipe app. The entities agreed so far are Recipe, Ingredient, Step, and RecipeIngredient, which holds the quantity and unit. The user then asked for field names for Recipe.",
          "signature": "EuYBCkQY..."
        }
      ]
    },
    {
      "role": "assistant",
      "content": "For Recipe, use title, description, servings, prep_minutes, and cook_minutes. Add created_at and updated_at timestamps."
    },
    { "role": "user", "content": "Now do the same for Ingredient." }
  ]
}

Questo esempio prosegue l'esempio di richiesta, che terminava con un turno user; il diagramma mostra il caso più semplice, in cui nessun turno viene svolto mentre il riepilogo viene scritto. Qui il secondo messaggio assistant è la risposta all'ultimo turno user riassunto. È arrivato mentre il riepilogo veniva scritto, quindi non era tra i messaggi riassunti. Due messaggi assistant consecutivi vanno bene in questo caso, perché il blocco viene comunque per primo.

L'API colloca il riepilogo dove si trova il blocco e passa a Claude invariati tutti i messaggi successivi. Segui queste regole:

  • Metti il blocco per primo in messages, come messaggio assistant a sé stante oppure come primo blocco di contenuto del primo messaggio, che si tratti di un messaggio user o assistant.
  • Rimuovi i messaggi riassunti. Se ne rimane qualcuno davanti al blocco, la richiesta restituisce un errore 400 (compaction_block_misplaced).
  • Invia esattamente un blocco compaction per richiesta, in ogni richiesta successiva.

La "threshold compaction" (compattazione a soglia) funziona al contrario: il suo blocco segue i messaggi che riassume, e l'API li elimina per te. Consulta Restituire i blocchi di compattazione.

In Python, usa client.beta.messages, come fanno gli esempi in questa pagina. Se chiami client.messages e serializzi i blocchi da solo, usa to_dict() o model_dump(exclude_none=True): un semplice model_dump() aggiunge citations: null e text: null al blocco, e l'API lo rifiuta.

Se mantieni dei turni dopo il blocco e rinvii i relativi blocchi di pensiero, le condizioni che mantengono valido quel pensiero sono descritte in Compattazione e pensiero preservato.

Compatta di nuovo

Per compattare una conversazione che inizia già con un blocco, invia di nuovo compaction. Il nuovo blocco riassume il vecchio riepilogo e tutto ciò che lo segue. Da quel momento in poi, invia solo il blocco più recente.

Compatta in un ciclo

Dopo ogni turno, il ciclo somma i token di input e di output dell'ultima risposta, perché la richiesta successiva invia anche la risposta. Quando quel totale supera un limite e deve ancora seguire un altro turno, il ciclo invia una richiesta di compattazione con lo stesso modello e lo stesso prompt system, controlla stop_reason, sostituisce la propria cronologia con il messaggio restituito e stampa il turno prima del quale ha compattato. Il limite di 2.500 token dell'esempio è volutamente basso, in modo che anche una conversazione breve venga compattata. Imposta il tuo limite vicino al tuo budget di input reale.

from anthropic.types.beta import BetaMessageParam

client = anthropic.Anthropic()

# Imposta questo valore vicino al tuo budget reale di input. Qui è basso così una breve conversazione viene compattata.
COMPACT_AT_TOKENS = 2500
SYSTEM = "You help design a recipe app's data model. Keep answers short."

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})

    # Anche la richiesta successiva invia questa risposta, quindi conteggiala.
    conversation_tokens = response.usage.input_tokens + response.usage.output_tokens
    if conversation_tokens > COMPACT_AT_TOKENS and turn < len(QUESTIONS):
        summary = client.beta.messages.create(
            model="claude-opus-5-5",
            max_tokens=4096,
            system=SYSTEM,
            betas=["compact-2026-09-04"],
            messages=history,
            compaction={"type": "summarize"},
        )
        if summary.stop_reason == "compaction":
            history = [{"role": "assistant", "content": summary.content}]
            print(f"Compacted before turn {turn + 1}")

Il controllo su stop_reason avviene prima che il codice cerchi il blocco; Gestisci un riepilogo mancante o un errore spiega perché. La cronologia viene sostituita, non estesa: il messaggio restituito sostituisce tutti i messaggi contenuti nella richiesta, secondo le regole descritte in Continua dal riepilogo. Quando non viene restituito alcun riepilogo, il ciclo mantiene la propria cronologia e riprova dopo il turno successivo.

Il "tool runner" (esecutore di strumenti) dell'SDK in Python, TypeScript, C#, Go e Java può inviare la richiesta di compattazione per te. Quando decidi di compattare, chiama compact_before_next_turn() sul runner (compactBeforeNextTurn() in TypeScript e Java, CompactBeforeNextTurn() in C# e Go). Una volta terminati il turno corrente e le relative chiamate agli strumenti, il runner invia la richiesta di compattazione e sostituisce la propria cronologia con il messaggio restituito. Crea il runner con la beta compact-2026-09-04, perché il runner non la aggiunge. Il runner costruisce la richiesta a partire dai propri parametri e omette context_management. Se tali parametri includono stop_sequences, un tool_choice di tipo any o tool, oppure un output_config.format per l'output strutturato, l'API rifiuta la richiesta con un errore 400. Richiedi un riepilogo spiega perché. Il runner si rifiuta di compattare finché il suo context_management contiene una modifica di compattazione, quindi usa un solo tipo di compattazione per runner.

Quando compattare

Puoi inviare una richiesta di compattazione dopo qualsiasi turno completato, quindi è il tuo codice a decidere quando.

Per stimare quanto sarà grande la richiesta successiva, somma input_tokens e output_tokens dall'usage dell'ultima risposta, come fa il ciclo. Con la "prompt caching" (cache dei prompt), input_tokens conta solo i token successivi all'ultimo breakpoint della cache, quindi aggiungi anche cache_read_input_tokens e cache_creation_input_tokens. Puoi anche inviare gli stessi messaggi all'endpoint di "token counting" (conteggio dei token).

Confronta quel numero con un limite a tua scelta, inferiore alla finestra di contesto del modello.

Scrivi il tuo prompt di riepilogo

Senza instructions, l'API usa il proprio prompt di riepilogo. Una stringa instructions non vuota (fino a 16.384 caratteri) sostituisce completamente quel prompt. Ad esempio:

{
  "compaction": {
    "type": "summarize",
    "instructions": "Summarize this recipe app design conversation. Preserve every entity and field name agreed so far, and the user's latest open request. Do not call tools; respond with the summary text only."
  }
}

Il processo di riepilogo legge l'intera conversazione, incluso il pensiero precedente, con o senza instructions. Nelle tue instructions, indica cosa deve conservare il riepilogo e di' al modello di non chiamare strumenti. La chiamata di riepilogo viene eseguita con le stesse misure di sicurezza di qualsiasi altra richiesta.

Gestisci un riepilogo mancante o un errore

Un riepilogo viene prodotto solo quando la chiamata di riepilogo termina normalmente con del testo e senza chiamate a strumenti. Altrimenti, la risposta è comunque un 200 con content vuoto, quindi controlla stop_reason prima di cercare il blocco. La chiamata viene comunque fatturata e riportata in usage.iterations, con utilizzo pari a zero quando non è stato possibile effettuare alcuna chiamata. Lo stop_reason è quello con cui è terminata la chiamata di riepilogo. In ogni caso puoi continuare senza un riepilogo e compattare in seguito.

stop_reasonCausaCosa fare
"max_tokens"Il riepilogo è stato troncato.Invia di nuovo con un max_tokens più grande.
"model_context_window_exceeded"Non c'era spazio per il prompt di riepilogo.Invia di nuovo con instructions più brevi o con meno messaggi.
"tool_use"Il modello ha chiamato uno strumento invece di scrivere il riepilogo.Invia di nuovo con instructions che dicano al modello di non chiamare strumenti.
"refusal"La richiesta è stata rifiutata.Continua senza un riepilogo.
"end_turn"La chiamata non ha restituito alcun testo.Continua senza un riepilogo.

La chiamata di riepilogo è soggetta alle stesse misure di sicurezza delle tue altre richieste. Dopo un "refusal", stop_details identifica la categoria di policy che lo ha determinato.

Errori

Anche una richiesta di compattazione, o una richiesta che contiene un blocco, può fallire del tutto. La maggior parte degli errori 400 ha un messaggio che indica cosa rimuovere o inviare di nuovo. Alcuni contengono anche un error.details.error_code che inizia con compaction_. Gli errori sui parametri, come un campo che non può essere combinato con compaction, contengono solo il messaggio.

ErroreCausaCosa fare
529 overloaded_error, error.details.error_code compaction_unavailableUn problema temporaneo del server durante la produzione di un blocco, o durante la lettura di un blocco che hai rinviato.Riprova la richiesta.
400 compaction_block_misplacedDei messaggi riassunti rimangono davanti al blocco.Rimuovili, in modo che il blocco venga per primo in messages.
400 compaction_signature_invalid o compaction_content_mismatchLa signature o il content del blocco sono stati modificati dopo che l'API lo ha restituito.Invia il blocco esattamente come è stato restituito, inclusa la sua signature.
400La richiesta contiene più di un blocco compaction.Inviane esattamente uno, il più recente.
400L'ultimo turno assistant termina con una chiamata a uno strumento ancora priva di risultato.Invia i risultati degli strumenti di quel turno, poi compatta.
400 compaction_nothing_to_summarizemessages non ha contenuto user o assistant, ad esempio una lista vuota.Invia almeno un messaggio user o assistant.
400 sulla richiesta di compattazione, con un messaggio che indica che il parametro compaction requires anthropic-beta: compact-2026-09-04La richiesta di compattazione ha omesso l'header beta.Aggiungi l'header beta; consulta Richiedi un riepilogo.
400 su una richiesta successiva che contiene il blocco: un errore di validazione che indica che compaction non è uno dei tipi di blocco di contenuto previsti. Il messaggio non menziona l'headerQuella richiesta ha omesso l'header beta.Aggiungi l'header beta a ogni richiesta che contiene il blocco; consulta Richiedi un riepilogo.
Errore di validazione 400, come messages.0.content.0.compaction.citations: Extra inputs are not permittedUn blocco è stato rinviato con campi che l'API non aveva restituito, come citations: null.Invia il blocco esattamente come è stato restituito; consulta Continua dal riepilogo.

Conteggia l'utilizzo della compattazione

La chiamata di riepilogo viene fatturata ed è soggetta ai "rate limit" (limiti di velocità) come qualsiasi altra richiesta, e usage.iterations la riporta come voce compaction. I campi di primo livello input_tokens e output_tokens sono pari a zero perché non è stata generata alcuna risposta. Per conteggiare ciò che una conversazione ha consumato, somma i valori in usage.iterations, non i campi di primo livello. Rinviare un blocco nelle richieste successive non aggiunge alcun costo di compattazione.

Ora hai un ciclo funzionante che compatta una conversazione e gestisce un riepilogo mancante. Due pagine cambiano il modo in cui funziona, e puoi combinarle: Compattazione che mantiene i turni recenti mantiene gli ultimi turni parola per parola, e Compattazione in background consente alla conversazione di proseguire mentre il riepilogo viene scritto. Compattazione e pensiero preservato si applica se rinvii i blocchi di pensiero e usi una delle due.

Limiti e interazioni con altre funzionalità

  • Compattazione a soglia e modifica del contesto. Non puoi inviare compaction e context_management nella stessa richiesta. La compattazione a soglia (compact_20260112) non può essere eseguita su una richiesta che contiene un blocco firmato.
  • Cache dei prompt. cache_control sul blocco colloca un breakpoint dopo il riepilogo.
  • Messaggi di sistema a metà conversazione e modifiche agli strumenti. Anche i messaggi role: "system" all'interno dell'intervallo riassunto vengono riassunti, quindi le loro istruzioni testuali smettono di applicarsi una volta che il blocco li sostituisce. Se un'istruzione è ancora importante, ripetila in un messaggio role: "system". Invia quel messaggio subito dopo il tuo prossimo nuovo turno user e lascialo nella cronologia da quel momento in poi. Per le modifiche agli strumenti, e per sapere dove va quel messaggio quando mantieni dei turni dopo il blocco, consulta Modificare il prompt di sistema o gli strumenti.
  • Budget di attività. Non inviare il valore remaining di un "task budget" (budget di attività) (output_config.task_budget.remaining) insieme a compaction o nelle richieste che contengono il blocco. In tal caso viene restituito un errore 400.
  • Conteggio dei token. L'endpoint di conteggio dei token ignora il parametro compaction.
  • Contenuti che il riepilogo non può trasportare. Immagini, documenti, blocchi container_upload e URL recuperati all'interno dei messaggi riassunti vanno persi una volta che il blocco li sostituisce. Riformula o carica di nuovo tutto ciò di cui un turno successivo ha ancora bisogno.

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?