Siddharth Mishra-Sharma del team Discovery di Anthropic racconta come ha usato Claude Opus 4.6 per costruire un solver cosmologico differenziabile. Il progetto è durato qualche giorno di lavoro autonomo dell’agent – roba che normalmente richiederebbe mesi di lavoro umano.
Il cambio di paradigma
La maggior parte degli scienziati usa gli AI agent in modalità conversazionale stretta: ogni passo viene supervisionato. Ma i modelli sono migliorati tantissimo nell’ultimo anno, e si è aperto un nuovo modo di lavorare: definisci l’obiettivo ad alto livello, lasci partire un team di agent, e loro lavorano in autonomia. Progetti che ti prenderebbero giorni o settimane si chiudono in ore.
Certi task scientifici si prestano bene: reimplementare un solver numerico, convertire software legacy in Fortran arcaico verso linguaggi moderni, debuggare una codebase gigante confrontandola con un’implementazione di riferimento. Tutti casi dove il lavoro è ben definito, i criteri di successo sono chiari, e la supervisione umana può essere occasionale.
L’esempio concreto: un solver cosmologico
Mishra-Sharma ha usato Claude per implementare una versione differenziabile di un Boltzmann solver cosmologico. Questo è codice numerico che predice le proprietà statistiche dell’afterglow del Big Bang – la Cosmic Microwave Background (CMB). Lo fa evolvendo equazioni accoppiate per fotoni, barioni, neutrini e materia oscura attraverso l’universo primordiale.
I solver come CLASS e CAMB sono infrastruttura core in cosmologia, permettono di vincolare modelli cosmologici usando dati da survey tipo Planck. Una versione differenziabile – che può propagare gradienti attraverso l’intero solver – abilita metodi di inferenza basati su gradienti, velocizzando drasticamente la stima dei parametri. Scriverlo in JAX è una scelta naturale: ti dà differenziazione automatica e compatibilità con GPU essenzialmente gratis.
Punto interessante: il task non è nel dominio scientifico core di Mishra-Sharma. Ha familiarità ad alto livello con tools e scienza, ma non l’expertise per completarlo da solo in un tempo ragionevole. Gruppi che hanno quella expertise hanno costruito solver differenziabili in JAX con un subset delle feature presenti in CLASS. Questi sforzi tipicamente rappresentano mesi o anni di tempo-ricercatore. L’obiettivo era vedere se un agent potesse andare oltre con steering minimo da parte di un non-esperto del dominio.
Differenza strutturale rispetto al progetto C compiler
Il progetto C compiler di Anthropic (quello dove Claude ha lavorato attraverso circa 2.000 sessioni per costruire un compiler capace di compilare il kernel Linux) poteva essere distribuito su molti agent paralleli. Un Boltzmann solver invece è una pipeline profondamente accoppiata – un piccolo errore numerico o un’approssimazione scadente nel modellare come l’universo primordiale si ricombina può spostare sottilmente tutto downstream.
Richiede quindi un set diverso di skill per l’agent. Il debugging richiede tracciare causalmente attraverso l’intera catena e attingere da conoscenza di dominio. Probabilmente meglio adatto a un singolo agent che lavora sequenzialmente, spawna sub-agent quando serve, e usa l’implementazione di riferimento per bisezionare le discrepanze.
Setup pratico: HPC cluster con SLURM
L’ambiente computazionale era un cluster HPC che fa girare lo SLURM job scheduler, ma le idee core – un file di progresso, un test oracle, un prompt dell’agent con regole chiare – si applicano ovunque fai girare Claude Code.
Stesura del piano e iterazione locale
In questo shift verso gestire un team autonomo di agent, dovresti spendere la maggior parte del tempo (in consultazione con Claude) a craftare un set di istruzioni che articola chiaramente i deliverable del progetto e il contesto rilevante. Queste istruzioni dovrebbero vivere in un file CLAUDE.md nella root directory. Claude tratta questo file in modo speciale, lo tiene in context e lo referenzia per il piano complessivo. Crucialmente, Claude può editare queste istruzioni mentre lavora, aggiornandole per lavoro futuro mentre lavora attraverso i problemi.
Per arrivare al piano finale, Mishra-Sharma ha specificato gli obiettivi high-level: raggiungere feature-parity completa con l’implementazione di riferimento CLASS pur essendo completamente differenziabile, e avere un target di accuracy dello 0.1% contro CLASS nei main deliverable scientifici. Dato che 0.1% è il livello tipico di accordo tra i due codici Boltzmann canonici CLASS e CAMB, sembrava un buon target scientifico. Ha poi iterato con Claude finché il piano non sembrava soddisfacente.
Memoria attraverso le sessioni
Il file di progresso, chiamato per convenzione CHANGELOG.md, è la memoria long-term portabile dell’agent – una sorta di lab notes. Un buon file di progresso potrebbe tracciare status corrente, task completati, approcci falliti e perché non hanno funzionato, tabelle di accuracy a checkpoint chiave, e limitazioni conosciute.
Gli approcci falliti sono importanti – senza di essi, sessioni successive ri-tenteranno gli stessi dead end. Un’entry potrebbe essere tipo: “Provato a usare Tsit5 per l’ODE di perturbazione, il sistema è troppo stiff. Switchato a Kvaerno5.”
Il test oracle
Mentre discovery scientifica più open-ended via agent è certamente all’orizzonte, lavoro scientifico autonomo long-running oggi dipende crucialmente dall’agent che ha un modo per sapere se sta facendo progressi. Per codice scientifico, questo potrebbe essere un’implementazione di riferimento, un obiettivo chiaramente quantificabile, o una test suite esistente. Può anche essere utile istruire l’agent a espandere la test suite e far girare test mentre lavora, per prevenire regression.
Nel task esempio, Claude era istruito a costruire e far girare continuamente unit test usando il source C di CLASS come implementazione di riferimento.
Git come coordinazione
Git può essere un buon modo per monitorare e coordinare il progresso dell’agent in modo hands-off. L’agent dovrebbe committare e pushare dopo ogni unità di lavoro significativa. Questo ti dà una storia recuperabile se qualcosa va storto, rende il progresso visibile localmente, e previene che il lavoro venga perso se, per esempio, la tua allocazione di compute finisce a metà sessione.
Praticamente, questo potrebbe essere un set di istruzioni in CLAUDE.md, tipo: “Committa e pusha dopo ogni unità di lavoro significativa. Fai girare pytest tests/ -x -q prima di ogni commit. Non committare mai codice che rompe test passing esistenti.”
Il loop di esecuzione
Come menzionato sopra, è spesso utile iterare prima sul piano localmente finché non ne hai uno che sembra ragionevole ed è encodato in CLAUDE.md. Da lì, parti una sessione Claude Code dentro un terminal multiplexer come tmux su un compute node, dì all’agent dove trovare la tua codebase, e lascialo cuocere. Siccome la sessione gira dentro tmux, puoi detachare, chiudere il laptop, e checkare occasionalmente il progresso (nel caso del Boltzmann solver, Mishra-Sharma checkava su GitHub dal telefono, tipo mentre aspettava in fila per un caffè).
Il Ralph loop
Man mano che i modelli diventano più capaci, richiedono meno orchestrazione bespoke tipo prompt engineering, RAG, o context stuffing. A un dato punto nel tempo, comunque, può essere utile fornire un certo livello di scaffolding come capability uplift. Per esempio, i modelli correnti possono soffrire di agentic laziness – quando chiesti di completare un task complesso multi-parte, a volte possono trovare una scusa per fermarsi prima di finire l’intero task (“Si sta facendo tardi, riprendiamo domani?”).
Per aggirare questo, un pattern di orchestrazione utile è il Ralph loop, che è essenzialmente un for loop che calcia l’agent di nuovo in context quando dichiara completamento, e chiede se è davvero finito. Può essere utile per task long-running visto che l’agent ammetterà che il task non è up to spec, e continuerà a lavorare finché non lo è.
Ralph può essere installato via /plugin. Una tipica invocation prompt in Claude Code potrebbe essere tipo:
/ralph-loop:ralph-loop "Please keep working on the task until the success criterion of 0.1% accuracy across the entire parameter range is achieved." --max-iterations 20 --completion-promise "DONE"
Qui, Claude itererà fino a 20 volte finché non garantisce che il task è fatto con un’incantazione “DONE”.
Il risultato
Claude ha lavorato sul progetto da zero per qualche giorno, raggiungendo accordo sub-percent con l’implementazione di riferimento CLASS attraverso i suoi vari output. La traiettoria di sviluppo dell’agent era un po’ goffa. Per esempio, c’erano gap chiari nella sua test coverage – per un po’ stava solo testando il codice a un singolo punto di parametri (fiducial), riducendo drasticamente la sua superficie di bug-catching. Può anche fare errori elementari, tipo inciampare su convenzioni di gauge o spendere ore a inseguire bug che un cosmologo spotterebbe istantaneamente.
Ma ha continuato a fare progresso sostenuto verso l’obiettivo dichiarato di accuracy sub-percent. Un side effect del progetto era che Mishra-Sharma ha imparato una quantità sorprendente su Boltzmann solver e la fisica che modellano guardando la git commit history. Il progetto non viene dal suo dominio scientifico core, ma seguire il progresso incrementale di Claude e cercare quello che non riconosceva si è rivelato un modo efficace per osmosare la scienza. Il commit log si legge come lab notes da un postdoc veloce e hyper-letterale.
Mentre il solver risultante non è production-grade (tipo, non matcha l’implementazione di riferimento CLASS a un’accuracy accettabile in ogni regime), dimostra che sviluppo agent-driven può comprimere mesi o anche anni di lavoro ricercatore in giorni.
Il nuovo costo opportunità
Questo tipo di compressione cambia cosa conta come idle time. Un’esperienza universale nella ricerca AI è lanciare un esperimento (tipo un training run) overnight e poi avere la soddisfazione di vedere i risultati al mattino. Non far girare l’esperimento viene con un costo opportunità.
Questi giorni, non far girare agent sembra avere un costo pure. Se hai il compute e progetti con criteri di successo ben definiti, ogni notte che non hai agent che lavorano per te è progresso potenziale lasciato sul tavolo.
