Una metafora visiva che mostra il contrasto tra un sistema probabilistico caotico e un grafo deterministico strutturato che controlla un agente di IA, nel contesto della prenotazione di viaggi.
Artificial IntelligenceSoftware EngineeringMachine Learning

GPT-4 ha fallito il 99.4% delle volte — così abbiamo smesso di lasciargli prendere le decisioni

Ashutosh SinghalAshutosh Singhal16 febbraio 202613 min

Era quasi mezzanotte e stavo guardando il nostro agente prenotare un volo per la città sbagliata per la terza volta di fila.

Non una città sbagliata diversa ogni volta — la stessa città sbagliata. Delhi invece di Dehradun. L'utente aveva digitato chiaramente "Dehradun". L'LLM lo aveva interpretato correttamente nel suo ragionamento chain-of-thought. E poi, quando generava la chiamata API, sostituiva il codice aeroportuale con quello di Delhi. Con sicurezza. In silenzio. Tre volte.

Il mio co-fondatore era in chiamata. Disse: "Sa la risposta giusta. Guarda la traccia di ragionamento. Dice letteralmente Dehradun. E poi fa qualcos'altro."

Fu quella la notte in cui smisi di credere che prompt migliori ci avrebbero salvati.

Stavamo costruendo un agente di IA per la prenotazione di viaggi — quello che dialoga con i Global Distribution Systems come Amadeus e Sabre, quei backend antichi dell'era dei mainframe che alimentano ogni prenotazione aerea del pianeta. E stavamo facendo ciò che facevano tutti gli altri nel 2023: avvolgere GPT-4 in un sottile strato di orchestrazione, dargli degli strumenti e pregare.

La preghiera non funzionava.

Il numero che ha cambiato tutto

Qualche settimana dopo quell'incidente di Dehradun, mi sono imbattuto nel benchmark TravelPlanner — una rigorosa valutazione accademica che mette alla prova gli LLM nella pianificazione di itinerari di più giorni con vincoli reali: budget, trasporti, ristorazione, alloggio. Il genere di cosa che un agente di viaggio competente sbriga in venti minuti.

Il tasso di successo complessivo di GPT-4: 0.6%.

Non il 60%. Non il 6%. Zero virgola sei per cento.

L'ho letto tre volte. Poi ho tirato fuori la metodologia per assicurarmi che non avessero commesso un errore. Non l'avevano fatto. Quando chiedi al modello linguistico più avanzato del mondo di pianificare un viaggio che rispetti un budget, colleghi i voli agli hotel ai ristoranti e non violi la logica temporale di base — fallisce il 99.4% delle volte.

Quando è stato chiesto a GPT-4 di pianificare viaggi con vincoli reali, ci è riuscito lo 0.6% delle volte. Un agente neuro-simbolico che risolveva lo stesso problema ha ottenuto il 97%.

Il sistema che ha ottenuto il 97% non usava un modello più intelligente. Usava un'architettura fondamentalmente diversa — una in cui l'LLM traduceva la richiesta dell'utente in dati strutturati, e poi un solutore deterministico faceva la pianificazione vera e propria. L'LLM era il traduttore. Il codice era il cervello.

Quel benchmark non si è limitato a convalidare la nostra frustrazione. Ci ha dato un progetto.

Perché il tuo agente di IA continua a fallire?

Un'infografica che mostra il decadimento esponenziale dell'affidabilità dei passaggi LLM concatenati — il problema della "Catena di Probabilità" — con percentuali di successo concrete a 1, 5 e 10 passaggi.

Ecco la cosa di cui nessuno nella corsa all'oro degli "agenti di IA" vuole parlare: Gli LLM non ragionano. Predicono.

Quando GPT-4 "decide" di chiamare un'API di ricerca, non sta eseguendo della logica. Sta predicendo il token successivo statisticamente più probabile in base ai pattern presenti nei suoi dati di addestramento. In una conversazione, quella predizione è di solito abbastanza buona. In un flusso di lavoro API di dieci passaggi in cui ogni passaggio dipende dall'output esatto del precedente? È un disastro.

Ho iniziato a chiamare tutto questo il problema della Catena di Probabilità. Immagina che il tuo LLM svolga correttamente ogni passaggio il 90% delle volte — una stima generosa per un uso complesso degli strumenti. Ecco la matematica:

  • 1 passaggio: 90% di successo
  • 5 passaggi: ~59% di successo
  • 10 passaggi: ~34% di successo

Un flusso di lavoro di prenotazione voli — cercare, filtrare, selezionare, tariffare, raccogliere i dati del passeggero, creare il PNR, validare, pagare, emettere il biglietto — supera abitualmente i dieci passaggi. Con un successo teorico del 34%, non stai costruendo software. Stai costruendo una slot machine.

E il 34% è il tetto. Le prestazioni reali sono peggiori a causa di due fenomeni in cui continuavamo a imbatterci in produzione.

La Cascata di Allucinazioni

Il primo è ciò che io chiamo la Cascata di Allucinazioni. In un'architettura concatenata, l'output del Passaggio 2 diventa l'input del Passaggio 3. Se l'LLM commette un errore sottile all'inizio — interpretando male l'orario di arrivo di un volo come le 14:00 invece delle 2:00 — quell'errore non viene rilevato. Si propaga. L'agente prenota il check-in di un hotel per il giorno sbagliato in base all'orario allucinato. L'API del GDS non conosce l'intento dell'agente, solo il suo input, quindi elabora la richiesta con successo. L'agente vede una risposta 200 OK e rafforza il proprio errore.

Ti ritrovi con una traccia di esecuzione "riuscita" che produce un esito reale catastrofico. L'agente pensa di averci azzeccato. Il cliente si presenta all'aeroporto e scopre il contrario.

Il secondo fenomeno è la Deriva del Contesto. Man mano che l'agente procede attraverso un piano a più passaggi, la finestra di contesto si riempie di dati intermedi — risultati di ricerca, risposte API, messaggi dell'utente. Il meccanismo di attenzione del modello si diffonde sempre più sottile su tutti quei token. Al Passaggio 10, ha di fatto "dimenticato" il vincolo di budget che aveva correttamente identificato al Passaggio 2. I punteggi di attenzione, governati dalla funzione softmax, si diluiscono su troppi token irrilevanti.

L'ho visto accadere dal vivo durante una demo per un potenziale partner. L'agente aveva trovato un hotel entro il budget al Passaggio 3. Al Passaggio 8, mentre selezionava un ristorante, aveva completamente perso di vista il budget rimanente. Ha consigliato un locale che avrebbe sforato il limite di spesa dell'utente del 40%. Il partner si è girato verso di me e ha detto: "Quindi... semplicemente dimentica?"

Già. Semplicemente dimentica.

Cosa succede quando l'IA incontra un mainframe?

Per capire davvero perché avevamo bisogno di un approccio diverso, devi capire com'è lavorare con i Global Distribution Systems.

Amadeus, Sabre, Travelport — sono la spina dorsale del trasporto aereo globale. Sono stati progettati nell'era dei mainframe, e si comportano di conseguenza. Una prenotazione di volo non è una singola chiamata API. È una macchina a stati finiti con una precisa sequenza di operazioni che non possono essere riordinate, saltate o approssimate.

Ti autentichi e ottieni un token di sessione. Quel token deve essere passato in ogni intestazione successiva — se l'LLM lo "dimentica" o ne allucina uno nuovo, l'intero contesto della transazione è perso. Poi cerchi i voli, e il GDS restituisce enormi payload JSON annidati — spesso oltre 50KB — contenenti codici di base tariffaria, modelli di bagaglio, riferimenti di segmento. L'LLM deve estrarre uno specifico offerId da quel payload per procedere. Ma gli LLM sono compressori con perdita. Riassumono. Troncano. Normalizzano "servizievolmente" formati di dati che il GDS richiede siano esatti, fino al byte.

Una notte, abbiamo passato quattro ore a fare debug di un fallimento di prenotazione. L'LLM aveva "corretto" un codice di base tariffaria — cambiando una lettera minuscola in maiuscola, perché sembrava più "giusto" a un modello addestrato su testo inglese. Il GDS lo ha rifiutato con un errore criptico: ERR 1209 - SEQUENCE ERROR. Nessuna spiegazione. Nessun suggerimento. Solo un muro.

Gli LLM sono compressori con perdita. Quando trasferiscono dati tra chiamate API, "correggono automaticamente" e "normalizzano" in modi che infrangono l'integrità crittografica che i sistemi aziendali richiedono.

E quando il GDS restituisce un errore come UC (Unable to Confirm), l'LLM non ha idea di cosa fare. È addestrato a essere utile, quindi interpreta l'errore come un difetto e riprova esattamente la stessa richiesta. Ancora. E ancora. Abbiamo visto agenti bruciare migliaia di token e raggiungere i limiti di frequenza delle API, bloccati in quello che abbiamo iniziato a chiamare il "Loop della Morte" — sbattendo ripetutamente contro un muro che non riuscivano a capire.

La notte in cui abbiamo ribaltato l'architettura

Il punto di svolta è arrivato durante una discussione.

Eravamo a tre mesi dall'inizio del progetto. Il mio responsabile ingegneristico voleva continuare a migliorare i prompt — messaggi di sistema più lunghi, più esempi, istruzioni chain-of-thought. "Ci siamo quasi", continuava a dire. "Se solo strutturassimo meglio il prompt per il passaggio di creazione del PNR..."

Ho tirato fuori i nostri log. Nella settimana precedente, avevamo avuto 47 tentativi di prenotazione falliti nel nostro ambiente di test. Undici erano il Loop della Morte. Nove erano codici aeroportuali allucinati. Sei erano l'LLM che cercava di eseguire il commit di un PNR prima di aggiungere il campo obbligatorio "Received From" — un errore di sequenza che nessuna quantità di prompting sembrava risolvere, perché il modello non aveva alcun concetto intrinseco di ordinamento temporale al di là di ciò che aveva assorbito dai dati di addestramento.

"Non ci siamo quasi", dissi. "Siamo al tetto. L'architettura è il problema."

Quella settimana, abbiamo riscritto tutto. Abbiamo smesso di chiedere all'LLM di orchestrare. Abbiamo smesso di lasciargli decidere quale fosse il passaggio successivo. Abbiamo smesso di dargli in pasto risposte GDS grezze sperando che estraesse i campi giusti.

Invece, abbiamo costruito un grafo.

Per l'analisi tecnica completa di ciò che abbiamo costruito e perché, ho scritto un dettagliato paper di ricerca che approfondisce l'architettura.

Come funziona davvero l'IA neuro-simbolica?

Un diagramma di architettura etichettato che mostra la suddivisione neuro-simbolica a due strati — l'LLM come strato di traduzione/interfaccia contro il grafo deterministico come strato di esecuzione/gestione — con esempi specifici di ciò che ogni strato gestisce.

L'idea centrale è ingannevolmente semplice: il controllo del flusso non è un compito linguistico.

Decidere cosa fare dopo in un rigido processo aziendale non dovrebbe essere una questione di predizione di token. Dovrebbe essere una questione di logica condizionale. La decisione di "chiedere il pagamento" dovrebbe attivarsi solo se "il volo è selezionato" E "il prezzo è confermato". Questa è una condizione booleana, non un suggerimento probabilistico.

Abbiamo diviso il nostro sistema in due strati:

L'LLM è diventato lo strato di interfaccia — il traduttore. Analizza il linguaggio naturale dell'utente ("Voglio un volo mattutino per Dehradun, non troppo costoso") in dati strutturati: {origin: "DEL", destination: "DED", date: "2024-03-15", time_preference: "morning", budget: "economy"}. È questo ciò in cui gli LLM sono davvero eccellenti: comprendere il caotico intento umano.

Il grafo è diventato lo strato di esecuzione — il manager. Riceve quei dati strutturati ed esegue la logica di business usando codice deterministico. Nodi hard-coded. Schemi di stato tipizzati. Archi condizionali che ispezionano variabili, non sensazioni.

Abbiamo usato LangGraph per costruirlo, perché ti offre le primitive di cui hai bisogno: uno schema di stato condiviso (supportato da un database, non da una cronologia di chat), nodi che sono semplici funzioni Python e archi condizionali che instradano in base ai valori effettivi delle variabili.

L'LLM dovrebbe essere il lavoratore — estrarre dati, riassumere testo, formattare JSON — mentre il manager dovrebbe essere software hard-coded. Questa inversione del controllo è la caratteristica distintiva dei sistemi agentici robusti.

Nella nostra architettura, l'LLM letteralmente non può saltare passaggi. È fisicamente impossibile per il sistema tentare una prenotazione prima che la variabile selected_offer_id sia popolata nello stato. Non perché abbiamo detto all'LLM "non farlo" in un prompt, ma perché l'arco del grafo non si attiverà. È come cercare di guidare attraverso un muro — il codice semplicemente non lo permette.

Che aspetto ha il sistema reale?

Un diagramma di flusso dettagliato nodo per nodo della pipeline di prenotazione reale descritta nell'articolo, che mostra ogni tipo di nodo (Collector, Retriever, Summarizer, Selector, Gatekeeper, Transactor), se usa un LLM o codice, e la capacità di sospensione/ripresa al Gatekeeper.

Lascia che ti spieghi cosa succede quando qualcuno dice "Prenotami un volo da Mumbai a Londra martedì prossimo."

Innanzitutto, un nodo Collector — alimentato da un LLM — analizza quella frase in campi strutturati. Usa la generazione guidata (JSON Mode) per produrre uno schema specifico. Un validatore Python controlla se i codici aeroportuali sono reali. "London" è ambiguo — Heathrow o Gatwick? — quindi il grafo instrada verso un nodo di disambiguazione. L'LLM non tira a indovinare. Chiede.

Una volta che abbiamo criteri di ricerca convalidati, un nodo Retriever chiama l'API di Amadeus. Questo è codice puro. Nessun LLM coinvolto. La risposta torna indietro, viene messa in cache nello stato, e solo allora un nodo Summarizer — un LLM — converte i primi cinque risultati in un messaggio leggibile dall'uomo. Ma è rigorosamente vincolato: può visualizzare solo i dati presenti nel JSON in cache. Non può inventare vantaggi o modificare i prezzi.

L'utente sceglie un'opzione. Un nodo Selector risolve "il secondo" nell'hash offer_id specifico. Un nodo Gatekeeper controlla le regole di business — rientra nella policy aziendale? Il vettore è nella lista nera? Se c'è una violazione, il grafo si sospende. Persiste il suo stato nel database, invia una richiesta di approvazione a un manager e attende. Ore dopo, quando il manager clicca "Approva", il grafo ricarica lo stato esatto e riprende dal nodo di prenotazione.

Infine, un nodo Transactor esegue la sequenza di creazione del PNR — segmenti, dettagli del passeggero, tariffazione, commit — nell'ordine esatto che il GDS richiede. Se il GDS restituisce un avviso di variazione di prezzo (comune nei viaggi), il nodo si ferma e chiede all'utente di confermare. Non prenota automaticamente alla tariffa più alta.

Ogni transizione di nodo viene registrata. Ogni decisione è tracciabile. Un auditor può leggere il log di esecuzione e capire esattamente perché il sistema ha prenotato un volo specifico — non interpretando un groviglio di token, ma leggendo un record strutturato: Node:Gatekeeper | Input: Price=1200 | Rule: Policy_Limit=1000 | Output: REJECT_NEED_APPROVAL.

Ho scritto dell'intera architettura, compresi i diagrammi interattivi, nella versione interattiva del whitepaper.

Non è forse solo... normale ingegneria del software?

Me lo chiedono di continuo. "Quindi stai dicendo che dovremmo scrivere codice invece di usare l'IA? Rivoluzionario."

No. Sto dicendo che l'industria dell'IA è stata così inebriata dalla magia dei modelli linguistici da dimenticare gli ultimi sessant'anni di informatica. Macchine a stati, schemi tipizzati, ramificazione condizionale, integrità transazionale — non sono concetti superati. Sono il motivo per cui la tua banca non trasferisce accidentalmente denaro sul conto sbagliato.

L'approccio neuro-simbolico non è anti-IA. È pro-architettura. Usiamo gli LLM in modo aggressivo — per l'analisi dell'intento, per la disambiguazione, per la sintesi, per gestire il problema genuinamente difficile di capire cosa un essere umano intende quando digita qualcosa di ambiguo. Ma non lasciamo che l'LLM tocchi il volante quando l'auto è in autostrada.

Puoi costruire un chatbot che parla del lavoro da fare, oppure puoi progettare un agente che fa il lavoro. La differenza è il grafo.

C'è anche un argomento di costo che mi ha sorpreso. Gli agenti puramente LLM sono costosi — non perché l'inferenza costi molto per chiamata, ma a causa dei loop di fallimento. Quando un agente rimane bloccato a riprovare un errore GDS allucinando nuovi parametri, brucia migliaia di token prima di andare in timeout. Una singola sessione bloccata può costare $5-$10 in crediti API. I nostri gestori di errori hard-coded intercettano quei fallimenti a costo zero di token. E poiché inviamo all'LLM solo i 5 campi rilevanti da una risposta GDS di 50KB invece dell'intera cosa, riduciamo l'uso della finestra di contesto di circa il 90%.

Ma i modelli non diventeranno abbastanza bravi, prima o poi?

Forse. Sinceramente non so se GPT-6 o GPT-7 saranno abbastanza affidabili da orchestrare flussi di lavoro API di dieci passaggi senza guardrail. Ma so due cose.

Innanzitutto, anche se i modelli migliorassero drasticamente, il problema della Catena di Probabilità è matematico, non tecnologico. Se il tuo modello è affidabile al 99% per passaggio — un risultato straordinario — un flusso di lavoro di dieci passaggi fallisce comunque il 10% delle volte. Per le transazioni aziendali, è comunque inaccettabile. Il grafo elimina del tutto tutto questo perché il routing non è probabilistico.

In secondo luogo, aspettare che i modelli migliorino è un lusso che la maggior parte delle aziende non si può permettere. Hanno bisogno di agenti che funzionino ora, che siano verificabili ora, che rispettino i requisiti di trasparenza dell'EU AI Act ora. L'approccio neuro-simbolico non scommette sul futuro. Si fonda su principi ingegneristici comprovati sfruttando al contempo le migliori capacità di IA disponibili oggi.

L'architettura è il prodotto

Sono stato in abbastanza stanze con investitori e acquirenti aziendali da sapere che l'industria dell'IA sta iniziando a svegliarsi. La domanda sta passando da "Chi ha il modello più intelligente?" a "Chi ha il sistema più robusto?" Le demo che abbagliano in un intervento a una conferenza — quelle in cui un agente prenota impeccabilmente un volo in un ambiente controllato — costano poco. Ciò che è costoso, e ciò che conta, è costruire qualcosa che funzioni alla diecimillesima richiesta con la stessa affidabilità della prima.

Stiamo entrando in un'era in cui la differenziazione non sarà il modello. Sarà il grafo. Lo schema di stato. I gestori di errori. Gli archi condizionali. La noiosa, rigorosa, deterministica ingegneria del software che avvolge la magia probabilistica e le impedisce di dare fuoco alla casa.

La magia non è mai stata nel prompt. È sempre stata nell'architettura.

Related Research

Also Published On