Ho costruito un'AI per ottimizzare meglio il recupero equipaggi IROPS. Un solver CBC maturo l'ha battuta, così ho cambiato l'affermazione in legalità per costruzione e secondi, non una corsa.
AirlinesAviationOptimization

Ho costruito un'AI per battere il solver nel recupero equipaggi. Ha perso, e quella sconfitta è diventata il prodotto.

Ashutosh SinghalAshutosh Singhal5 luglio 202611 min

Il benchmark che ho costruito per vincere, e ho perso

Ho costruito la prima versione di StormCrew per battere il solver. Quella era l'intera pitch nella mia testa. Il controllo operativo delle compagnie aeree gira su motori di ottimizzazione vecchi di decenni, quindi se fossi riuscito ad addestrare qualcosa di più intelligente avrei avuto una storia degna di essere raccontata. Ci ho passato settimane. Poi ho confrontato il mio motore di recupero con CBC, un solver mixed-integer open source maturo, collaudato sul campo da prima che sapessi scrivere un for-loop, e CBC ha vinto. Non di un errore di arrotondamento.

Ricordo di aver fissato le due colonne di numeri e di aver sentito quel vuoto particolare che si prova quando l'esperimento che hai progettato per dimostrare di avere ragione dimostra invece che hai torto. Il solver era più veloce. I suoi piani erano più economici. Non ha mai restituito un programma non fattibile. La mia versione furba ha perso su tutti e tre i fronti.

Quindi ho fatto l'unica cosa onesta che mi venisse in mente. Ho cambiato l'affermazione, non i numeri.

Ho costruito l'AI per battere il solver. Il solver ha vinto. La parte interessante si è rivelata tutto ciò che quella lotta nascondeva.

Quella inversione è la spina dorsale di ciò che StormCrew è davvero diventato, e credo sia la storia più utile di quella che mi ero proposto di raccontare. Puoi eseguire tutto da solo su veriprajna.com/it/demos/stormcrew-recovery-equipaggio-irops-aereo-in-secondi-legale-per-costruzione, ma lasciami spiegare cosa mi ha fatto cambiare idea, perché il punto di svolta è il punto.

Cosa si rompe davvero quando una tempesta mette a terra un hub?

Sono tornato a leggere i post-mortem dei meltdown dopo che CBC mi aveva umiliato, e quasi nessuno dei fallimenti era «la matematica era leggermente subottimale». Le operazioni irregolari, ciò che il settore chiama IROPS, costano alle compagnie aeree circa $60B all'anno (IATA). Il disastro canonico, Southwest nel dicembre 2022, è costato circa $1.2B, con circa 16.900 cancellazioni e circa 2 milioni di passeggeri bloccati. Quando ho ricostruito come quei giorni si sfilacciano davvero, l'ottimizzatore non è mai stato il cattivo.

Si rompono invece tre cose. Il recupero è troppo lento: quando una tempesta mette a terra un hub, il re-crewing della cascata a valle è ancora in gran parte una corsa manuale di 4-12 ore (un benchmark da fonte, non un numero inventato da me). È troppo rischioso: ogni re-crew deve rispettare i limiti di servizio e di riposo FAA Part 117 e, per vettore, un CBA sindacale, e una singola violazione è un evento di conformità, non una nota a piè di pagina. Ed è troppo opaco: la cascata di voli a valle che hanno appena perso il loro equipaggio è invisibile finché quei voli non stanno già cancellando.

Quell'ultimo è ciò che gli strumenti legacy non colgono, ed è la prima cosa che ho fatto mostrare al demo. Inietta una tempesta nell'hub più trafficato e l'app evidenzia il raggio d'impatto: i voli a terra più i voli a valle a un hop che perdono l'equipaggio attraverso la rotazione. Nello scenario seed è 53 voli a rischio sulla rete.

Dashboard StormCrew dopo l'iniezione di una tempesta nell'hub DEN, con 53 voli a valle evidenziati in ambra come raggio d'impatto
Inietta la tempesta e il raggio d'impatto si illumina: 53 voli sulla rete hanno appena perso l'equipaggio, la cascata che gli strumenti legacy vedono solo dopo che le cancellazioni iniziano.

Dall'entrata in vigore della regola DOT di rimborso automatico (ott. 2024), ogni ritardo a cascata di oltre 3 ore è ora anche un colpo finanziario automatico. Quindi il costo di essere lenti, illegali o ciechi è salito proprio mentre gli strumenti restavano gli stessi. Nessuno di quei tre fallimenti si risolve con una funzione obiettivo migliore. Stavo ottimizzando l'unica cosa che andava già bene.

Perché ho smesso di cercare di battere CBC e ho iniziato ad alimentarlo?

Ho fatto pace con la sconfitta contro CBC dandogli un lavoro diverso. Invece di competere con il solver, l'ho avvolto. La pipeline è tutta codice reale, deterministico e seedato: una rete aerea sintetica e lo stato degli equipaggi, un iniettore di disruption che calcola il raggio d'impatto per raggiungibilità del grafo sulla rotazione, un generatore di duty, poi CBC come motore che sceglie il piano, poi un confronto shadow contro il non fare nulla, poi un certificato firmato.

Quando lo eseguo sulla tempesta seedata, il generatore produce 1.762 duty di recupero legali (52 dei quali riposizionamenti deadhead per spostare gli equipaggi dove servono), più 53 fallback di cancellazione, per 1.815 colonne candidate in totale. CBC risolve la 1.815 variabili, 115 vincoli set-partition a costo minimo a OPTIMAL e restituisce un piano in circa 0,11 secondi. Risultato su quello scenario: 52 di 53 voli ri-equipaggiati (98 percento), 1 cancellazione, 34 equipaggi usati (25 di linea e 9 di riserva).

Fase di solve CBC che mostra 1.815 variabili binarie, 115 vincoli e stato del solver OPTIMAL
Il motore sullo schermo è CBC, dichiarato, non mascherato: una set-partition a 1.815 variabili e 115 vincoli risolta a OPTIMAL. Uso il solver. Non pretendo mai di batterlo.
Il problema della compagnia aerea non è mai stato che il solver fosse troppo debole. Era che il recupero era troppo lento, troppo rischioso e invisibile finché non era troppo tardi.

Nota l'onestà di quello screenshot. Il motore di recupero è CBC, nominato sul pannello. L'affermazione duratura non è che il mio codice ottimizza meglio di un solver. È che il piano arriva ampiamente sotto il secondo dove il processo manuale da fonte richiede dalle 4 alle 12 ore, e l'app misura quel gap alla luce del sole. Voglio essere preciso sul perimetro, perché questa è una demo e mi rifiuto di farla passare per più di quello che è: quelle cifre esatte sono i risultati di una rete sintetica seedata, non una garanzia open-world. L'affermazione velocità-contro-manuale è quella che viaggia.

La garanzia di legalità appartiene al codice, non al giudizio di un modello

Ho un'opinione forte che ho guadagnato solo costruendo questo, quindi la dico chiaramente. Una garanzia di legalità non può vivere nel giudizio di un modello. Deve vivere in codice deterministico, per costruzione. Il modo per impedire che un duty di equipaggio illegale venga mai raccomandato non è addestrare un modello a evitarlo, né aggiungere un termine di penalità all'obiettivo e sperare che l'ottimizzatore lo aggiri. È rendere il duty illegale impossibile da generare in primo luogo.

Quindi i vincoli sono applicati in fase di generazione, non valutati dopo. Part 117 limita un periodo di duty a 780 minuti, il tempo di volo a 480 minuti, e richiede un sit minimo di 30 minuti; il CBA di esempio limita un duty a 4 segmenti. Solo i duty che soddisfano tutti questi diventano mai colonne candidate. Questo è action masking. Un'assegnazione illegale non è penalizzata, è non rappresentabile. Qualunque cosa CBC faccia con le colonne che gli vengono passate, e qualunque cosa il copilot opzionale dica poi sul piano, nessuno dei due può far tornare in vita un duty illegale, perché non è mai stato nell'insieme.

Questo mi dà un invariante invece di un punteggio: 0 assegnazioni illegali, mai, verificate con unit test (la suite di test è 3/3 passante, verifica che il raggio d'impatto non sia vuoto, che siano generate solo colonne legali e che il piano recuperato sia una partizione legale). Un punteggio può regressare. Un invariante lo puoi promettere.

Pannello del risultato di recupero che mostra il gate di legalità con 0 illegal, etichettato enforced in code by column masking, not by the model
La riga che mi interessa di più: 0 illegal, enforced in code by column masking, not by the model. Part 117 e il CBA sono garantiti per costruzione, non da un modello che si comporta bene.

È anche per questo che non trovo più convincenti i pitch di «autonomous AI ops» quando la storia sulla sicurezza è «il modello ha imparato a non farlo». Ho affidato a un modello il rispetto di una regola dura esattamente una volta durante questa build, all'inizio, ed è andato bene finché non è arrivato l'input in cui non lo era. In un dominio in cui una singola violazione è un evento normativo, «di solito legale» è uguale a «non legale». Preferisco eliminare la possibilità piuttosto che supervisionarla.

Cosa succede nel giorno peggiore dell'anno?

Ho quasi rilasciato una versione che avrebbe auto-approvato qualsiasi cosa, e sono contento che uno scenario mi abbia fermato. Imposta la demo su severe, dove l'evento è abbastanza grave da esaurire le riserve e lasciare solo circa il 30 percento degli equipaggi rimanenti. CBC trova comunque un piano pienamente legale, in circa 0,05 secondi, ancora 0 illegal. Ma quel piano cancellerebbe 20 di 53 voli, cioè il 38 percento del raggio, ben sopra la soglia di auto-approvazione del 15 percento dell'OCC.

La mossa giusta lì non è timbrare in silenzio un piano che cancella più di un terzo della rete colpita. Quindi lo stato passa a ESCALATE, firma umana richiesta, con il motivo mostrato. Il piano è ancora calcolato, ancora legale, ancora mostrato al controller (33 voli recuperati, 62 percento del raggio). Semplicemente non è auto-approvato.

Risultato dello scenario severe che mostra ESCALATE al controller perché il recupero cancella 20 di 53 voli, 38 percento, sopra la soglia del 15 percento
Il caso difficile onesto: un piano legale che cancella comunque il 38 percento del raggio passa a ESCALATE, firma umana richiesta. Il piano è mostrato e segnalato, mai approvato di routine.
La parte che la maggior parte dei pitch «autonomous» salta è sapere quando l'azione corretta è non agire, e consegnare la giornata a un umano.

Costruire quel gate ha cambiato come mi sento sull'intera categoria. L'escalation non è il sistema che fallisce. È il sistema che è onesto su una brutta giornata. Un advisor che restituisce sempre una risposta sicura di sé è facile da mostrare in demo e pericoloso a cui affidarsi. Quello che ogni tanto dice «questo è sopra la tua linea, decidi tu» è quello che metterei davvero accanto a un controller alle 3 di notte.

L'artefatto che vorrei se fossi il controller

Continuavo a chiedermi di cosa avrebbe bisogno un operations controller il mattino dopo, e la risposta non era una dashboard, era un verbale. Quindi ogni recupero si sigilla in un recovery_plan.json firmato: la disruption, il piano scelto azione per azione con equipaggio e volo, la specifica clausola Part 117 e CBA verificata per azione contro il suo tetto, il wall-clock del recupero e le cifre di risparmio. È il verbale di audit dell'OCC sul perché questo recupero è stato raccomandato, esportabile in un clic.

Fase certificato che mostra il recovery_plan.json firmato con stato RECOVERED, limiti normativi e garanzia di legalità
Ogni raccomandazione esporta un recovery_plan.json firmato: stato, i limiti Part 117 verificati e la garanzia di legalità dichiarata come enforced by action masking. La traccia di audit è il punto.

C'è anche un piano copilot opzionale, e voglio essere chiaro su dove si colloca. È un adattatore sottile a un LLM (default Claude, provider scambiabile, o un bridge locale senza chiave) che spiega il piano in inglese semplice. Si astiene del tutto senza una chiave, tutto il resto gira offline e senza chiave, e vive fuori dal nucleo decisionale. La maschera deterministica, CBC e il gate di escalation decidono. Il modello narra solo dopo i fatti. L'ho messo lì di proposito, perché nel momento in cui il language model influenza se un duty è legale, ho perso la garanzia che ho speso l'intera build a guadagnare.

Sui risparmi vale la stessa disciplina. Nello scenario normale il confronto shadow mostra 52 cancellazioni evitate e circa $2.37M di esposizione rimborsi DOT evitata (un modello da $300 per passeggero) rispetto a non fare nulla. È l'inquadratura più lusinghiera possibile, perché la baseline è lasciare a terra l'intero raggio d'impatto, ed è etichettata come illustrativa di quello scenario. Non è un titolo, e di certo non è la prova che il mio codice ottimizza meglio di qualsiasi cosa. Ho perso quell'argomento contro CBC il primo giorno. Non sto per riconquistarlo in silenzio con un numero di marketing.

Quindi cosa significa davvero «potenzia, non sostituire»?

Una volta pensavo che l'augmentation fosse la scelta timida, quella che dici quando non riesci a costruire la cosa audace. Ora penso il contrario. Il buyer qui possiede già un buon stack di solver, Jeppesen o IBS, e non può tollerare rip-and-replace, lock-in o una raccomandazione inspiegabile nel giorno peggiore dell'anno. Dire a quel buyer «buttalo per il mio modello più intelligente» non è audace, è un'affermazione che ho già smentito a me stesso con un benchmark.

Ciò che posso offrire onestamente è il layer operativo intorno al solver di cui già si fidano. Rendere la cascata visibile prima che morda. Rendere le mosse illegali impossibili da generare piuttosto che solo scoraggiate. Collassare le ore in secondi. E sapere quando la giornata è abbastanza brutta che la risposta giusta è escalation, non auto-approvazione. Tutto nella demo è sintetico e seedato, la rete, gli equipaggi, la disruption, le cifre in dollari, nessun dato reale di compagnia aerea da nessuna parte. Ciò che è reale è il meccanismo, e puoi guardarlo girare da capo a fine su veriprajna.com/it/demos/stormcrew-recovery-equipaggio-irops-aereo-in-secondi-legale-per-costruzione.

E se preferisci vederlo piuttosto che leggermi descriverlo, ecco l'intera cosa che gira da capo a fine.

Ecco la domanda che non ho smesso di rivoltare da quando CBC mi ha battuto. Quando il solver con cui stai competendo è già buono, e il buyer lo possiede già, ciò che resta da costruire non è una risposta migliore. È una relazione migliore con la risposta: più veloce, dimostrabilmente legale, visibile e abbastanza umile da fare escalation. Quindi quanto dell'AI che ti stanno vendendo quest'anno risolve davvero la parte difficile, e quanto ristabilisce la parte che non era mai rotta?

Ricerca correlata

Pubblicato anche su

Costruisci la tua IA con fiducia.

Collabora con un team che vanta una profonda esperienza nella creazione della prossima generazione di IA aziendale. Lascia che ti aiutiamo a progettare, sviluppare e implementare una strategia di IA di cui ti puoi fidare.

Veriprajna società di consulenza Deep Tech è specializzata nella creazione di sistemi di IA safety-critical per i settori sanitario, finanziario e regolamentato. Le nostre architetture sono validate rispetto a protocolli consolidati con una documentazione di conformità completa.