13 novembre 2026
Finestre di contesto “quasi infinite” per agenti: compressione incrementale, recupero e trade-off reali
Un proxy locale può tenere la sessione leggera, archiviare il passato su disco e renderlo ricercabile, ma i vantaggi dipendono molto da caching, latenza e qualità dell’integrazione.
Gestire conversazioni e sessioni lunghe è uno dei problemi più concreti quando si lavora con agenti: ogni turno deve reinviare parte della storia e prima o poi si sbatte contro il limite della finestra di contesto. In questo articolo vediamo un approccio basato su compressione incrementale e recupero mirato del contesto: invece di riassumere tutto “in blocco” solo quando si è al limite, si comprime a piccoli passi mentre si lavora, mantenendo gli originali su disco e rendendoli interrogabili tramite tool dedicati. Analizziamo come funziona, cosa cambia rispetto alla compattazione tradizionale, e quali sono i compromessi pratici (token inviati, tempi, caching e affidabilità).
Il problema: le API sono stateless e il contesto cresce sempre
Chi costruisce agenti (o lavora con harness tipo “CLI di coding”, orchestratori e tool-call) si scontra presto con un fatto banale ma costoso: il modello non “ricorda” nulla tra una richiesta e l’altra.
Questo implica che a ogni turno:
- viene reinviata una porzione significativa della conversazione;
- finiscono nel contesto anche tool call, output degli strumenti, file letti, log, ecc.;
- il prompt “effettivo” tende a gonfiarsi fino a raggiungere il limite della finestra (200k, 1M… quello che avete scelto).
Quando si arriva vicino al tetto, molti sistemi attivano una compattazione: producono un grande riassunto della storia e rimpiazzano i messaggi precedenti con quella sintesi. Funziona, ma ha un difetto strutturale: ciò che non entra nel riassunto smette di esistere per il modello, a meno di rileggerlo da qualche parte.
Due strategie a confronto
1) Compattazione “a blocchi” (quando sei quasi pieno)
La logica è semplice:
- la sessione cresce;
- appena oltre una soglia (es. 170–180k su 200k) scatta la compattazione;
- viene prodotto un riassunto unico;
- si continua a lavorare solo con il riassunto + gli ultimi turni.
Pro:
- implementazione lineare;
- pochi interventi del sistema;
- spesso si integra bene con meccanismi di caching del provider.
Contro:
- rischio di perdere dettagli “minori” (ID, numeri, righe di log, piccole decisioni);
- quando un dettaglio diventa improvvisamente importante, il modello non può recuperarlo se non tramite letture esterne (file/sessioni).
2) Compressione incrementale + recupero (il “contesto lungo” su disco)
Un approccio alternativo è usare un proxy locale tra client/agent e provider:
- intercetta tutte le richieste e quindi “vede” l’intera conversazione;
- assegna un ID a ogni messaggio/turno, per poter referenziare intervalli precisi;
- monitora i token e, superata una soglia configurabile (es. +50k), chiede al modello di comprimere una finestra di messaggi “vecchi”;
- rimpiazza quell’intervallo con una sintesi compatta;
- salva però gli originali in un database locale, anziché buttarli.
Il punto chiave non è “avere miliardi di token in RAM”: è impossibile che il modello tenga davvero un miliardo di token nella finestra. Il senso è che la sessione può durare molto oltre il limite della finestra, perché il passato viene:
- compresso nel prompt corrente;
- archiviato su disco;
- reso recuperabile quando serve.
Per farlo bene servono tool dedicati, tipicamente:
search_context: ricerca nel contesto archiviato;decompress: reintroduce porzioni originali (o le espande) in base a un intervallo o a un risultato di ricerca.
In pratica, invece di “una grande amnesia controllata”, si ottiene una memoria che alterna:
- recente = raw (alta fedeltà)
- vecchio = compresso (basso costo nel prompt)
- archivio = interrogabile (recupero mirato)
Cosa cambia davvero: token, tempi e caching
Dai test su sessioni lunghe con finestra a 200k emergono tre considerazioni pragmatiche.
1) Token inviati: riduzioni importanti
Con compressione incrementale si può arrivare a riduzioni molto forti dei token spediti al provider (ordine di grandezza: -68% fino a -83% in scenari misurati). Su carichi estremi (molti log turn-by-turn) la differenza può diventare enorme (es. decine di milioni di token contro pochi milioni).
Questo è intuitivo: se il prompt resta “magro” perché il passato viene continuamente piegato in sintesi piccole, si reinvia molta meno storia a ogni turno.
2) Tempo di completamento: spesso peggiore
C’è un rovescio della medaglia: la gestione continua (contare token, scegliere range, comprimere, aggiornare database, eventualmente cercare e decomprimere) introduce overhead.
Risultato tipico:
- meno token non significa automaticamente meno tempo;
- la pipeline diventa più complessa e può richiedere retry se la formattazione del prompt/strumenti non è robusta.
3) Costi: dipendono dal caching del provider
Qui la sorpresa più grande. Ci si aspetterebbe che meno token = meno costo. Spesso è vero, ma non sempre.
Molti provider applicano input caching: porzioni ripetute del prompt costano molto meno (cache hit). Con compattazione “a blocchi”, il prompt tende a rimanere più stabile per più turni; con compressione incrementale, invece, il prompt “cambia forma” più spesso (perché sostituisci intervalli con nuove sintesi). Questo può:
- ridurre il cache hit rate;
- rendere più costosi token che altrimenti sarebbero stati fatturati a tariffa cache.
In test con contesti molto lunghi, è possibile vedere:
- token inviati drasticamente inferiori con compressione incrementale;
- costi simili o persino leggermente maggiori rispetto alla compattazione tradizionale, proprio per il diverso profilo di caching.
Memoria di “fatti importanti” vs dettagli minuti
Un altro aspetto pratico: che cosa si perde quando si riassume?
- Per fatti dichiarati come importanti (codename di release, scelte di CI, error code evidenziati), la compattazione tradizionale può funzionare sorprendentemente bene: i riassunti tendono a conservare ciò che “sembra” centrale.
- Per dettagli minuti nascosti in mezzo a righe ripetitive (es. una latency associata a un request ID in un heartbeat log), un riassunto globale tende a scartarli.
La compressione incrementale con archivio interrogabile cambia il gioco: quei dettagli possono non stare nei riassunti, ma restano recuperabili via search_context, e poi reinseribili nel flusso con decompress.
“Ma tanto le sessioni spesso sono già salvate su disco”
Molti strumenti di coding salvano effettivamente una copia integrale della sessione (spesso in JSONL o formati simili). Quindi, in teoria, anche senza un proxy di compressione, un agente potrebbe:
- leggere il file di sessione;
- cercare la riga utile;
- reinserirla nel contesto.
La differenza è nell’ergonomia e nelle prestazioni:
- leggere file grandi inquina di nuovo il contesto;
- manca spesso un tool nativo “semantico” per interrogare quella memoria;
- un database locale indicizzato (anziché blob JSON enormi) permette ricerche più rapide e mirate.
Implicazioni per chi costruisce agenti (e per chi fa frontend tooling)
Se state sviluppando un agent o un’app che integra LLM, questo pattern suggerisce alcune scelte architetturali:
-
Pensate al contesto come a una cache multilivello
- hot: ultimi turni raw;
- warm: riassunti incrementali;
- cold: archivio su disco indicizzato.
-
Separate “memoria operativa” e “memoria forense”
- operativa: ciò che serve a ragionare ora;
- forense: ciò che serve a ritrovare un dettaglio quando diventa improvvisamente rilevante.
-
Misurate costo e latenza nel vostro provider reale La riduzione token è un KPI utile, ma con caching aggressivo il costo può sorprendere. Serve osservare:
- cache hit rate;
- retry/error rate dell’infrastruttura;
- tempi end-to-end.
-
Tooling conta quanto il modello Un
search_contextben progettato (query per intervallo, full-text, metadati, ID di messaggio) spesso vale più di una finestra più grande ma opaca.
Sintesi: quando conviene la compressione incrementale
La compressione incrementale con recupero su archivio locale è particolarmente utile quando:
- le sessioni durano giorni/settimane;
- l’agente deve poter recuperare dettagli specifici “a posteriori”;
- lavorate con grandi volumi di log o output tool;
- il vostro stack non beneficia molto di input caching (o il caching è limitato).
Se invece il vostro flusso sfrutta caching molto efficace e i dettagli “minori” non sono critici, la compattazione a blocchi può rimanere una scelta pragmaticamente ottima.
La conclusione operativa è semplice: non esiste una “memoria infinita” gratuita. Esiste però un buon design del contesto: comprimere presto, archiviare bene e recuperare solo quando serve. In un agente moderno, è spesso questa la differenza tra una sessione che regge il lavoro reale e una che si perde nei propri riassunti.