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:

  1. la sessione cresce;
  2. appena oltre una soglia (es. 170–180k su 200k) scatta la compattazione;
  3. viene prodotto un riassunto unico;
  4. 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:

  1. Pensate al contesto come a una cache multilivello

    • hot: ultimi turni raw;
    • warm: riassunti incrementali;
    • cold: archivio su disco indicizzato.
  2. 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.
  3. 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.
  4. Tooling conta quanto il modello Un search_context ben 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.