La repo di Harness²: la demo gira in tre secondi, un banco vero chiede la rete chiusa

Una ricetta pubblicata e la cucina in cui è nata non dicono le stesse cose. La ricetta dice quanto sale e per quanti minuti; la cucina dice dove stanno i coltelli, che cosa manca in dispensa e quale finestra resta aperta mentre il piatto cuoce. Per capire se la ricetta funziona basta leggerla. Per rifarla bisogna entrare in cucina.

Harness², il sistema di Google Cloud AI Research che corregge l’harness di un agente un compito alla volta, senza conoscere la risposta giusta, è uscito con le due cose insieme. Il paper è su arXiv dal 9 ottobre 2026; il codice sta su GitHub, in google-research/harness2, e il suo primo commit è del giorno prima. In dieci giorni ha raccolto più di 3.200 stelle e 273 fork. La licenza è Apache 2.0, il linguaggio Python 3.12. Il metodo lo abbiamo raccontato nel paper-summary dedicato; qui siamo entrati in cucina: abbiamo letto il codice e fatto girare la parte che gira senza un conto cloud.

Che separare i file di un agente non basti, perché i suoi comandi toccano anche la rete, le credenziali e il resto del computer, e che per questo servano permessi minimi e un ambiente isolato, il libro lo spiega nel capitolo sul loop engineering.

Leggi «Loop engineering: progettare il ciclo» nel libro →

La prova che non costa niente

Il README chiede Linux, Python 3.12 e uv, e propone come primo passo una dimostrazione che non chiama nessun modello:

uv venv --python 3.12 .venv
source .venv/bin/activate
uv pip install -e '.[render]'
harness2-demo --output runs/demo --k 2

Il nucleo del pacchetto non ha dipendenze esterne, quindi la demo si può lanciare anche senza installare niente. L’abbiamo fatta girare in un contenitore Docker con la rete staccata e il codice in sola lettura, che è il modo giusto di provare un programma appena scaricato: due compiti, budget $k=2$, le due modalità (in parallelo e in sequenza). Tre secondi, 28 esecuzioni del compito, 32 chiamate ai ruoli che nella versione vera spettano a un modello, nessun errore.

Il compito è piccolo e onesto. Un registro di movimenti con entrate e uscite, da sommare; l’harness di partenza contiene uno script che somma solo gli importi positivi, cioè un difetto messo apposta. Il correttore toglie il filtro, il nuovo harness dà il totale giusto, e alla fine del giro nella cartella library/ compare un file EXPERIENCE.md con la lezione: quando un registro contiene entrate e uscite, somma entrambi i segni, con la prova accanto (il totale della prova includeva gli importi negativi che il giro di partenza aveva perso). Il compito successivo, nello stesso dominio, trova quella voce nell’indice della biblioteca.

C’è però un dettaglio da sapere prima di trarne conclusioni. Nella demo il correttore e il selettore sono scritti a mano, non sono modelli; e il selettore, per scegliere fra i candidati, ricalcola la somma giusta dal registro e prende quello che la riporta. Conosce la risposta, cioè proprio la cosa che Harness² dichiara di non usare. La demo prova l’impianto (le cartelle, i turni, la biblioteca, i file che passano da una fase all’altra), non il metodo. Per vedere il metodo servono un modello vero e un banco di prova vero.

Che cosa si legge nel codice

Il pacchetto conta circa 12.700 righe di Python, e il cuore sta in harness2/core/. Tre scelte valgono anche per chi non userà mai Harness².

L’harness è una cartella di file. Con OpenCode come esecutore sono otto componenti: systemprompt.md, guardrails.md, LongTermMEMORY.md e le indicazioni sugli strumenti, sempre caricati; poi le skill, gli script, i sottoagenti e un plugin. I quattro file sempre caricati hanno un tetto di 24.000 caratteri, con la ragione scritta nel codice: ogni token lì dentro toglie spazio a quello che l’agente deve scrivere. Una proposta di modifica contiene solo quello che cambia, e il resto si eredita. E a ogni skill che il correttore aggiunge, il codice scrive da sé in guardrails.md la riga che dice all’agente quando caricarla: una skill che nessuno richiama è una skill che non esiste.

Il voto del giudice non deve arrivare al correttore. Ogni volta che il programma prepara la cartella che un modello leggerà, un controllo ne scorre i file, nomi e contenuti, e si ferma se trova le tracce di un verdetto: pass_rate, passed_count, i riassunti della valutazione automatica. Il commento nel codice è più onesto di molti paper: è un allarme sul confine, non la difesa. La difesa vera è che gli adattatori dei banchi di prova non leggano mai quei file; se l’allarme scatta, c’è una falla da trovare, non una lista di parole da allungare. Quando i risultati sono più d’uno, poi, il selettore li riceve anonimi, con lettere rimescolate in modo riproducibile, e sceglie solo fra gli harness corretti: le esecuzioni di partenza non sono fra i candidati.

Ogni passo ha un costo fisso. La documentazione interna lo dice in una riga: ogni modalità prevede $4k$ esecuzioni del compito e $3k$ fasi di correzione, più la riflessione finale. Con $k=1$ sono quattro esecuzioni e tre sessioni del correttore per ogni compito; una proposta che non passa la validazione ha un secondo tentativo, poi si tiene l’harness di prima.

Il controllo sta sui file del correttore, non sulla rete dell’esecutore Che cosa legge il correttore task.md il compito rollouts/ le tracce, per intero deliverables/ il lavoro consegnato harness/ gli otto componenti library/ la biblioteca del dominio niente voti, niente griglie il controllo nel codice pass_rate, passed_count… Il verdetto del giudice punteggi e criteri superati score.json, judged.json se entra, il passo si ferma tracce e consegne L’esecutore OpenCode o Codex, sandbox spenta rete aperta huggingface.co le griglie di JobBench, pubbliche

Prima di lanciarlo su un banco vero

Il passo successivo alla demo è uno dei tre banchi di prova del paper, e lì la cucina mostra le finestre aperte.

Serve Google Cloud. La configurazione fornita usa Vertex AI: un progetto, le credenziali di gcloud, Gemini come esecutore e come giudice, Claude o Gemini come correttore. Per Codex c’è un ponte locale basato su LiteLLM che traduce le chiamate. Servono anche Node.js 20 o successivo, Docker per WorkBuddy-Bench, Pandoc e Poppler per LAB. Il README chiede di copiare un file .env.example che, alla versione di oggi, nella repo non c’è: le variabili si ricavano dalla guida di installazione.

La rete dell’esecutore è aperta. È il punto più importante, e la documentazione lo dichiara: l’agente che lavora può navigare, e Codex gira con la sandbox disattivata. I tre banchi sono pubblici, e JobBench pubblica su Hugging Face la griglia di valutazione di ogni compito. Nel collaudo di questa versione, raccontano gli autori, un’esecuzione di Codex su JobBench ha scaricato la griglia del proprio compito senza che nessuno glielo chiedesse. Il controllo sui file del correttore, cioè, non vede la porta da cui la griglia è entrata. La raccomandazione è bloccare per l’esecutore, a installazione finita, huggingface.co, hf.co, github.com e raw.githubusercontent.com, con un firewall o una regola DNS sulla macchina e non con un’impostazione dello strumento, e dichiarare i blocchi accanto ai risultati. È la questione di chi può toccare il metro, spostata dal codice alla rete.

Da qui, uno dei tre banchi non si usa. La licenza di WorkBuddy-Bench, di Tencent, si apre con una clausola territoriale che prevale su tutto il resto: il banco non è destinato all’uso nell’Unione Europea. La documentazione di Harness² la segnala e invita a leggerla. Per chi lavora in Italia restano LAB, di Harvey, con licenza MIT, e JobBench, con il codice sotto Apache 2.0 e i dati sotto MIT.

I numeri del paper non si rifanno con un comando. Il file delle dipendenze avverte che le esecuzioni storiche del paper possono aver usato compiti, modelli e strumenti locali diversi. La versione di LAB fissata nella repo ha 1.143 compiti, il paper ne contava 1.251; il dataset di JobBench non è fissato a una versione, e l’installazione si limita a registrare quella scaricata, da riportare insieme ai risultati. Per cominciare ci sono --dry-run, che mostra i compiti scelti senza chiamare modelli, e --max-tasks, che però vale per dominio e non per l’intera corsa.

La biblioteca vive dentro una corsa. È separata per banco, esecutore, modalità, budget e seme, e fra le opzioni del programma non ce n’è una per partire dalla biblioteca di un’altra corsa. L’esperimento del paper che porta le lezioni di JobBench su WorkBuddy-Bench, in questa versione, non ha un comando pronto. Il quaderno c’è, ma per ora resta nella cartella dell’esperimento che l’ha scritto.

Resta lo stato del progetto. Dopo il primo rilascio i commit sono stati due, l’ultimo il 14 ottobre per correggere un link. Intanto sono state aperte 38 richieste di modifica, quasi tutte correzioni puntuali: una impedirebbe ai processi figli di ereditare tutte le chiavi dell’ambiente di chi lancia, un’altra aggiungerebbe il .gitignore che manca, senza il quale un git add distratto salva nel repository anche il file con le credenziali. Al 18 ottobre nessuna è stata accettata. Il README avverte che non è un prodotto Google supportato ufficialmente. È codice di ricerca, scritto con cura, ma da trattare come tale.

Dieci repo da tenere accanto

Harness² non lavora da solo. Sotto ha gli agenti che fa lavorare, accanto altri modi di migliorare un harness, intorno gli strumenti per misurarlo. Queste dieci servono a chi l’harness lo scrive, lo misura o lo fa scrivere a un modello; le abbiamo controllate una per una il 18 ottobre, e nessuna è archiviata.

Gli agenti su cui lavora

OpenCode (MIT) è l’esecutore predefinito di Harness², un agente di programmazione aperto che gira nel terminale; il vecchio indirizzo sst/opencode ora rimanda qui. Le sue superfici di personalizzazione sono la stessa anatomia degli otto componenti: istruzioni in AGENTS.md (e, in mancanza, CLAUDE.md), skill in file SKILL.md, agenti e sottoagenti scritti in markdown, plugin e strumenti in JavaScript o TypeScript, server MCP.

Codex (Apache 2.0) è il secondo esecutore. Legge un AGENTS.md per cartella, dalla radice del progetto a quella corrente, e quello più vicino prevale; ha skill, server MCP e tre modalità di sandbox, da sola lettura ad accesso completo. Harness² lo lancia con l’opzione che salta approvazioni e sandbox: chi lo usa fuori da un banco di prova parte dalla modalità intermedia, che limita le scritture alla cartella di lavoro.

mini-swe-agent (MIT), degli autori di SWE-bench, è l’harness più piccolo che valga la pena leggere: un solo strumento, la shell, nessuna chiamata strutturata agli strumenti, una storia lineare. Il README parla di «circa 100 righe» per la classe dell’agente (il file oggi ne conta 190) e di oltre il 74% su SWE-bench Verified, senza dire con quale modello. È il punto di partenza giusto per capire che cosa aggiunge tutto il resto.

Chi migliora l’harness in automatico

Meta-Harness (MIT), di Stanford, KRAFTON e MIT, è uno dei metodi con cui il paper di Harness² si confronta. Un agente di programmazione (Claude Code, negli esempi) legge una cartella con il codice, i punteggi e le tracce di tutti i candidati precedenti e scrive un harness nuovo. La differenza con Harness² è il voto: Meta-Harness lo usa, su un insieme di compiti di ricerca, e l’harness trovato poi resta fisso. Su Terminal-Bench 2.0, dice il paper, ricerca e valutazione finale sono state fatte sugli stessi 89 compiti. Il README avverte che è una versione ripulita del codice del paper, provata solo nel senso che parte.

GEPA (MIT) ottimizza qualunque testo, istruzioni, codice, architetture di agenti, facendo leggere a un modello le tracce complete per capire perché un candidato ha fallito, e tenendo i migliori su una frontiera di Pareto. Vuole una funzione che restituisca un punteggio; il commento testuale è facoltativo. Il motto del README, «se lo puoi misurare, lo puoi ottimizzare», è il rovescio esatto di Harness², che il punteggio non lo vuole vedere. È anche dentro DSPy, come dspy.GEPA.

ADAS (Apache 2.0), presentato a ICLR 2025, è il capostipite: un meta-agente scrive nuovi agenti in Python, ciascuno si valuta sui dati di validazione ed entra in un archivio con i suoi punteggi. L’ultimo commit è del gennaio 2025, e il README avverte che il codice esegue programmi scritti da un modello. Vale la lettura più dell’installazione.

Per misurare

Harbor (Apache 2.0), degli autori di Terminal-Bench, è il sistema ufficiale con cui si esegue Terminal-Bench 2.0; anche WorkBuddy-Bench, nell’installazione di Harness², gira su un ambiente costruito su Harbor. Fa girare in contenitori, in locale con Docker o su sandbox in cloud, agenti già pronti come Claude Code, Codex, OpenCode, OpenHands e mini-swe-agent, e riusa le ricompense dei compiti per l’addestramento con rinforzo o per ottimizzare un harness con GEPA. Da sapere: la telemetria d’uso è accesa per impostazione predefinita (agenti, modelli, token, costi, ricompense, non le istruzioni); si spegne con HARBOR_TELEMETRY=off.

Inspect (MIT), dell’AI Security Institute britannico, è un sistema di valutazione con più di 200 valutazioni già pronte, un agente ReAct incluso e, con un pacchetto a parte, la possibilità di misurare anche Claude Code e Codex. La sandbox Docker è compresa; quella chiamata local significa, alla lettera, nessuna sandbox.

Per scriverlo a mano

deepagents (MIT), di LangChain, si presenta come un harness «con le batterie incluse»: pianificazione con una lista di cose da fare, sottoagenti con un contesto separato, un filesystem, il riassunto del contesto quando si riempie, la shell, una memoria che dura, l’approvazione umana, le skill. Funziona con qualunque modello che sappia chiamare strumenti, e dichiara di fidarsi del modello: i confini, avverte, vanno messi al livello degli strumenti e della sandbox.

AGENTS.md (MIT) non è un programma ma un formato: un file markdown senza campi obbligatori, «un README per gli agenti», oggi affidato all’Agentic AI Foundation della Linux Foundation. Il sito lo dice usato da oltre 60.000 progetti e letto da Codex, OpenCode, Cursor, Jules, Gemini CLI e dall’agente di GitHub Copilot, fra gli altri. Claude Code, che legge CLAUDE.md, nell’elenco non c’è.

Che cosa c’è in gioco

La repo di Harness² dimostra due cose insieme. La prima è che l’idea di un harness fatto di file leggibili, corretto da un modello e accompagnato dal motivo di ogni scelta, si può impacchettare in un programma che chiunque installa. La seconda è che il confine fra chi lavora e chi giudica non sta tutto nel codice. Gli autori ne hanno messo una parte dove si può controllare con un test; l’altra passa per la rete della macchina, e quella la chiude chi lancia l’esperimento. Nella cucina, la finestra la chiude chi cucina.

Per approfondire

Il codice: github.com/google-research/harness2, con la guida di installazione, quella agli esperimenti (accesso alla rete compreso) e quella ai banchi di prova. Il paper: Harness²: Recursive Agent Harnessing for an Open World, arXiv 2610.14224.

I banchi di prova: LAB di Harvey, JobBench e WorkBuddy-Bench, con la sua licenza.

I paper dietro tre delle repo: Meta-Harness: End-to-End Optimization of Model Harnesses, arXiv 2603.28052; GEPA: Reflective Prompt Evolution Can Outperform Reinforcement Learning, arXiv 2507.19457; Automated Design of Agentic Systems, arXiv 2408.08435.

Nel Paithon Book: «Harness engineering: tutto ciò che non è il modello», «Loop engineering: progettare il ciclo» e «Finito vuol dire collaudato: la verifica di un lavoro lungo».

I commenti sono riservati agli iscritti.

Accedi per commentare