Sei lo 0,1% del contesto che legge il tuo agente AI: lo dimostra la misura token per token


Digiti sei parole in una chat con un agente di coding e hai la sensazione che il modello stia leggendo proprio quelle sei parole. Non è così. Prima che tu scriva qualsiasi cosa, la harness — il programma che avvolge il modello e gli passa il lavoro — gli ha già messo in mano istruzioni di sistema, definizioni di tool, file di configurazione, hook, skill. Contesto che paghi e che pesa, scritto da qualcun altro. Sono un security engineer e sul mio blog Signal Pirate mi sono chiesto quanto pesi la parte scritta dall’utente rispetto a quella montagna. Invece di indovinarlo, l’ho misurato token per token, attribuendo ogni singolo token della sessione alla sua sorgente. Il risultato, sul task misurato: 98% harness (costo fisso), 1,5% risultati dei tool (file e comandi), 0,7% ragionamento dell’agente e 0,1% utente — la tua richiesta.

Non è l’ennesima spiegazione del ciclo “pensa, agisci, osserva” che muove un agente — quella si trova ovunque. È un conteggio: quanto contesto arriva dal sistema, quanto dai risultati dei tool, quanto dal ragionamento dell’agente e quanto, alla fine, dall’utente.





Un bug finto, per non esporre lavoro vero

Per l’esperimento ho scelto un task che capisse chiunque e che non raccontasse nulla del mio lavoro reale: un toy project con un carrello della spesa e un bug nello sconto, dove un + scritto al posto di un - fa venire un totale più alto invece che più basso. Il classico errore che si vede in due minuti.

Ho poi ricostruito la sessione tipica che farebbe un agente per sistemarlo: richiesta dell’utente, lettura del file, lancio dei test che falliscono, correzione, nuovo lancio dei test che passano, riepilogo finale. Cinque o sei mosse, con il conteggio dei token diviso in quattro categorie: harness (istruzioni di sistema, tool, file di progetto, hook, skill — il costo fisso presente ancora prima che l’utente parli), risultati tool (file letti, output dei comandi), agente (il suo ragionamento) e utente (la richiesta digitata).

Il dato sulla harness è un numero reale, preso dai campi di fatturazione dell’API: è overhead di tooling puro, uguale per tutti. Il resto è stato contato con un tokenizzatore standard (cl100k_base, quello di OpenAI, non quello di Anthropic), quindi i valori assoluti sono stime entro un 10-15%, ma le proporzioni reggono.


Sul task corto, l’utente pesa lo 0,1% di ciò che l’agente legge per rispondere.

Sul task corto la harness sono 19.694 token fissi, quelli che ci sono sempre. File letti e output dei test: trecento. Ragionamento dell’agente: centotrenta. La richiesta dell’utente — “il totale del carrello è sbagliato quando scatta lo sconto, sistemalo” — pesa venti token su un contesto totale di circa ventimila.

Il dato è controintuitivo: in volume, l’utente è una riga in un testo scritto quasi tutto da altri — system prompt, definizioni dei tool, hook. Ma attenzione a cosa dice davvero questo numero: non misura l’importanza di un token, misura solo la sua presenza nel contesto. Pochi token non vuol dire poca influenza — una singola istruzione dell’utente può cambiare da cima a fondo il comportamento dell’agente. Quello che l’esperimento dimostra non è che la richiesta dell’utente conti poco, ma che occupa pochissimo spazio.

Nelle sessioni vere cambia il padrone, non l’utente

L’obiezione naturale: su un task da due minuti la harness domina perché non è ancora successo nulla, ma in una sessione vera l’agente apre venti file, lancia i test più volte, esplora il codebase, e lì il contesto si gonfia. Ho modellato anche questo scenario, con l’agente che legge ventidue file per orientarsi in una sessione lunga.

Fonte del contesto Task corto Sessione lunga
Harness 98% 46%
Risultati tool 1,5% 52%
Utente 0,10% 0,12%

Nella sessione lunga i risultati dei tool arrivano al 52% e superano la harness, scesa al 46%: la barra si capovolge, cambia chi comanda il contesto. Ma la quota dell’utente passa da venti a 53 token, cioè dallo 0,10 allo 0,12%. Un movimento di due centesimi di punto, in pratica invariato. Ed è un risultato peggiore, non migliore: nel task corto il padrone del contesto è almeno codice scritto da umani (le istruzioni della harness); nella sessione lunga il padrone diventa roba che l’agente si è procurato da solo — file che ha deciso di aprire, comandi che ha deciso di lanciare. In entrambi i casi, chi riempie la finestra di contesto non è l’utente.


Cosa c’è dentro quei diciannovemila token

Cosa sono, in pratica, i token che si trovano nel contesto ancora prima di scrivere qualcosa? C’è il system prompt, che dice al modello chi è e come comportarsi. Ci sono le definizioni di tutti i tool disponibili — leggere file, scriverli, lanciare comandi, cercare sul web — ciascuna con i parametri descritti per esteso. C’è il file di progetto (l’equivalente di un CLAUDE.md con le regole del progetto). E due categorie che quasi nessuno considera: hook e skill.

Gli hook sono programmi che la harness lancia da sola in momenti precisi — per esempio all’apertura della sessione — e il cui output finisce dritto nel contesto del modello: memoria di progetto, regole imparate in sessioni passate, suggerimenti. Utile, spesso, ma è materiale che entra nella “testa” dell’agente senza passare dall’utente, a volte senza che l’utente sappia nemmeno che c’è. Le skill sono pacchetti di istruzioni specializzate, e anche le loro descrizioni occupano spazio.

Il contesto ha due nature. Statico: system prompt, definizioni tool, skill, hook, file di progetto — entra al primo turno e resta fisso per tutta la sessione. Dinamico: file letti, output dei comandi, messaggi dell’utente, ragionamento dell’agente — cresce a ogni turno successivo. Il problema è che la parte statica, anche se piccola come numero di voci, viene riletta a ogni singola chiamata del modello. E tutto ciò che entra nel contesto — compresi hook e output di tool malevoli — l’agente in qualche misura lo tratta come dato di contorno affidabile.

Sono netto su un punto: quei 19.694 token sono il mio numero, non una costante universale. Dipendono da come è stata configurata la harness — un’installazione spoglia ne ha molti meno, una piena di hook, server esterni e skill ne ha di più. Più si personalizza l’agente, più si allarga la fetta di contesto scritta da chiunque tranne l’utente.

C’è anche un risvolto di sicurezza. Quella finestra di contesto è una superficie: tutto ciò che ci entra, l’agente in qualche misura lo considera attendibile. Se un hook scrive qualcosa, l’agente lo legge come dato di contorno; se l’output di un tool contiene una riga scritta apposta per impartire un ordine, quella riga arriva nel contesto con lo stesso peso del resto. È il meccanismo alla base della prompt injection: funziona perché trasforma dati in istruzioni. Lo stesso vale per gli output dei server MCP, sempre più diffusi — se finiscono nel contesto, diventano testo che il modello deve interpretare alla pari di tutto il resto.


La seconda dimensione: non quanto, ma quante volte

Fin qui la misura riguarda il volume. Ma c’è una seconda dimensione che cambia la lettura: il contesto è incrementale. A ogni turno il modello non legge solo l’ultimo messaggio: riceve tutta la conversazione accumulata fino a quel punto, più il nuovo output dei tool, più il contesto aggiunto dalla harness. Gli stessi token tornano dentro, daccapo, a ogni giro del ciclo — ed è anche il motivo per cui il costo cresce man mano che la sessione avanza.

Chiamo questa metrica read amplification, presa in prestito dal mondo dello storage: il rapporto tra tutti i token processati durante la sessione e quelli presenti nel turno più grande — in breve, R = token totali processati / picco del contesto. Sull’esempio da cinque turni l’amplificazione è già 5 volte — ventimila token al picco, ma centomila effettivamente riletti. Sulla sessione reale in cui ho costruito l’analisi — lunga e piena di lavoro — i numeri crescono molto di più: 99 turni (chiamate al modello), 121mila token di picco del contesto, 6,68 milioni di token riletti in totale, per un’amplificazione di 55 volte.

Un’obiezione tecnica prevista: molte implementazioni mantengono una KV cache che, nelle inferenze compatibili, evita di ricalcolare da zero l’attenzione sui token già visti — da qui gli sconti sui token “cached” nelle fatturazioni. Ma non cambia la sostanza: quei token continuano a far parte di ogni inferenza, e un contesto più lungo aumenta comunque il lavoro richiesto ai meccanismi di attenzione, anche con le ottimizzazioni dei modelli moderni.

Sono esplicito sui limiti della misura: non dico quanto ogni sorgente influenzi davvero la risposta finale, dico solo quanto spazio occupa e quanto a lungo resta nel contesto. L’influenza effettiva dipende anche dall’architettura del modello e da come l’attenzione pesa i token. E vale solo finché la conversazione non viene compressa: molti agenti, superata una soglia di riempimento, riassumono o tagliano la cronologia in automatico, e da quel momento la composizione del contesto cambia.

Uno script per misurarlo sulla propria sessione

Questi numeri vengono da un esempio inventato apposta, neutro. Ma la stessa misura si può fare sulla sessione reale di ciascuno: Claude Code tiene un registro di ogni sessione in un file di testo dentro ~/.claude/projects/, e lo script che ho pubblicato lo legge restituendo la stessa scomposizione — harness, tool, agente, utente — senza mai stampare il contenuto dei messaggi o dei file aperti, e girando interamente in locale.


Script Cosa fa
scenari.py I due scenari neutri (task corto e sessione lunga), scomposizione del contesto per sorgente
persistenza.py Quante volte ogni sorgente viene riprocessata, e la read amplification sull’esempio
analizza-la-tua-sessione.py Sul transcript reale dell’utente: la scomposizione del contesto, solo conteggi
read_amplification.py Sul transcript reale: la read amplification effettiva (turni, picco, token riletti)
cart.py + test_cart.py Il toy project col bug dello sconto, usato come esempio neutro

Lanciato sulla sessione reale in cui ho costruito questa stessa analisi — lunga e piena di lavoro — il risultato è: harness al 72%, ragionamento dell’agente al 20%, file letti all’8%, e l’utente allo 0,25%. Trecentonovantadue token non miei per ogni token mio. Diverso nei dettagli dall’esempio inventato, identico nella sostanza. Tutto il codice, compreso lo script gemello per la read amplification, è pubblicato su GitHub, nella cartella scripts/sei-lo-zero-virgola-uno/.

Cosa questa analisi non fa: non misura l’importanza reale di ogni token, solo la sua presenza e persistenza nel contesto. I valori assoluti sono stime entro il 10-15%, perché il tokenizzatore usato (cl100k_base) non è quello di Anthropic. La misura vale prima di un’eventuale compattazione automatica della cronologia; dopo, la composizione cambia. I numeri assoluti dipendono dall’agente e dal setup: cambiano con Codex, Gemini CLI, Aider, Cursor o Windsurf, non cambia il principio.

Quattro regole pratiche per chi costruisce agenti

Dai due numeri — volume e persistenza — discendono conseguenze pratiche per chi progetta agenti: ogni token viene pagato moltiplicato per i turni che restano nella sessione.

La scelta Perché pesa La mossa
Output dei tool lunghi Riletti a ogni turno restante Troncare e filtrare alla fonte
Hook e system prompt gonfi Parte statica, riletta sempre Solo l’essenziale, niente dump
Leggere file in massa Restano nel contesto e diluiscono il segnale Retrieval mirato, lettura solo quando serve
Sintesi tardiva Si paga la rilettura piena fino alla soglia Comprimere presto, sotto controllo

Un comando che restituisce mille righe, un file letto per intero quando serviva una funzione: quel token non si paga una volta, si paga per ogni turno fino a fine sessione. Un hook che inietta duemila token di “stato del progetto” non costa duemila token, ne costa duemila per turno — su una sessione da 99 giri sono duecentomila. E dare all’agente cinquanta file “per sicurezza” si ritorce doppio: ogni file aperto resta nel contesto per tutti i turni successivi, e dilata il pagliaio in cui il modello deve ritrovare l’ago.

Il token più costoso non è quello che occupa più spazio. È quello che viene riletto più volte.

Il fenomeno non è di un prodotto solo

Il mio pezzo nasce come misura su Claude Code, ma il fenomeno non è specifico di quello strumento: riguarda qualunque agente che costruisce il contesto turno dopo turno, da Codex a Gemini CLI, da Aider a Cursor o Windsurf. Cambiano i numeri e la forma della harness, non cambia la logica di fondo — quella che oggi va sotto il nome di context engineering: progettare un agente vuol dire soprattutto progettare il contesto che gli verrà mostrato, prima ancora del modello che lo legge.


La lettura di fondo, per chi lavora ogni giorno con agenti di coding, è una correzione di prospettiva più che un allarme: in volume, la parte scritta dall’utente è minima, e il grosso del contesto lo riempiono altri — chi ha scritto il system prompt, chi ha definito i tool, chi ha messo gli hook, e l’agente stesso con i file e i comandi che apre. Resta vero che quella parte minima è comunque il segnale che orienta tutto il resto. Ma quando un agente si comporta in modo imprevisto, vale la pena allargare lo sguardo oltre le proprie due righe di prompt: la spiegazione, spesso, sta in quei diciannovemila token che nessuno ha scritto.


Andrea Amani — Security Engineer · Signal Pirate
Security engineer. Sul suo laboratorio Signal Pirate smonta algoritmi, protocolli e sistemi e ne pubblica l’analisi tecnica con dati reali e codice riproducibile. Studia come funzionano le cose, dalla sicurezza offensiva agli agenti AI, e scrive quello che trova.


#Adessonews seleziona nella rete articoli di particolare interesse.
Se vuoi leggere l’articolo completo clicca sul seguente link
 Andrea Amani

Source link

Di