Paithon Book Paithon Book
Esegui il codice

Architetture di agenti e come valutarli#

Nella sezione sul ciclo dell’agente ne abbiamo costruito uno e l’abbiamo fatto girare: pensa, agisce, osserva, ripete, e quello schema si chiamava ReAct. Su un compito ben delimitato (trova un dato, fai un conto, rispondi) quel ciclo va sorprendentemente lontano.

Ma prova a chiedergli qualcosa di grosso: «prendi questa segnalazione di errore, trova il file giusto in un progetto da centomila righe, scrivi la correzione e verifica che i test passino». Lì un ciclo semplice può perdere il filo, e quanto spesso lo perda dipende molto dal modello e dagli strumenti. Nello stesso ciclo minimo (un centinaio di righe di Python, con la shell come unico strumento), su cinquecento segnalazioni ripulite di SWE-bench, la quota di correzioni riuscite andava nel 2025 dal 9% con un modello aperto di medie dimensioni al 22% con GPT-4o, fino al 74% con Claude Opus 4.5 (misure verificate dalla squadra di SWE-bench, con una riserva sulla contaminazione che si vedrà parlando di valutazione).

Dove il modello da solo non basta, le risposte sono tre, e vanno giudicate caso per caso. La prima è pianificare in anticipo invece di reagire un passo alla volta. La seconda è comporre più agenti, ciascuno con un mestiere, come si mette insieme una squadra. La terza è dare all’agente una memoria che duri più di una finestra.

E dietro tutte e tre si nasconde la domanda più scomoda del campo, quella che nessuno ha davvero chiuso: come si fa a sapere se un agente funziona davvero? Già dare un voto a un modello che si limita a rispondere è difficile, specie quando la risposta è libera e non esiste una soluzione unica con cui confrontarla (ci torna la sezione su LLMOps). Dare un voto a un agente che agisce, in più passi, in un ambiente che cambia sotto i suoi piedi, è molto più difficile ancora.

Pianificare: scomporre il problema#

ReAct ragiona e agisce un passo alla volta: decide la mossa, la esegue, guarda com’è andata, decide la prossima. È flessibile, ma su un compito lungo rischia di procedere a naso, senza una visione d’insieme, e di infilarsi in vicoli ciechi. L’alternativa è ribaltare l’ordine: prima scomporre il problema in un piano di sotto-compiti, poi eseguirli. Questo modo di procedere si chiama plan-and-execute, «pianifica ed esegui».

Ci sono due modi di fare la spesa. Il primo è entrare al supermercato e decidere scaffale per scaffale, guardandoti intorno: prendo la pasta, ah già mi serviva anche il latte, torno indietro… Funziona per due o tre cose, ma per una spesa grossa giri a vuoto, dimentichi metà roba e ti ritrovi tre volte davanti al banco frigo. L’altro modo è scrivere la lista prima di entrare: la dividi per reparto, e dentro segui l’ordine senza pensarci. Fai meno strada, non dimentichi niente.

Un agente che pianifica fa la seconda cosa. Prima di toccare qualunque strumento, si ferma e scrive il piano: «per sistemare questo errore devo (1) trovare dove nasce l’errore, (2) capire la causa, (3) scrivere la correzione, (4) far girare i test». Poi esegue i punti uno per uno. Il vantaggio è la visione d’insieme; il rischio è che la lista, scritta al buio prima di entrare, non tenga conto di una sorpresa (lo scaffale vuoto, il reparto spostato) e vada rifatta a metà strada.

ReAct intreccia ragionamento e azione a ogni passo: la policy sceglie \(a_t\) dal contesto accumulato \(s_t\), che contiene i pensieri precedenti (compreso un eventuale piano scritto in uno di essi), ma nessun passo è vincolato da un piano fissato in anticipo. È reattivo (si adatta bene alle sorprese) ma su orizzonti lunghi può perdere coerenza, ripetere azioni o divagare. Il pattern plan-and-execute separa due ruoli: un pianificatore produce in un colpo solo una sequenza di sotto-obiettivi \(g_1, \dots, g_k\) che decompongono il compito, e un esecutore li affronta uno per uno (spesso con un mini-loop ReAct dentro ciascuno). Il piano dà struttura, coerenza globale e spesso meno chiamate al modello per il ragionamento di alto livello. ReWOO [XPL+23] ne dà una misura: scrive il piano una volta sola, con segnaposto al posto delle osservazioni ancora da ottenere (il passo 2 usa «il risultato del passo 1» senza conoscerlo), fa eseguire gli strumenti e chiama il modello un’ultima volta per comporre la risposta. Su mille domande di HotpotQA, con gpt-3.5-turbo (2023), consuma circa duemila token per domanda contro i quasi diecimila di un ciclo intercalato alla ReAct, cinque volte meno, con un’accuratezza di poco più alta (42,4 contro 40,8), mentre la corrispondenza esatta scende anzi di quasi due punti. Su altri compiti dello stesso articolo il quadro cambia: su TriviaQA ReWOO batte ReAct più nettamente (66,6 contro 59,4), su GSM8K lo pareggia (62,4 contro 62,0), e lì la semplice catena di pensiero fa meglio di entrambi (67,4). Il risparmio viene dal non rileggere a ogni passo prompt e cronologia; il prezzo è che il piano non vede le osservazioni mentre le raccoglie, e un’osservazione inattesa la paga tutta il re-planning.

Il compromesso è netto e va dichiarato. Pianificare in anticipo conviene quando il compito è decomponibile e l’ambiente prevedibile: il piano regge fino in fondo. Ma un piano rigido non sa reagire a ciò che non aveva previsto (un test che rivela un secondo bug, un file che non esiste) e allora serve una fase di re-planning: quando un sotto-obiettivo fallisce, si torna dal pianificatore e si aggiorna la lista. È lo stesso spendere calcolo mentre si risponde incontrato con i Transformer, ma speso prima di agire anziché durante: la pianificazione è ragionamento su come muoversi, scritto in anticipo. Nessuno dei due estremi vince sempre; i sistemi robusti mescolano: un piano di massima, rivisto quando la realtà lo smentisce.

Più agenti che collaborano#

Finora un agente, un modello. Ma se un compito ha nature diverse (pianificare, scrivere codice, criticarlo), perché affidarlo a un solo generalista? Da qui l’idea dei sistemi multi-agente: più agenti, ciascuno con un ruolo specializzato, che si passano il lavoro e conversano tra loro. In questa forma gli agenti sono modelli di linguaggio con istruzioni diverse; l’idea di molti agenti che decidono insieme è più antica degli LLM, e la racconta il capitolo sui sistemi multi-agente.

Uno schema gerarchico su tre livelli: in alto un agente orchestratore, che divide e sintetizza, ed è collegato da tre linee, etichettate «delega», ad altrettanti esecutori disposti sotto di lui; ciascuno ha il proprio mestiere, la ricerca sul web, l'interrogazione di un database, la lettura di documenti. Dai tre esecutori scendono tre linee tratteggiate, etichettate «risultati», che convergono in un unico riquadro in basso: la risposta unica. Uno schema gerarchico su tre livelli: in alto un agente orchestratore, che divide e sintetizza, ed è collegato da tre linee, etichettate «delega», ad altrettanti esecutori disposti sotto di lui; ciascuno ha il proprio mestiere, la ricerca sul web, l'interrogazione di un database, la lettura di documenti. Dai tre esecutori scendono tre linee tratteggiate, etichettate «risultati», che convergono in un unico riquadro in basso: la risposta unica.

Fig. 20.12 Uno che divide, l’orchestratore, e tre che eseguono (nel disegno sono etichettati worker, che è il termine inglese per gli esecutori). I tre risultati si ricompongono in una risposta sola. La specializzazione non sta nel modello, che può essere lo stesso per tutti: sta nelle istruzioni e negli strumenti che ciascun ruolo riceve.#

La Fig. 20.12 aiuta a fare una precisazione: i quattro agenti del disegno possono essere lo stesso identico modello, interpellato quattro volte con quattro prompt diversi. «Multi-agente» descrive come è organizzato il lavoro, non quanti modelli diversi ci sono sotto.

Nel disegno i ruoli sono divisi per mestiere, cioè per lo strumento che ciascuno ha in mano: uno cerca sul web, uno interroga un archivio di dati, uno legge documenti. Ma si possono dividere anche per momento del lavoro, e questa seconda divisione tornerà spesso: un pianificatore scompone il compito, un esecutore lo svolge, un critico rilegge il risultato e segnala gli errori, e il giro ricomincia finché il critico è soddisfatto.

È la differenza tra un artigiano solitario e una piccola bottega. Da solo, fai tutto tu: progetti, costruisci, controlli il tuo stesso lavoro, e proprio perché è il tuo, i difetti tendi a non vederli. In una bottega ci sono ruoli: uno disegna il progetto, uno lo realizza, un terzo (il collaudatore) lo prova e dice cosa non va. Il collaudatore non ha costruito niente, e proprio per questo nota lo scricchiolio che l’artigiano innamorato del proprio lavoro ignorava.

Con gli agenti funziona uguale. Invece di un modello che fa e si giudica da solo, se ne mettono in fila alcuni con compiti diversi, che si scrivono l’un l’altro come colleghi in chat: «ecco il piano», «ecco il codice», «ho provato, il test 3 non passa, correggi qui». La specializzazione aiuta: un critico dedicato pesca errori che l’esecutore non vedeva. Il guaio è che spesso manca: nelle botteghe vere il posto del collaudatore è il primo a restare vuoto, e il lavoro esce lo stesso, senza che nessuno l’abbia provato.

Ma attenzione: più teste vuol dire anche più stipendi. Ogni volta che un agente parla, qualcuno da qualche parte fa lavorare un modello, e quel lavoro si paga a consumo: quattro agenti che si scrivono a vicenda per dieci giri fanno quaranta interventi, ma costano molto più di quaranta chiamate isolate: ogni volta che uno prende la parola rilegge da capo tutto quello che gli altri hanno già detto. Il primo intervento non rilegge niente, il quarantesimo rilegge trentanove messaggi, e sommate le riletture fanno settecentottanta messaggi letti per quaranta scritti. Quella rilettura si paga come il resto. E ci sono più modi di litigare o fraintendersi.

Non sempre la bottega batte il buon artigiano. Rende quando il lavoro si divide in pezzi che si possono fare in parallelo, come dieci ricerche in dieci biblioteche diverse; quando ogni pezzo dipende da quello prima, come in un mobile da montare in ordine, l’artigiano da solo fa quasi lo stesso e spende meno.

Un framework che ha reso concreto questo schema è AutoGen [WBZ+24], che modella un sistema multi-agente come una conversazione tra agenti conversabili: ognuno ha un ruolo e un prompt di sistema che lo definisce (assistente, esecutore di codice, revisore, proxy umano), e l’orchestrazione è il protocollo con cui si scambiano messaggi (sequenziale, a turni, o con un agente «manager» che decide chi parla dopo). Lo stesso motore linguistico, istanziato con istruzioni diverse, diventa una squadra.

Aggiungere agenti non è gratis e non è sempre meglio. Ogni agente in più è contesto in più da riempire e generazioni in più da pagare, e il costo cresce con il numero di partecipanti e con i giri di conversazione. Su una conversazione condivisa di \(T\) messaggi, dove ciascuno rilegge tutti quelli prima, i messaggi letti sono \(\sum_{t=0}^{T-1} t = T(T-1)/2\), quadratici nel numero di quelli scritti (\(780\) per \(T = 40\)); moltiplicati per la lunghezza media di un messaggio danno i token in ingresso, e la cache dei prefissi ne abbassa il prezzo, non la crescita.

Il guadagno, poi, dipende dal compito. Anthropic riporta (giugno 2025), per un proprio sistema di ricerca con un agente guida e sotto-agenti in parallelo, un risultato superiore del 90,2% a quello di un agente solo su una valutazione interna, a un costo di circa quindici volte i token di una conversazione (un agente solo ne usa circa quattro volte); e indica le condizioni in cui conviene: sotto-compiti parallelizzabili, informazione che non sta in una finestra, molti strumenti, mentre nella programmazione, con meno parti davvero indipendenti, il vantaggio è minore [HZL+25]. È la valutazione interna di un fornitore, non una misura indipendente.

E moltiplicare gli agenti moltiplica i modi di sbagliare: un fraintendimento che si propaga, due agenti che entrano in un ping-pong senza convergere, l’errore di uno che diventa la premessa dell’altro. Cemri e colleghi [CPY+25] ricavano da oltre centocinquanta tracce lette da esperti una tassonomia di quattordici modi di fallire, in tre famiglie, e la applicano poi, con un annotatore automatico validato sugli umani, a 1.642 tracce di sette framework: il progetto del sistema (ruoli e specifiche ambigue, il 44,2% dei fallimenti annotati), il disallineamento fra gli agenti (32,3%) e la verifica del risultato (23,5%), cioè nessuno che controlli se il lavoro è fatto. Nelle loro prove di intervento, con lo stesso modello, su trentadue compiti di programmazione affidati alla squadra simulata di ChatDev, il 25% di riuscite di partenza sale al 34,4% ridando l’ultima parola al ruolo a cui spetta, e al 40,6% riorganizzando la squadra con una verifica dell’obiettivo; ma nessuna delle due correzioni basta da sola, e i fallimenti nascono dall’organizzazione del sistema più che dal singolo agente.

Sui banchi di prova correnti il vantaggio dei sistemi multi-agente su un agente solo è spesso modesto: è la premessa da cui parte l’articolo di Cemri e colleghi, non una loro misura, e va verificato caso per caso. E i guasti stanno più nell’organizzazione che nel singolo agente: ruoli descritti male, agenti che vanno per conto proprio, e nessuno incaricato di controllare se il risultato finale sta in piedi. La regola prudente viene da sé: un ruolo si aggiunge quando risolve un problema che con un agente solo restava aperto, non per il gusto della squadra.

I meccanismi con cui una squadra di agenti si organizza davvero hanno un capitolo tutto loro più avanti, i sistemi multi-agente: là si vedrà quanto costa il coordinamento e quando lo ripaga, chi conviene che parli con chi, come ci si mette d’accordo quando i partecipanti non sono affidabili, e come si può imparare a coordinarsi invece di essere programmati per farlo.

La memoria che dura#

La sezione sul contesto ha lasciato aperta una domanda: come si sceglie che cosa ripescare dalla memoria esterna e riportare nella finestra? Una risposta concreta, fra le altre, viene da un piccolo esperimento del 2023 che sembra un videogioco: gli agenti generativi di Park e colleghi [POBrienC+23], che nel titolo originale si chiamano generative agents, e la loro risposta non è una regola sola ma tre criteri messi insieme.

Venticinque agenti abitano un paesino simulato, Smallville, ispirato al videogioco The Sims: si svegliano, fanno colazione, vanno al lavoro, si incontrano, chiacchierano. Nessuno ha scritto la loro giornata a mano: ciascuno è guidato da un modello di linguaggio (ChatGPT, nella versione gpt-3.5-turbo) che decide cosa fare in base a ciò che ricorda, e l’esperimento non chiede loro di svolgere compiti, ma di comportarsi in modo credibile. Il risultato più citato è un comportamento emerso, cioè venuto fuori da sé. Gli autori danno a un solo agente, Isabella, l’intenzione di organizzare una festa di San Valentino; il resto nessuno l’aveva programmato. L’invito si propaga di bocca in bocca (alla fine lo conoscono dodici agenti oltre a lei), gli agenti si invitano a vicenda e il giorno della festa cinque dei dodici invitati si presentano al caffè, senza che nessuno avesse scritto una riga per farli coordinare. La domanda interessante non è «è vivo?» (non lo è), ma come faccia un modello a comportarsi in modo coerente su un arco di tempo così lungo.

Il segreto è un diario. Ogni agente annota in un quaderno, in frasi normali, tutto ciò che gli capita: «ho fatto colazione al bar», «Isabella mi ha detto che organizza una festa». Il quaderno cresce a dismisura (migliaia di righe) e rileggerlo tutto ogni volta è impossibile. Serve quindi un bibliotecario che, quando l’agente deve decidere qualcosa, gli tiri fuori dal quaderno solo le pagine che contano adesso.

E come sceglie quali pagine? Con tre criteri di buon senso. Quanto è recente il ricordo (ciò che è successo un’ora fa pesa più di ieri, e una pagina appena ripescata resta in cima); quanto è importante (una festa conta più di una colazione qualsiasi); e quanto c’entra con la situazione di adesso (se sto pensando alla festa, ripesco i ricordi sulla festa). Il bibliotecario non guarda un criterio solo: dà tre voti e porta le pagine con il totale più alto. Un appunto di una settimana fa, importante e in tema, batte così la nota di stamattina che non c’entra niente. Quando si è accumulata abbastanza roba importante, due o tre volte al giorno, l’agente si ferma e riflette: rilegge gli ultimi cento appunti e ne ricava una conclusione più alta («a Isabella piace organizzare eventi») che riscrive nel quaderno come un nuovo ricordo. Da questi pensieri più maturi nascono i suoi piani. Ricordare, ripescare, riflettere, pianificare: è così che un mucchio di appunti diventa un comportamento coerente.

L’architettura ha tre pezzi. Il memory stream è un registro append-only di osservazioni in linguaggio naturale, ciascuna con un timestamp. Il recupero seleziona, a ogni decisione, le memorie rilevanti con un punteggio che combina tre segnali normalizzati:

\[ \text{punteggio}(m) = \alpha_{\text{rec}}\,\text{recency}(m) + \alpha_{\text{imp}}\,\text{importance}(m) + \alpha_{\text{rel}}\,\text{relevance}(m, q), \]

dove \(m\) è una memoria e \(q\) la situazione corrente: \(\text{recency}(m)\) decade esponenzialmente con il tempo trascorso dall’ultimo accesso, \(\text{importance}(m)\) è un voto di salienza da 1 a 10 che il modello stesso assegna alla memoria quando la scrive, e che la normalizzazione riporta in scala con gli altri due, e \(\text{relevance}(m, q)\) è la similarità tra gli embedding della memoria e della query. Nel lavoro originale \(\text{recency}(m) = 0{,}995^{h}\), con \(h\) le ore di gioco dall’ultimo accesso, i tre punteggi sono riportati in \([0, 1]\) con una normalizzazione min-max prima della somma, e i pesi \(\alpha\) valgono tutti 1: tre criteri sommati, non uno solo. Sono i parametri di una simulazione di venticinque agenti, non costanti universali.

Il terzo pezzo è la riflessione: quando la somma delle salienze degli eventi recenti supera una soglia (150 nell’articolo, il che accadeva due o tre volte per giorno simulato), l’agente sintetizza dalle cento memorie più recenti alcune inferenze di livello più alto (proposizioni astratte come «Klaus è appassionato di ricerca») e le riscrive nel memory stream come nuove memorie, recuperabili a loro volta. Si forma così un albero: osservazioni grezze in basso, riflessioni via via più astratte in alto. La pianificazione traduce infine queste sintesi in piani giornalieri, decomposti dal grossolano al fine. Il punto architetturale generale, oltre l’esperimento: la memoria a lungo termine di un agente non è «tenere tutto nel contesto», ma memorizzare fuori, recuperare il pertinente, e ogni tanto ricomprimere in astrazioni (lo stesso schema recupera-e-condensa che governa il RAG e il context engineering).

Valutare un agente: il problema difficile#

Arriviamo alla domanda scomoda, e conviene partire dal caso più semplice per capire quanto questo sia difficile. Si prenda un classificatore che deve dire se una foto ritrae un gatto o un cane: per valutarlo si confronta la sua risposta con l’etichetta che una persona ha già messo alla foto, e si contano gli errori. Le cautele non mancano (classi sbilanciate, una soglia da scegliere, probabilità da calibrare, come mostra la sezione sulle metriche), ma la risposta giusta esiste, è una sola, ed è scritta lì accanto.

Con un agente non torna niente di tutto questo, per tre ragioni che si sommano. Primo: spesso non esiste una sola risposta giusta; a un compito come «sistema questo errore» corrispondono molte soluzioni valide. Secondo: il compito è fatto di molti passi, e un agente può arrivare al risultato giusto per la strada sbagliata, o fallire dopo aver fatto quasi tutto bene. Terzo: l’ambiente cambia sotto i suoi piedi (una ricerca sul web dà risultati diversi oggi e domani) e quindi la stessa prova, ripetuta, non è mai identica a se stessa.

Servono allora quattro misure diverse, e nessuna da sola basta.

Il tasso di successo è la più ovvia: su cento compiti, quanti ne ha portati a termine? È un sì o no, e ignora tutto il resto. La traiettoria è la strada che ha fatto per arrivarci: quali mosse, quante inutili, quanti giri a vuoto. Il costo è quel che si è consumato per strada, e si conta in token (i pezzetti in cui il modello taglia il testo), in chiamate agli strumenti e in secondi di attesa; quest’ultima voce si chiama latenza, ed è il tempo che l’utente passa a guardare lo schermo. E il costo entra nel giudizio: un agente che risolve il compito consumando diecimila token e trenta passi non è «riuscito» allo stesso modo di uno che lo chiude in quattro.

La quarta è la dispersione, e viene diritta dalla terza difficoltà di prima. Se la stessa prova ripetuta non dà mai lo stesso esito, un numero solo non vuol dire niente: bisogna rifare ogni compito più volte e riportare di quanto i risultati oscillano da una ripetizione all’altra. Un agente che riesce tre volte su cinque, provato una volta sola e riuscito, non si distingue con nessuna sicurezza da uno che riesce sempre.

Come giudichi uno chef? Non dal singolo piatto assaggiato di sfuggita. Lo giudichi dal servizio di un’intera serata: gli ordini sono usciti giusti? quanti sono tornati indietro? il tavolo otto ha aspettato un’ora?

Con un agente è lo stesso. Non basta guardare la risposta finale di una prova: gli si danno tanti compiti e si conta la frazione portata a termine davvero (il tasso di successo). Ma un buon capocuoco guarda anche la cucina, non solo i piatti in uscita: se un piatto è venuto bene per puro caso, in mezzo a un caos di padelle bruciate, non è un successo su cui contare domani. Per questo si ispeziona anche come l’agente ci è arrivato (la traiettoria) e quanto è costato in tempo e fatica. Risultato giusto, strada pulita e conto ragionevole non sono la stessa cosa, e si guardano uno per uno.

Guardare la cucina non vuol dire pretendere che ogni gesto avvicini il piatto. Il cuoco che butta la salsa impazzita e la rifà da capo ha fatto la cosa giusta, anche se sembra un passo indietro. Il segnale brutto è un altro: la stessa salsa rimestata per dieci minuti, o tre viaggi in dispensa per la stessa cosa.

Più passaggi ha un piatto, più diventa un affare rischioso: se a ogni passo c’è anche solo un piccolo rischio di sbagliare, una ricetta di dieci mosse si salva per intero solo una volta su tre. Qualche intoppo si recupera, come la salsa rifatta. E le serate storte tendono a esserlo dall’inizio, per un fornitore che non è arrivato, più che per un inciampo a caso piatto per piatto: allora le serate perfette sono un po” più di quante ne prometta il conto, e quelle disastrose pure. Ma l’ultimo passaggio pesa quanto il primo, e chi rovescia il vassoio sulla soglia della sala aveva fatto tutto bene fino a lì.

E una serata sola non dice niente. La stessa sera ripetuta non esce mai uguale: fornitori diversi, sala più piena, un aiuto in meno. Per questo si torna, e accanto al voto si scrive di quanto le serate ballano fra loro: un cuoco che azzecca tre sere su cinque, giudicato da una sola serata riuscita, non si distingue da uno che non sbaglia mai.

Il tasso di successo (success rate) è la frazione di compiti risolti su un insieme di prove: la metrica principe, ma grossolana, perché è un sì/no che ignora come si è arrivati e nasconde i successi fortunati. La valutazione della traiettoria (trajectory evaluation) guarda la sequenza di azioni: erano quelle giuste? quante non hanno prodotto informazione nuova? e quando l’agente è finito in un vicolo cieco, se n’è accorto e ne è uscito? Va evitata la tentazione di chiedere che ogni passo avvicini all’obiettivo: sarebbe un criterio di progresso monotono, e punirebbe esattamente le mosse mature di un agente, cioè il re-planning quando un sotto-obiettivo fallisce, il tornare indietro dai rami che non promettono del Tree of Thoughts, il tentativo fallito che Reflexion usa per orientare il successivo. Il fallimento tipico di un loop è il passo che si ripete, più che quello che allontana. Un agente può poi azzeccare la risposta per la strada sbagliata (giusto per caso) o sbagliarla dopo una traiettoria impeccabile (l’ultimo passo va storto): guardare solo il risultato finale confonde questi casi, e per capire davvero dove un agente fallisce serve la traccia.

Sotto tutto c’è la fragilità dei compiti lunghi, già incontrata: l’accumulo di errori. Un modellino illustrativo: se a ogni passo la probabilità di sbagliare la mossa è \(p\), e i passi sono indipendenti, la probabilità di una traiettoria di \(n\) passi senza un solo errore è

\[ P(\text{traiettoria senza errori}) = (1 - p)^n, \]

che precipita al crescere di \(n\): con \(p = 0{,}1\), dieci passi lasciano appena \((0{,}9)^{10} \approx 0{,}35\). Le due ipotesi vanno dichiarate. I passi reali non sono indipendenti. Se una difficoltà latente \(Z\) li rende correlati (un compito difficile fa sbagliare più passi insieme) e, dato \(Z\), ogni passo sbaglia con probabilità \(p_Z\),

\[ P(\text{nessun errore}) = \mathbb{E}\big[(1-p_Z)^n\big] \;\ge\; \big(1-\mathbb{E}[p_Z]\big)^n \]

per la disuguaglianza di Jensen, perché \((1-p)^n\) è convessa in \(p\): a parità di errore medio per passo, la correlazione alza la quota di traiettorie senza errori, e ne lascia altre piene di errori. E non ogni errore è fatale: la riflessione e il re-planning esistono proprio per recuperarne una parte, e allora il tasso di successo può superare questa cifra. Ma la morale del modellino regge: non basta essere bravi a un passo, bisogna esserlo per molti di fila, ed è la ragione strutturale per cui i compiti lunghi restano difficili. Alla misura del cosa si affianca poi quella del quanto: token consumati, latenza, numero di chiamate a strumenti; perché un agente sostenibile non è solo quello che riesce, ma quello che riesce a un costo accettabile. E ognuna di queste misure va presa più volte sullo stesso compito, perché l’ambiente non sta fermo: accanto alla media si riporta la dispersione fra le ripetizioni, senza la quale non si sa se una differenza fra due agenti esista davvero. Le ripetizioni si riassumono con due stimatori che rispondono a domande opposte. Se su un compito si fanno \(n\) tentativi indipendenti (qui \(n\) conta i tentativi, non i passi della traiettoria) e \(c\) riescono, la probabilità che almeno uno fra \(k \le n\) tentativi riesca si stima senza distorsione con

\[ \text{pass@}k = \mathbb{E}_{\text{compiti}}\!\left[1 - \binom{n-c}{k}\Big/\binom{n}{k}\right] \]

[CTJ+21], e dice quanto rende un verificatore perfetto che sceglie fra \(k\) proposte (con un verificatore vero è un tetto); la probabilità che riescano tutti e \(k\) si stima con

\[ \text{pass}^k = \mathbb{E}_{\text{compiti}}\!\left[\binom{c}{k}\Big/\binom{n}{k}\right] \]

[YSRN24], e dice l’affidabilità che serve quando ogni tentativo arriva a un utente. Con un tasso vero di \(0{,}6\) e tentativi indipendenti, \(\text{pass@}5 \approx 0{,}99\) e \(\text{pass}^5 \approx 0{,}08\): lo stesso agente è quasi infallibile nel primo senso e quasi inservibile nel secondo. I coefficienti binomiali servono perché la stima ingenua \(1-(1-c/n)^k\), concava in \(c/n\), è distorta verso il basso.

Un frammento di codice rende concreto perché il solo tasso di successo non basta. Immaginiamo di aver fatto girare un agente su un pugno di compiti e di aver registrato, per ciascuno, l’esito, i passi, i token e se la traiettoria era «pulita». Ogni singola prova, cioè una volta che gli si dà un compito e lo si lascia lavorare finché non finisce, la chiameremo un episodio, come si fa parlando di MDP e funzioni valore.

import math

# ogni episodio: esito, passi, token consumati, traiettoria valida?
# (valida: nessuna ricerca ripetuta e nessun giro a vuoto, giudicato a mano)
episodi = [
    {"successo": True,  "passi": 4,  "token": 2100, "traiettoria_ok": True},
    {"successo": True,  "passi": 9,  "token": 5400, "traiettoria_ok": False},
    {"successo": False, "passi": 12, "token": 8000, "traiettoria_ok": False},
    {"successo": True,  "passi": 5,  "token": 2600, "traiettoria_ok": True},
    {"successo": False, "passi": 6,  "token": 3100, "traiettoria_ok": True},
]

n = len(episodi)
successi = [e for e in episodi if e["successo"]]
tasso_successo = len(successi) / n
# fra i compiti riusciti, quanti per una strada "pulita"?
traiettorie_ok = sum(e["traiettoria_ok"] for e in successi) / len(successi)
token_medi = sum(e["token"] for e in episodi) / n

print(f"episodi: {n}")
print(f"tasso di successo: {tasso_successo:.0%}")
print(f"successi con traiettoria valida: {traiettorie_ok:.0%}")
print(f"token medi per episodio: {token_medi:.0f}")

# quanto vale davvero quel 60%? Fra quali due valori puo' stare il vero tasso
# di successo, viste cosi' poche prove? Si usa l'intervallo di Wilson, che con
# pochi episodi non esce da [0, 1] come farebbe la formula ingenua; la sua
# copertura media resta vicina al 95%, ma non in ogni punto.
# z = 1.96 e' il numero che corrisponde al "95 per cento di fiducia": lo si
# legge sulle tavole della distribuzione normale e non si ricava a mano.
z = 1.96
p_succ = tasso_successo          # attenzione: qui e' il tasso di SUCCESSO,
                                 # non la probabilita' di sbagliare un passo
centro = (p_succ + z**2 / (2*n)) / (1 + z**2 / n)
raggio = z * math.sqrt(p_succ*(1-p_succ)/n + z**2 / (4*n**2)) / (1 + z**2 / n)
print(f"intervallo al 95%: da {centro - raggio:.0%} a {centro + raggio:.0%}")

# e quanti episodi servirebbero perche' l'incertezza scenda a 10 o a 5 punti
# percentuali? Qui torna comoda la formula ingenua, che per dimensionare un
# esperimento basta: n = z^2 * p_succ * (1-p_succ) / errore^2, con l'errore
# al quadrato al denominatore.
for errore in (0.10, 0.05):
    n_serve = z**2 * p_succ * (1 - p_succ) / errore**2
    print(f"episodi per +/- {errore * 100:.0f} punti: {n_serve:.0f}")
episodi: 5
tasso di successo: 60%
successi con traiettoria valida: 67%
token medi per episodio: 4240
intervallo al 95%: da 23% a 88%
episodi per +/- 10 punti: 92
episodi per +/- 5 punti: 369

I numeri raccontano più del solo «60%». Un compito è riuscito con una traiettoria sporca (nove passi, con una ricerca ripetuta e un giro a vuoto): conta come successo, ma non è un comportamento su cui fare affidamento. E un fallimento è arrivato dopo una traiettoria valida: l’agente ha fatto le mosse giuste ed è inciampato all’ultimo; un caso ben diverso da chi ha sbagliato tutto. Il tasso di successo da solo appiattisce queste differenze; costo e traiettoria le fanno riemergere. Che una traiettoria sia valida, qui, lo dice una colonna scritta a mano; in un sistema vero lo decide una regola dichiarata prima (nessuna azione ripetuta senza un’osservazione nuova, per esempio) o un giudice, umano o automatico, che legge la traccia.

Detto questo, il primo di quei numeri va guardato con sospetto, ed è il difetto che il codice stesso smaschera calcolandolo nelle ultime righe: cinque episodi non misurano niente. Prova cinque volte, e il caso da solo può farti sembrare bravo o scarso, senza che ci sia modo di distinguere le due cose.

Il conto che lo dice si chiama intervallo di confidenza. Si prende il risultato osservato e ci si chiede fra quali due valori possa stare davvero quello vero, tenuto conto di quanto poche sono le prove. «Al 95%» è una proprietà del procedimento, non del singolo intervallo: se si rifacesse cento volte l’esperimento, rifacendo ogni volta il conto, circa novantacinque degli intervalli ottenuti conterrebbero il valore vero, e di quello che si ha in mano non si sa se sia fra i novantacinque. La formula usata nel codice si chiama intervallo di Wilson, ed è una delle più usate con poche prove: non esce mai da \([0, 1]\), e in media mantiene la promessa del 95%, anche se per certi valori veri del tasso la manca di qualche punto. Chi vuole una garanzia piena usa l’intervallo esatto di Clopper e Pearson, che è più largo.

Su tre successi su cinque quell’intervallo va dal 23% all’88%: quel «60%» è compatibile sia con un agente che fallisce tre volte su quattro, sia con uno che riesce quasi sempre. Non stiamo misurando l’agente, stiamo misurando il caso.

E per stringerlo? Le ultime due righe dell’uscita lo dicono: per un margine di dieci punti percentuali servono 92 episodi, per un margine di cinque (sapere che il tasso di successo sta fra il 55% e il 65%) ne servono 369, non cinque. Dimezzare il margine costa quattro volte le prove, perché nella formula il margine sta al denominatore elevato al quadrato, ed è una cosa da sapere prima di progettare un esperimento. È la ragione per cui un banco di prova dovrebbe riportare l’incertezza accanto al numero; di solito non lo fa (SWE-bench, per esempio, pubblica una percentuale per sistema), e un passo nella direzione giusta è τ-bench, che ripete ogni compito più volte e ne riporta il \(\text{pass}^k\) [YSRN24].

Quei banchi di prova (in inglese benchmark) misurano soprattutto il tasso di successo, e ciascuno un pezzo diverso del mestiere. AgentBench [LYZ+24] mette i modelli alla prova come agenti in otto ambienti diversi (un sistema operativo da manovrare, un archivio di dati da interrogare, una casa simulata, un negozio online da navigare, e altri) e misura quanti compiti ciascuno porta a termine. WebArena dà 812 compiti su siti web ricostruiti in locale, GAIA 466 domande che chiedono di navigare e usare strumenti per arrivare a una risposta breve da indovinare esatta, OSWorld 369 compiti su un computer vero, ciascuno con il suo programma di verifica, e τ-bench dei dialoghi con un cliente simulato, dentro le regole di un’azienda. Alla pubblicazione, fra il 2023 e il 2024, la distanza dagli esseri umani era larga dappertutto: il miglior agente risolveva il 14% dei compiti di WebArena contro il 78% delle persone, il 15% delle domande di GAIA contro il 92%, il 12% dei compiti di OSWorld contro il 72%. Sono numeri di quelle date: le classifiche invecchiano, e quelle correnti si leggono alla fonte.

SWE-bench [JYW+24] alza ancora l’asticella: le sue 2.294 segnalazioni di errore vere, tratte da dodici progetti Python, si risolvono soltanto producendo una modifica al codice che fa passare tutti i test del progetto. Nell’articolo che lo presentava il migliore dei modelli provati ne risolveva meno del 2%.

La lezione, però, non è quella cifra, che un sistema nuovo può migliorare da un mese all’altro. È che un banco di prova va messo alla prova anche lui. Nel 2024 Aleithan e colleghi [AXM+24] hanno riletto a mano i 251 successi del sistema che allora guidava la classifica, SWE-Agent con GPT-4, e hanno trovato che circa uno su tre (\(32{,}67\%\)) non era stato risolto ma letto, perché la soluzione era già scritta nella segnalazione o nei commenti sotto; e che un altro \(31{,}08\%\) passava grazie a test troppo deboli per bocciare alcunché.

Tolte le segnalazioni difettose, quel sistema scendeva dal \(12{,}47\%\) al \(3{,}97\%\): il numero pubblicato era più di tre volte quello che resta. Non era la prima volta che quei difetti venivano notati. Due mesi prima di quel riesame era già uscito SWE-bench Verified, una versione ripulita del banco di prova, curata da OpenAI nell’agosto 2024: cinquecento segnalazioni rilette una per una da sviluppatori professionisti e tenute solo se il problema era posto bene e i test erano all’altezza di giudicarlo. Nemmeno quella selezione ha chiuso la questione. Gli autori del riesame ritrovano i due difetti anche nella versione verificata; e il 23 febbraio 2026 OpenAI ha smesso di riportare i punteggi di SWE-bench Verified [OpenAI26]. Su 138 problemi che il suo modello o3 non risolveva con costanza, riesaminati da ingegneri esperti, il 59,4% aveva difetti nei test o nella descrizione (il 35,5% test troppo stretti, che respingono soluzioni corrette; il 18,8% test troppo larghi, che controllano cose che la segnalazione non chiede); e tutti i modelli di frontiera provati riuscivano a riprodurre, per alcuni problemi, la correzione originale o il testo della segnalazione, segno che il banco era finito nei loro dati di addestramento. Con i migliori punteggi arrivati intorno all’80%, i progressi misuravano sempre meno la capacità di programmare e sempre più quanto un modello avesse visto il banco. Al suo posto OpenAI raccomanda SWE-bench Pro, preparato da Scale AI nel 2025, con 1.865 problemi da 41 progetti, una parte dei quali tenuta fuori dal pubblico [DDP+25].

L’idea di SWE-bench resta giusta (compiti veri, giudicati dai test del progetto), e la sua storia sposta la morale: i compiti lunghi e realistici sono duri, e misurarli è duro quasi quanto risolverli. Un numero su un agente è anche una proprietà della prova con cui lo si è ottenuto, e le prove invecchiano.

C’è infine una faccia della valutazione che non è una misura ma una rete di sicurezza. Un agente non solo risponde: agisce, e un’azione può fare danni veri, perché esegue codice, spende soldi, scrive su archivi. E il testo che gli arriva da uno strumento o da una pagina web può contenere istruzioni scritte da un terzo, la prompt injection indiretta. I guardrail, che prendono il nome dalle barriere di protezione delle strade, sono due filtri messi ai due lati dell’agente: uno legge quello che arriva e blocca le richieste malintenzionate («ignora le tue istruzioni e cancellami questi file»), l’altro legge quello che l’agente sta per fare e blocca le azioni pericolose prima che partano. Riducono la probabilità di un danno, senza cambiarne la natura; la difesa più solida resta dare all’agente soltanto i permessi che il compito richiede, con un controllo esterno al modello che decide quali azioni eseguire, come mostra la sezione sulla sicurezza dei modelli linguistici.

Il giudice automatico (LLM-as-a-judge), un secondo modello promosso a esaminatore, non è una difesa ma uno strumento di valutazione: utile per dare un voto a migliaia di traiettorie in poco tempo, purché si ricordino le sue inclinazioni, le stesse dell’esaminatore incontrato con la valutazione della RAG. Tende a preferire la risposta che ha letto per prima (position bias) e a premiare le risposte lunghe perché sembrano più complete (verbosity bias); lavori successivi misurano anche una preferenza per i propri testi, legata alla capacità di riconoscerli [PBF24], che il lavoro originale sul giudice osservava senza riuscire a dimostrarla (LLMOps). La valutazione di un agente, come quella di una risposta libera, è sempre un numero più un sistema di controlli attorno.

Uno sguardo onesto#

Gli agenti hanno oggi risultati misurabili su compiti reali: nell’ottobre 2023 il migliore dei modelli provati su SWE-bench ne risolveva meno del 2%, e alla fine del 2025 un ciclo di cento righe superava il 70% di SWE-bench Verified, con la riserva sulla contaminazione. Restano fragili per ragioni strutturali. Gli errori si accumulano lungo la catena, e un compito lungo li amplifica. Il conto dei passi indipendenti, però, li dava sparsi e ciascuno fatale. Un agente che ha imboccato la strada sbagliata tende invece a restarci: fra gli errori che gli autori di ReAct contano nei fallimenti c’è proprio il non riuscire a uscire da un passo ripetuto [YZY+23]. Gli errori arrivano quindi a grappoli, e a parità di errore medio questo alza la quota di traiettorie che arrivano in fondo pulite; rileggersi dopo un fallimento o rifare il piano quando salta ne recupera poi una parte. La direzione non cambia; il numero sì. Il costo, intanto, cresce con i passi, con gli agenti, con i giri di conversazione. E l’imprevedibilità che rende versatile un motore linguistico è la stessa che rende difficile garantire cosa farà: più libertà d’azione, meno controllo.

È, soprattutto, un’area giovane: più procedure provate su casi particolari che teoria, banchi di prova che invecchiano in fretta, poche certezze su cosa funzioni e perché [XCG+23]. Chi lavora con gli agenti oggi costruisce su terreno che si muove. È un motivo per starci con lucidità, non per starne alla larga: misurare più che sperare, aggiungere complessità solo quando paga, e diffidare di ogni numero troppo bello. La distanza tra un agente che sembra funzionare in una dimostrazione e uno di cui fidarsi quando lo usa la gente si misura con il tasso di successo, la traiettoria, il costo e la dispersione, su una prova di cui ci si fida.

Da ricordare

  • Su un compito grosso il ciclo passo-passo regge tanto meglio quanto più è bravo il modello che ha dentro. Dove non basta, due mosse: scrivere la lista prima di entrare (prima il piano dei sotto-compiti, poi l’esecuzione) e mettere in fila più agenti con mestieri diversi (chi progetta, chi costruisce, chi collauda). Il piano dà una visione d’insieme, ma una lista scritta al buio va rifatta quando la realtà la smentisce.

  • Più teste non sono gratis e non sono sempre meglio: ogni agente in più è lavoro da pagare e un modo in più di fraintendersi. Chi è andato a guardare come falliscono davvero questi sistemi [CPY+25] ha trovato guadagni spesso modesti, e ha trovato che si sbaglia soprattutto nell’organizzazione (ruoli scritti male, passaggi di consegne, nessuno che controlla il risultato), più che dentro il singolo agente. La squadra rende quando il lavoro si divide in pezzi da fare in parallelo. Si aggiunge un ruolo solo quando risolve un problema vero.

  • La memoria che dura è un diario tenuto fuori, da cui si ripesca solo la pagina che conta adesso. Gli agenti di Smallville [POBrienC+23] la ripescano con tre criteri sommati insieme (quanto è recente il ricordo, quanto è importante, quanto c’entra con la situazione di adesso), e quando si è accumulata abbastanza roba importante si fermano a riflettere, ricavando dagli appunti una conclusione più alta che riscrivono nel diario.

  • Dare un voto a un agente è più duro che darlo a un classificatore: non c’è una risposta unica, il compito è fatto di molti passi e l’ambiente cambia sotto i piedi. Servono il tasso di successo, uno sguardo alla strada che ha fatto (non solo al risultato) e il conto di quanto è costato in tempo e denaro. E una prova sola non basta: chi riesce tre volte su cinque, provato una volta e riuscito, non si distingue da chi riesce sempre; per stringere il margine da dieci a cinque punti le prove vanno quadruplicate.

  • I banchi di prova AgentBench [LYZ+24] (otto ambienti diversi) e SWE-bench [JYW+24] (segnalazioni di errore vere) mostrano risultati inizialmente modesti: un promemoria di onestà. Ma un benchmark misura anche se stesso: rileggendo a mano i successi del sistema che nel 2024 guidava la classifica di SWE-bench, circa uno su tre non era stato risolto, era stato copiato dalla segnalazione [AXM+24]. E nel 2026 OpenAI ha smesso di usare perfino la versione ripulita del banco, perché i suoi test respingevano soluzioni giuste e i modelli l’avevano vista durante l’addestramento.

  • Gli errori si sommano sui compiti lunghi: se sbagli una mossa su dieci e le mosse sono dieci, la probabilità di non sbagliarne nessuna è \(0{,}9^{10} \approx 0{,}35\), cioè poco più di una volta su tre. È un modellino, e nella pratica va un po’ meglio, perché gli errori tendono ad arrivare insieme, perché non tutti sono fatali e perché rileggersi e ripianificare ne recuperano una parte. Gli agenti sono promettenti ma fragili, e restano un campo giovane [XCG+23]. Misurare più che sperare.

Da ricordare

  • Nello stesso ciclo minimo, su SWE-bench Verified, il tasso di successo va dal 9% al 74% cambiando solo il modello (misure del 2025): il ciclo ReAct non si smarrisce in generale. Dove non basta, due mosse: plan-and-execute (prima un piano di sotto-compiti, poi l’esecuzione; ReWOO risparmia cinque volte i token su HotpotQA, ma non vince ovunque) e i sistemi multi-agente con ruoli specializzati (pianificatore, esecutore, critico). Pianificare dà struttura ma un piano rigido va rifatto quando la realtà lo smentisce.

  • I sistemi multi-agente (come nel framework AutoGen [WBZ+24], che li modella come una conversazione tra agenti) non sono gratis né sempre migliori: i messaggi letti crescono come \(T(T-1)/2\), i guadagni sui benchmark correnti sono spesso piccoli (è la premessa da cui parte [CPY+25], non una sua misura), e pagano soprattutto su compiti parallelizzabili (la valutazione interna di Anthropic, 2025). Delle tre famiglie di modi di fallire che quell’articolo ricava e applica a 1.642 tracce, la più frequente è il progetto del sistema (44,2%), poi il disallineamento fra agenti (32,3%) e la verifica del risultato (23,5%), e correggere ruoli o aggiungere una verifica aiuta senza bastare. Si aggiunge un ruolo solo quando risolve un problema reale.

  • La memoria a lungo termine non è tenere tutto nel contesto: i generative agents [POBrienC+23] memorizzano fuori, recuperano il pertinente combinando recenza, salienza e pertinenza normalizzate (con parametri di quella simulazione, non universali), e riflettono condensando le memorie in astrazioni (lo stesso schema recupera-e-condensa del RAG).

  • Valutare un agente è più duro che valutare un classificatore: nessuna risposta unica, compito multi-passo, ambiente che cambia. Servono tasso di successo, valutazione della traiettoria (che non deve pretendere un progresso monotono, o punirebbe il backtracking), costo/latenza e la dispersione su ripetizioni: su \(3/5\) l’intervallo di Wilson al 95% va dal 23% all’88% (copertura vicina al 95% in media, non in ogni punto), e dimezzare il margine quadruplica le prove.

  • I benchmark AgentBench [LYZ+24] (otto ambienti) e SWE-bench [JYW+24] (issue reali di GitHub) mostrano tassi di successo inizialmente modesti, ma la cifra misura anche il benchmark: dei 251 successi di SWE-Agent con GPT-4, SWE-Bench+ ne trova il \(32{,}67\%\) con la soluzione già scritta nella issue [AXM+24], e nel febbraio 2026 OpenAI ha smesso di riportare SWE-bench Verified per test difettosi e contaminazione [OpenAI26]. In produzione servono i guardrail e i permessi minimi; l’LLM-as-a-judge è uno strumento di valutazione, con i suoi bias.

  • Gli errori si accumulano sui compiti lunghi: se i passi sono indipendenti, una traiettoria senza errori ha probabilità \((1-p)^n\), dove \(p\) è la probabilità di sbagliare un passo e \(n\) il numero di passi, e precipita con \(n\) (nel modellino illustrativo; nella pratica i passi sono correlati, e per Jensen la correlazione alza la quota di traiettorie pulite, mentre riflessione e re-planning ne recuperano una parte). Gli agenti sono promettenti ma fragili, e restano un’area giovane [XCG+23]. Misurare più che sperare.

Un agente è un sistema fragile, perché ogni passo in più è un’altra occasione di sbagliare, e quanto vale dipende insieme dal modello che ha dentro e da quello che gli si mette davanti: nello stesso ciclo, cambiare soltanto il modello sposta il risultato di decine di punti, e con lo stesso modello contano le istruzioni, gli strumenti e il contesto che il ciclo, a ogni passo, gli rimette davanti. Quella seconda metà è il mestiere a cui è dedicato per intero il capitolo su prompt, contesto e loop.