Il budget di attenzione, non lo spazio libero

Nella finestra di contesto entra tutto quello che spedisci: system prompt, ogni messaggio dell’array messages (tool result, immagini e documenti compresi), le definizioni dei tool, e l’output che Claude genera nel turno, thinking incluso. Il campo usage della risposta dice quanto è costata la richiesta; con il prompt caching l’input si divide fra input_tokens, cache_read_input_tokens e cache_creation_input_tokens, e tutti e tre occupano finestra. La cache cambia quanto paghi quei token, non il fatto che stiano lì. Per stimare prima di spedire c’è l’endpoint di token counting.

Le finestre da un milione di token non chiudono la questione. La documentazione chiama context rot il fenomeno per cui, al crescere del numero di token, accuratezza e recall degradano. Il context engineering è quindi la disciplina di curare e mantenere l’insieme ottimale di token durante l’inferenza: non quanto ci sta, ma cosa merita di starci.

Potatura: prima guarda dove finiscono i token

Ci sono quattro leve, ognuna su una fonte diversa di pressione, e si combinano. Il tool search tiene le definizioni dei tool fuori dal contesto finché Claude non le chiede: paga oltre la ventina di tool, al prezzo di un turno in più. Il programmatic tool calling collassa una catena di chiamate in uno script eseguito nella sandbox, così i risultati intermedi non entrano mai nella conversazione. Il prompt caching non riduce i token, riduce quello che paghi su un set di tool stabile. Il context editing toglie dalla storia i blocchi tool_result che hanno esaurito la loro funzione.

Il context editing è la potatura vera. La strategia clear_tool_uses_20250919 scatta quando il prompt supera la soglia trigger e svuota i risultati più vecchi in ordine cronologico, sostituendo ciascuno con un segnaposto che dice a Claude che è stato rimosso. keep fissa quante coppie recenti conservare, exclude_tools protegge i tool i cui risultati non vanno mai persi, clear_tool_inputs decide se cancellare anche gli argomenti della chiamata (di default no: resta visibile cosa Claude aveva chiesto). Tutto avviene lato server, prima che il prompt arrivi al modello: il tuo client continua a tenere la storia integrale e non deve sincronizzare niente.

L’errore tipico è attivarlo e vedere salire il costo. Ogni pulizia invalida il prefisso in cache e ti fa pagare una cache write. Per questo esiste clear_at_least: se non si liberano almeno quei token la strategia non si applica, e non spendi una cache invalidata per recuperare quattro righe.

Compattazione: riassumere invece di tagliare

Quando la conversazione si avvicina al limite, la compattazione riassume lato server la parte vecchia e continua. Si attiva con l’header beta compact-2026-01-12 e una voce nell’array degli edit:

{
  "context_management": {
    "edits": [
      { "type": "compact_20260112",
        "trigger": { "type": "input_tokens", "value": 100000 } }
    ]
  }
}

La soglia di default è 150.000 token di input e il valore minimo accettato è 50.000. L’API produce un blocco compaction con il riassunto: devi rispedirlo nelle richieste successive, e da lì in poi l’API ignora automaticamente tutti i blocchi che lo precedono. Il modo più semplice è appendere l’intera risposta all’array dei messaggi.

Due trappole. La prima: la compattazione costa un giro di sampling in più, che non compare in usage.input_tokens e usage.output_tokens — quelli riportano solo l’iterazione principale. Il totale vero è la somma delle voci di usage.iterations, ed è lì che devi guardare prima di dire che ti costa poco. La seconda: count_tokens applica i blocchi di compattazione già presenti ma non ne innesca di nuovi, quindi non usarlo per prevedere quando scatterà. Se ti serve intercettare il riassunto prima di proseguire, pause_after_compaction ferma il turno subito dopo averlo generato.

Isolamento: delegare a un subagente

La terza strategia non riduce il contesto, lo separa. Nel Claude Agent SDK (documentato su code.claude.com, non su platform.claude.com) definisci i subagenti con il parametro agents della query(), e ogni definizione ha description — è la frase con cui Claude decide quando invocarlo — più prompt, tools e model. Il subagente parte con la sua finestra: le chiamate a tool e i risultati intermedi restano dentro, e al genitore torna solo il messaggio finale. Un agente che esplora trenta file restituisce una sintesi, non trenta file. In più girano in parallelo e possono avere tool ridotti, quindi un revisore che non deve scrivere riceve solo lettura e ricerca.

Il modo tipico di sbagliare è dare per scontato che erediti il contesto. Non è così: l’unica cosa che passa dal genitore è la stringa di prompt della chiamata al tool Agent, quindi percorsi di file, messaggi di errore e decisioni già prese vanno scritti lì dentro. E poiché ogni subagente fa richieste sue e può generarne altri, conviene mettere un tetto a profondità, concorrenza e spesa prima di andare in produzione.

Ciò che deve sopravvivere al riassunto

Compattazione e potatura perdono informazione per definizione. Quello che deve attraversare le sessioni va scritto fuori: il memory tool (memory_20250818) fa esattamente questo, con i comandi view, create, str_replace, insert, delete e rename su una directory /memories. È client-side — Claude chiede l’operazione, la esegui tu — quindi lo storage è tuo, e con esso la responsabilità: valida ogni percorso, perché una stringa come /memories/../../.env esce dalla directory se non la respingi. Accoppiandoli, la compattazione tiene piccolo il contesto attivo e la memoria conserva ciò che il riassunto non deve poter perdere.