Headroom si installa con pip, si mette davanti al tuo LLM come proxy e comprime gli output rumorosi — log, JSON, chunk RAG — prima che arrivino al modello. Sul mio homelab, davanti a Ollama e LM Studio, ha tagliato in media il 51% dei token. Ma con un asterisco grosso: su un log compresso al 95% ha fatto sparire la causa dell'errore. Ecco come si usa e dove sta il confine.
Nel pezzo precedente su Headroom avevo smontato il claim del "60-95% di token in meno, stesse risposte": è marketing, i numeri reali sono molto più sfumati. Restava però la domanda pratica: ok, ridimensionato — ma allora come si installa, come si usa, e quanto rende davvero? Questa è la prova sul campo. L'ho installato, gli ho costruito un banco di prova riproducibile e l'ho cronometrato.
Come si incastra, in 60 secondi
Headroom è un layer di compressione del contesto open-source (licenza Apache-2.0). Non è un modello: è un intermediario. Si piazza tra la tua applicazione (o il tuo agente) e l'LLM, intercetta quello che stai per mandare al modello, riconosce il tipo di contenuto (JSON, codice, log, testo) e lo comprime con compressori specializzati.
Lo puoi usare in tre forme: come libreria Python, come proxy HTTP compatibile con le API OpenAI e Anthropic, o come wrapper per agenti già pronti come Claude Code, Cursor e Aider. Il caso d'uso classico non è comprimere il tuo prompt — quello resta intatto — ma comprimere gli output dei tool: il docker ps da 400 righe, il dump di log, i venti chunk del RAG. È lì che si annida il grasso.
Installazione passo-passo (e la trappola che non ti dicono)
Serve Python 3.10 o superiore. Sul mio homelab giro tutto in WSL, dove avevo solo Python 3.14 (troppo nuovo per alcune dipendenze ML), quindi mi sono creato un ambiente isolato con uv:
bash
# uv installa al volo un Python 3.13 dedicato, senza toccare il sistema
curl -LsSf https://astral.sh/uv/install.sh | sh
uv python install 3.13
uv venv --python 3.13 .venv && source .venv/bin/activate
La via "tutto incluso" della documentazione è questa:
bash
pip install "headroom-ai[all]"
Qui c'è il trabocchetto. L'extra [all] si tira dietro hnswlib (la memoria vettoriale), che va compilato da sorgente. Se sulla macchina non hai un compilatore C++, l'installazione si pianta a metà con un secco
Ollama Proxmox LXC senza GPU: gotcha reali, 15 t/s CPU-only
Come far girare ollama proxmox lxc senza GPU: zstd mancante, systemd da zero, 13-15 t/s reali con llama3.2 su CPU AMD Ryzen.
RuntimeError: Unsupported compiler -- at least C++11 support is needed!
e — peggio —
pip
annulla tutto, lasciandoti senza Headroom installato.
Due strade. O metti il compilatore con sudo apt install build-essential, oppure, se la memoria vettoriale non ti serve (a me no), installi solo gli extra che ti interessano e salti del tutto il pacchetto che non compila:
bash
pip install "headroom-ai[proxy,code,ml]"
[proxy] per il server, [code] per la compressione del codice, [ml] per il compressore di testo. Poi verifica che la CLI risponda con headroom --help: deve elencare i comandi proxy, doctor, perf, wrap, mcp, memory. La versione installata nel mio test è la 0.27.0.
I tre modi d'uso, con output reali
Come libreria: una riga
python
from headroom import compress
res = compress(messages, model="gpt-4o-mini")
print(res.tokens_before, "->", res.tokens_after)
print("risparmiati:", res.tokens_saved)
print(res.transforms_applied)
compress() restituisce un oggetto con tokens_before, tokens_after, tokens_saved, compression_ratio e transforms_applied; i messaggi compressi te li ritrovi in res.messages, pronti da inoltrare al modello. Comodo per misurare prima di committare qualunque scelta.
Poi la tua app parla col proxy invece che col modello, puntando OPENAI_BASE_URL a http://localhost:8787/v1. Quel --no-ccr-inject-tool serve con i client "semplici" (come Ollama o un'app OpenAI generica) che non sanno gestire il tool di retrieval che Headroom inietterebbe; senza, rischi un errore. Con Claude Code via MCP, invece, lo lasci attivo.
Mandati due scenari attraverso il proxy, le metriche compaiono subito con headroom doctor e headroom perf. Quest'ultimo, in formato JSON, mi ha riportato 2 richieste, 14.774 token in ingresso ridotti a 5.542, cioè il 62,6% risparmiato. E ogni richiesta finisce nel log con il suo bilancio:
headroom wrap claude # instrada Claude Code attraverso il proxy
headroom wrap cursor
headroom wrap aider
È il modo zero-config se vivi dentro un coding agent: parte il proxy e l'agente ci viene instradato.
Il mio banco di prova
Volevo numeri miei, non da brochure. Ho costruito un dataset riproducibile (seed fisso) di cinque scenari, ognuno modellato come una traccia di agente realistica — un tool che restituisce un output rumoroso con dentro un fatto verificabile, "l'ago nel pagliaio". Il primo è l'output di docker ps con 12 container, uno solo unhealthy. Il secondo, 200 righe di log applicativo con un solo errore 500 sepolto. Poi un file di codice Python di circa 160 righe; otto chunk di documentazione in stile RAG, di cui solo uno contiene il dato giusto; e infine una conversazione lunga, dove un codice di verifica detto al primo turno resta sepolto sotto dodici turni di chiacchiere.
Per ogni scenario misuro due cose: quanti token risparmia Headroom, e se la risposta sopravvive — cioè se il modello, ricevendo il contesto compresso, trova ancora l'ago. Ho fatto girare tutto su due backend: Ollama con qwen2.5:14b (in WSL) e LM Studio con qwen3-14b (su Windows).
I numeri
Stessa compressione su entrambi i backend — ovvio, perché Headroom lavora a monte del modello: il risparmio non dipende da chi genera la risposta (i token sono contati da Headroom con tiktoken). Ecco il risparmio per tipo di contenuto, e se l'ago è sopravvissuto alla compressione:
Log applicativo: da 6.527 a 346 token, meno 95 per cento. L'ago non sopravvive: si perde la causa nello stack-trace.
Conversazione lunga: da 8.903 a 4.767 token, meno 46 per cento. Ago ritrovato.
JSON (docker ps): da 5.139 a 4.067 token, meno 21 per cento. Ago ritrovato.
Codice: da 912 a 912 token, zero per cento (protetto di default). Ago ritrovato.
Chunk RAG: da 840 a 840 token, zero per cento (prosa conservata). Ago ritrovato.
In totale: da 22.321 a 10.932 token, meno 51 per cento. Accuratezza: 5 risposte su 5 corrette col contesto pieno, 4 su 5 col contesto compresso. Tre cose saltano all'occhio.
Il grosso del risparmio viene dagli output ripetitivi. I log volano via al 95%, perché Headroom riconosce le righe-fotocopia (gli heartbeat, i 200 OK) e ne tiene una manciata rappresentativa. Il JSON si comprime "solo" del 21%: è già denso, c'è meno aria da togliere.
Codice e prosa, di default, non li tocca. Il file Python esce a 0%: Headroom è deliberatamente conservativo, per non rischiare di rompere ciò che è fragile. Stessa cosa per i chunk RAG, che restano interi. Niente "meno 90% su tutto": dove il dettaglio conta, resta.
Su contesto lungo regge bene. La conversazione da quasi 9.000 token si dimezza, e il codice di verifica detto al primo turno viene comunque ritrovato. La compressione dello storico non ha mangiato l'informazione critica.
Dove l'ago è caduto
L'unico KO è il log al 95% — ed è esattamente la lezione del pezzo precedente, ora misurata. Ecco cosa resta del log compresso, da circa 13 KB a poche righe:
text
2026:6:21T03:14:07Z ERROR [worker-3] 500 POST /api/v1/import/catalog - request failed
[... and 195 more matches in 2026]
[200 matches compressed to 5. Retrieve more: hash=e42faf1f...]
Headroom ha tenuto la riga dell'errore — ora ed endpoint corretti — ma ha buttato via le righe indentate dello stack-trace che la seguivano, dove c'era la causa vera: psycopg2.OperationalError: connection pool exhausted. Risultato: con il contesto pieno il modello rispondeva indicando esattamente quella causa, mentre con quello compresso ammetteva, onestamente, che nello stack-trace non c'erano più dettagli sulla causa specifica.
Identico su Ollama e su LM Studio: due modelli diversi, stesso buco. Non è il modello che sbaglia — è l'informazione che non c'è più. L'ho verificato anche cercando la stringa direttamente nel testo compresso: sparita.
Una nota di equità, però: quel Retrieve more: hash=... non è un caso. È il meccanismo CCR di Headroom — il dettaglio tagliato non è perso per sempre, è recuperabile su richiesta. Un agente che parla via MCP (come Claude Code) può chiamare il tool di retrieval ed espandere quella riga quando gli serve. Un client semplice come il mio no: per lui la causa è andata. Morale: la compressione aggressiva sui log va benissimo per il triage, ma se ti serve la diagnosi profonda assicurati che il tuo client sappia ri-espandere.
In locale comprimere ti fa anche andare più veloce
In cloud il risparmio di token sono soldi; in locale è soprattutto velocità e spazio nel contesto. Meno token in ingresso significa meno prefill da macinare. Misurato su Ollama (qwen2.5:14b, modello già caldo, cache invalidata a ogni run, mediana di 3 esecuzioni) il tempo di risposta sul prompt compresso scende parecchio:
JSON (meno 21% di token): da 3,04s a 2,51s, cioè 1,2 volte più veloce.
Conversazione lunga (meno 46%): da 6,01s a 3,02s, 2 volte più veloce.
Log (meno 95%): da 5,38s a 1,28s, 4,2 volte più veloce.
Più comprimi, più voli. E sul context window: i log che mi avevano fatto sforare la finestra di default di Ollama, una volta compressi ci stanno comodi. Su modelli locali con finestra piccola, questo è spesso il beneficio più concreto di tutti.
Le manopole che contano
Di serie Headroom è prudente. Se vuoi spingere, ci sono leve da conoscere — con i loro rischi.
La compressione del codice è spenta di default. La accendi con --code-aware (o HEADROOM_CODE_AWARE_ENABLED=1): attiva la compressione AST. È il motivo per cui il mio file Python usciva a 0%. Accendila solo se hai misurato che non ti rompe le risposte.
`--target-ratio` regola l'aggressività sul testo (più basso, più aggressivo). Di default è conservativo. Nei miei test, alzarlo non ha toccato i contenuti già protetti: Headroom non si fa forzare facilmente sul materiale delicato.
`--mode token` contro `--mode cache`. La modalità token riscrive anche i turni passati per massimizzare il risparmio; cache invece "congela" il prefisso per massimizzare gli hit della cache del provider. Se il tuo backend ha il prompt caching e lo riusi spesso, cache può rendere più di token.
`--intercept-tool-results` è opt-in e intercetta gli output dei tool con outliner dedicati: è esattamente il caso d'uso che conta per gli agenti.
Quando conviene (e quando no)
Conviene quando dai in pasto al modello tanto rumore ripetitivo: log, output di tool verbosi, RAG voluminoso, conversazioni lunghe. Lì il taglio è reale e gratis in qualità. Rende poco — per disegno — su prompt brevi, prosa curata e codice, che restano protetti.
Verdetto pratico
Headroom è ingegneria solida e — questo è il punto — onesta nei default: comprime forte solo dove può, protegge dove deve. Sul mio homelab ho visto un risparmio reale del 51% medio, fino a un log elaborato 4 volte più in fretta, pagando un solo errore: la causa di un'eccezione persa in un log spremuto al 95%. Non è "il 90% di token in meno, stesse risposte". È uno strumento che, usato con la testa e tarato sui tuoi dati, taglia il grasso e ti lascia il segnale — a patto che tu sappia dov'è il confine. Ora lo sai.
Domande frequenti
Headroom comprime davvero il 90% dei token?
No, dipende dal contenuto. Sui log ripetitivi nei miei test ha tagliato il 95%, ma sul JSON solo il 21% e su codice e prosa lo 0% (sono protetti di default). La media sui miei cinque scenari è stata del 51%.
Headroom peggiora le risposte del modello?
Può, sui contenuti compressi più aggressivamente. Nei miei test, su 5 scenari 4 risposte erano perfette anche dopo la compressione; in un caso — un log spremuto al 95% — è sparita la causa dell'errore. Per questo va misurato sul proprio workload.
Funziona con Ollama e LM Studio?
Sì. Headroom fa da proxy davanti a qualsiasi endpoint compatibile OpenAI: basta puntarlo all'URL di Ollama (localhost:11434/v1) o di LM Studio (localhost:1234/v1). Nei miei test il risparmio di token è stato identico sui due, perché la compressione avviene prima del modello.
Quanto è difficile da installare?
Un pip install, con un'insidia: l'extra [all] include hnswlib, che va compilato e fallisce senza un compilatore C++. La soluzione è installare build-essential oppure scegliere solo gli extra che servono, ad esempio headroom-ai[proxy,code,ml].
Resta Aggiornato
Iscriviti alla newsletter per ricevere i migliori articoli direttamente nella tua inbox.