Note di build del founder sull'Inspection Trust Gate: rilevamento drift, gate deterministici e lineage di audit pronto per l'EU AI Act tra modello di visione e PLC.
ManufacturingMachine LearningComputer Vision

Continuavo a cercare di sistemare il modello. Il problema era la luce.

Ashutosh SinghalAshutosh Singhal24 giugno 202615 min

Il primo numero che ho messo sulla lavagna per questa build è stato 97 percento. Il secondo è stato 14.

Descrivono lo stesso modello. Nell'esempio di stampaggio della nostra ricerca, un modello di visione validato al 97% di accuratezza in laboratorio va su una pressa a stampo progressivo da 200 tonnellate che gira a 40 colpi al minuto e inizia a scartare falsamente il 14% dei pezzi buoni. Dentro il modello non è cambiato nulla. Sono cambiati gli input: il riverbero delle luci del capannone che si sposta con l'angolo di colpo, il lubrificante che si accumula in modo diverso sugli stampi caldi rispetto a quelli freddi, i primi 50 pezzi di ogni turno prodotti prima che la pressa raggiunga l'equilibrio termico. La fisica della linea ha spinto le immagini fuori dalla distribuzione su cui il modello era stato validato, e nessun modello, a qualsiasi accuratezza, è affidabile là fuori.

Nell'ultima fase di questo progetto ho costruito una demo per prendere sul serio quella frase. Si chiama Inspection Trust Gate, e puoi guardarla decidere, pezzo per pezzo, su veriprajna.com/it/demos/ispezione-qualita-edge-ai-in-manifattura-l-inspection-trust-gate. Non è un modello di difetti migliore. È il layer di runtime tra il modello di visione e l'attuatore di scarto del PLC, e il suo unico compito è decidere, per ogni singolo pezzo, se il verdetto del modello è sicuro da attuare.

Quello che segue è la storia della build attraverso i tre momenti che hanno cambiato il modo in cui penso all'AI di ispezione: un evento di drift a un 06:00 scriptato, un numero di benchmark che mi sono rifiutato di credere, e una regola che ho quasi cancellato.

La correzione non è un modello migliore

Ho resistito a quella frase più a lungo di quanto avrei dovuto. Quando un detector si comporta male, ogni istinto da builder che ho dice di riaddestrarlo, aggiornare il backbone, comprare più etichette. La ricerca ha continuato a rifiutarsi di collaborare. I sistemi AOI out-of-box scartano falsamente dal 5 al 15% dei pezzi buoni, e quelli ben tarati scendono sotto il 2%, cosa che la nostra pagina della soluzione chiama "un problema di calibrazione e di dati, non di architettura del modello". La stessa ricerca riporta che l'84% dei progetti di system integration fallisce o fallisce in parte, e che in un tipico deployment di ispezione il lavoro di integrazione è il 60% della timeline del progetto mentre il training del modello è il 15%. La riga che continuavo a rileggere: "L'hardware è un ordine di acquisto."

Così ho fatto qualcosa che sembrava lievemente eretico: ho reso il modello di difetti della demo deliberatamente poco straordinario. È una distanza kNN dalla texture known-good, un sostituto PatchCore-lite, e ottiene un AUROC di 0.845 nel separare pezzi buoni puliti da quelli difettosi sullo split di test held-out MVTec AD metal_nut (fotografie reali di pezzi davvero prodotti, etichette pubbliche). Non sto nascondendo quel numero e non lo sto vendendo. In produzione quello slot ospita la tua pipeline NVIDIA Metropolis, il tuo sistema Cognex, il tuo modello custom, dietro un'interfaccia fissa. Il prodotto è il layer intorno al motore, non il motore.

Il layer parte da una domanda a cui nessuna metrica di accuratezza risponde: questa immagine è dentro le condizioni di cattura su cui il modello è stato validato? L'EnvelopeDetector della demo calcola una distanza di Mahalanobis nello spazio dei segnali fisici (esposizione, contrasto, dynamic range, un proxy di messa a fuoco, dettaglio ad alta frequenza, cast termico del colore, saturazione, frazione di glare), adattata sulle 220 immagini known-good di training e su nient'altro. Quando un pezzo cade al di fuori di quell'inviluppo di validazione, il gate smette del tutto di fidarsi dell'output del modello, per quanto il modello si senta confidente al riguardo.

Anche un modello perfetto è valido solo su input dentro il suo inviluppo di validazione.

È la frase su cui poggia l'intera build. Il drift è un fallimento di input, non un fallimento del modello, e un fallimento di input non compare mai nella tua dashboard di accuratezza. Compare nel cassone degli scarti.

Cosa succede alle 06:00?

Il momento di cui mi fido di più in tutta la demo è un timestamp. L'app ripete un turno scriptato deterministico sulla stazione "Line 3 - metal_nut press," inviando in streaming fotografie reali MVTec AD metal_nut attraverso l'intera pipeline. A un certo punto, un marker attraversa lo schermo: "SHIFT CHANGE 06:00 - stampi freddi, luci del capannone accese." Poi arrivano 12 pezzi buoni corrotti con glare, defocus e cast termico. Voglio essere preciso su cos'è: le fotografie sono reali, il drift è una corruzione onesta delle immagini applicata a esse, e l'app lo etichetta come tale. Non avevo una linea di stampaggio da filmare, e fingere il contrario avrebbe vanificato l'intero punto.

Quello che succede dopo è il motivo per cui la demo esiste. Il monitor dell'inviluppo diventa rosso. Il gate legge ogni pezzo driftato come fuori dall'inviluppo di validazione e rifiuta di lasciare che il verdetto del modello tocchi l'attuatore. Verdetto dopo verdetto torna HOLD, instradato alla coda di escalation per un umano, mentre il pannello accanto mostra cosa avrebbe fatto un AOI ingenuo senza controllo dell'inviluppo con la stessa immagine: REJECT.

Il momento del drift: un verdetto HOLD con un anello di violazione fuori inviluppo, accanto a una colonna AOI ingenua che mostra che lo stesso pezzo buono sarebbe stato scartato
Il beat delle 06:00 nella demo: il banner SHIFT CHANGE scatta, l'anello di violazione segnala il pezzo come fuori dall'inviluppo di validazione, il verdetto del gate legge HOLD in attesa di prova, e la colonna AOI ingenua ammette che avrebbe scartato questo pezzo buono.

La prima volta che ho visto la coda riempirsi, ho cliccato su un pezzo in hold aspettandomi di vedere una vaga scusa del tipo "anomalia rilevata". Invece il monitor dell'inviluppo ha scomposto la violazione segnale per segnale, perché l'avevo costruito con misure fisiche piuttosto che con embedding, e le misure fisiche possono spiegarsi da sole. Su un pezzo driftato, la luminosità sta a 7.6 sigma dal fit di validazione e porta l'87.1% della distanza di Mahalanobis al quadrato. Non è un modello che ha una sensazione. È una lettura di strumento.

Pannello di evidenza della violazione dell'inviluppo che scompone lo score out-of-distribution segnale per segnale
La violazione spiegata come lettura di strumento: luminosità a +7.6 sigma dal fit di validazione, che spiega l'87.1% della distanza di Mahalanobis al quadrato su questo pezzo in hold.

Alla fine della fase di drift il tabellone è netto. La baseline ingenua ha scartato automaticamente 12 pezzi buoni. Il Trust Gate ne ha scartati automaticamente zero, tenendoli tutti in revisione. Le stesse immagini, lo stesso modello di difetti sostitutivo, le stesse soglie sullo score di difetto. L'unica differenza è che un percorso ha controllato l'input prima di fidarsi dell'output.

La baseline ingenua e il gate hanno visto gli stessi pezzi e lo stesso modello. L'unica differenza era il permesso di attuare.
Pannello di confronto: la baseline ingenua ha scartato 12 pezzi buoni, il Trust Gate ne ha scartati automaticamente 0, con la proiezione di scarto per turno
Il pannello del risultato: 12 pezzi buoni scartati dalla baseline ingenua contro 0 del gate, il KPI di falso scarto che scende dal 57.1% allo 0% su questa run, e una proiezione di circa $26.5k per turno, etichettata come proiezione.

A proposito di quella cifra in dollari, perché è qui che le demo di solito iniziano a mentire: il pannello estrae il tasso misurato di falso scarto ingenuo su un turno intero (40 colpi al minuto per 8 ore sono 19,200 pezzi) a $2.42 per pezzo scartato. Il $2.42 è un ordine di grandezza con fonte, ancorato a un caso pubblicato di un produttore di biscotti in cui una riduzione dell'8.7% degli scarti-sprechi ha risparmiato $94K all'anno e 38,800 kg di prodotto. Non è il numero di un cliente, e il contatore è etichettato come proiezione ovunque appaia. Ho misurato i falsi scarti; ho proiettato i dollari; la UI dice quale è quale.

Un'altra cosa che ho controllato prima di credere alla mia stessa storia di drift: i pezzi difettosi iniettati durante la fase di drift vengono comunque intercettati o inviati in escalation, mai auto-passati. Sull'intero split held-out quella cifra è 93 su 93. Tenere i pezzi buoni non vale nulla se i pezzi cattivi passano nel caos.

Il mio controllo dell'inviluppo stava correggendo i propri compiti?

Il numero di benchmark di cui mi fidavo di meno era il mio migliore. Quando ho eseguito per la prima volta lo script di bench, il detector dell'inviluppo separava le immagini driftate da quelle pulite in modo sostanzialmente perfetto. La mia reazione immediata non è stata orgoglio. È stata sospetto, perché avevo costruito entrambi i lati dell'esame: avevo scritto le corruzioni di glare, defocus e cast termico, e avevo scelto i segnali fisici che il detector osserva. Ovvio che un detector di glare catturi il glare. Un revisore con un minimo di rigore lo chiamerebbe circolare, e avrebbe ragione.

Così ho tenuto una famiglia di drift completamente fuori. Il detector non è mai stato tarato contro l'underexposure, non l'ha mai vista durante lo sviluppo. Poi ho rieseguito bench.py (più di recente il 2026-07-17) sullo split di test held-out MVTec AD metal_nut: 22 pezzi buoni, 93 difettosi, fit di training solo sulle 220 immagini buone. Sulla famiglia underexpose held-out, il detector dell'inviluppo ha ottenuto AUROC 1.000. È il numero che sostiene la tesi, proprio perché è stato guadagnato su una modalità di fallimento che non avevo mai progettato. Lo script stampa "THESIS HOLDS" solo se i numeri misurati supportano davvero l'affermazione; l'ho scritto così perché il marketing non potesse allontanarsi dalla misura.

Il resto del benchmark merita il suo ambito esatto, quindi eccolo senza arrotondamenti a mio favore. Sui pezzi buoni driftati, la baseline ingenua senza inviluppo scarta falsamente dal 95.5 al 100% per famiglia di drift (glare 100%, defocus 100%, cast termico 100%, underexpose 95.5%, media 98.9%). Il Trust Gate ne scarta falsamente lo 0.0%, tenendo ognuno in revisione. E il caveat onesto: le corruzioni sono a piena forza, quindi il collasso della baseline è quasi totale per costruzione. La tesi che difenderò è la direzione, cioè che un modello validato in modo pulito collassa quando gli input escono dal suo inviluppo, non la percentuale particolare. Queste sono misure su un benchmark di ricerca sotto drift sintetico. Non sono garanzie open-world, e chiunque le citi come performance di produzione le sta usando male, me compreso.

La regola che ho quasi cancellato

La chiamata di onestà più dura che ho fatto in questa build riguardava una regola che funziona a malapena. All'inizio ho aggiunto una regola di zona geometrica: localizzare l'anomalia su una griglia grossolana 8 per 8, e trattare un difetto dentro la zona funzionale in modo diverso da una imperfezione al bordo cosmetico. Suona come metrologia vera. Poi l'ho misurata, e le misure sono state umilianti. Il proxy di rugosità locale localizza un'anomalia su 33 dei 93 difetti held-out, circa il 35%. Cambia l'esito del gate su esattamente 1 su 93. E 0 dei 18 auto-reject sono supportati da un'anomalia davvero localizzata; quando nulla si localizza, il centroide ricade al centro della griglia, che per default si legge come in-zone.

Mi sono ritrovato con tre opzioni. Cancellare la regola e fingere di non averci mai provato. Tenerla e lasciare che la UI implichi una metrologia di precisione che non ho. Oppure tenerla e far confessare l'interfaccia. Ho scelto la confessione. Quando il difetto in evidenza della demo viene auto-scartato (pezzo test-flip-264, un vero difetto strutturale grossolano della classe flip di MVTec), il drill-in geometrico afferma chiaramente che nulla è stato localizzato su questo pezzo e lo scarto poggia solo sulla confidenza di texture.

Drill-in geometrico che dichiara che nessuna anomalia è stata localizzata e che lo scarto poggia solo sulla confidenza di texture
La disclosure che ho quasi tagliato: il drill-in ammette che nulla è stato localizzato su questo pezzo auto-scartato, quindi il verdetto poggia solo sulla confidenza di texture. La regola si astiene in pubblico invece di fingere.

La regola si guadagna il posto esattamente una volta, e ho fatto sì che l'app lo dimostrasse invece di metterlo in scena. All'avvio, la demo cerca tra tutti i 93 difetti held-out un pezzo con un'anomalia genuinamente localizzata fuori dalla zona funzionale su un pezzo altrimenti confidente. Nello split spedito quella ricerca trova test-flip-251, centroide alla riga 2, colonna 6, e il gate lo instrada a HOLD invece di far scattare l'attuatore. Se i dati cambiassero e nessun pezzo qualificasse, quel beat semplicemente non apparirebbe. Ho anche fatto A/B test della soglia sigma della regola con cross-validation a 5 fold; il valore adattato non ha mostrato miglioramenti rispetto al 2.5 impostato a mano, quindi ho tenuto 2.5 e ho registrato il risultato negativo nel repo con "shipped": false. In un engagement di produzione questa regola è sostituita da metrologia pixel-accurate e ancorata al CAD. Nella demo è un sostituto onesto, e la UI lo dice su ogni pezzo.

Un layer di trust che si vende troppo è una contraddizione in termini.

Quella riga è diventata una regola di design. Se l'intera promessa del prodotto è sapere quando non fidarsi di un modello, non può allo stesso tempo bluffare sul proprio componente più debole.

Gli agenti consigliano, il codice decide

La decisione che rifiuto di delegare è quella che muove il metallo. Il gate stesso è codice deterministico semplice, fuori da qualsiasi LLM e fuori anche dal modello di visione. Le sue soglie sono adattate dai dati della demo stessa, non tirate a indovinare: auto-pass sotto 0.948 e auto-reject sopra 1.30 sulla scala di confidenza calibrata, con tutto ciò che sta in mezzo, e tutto ciò che è fuori inviluppo, che va in HOLD. Corre contro un budget rigido di finestra di colpo di 750 ms, e nel log di audit spedito le decisioni arrivano in decine di millisecondi: test-good-288 auto-passato in 37.7 ms, test-good-289 in 24.4 ms, e il log dell'attuatore di scarto per test-flip-264 legge "REJECT actuated in 25ms (budget 750ms)."

Devo essere chiaro su cosa attua: niente, ancora. Il percorso EtherNet/IP verso un attuatore di scarto Allen-Bradley ControlLogix è un simulatore che registra esattamente ciò che avrebbe fatto, e il sink MES è uno stub che scrive la riga di tracciabilità che avrebbe scritto. Entrambi sono etichettati come stub nell'app. Hanno la forma degli adapter reali perché la realtà OT (impianti misti Siemens e Allen-Bradley, una finestra di scarto misurata in millisecondi) è la vera superficie del prodotto, ma una demo che implicasse una linea live fallirebbe il proprio test di trust.

Ci sono agenti nel sistema, e li ho delimitati di proposito. Quando i pezzi si accumulano nella coda di escalation, una coppia Drift Triage si mette al lavoro: un agente di diagnosi legge le deviazioni dei segnali fisici ordinate sui pezzi in hold e propone un'ipotesi di root-cause con un'azione raccomandata, e un agente critico poi controlla quella ipotesi contro l'evidenza numerica, declassandola a "investigazione manuale" se il segnale citato non è davvero la deviazione dominante. Sono costruiti su Pydantic AI e intercambiabili per provider, e senza una API key configurata l'intero sistema degrada a un triage template deterministico, così la demo gira completamente offline. Ciò che gli agenti non possono fare, per costruzione, è toccare l'attuatore. Quando parlano, il gate ha già deciso.

Gli agenti consigliano, il codice decide.

Ognuna di quelle decisioni lascia una ricevuta. Ogni pezzo scrive un record di lineage JSONL: part id, stazione, model id metalnut-defect-knn version v7, dataset hash ae95b5b533c8, confidenza di difetto, score OOD, i segnali fisici, quali regole del gate sono scattate, latenza rispetto al budget di 750 ms, le righe di log di attuazione e MES, cosa avrebbe fatto la baseline ingenua, e il risk tag high-risk:quality-gate (EU AI Act Allegato III, eff. 2026-08-02). Un click esporta il turno come inspection_audit.jsonl.

Record di lineage di audit per pezzo che mostra versione del modello, dataset hash, regole scattate e il risk tag EU AI Act
Il lineage di audit di un pezzo: model id metalnut-defect-knn v7, dataset hash ae95b5b533c8, le regole che sono scattate, latenza rispetto al budget di 750 ms, e il risk tag EU AI Act Allegato III su ogni decisione.

L'orologio normativo conta qui. Gli obblighi high-risk dell'EU AI Act diventano pienamente applicabili il 2 agosto 2026, le decisioni di qualità safety-critical stanno nell'Allegato III, e le sanzioni massime arrivano a €35M o al 7% del fatturato globale per le violazioni di pratiche proibite più gravi. Voglio stare attento alle parole, perché è esattamente dove le parole attente contano: la demo non è certificata EU AI Act, e nessuna demo può esserlo. Ciò che mostra è lineage pronto per l'EU AI Act, un record per decisione progettato per essere evidenza archiviabile in un fascicolo di conformità high-risk, generato alla velocità di linea invece di essere ricostruito dopo un incidente.

Cosa sopravvive al prossimo upgrade del modello?

La domanda che continuavo a farmi mentre costruivo questo era brutale per chi costruisce demo: se il prossimo modello di difetti del cliente è notevolmente migliore del mio sostituto, qualcosa di tutto questo conta ancora? Ora penso che sia esattamente al contrario. Deloitte prevede che l'adozione di AI agentica nella manufacturing salga dal 6% al 24% nel 2026 (Deloitte), il che significa più modelli e più autonomia che arrivano a più attuatori. Ognuno di quei modelli avrà un inviluppo di validazione, e la fisica di una linea di presse (glare, stampi freddi, equilibrio termico) continuerà a spingere gli input fuori da esso. Un modello perfetto non cambia nulla di questo, perché il fallimento che il gate previene è un fallimento di input, e l'obbligo di audit che serve è giuridico, non di modeling. Drift-gating, provenance e attuazione governata reggono a qualsiasi accuratezza del modello. È questa la proprietà che mi ha convinto che questo layer, e non un altro modello, fosse la cosa che valeva la pena costruire; il turno scriptato su veriprajna.com/it/demos/ispezione-qualita-edge-ai-in-manifattura-l-inspection-trust-gate è il mio tentativo di farti guardare mentre guadagna quella affermazione pezzo per pezzo.

E se preferisci vederla piuttosto che leggermi mentre la descrivo, ecco il founder cut, dall'inizio alla fine.

Quindi la domanda che farei su qualsiasi modello di ispezione sulla tua linea, compreso uno al 97%, non è "quanto è accurato?". È: per il pezzo che ha appena attraversato la telecamera, sai se quell'immagine era dentro l'inviluppo su cui il modello è stato validato? Se non puoi rispondere pezzo per pezzo, in millisecondi, con un record che potresti consegnare a un auditor, allora non penso che tu abbia un problema di accuratezza. Penso che tu abbia un problema di inviluppo, e vorrei davvero sapere quale dei due ha la tua linea.

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.