Vai al contenuto principale
Agentic data engineering: pipeline, runbook e incidenti - immagine header GinnyTech con visual cosmico editoriale

Agentic data engineering: pipeline, runbook e incidenti

Agentic data engineering: pipeline, runbook e incidenti su GinnyTech: stabilire quali azioni operative puo suggerire o compiere un agente durante incidenti dati con controlli, ownership e output revisionabili.

AD
Creato daAndrii Dyshkantiuk
Lezione 231 / 236Livello: AvanzatoDurata: 32 minPrerequisiti: 1

Cosa imparerai

  • Progettare workflow AI per dati con controlli, owner e output revisionabili
  • Applicare AI, AutoML o agentic AI a casi business analytics senza perdere rigore
  • Riconoscere rischi di leakage, drift, costo, privacy e automazione non governata

Agentic data engineering: pipeline, runbook e incidenti

Alle tre di notte una pipeline ordini si ferma, Slack si riempie di messaggi e nessuno sa se il problema è un cambio di schema, un job in ritardo o un dato sporco arrivato dal tracking. Qui l’agente non è un mago che sistema tutto: è un operatore veloce che raccoglie segnali, propone un percorso e lascia a un umano la decisione che conta. Questo articolo spiega come progettare quel comportamento, cosa l’agente può fare da solo, cosa deve chiedere e come si misura se il sistema regge, senza trasformare ogni incidente in un salto nel buio. La lezione appartiene al binario sistemi-llm.

Il punto di partenza è scomodo ma liberatorio: un agente sui dati aumenta copertura e velocità, non giudizio. Legge log in secondi, confronta decine di run, abbozza runbook e post-mortem, ma non sa quanto costa fermare il magazzino per un backfill né se una colonna contiene dati soggetti a vincoli legali. Chi progetta il workflow deve quindi disegnare tre cose prima di accendere qualsiasi automazione: il perimetro delle azioni consentite, i controlli che rendono ogni proposta verificabile e il modo in cui ogni passo resta tracciato. Il resto, modelli, orchestrazione, prompt, viene dopo.

Quando una pipeline si rompe davvero

Prendi un caso concreto. Una pipeline orders_mart gira ogni ora su Airflow: estrae ordini da Postgres, li normalizza con dbt e li espone a una dashboard commerciale. Martedì mattina la dashboard mostra un crollo del 40 per cento sugli ordini del giorno prima. Il canale incidenti si attiva. Senza agente, il data engineer apre Airflow, controlla i log del task dbt_run, interroga la tabella raw, confronta i conteggi con la settimana scorsa e cerca deploy recenti nel repo dbt. Quarantacinque minuti per capire che un deploy ha rinominato coupon_code in discount_code e il modello a valle ha scartato in silenzio 12.000 righe con un join fallito.

Con un agente progettato bene, la stessa sequenza dura pochi minuti: l’agente correla l’alert con il run fallito, estrae l’errore dominante dai log, confronta lo schema attuale con quello dell’ultimo run verde, trova il commit sospetto e apre una bozza di ticket con evidenze collegate. La differenza non è l’intelligenza, è la preparazione: l’agente sa dove guardare perché qualcuno gli ha dato accesso a orchestratore, catalogo, repo e storico degli incidenti, e sa cosa non toccare perché il runbook glielo vieta.

Il dettaglio che decide tutto è il silenzio. La pipeline non ha fallito: ha prodotto dati sbagliati senza alzare errori. Sono gli incidenti peggiori, quelli che scopre il commerciale guardando una dashboard. Per questo il runbook agentico deve coprire non solo i task rossi ma gli scostamenti semantici, volumi, distribuzioni, freschezza, e l’agente deve saper dire che non ha abbastanza evidenze invece di inventare una causa plausibile.

Il confine tra suggerire e agire

Ogni incidente pone la stessa domanda: fin dove si spinge l’agente senza chiedere. La risposta non è filosofica, è una matrice di permessi scritta nel runbook e applicata dal codice, non dal prompt. Tre fasce bastano nella maggior parte dei team.

Le azioni di sola lettura sono sempre consentite: leggere log, interrogare tabelle di monitoraggio, confrontare schemi, cercare incidenti simili, abbozzare diagnosi. Le azioni reversibili a basso rischio richiedono una policy esplicita: riavviare un task idempotente, marcare un run come stale, aprire ticket, notificare un canale, generare una patch come proposta. Le azioni distruttive o costose non si eseguono mai senza approvazione umana: backfill su tabelle grandi, cancellazioni o troncamenti, modifiche allo schema di produzione, deploy, rollback, qualsiasi cosa tocchi dati personali o spedisca comunicazioni esterne.

Il trucco è rendere il confine verificabile dal sistema, non interpretabile dal modello. Un agente a cui dici di essere prudente prima o poi eseguirà un backfill da 4.000 euro di warehouse. Un agente i cui tool esposti semplicemente non includono il backfill in produzione non può farlo, per costruzione. La prudenza sta nel catalogo dei tool, negli scope delle credenziali e nei gate di approvazione, non negli aggettivi del system prompt.

Come l’agente fa triage in pochi minuti

Un triage solido segue sempre lo stesso ordine: cosa si è rotto, da quando, quanto è grave, cosa è cambiato. L’agente esegue queste quattro domande come una sequenza di tool, non come ragionamento libero. Prima interroga l’orchestratore per stato di task e run recenti, poi legge metriche di freschezza e volume, poi confronta schema e codice con l’ultimo stato buono, infine cerca nel catalogo degli incidenti se qualcosa di simile è già successo.

La freschezza si misura in modo semplice ma va definita con cura. Il ritardo è la differenza tra il momento attuale e il timestamp massimo presente nella tabella servita. La soglia oltre cui scatta l’alert dipende dal contratto della pipeline: 70 minuti possono essere normali per un job orario con retry, inaccettabili per uno streaming da 5 minuti. L’agente non decide la soglia, la legge dal catalogo e la applica. Stesso discorso per i volumi: uno scostamento si valuta contro una baseline, mediana mobile a 7 giorni sullo stesso giorno della settimana, non contro il run precedente, che potrebbe già essere corrotto.

Il confronto tra schemi merita un tool dedicato. Molti incidenti misteriosi sono rinominazioni, cambi di tipo o nuove colonne nullable che rompono join e cast a valle. L’agente deve mostrare il diff esatto, colonna, tipo prima, tipo dopo, commit che l’ha introdotto, non riassumerlo a parole. Un diff mostrato male è peggio di nessun diff: invita a fidarsi del riassunto invece di leggere l’evidenza.

# Triage minimale: l'agente raccoglie evidenze, non decide la causa.
def triage_pipeline(run_corrente, run_verde, catalogo):
    # Confronta stato task, ritardo dati e diff di schema
    evidenze = {}
    # Ritardo in minuti rispetto al timestamp massimo servito
    evidenze["lag_minuti"] = (run_corrente["now"] - run_corrente["t_max"]).seconds // 60
    # Soglia letta dal catalogo, mai inventata dal modello
    evidenze["soglia_sla"] = catalogo["sla_minuti"]
    # Diff di schema tra ultimo run verde e run corrente
    evidenze["schema_diff"] = diff_schema(run_verde["schema"], run_corrente["schema"])
    # Incidenti simili per riuso del runbook, non per analogia libera
    evidenze["precedenti"] = cerca_incidenti_simili(run_corrente["firma_errore"], k=3)
    return evidenze

La funzione sembra ovvia ed è proprio questo il punto: il valore sta nel cablare gli accessi, orchestratore, catalogo, repo, storico ticket, non nel prompt. Senza questi connettori l’agente parla bene e conclude poco.

Scrivere un runbook che un agente può eseguire

Un runbook scritto per umani dice di controllare i log e valutare. Un runbook eseguibile dice quale log, con quale query, con quale soglia e con quale esito si passa al passo successivo. La struttura minima ha cinque campi per passo: obiettivo, comando o query esatta, risultato atteso, criterio di uscita verso il passo dopo, azione di fallback se il controllo fallisce.

Un esempio reale su orders_mart: passo 1, verifica stato task su Airflow per dbt_run nelle ultime 3 esecuzioni; passo 2, conta righe raw contro mart per la partizione del giorno e calcola il tasso di scarto; passo 3, diff di schema tra snapshot di ieri e di oggi; passo 4, cerca deploy dbt nelle ultime 24 ore; passo 5, se lo scarto supera il 5 per cento e c’è un diff di schema, propone patch e apre ticket con priorità alta, altrimenti scala a un umano con le evidenze raccolte. Ogni passo produce un artefatto, tabella, diff, link al commit, che finisce nel ticket. Niente artefatto, niente fiducia.

La copertura del runbook si misura: percentuale di tipi di incidente con un percorso scritto ed eseguibile, percentuale di passi che l’agente può svolgere senza credenziali extra, tempo mediano dal trigger alla prima evidenza utile. Un team che parte da zero di solito copre prima i tre incidenti più frequenti, ritardo, scarto righe, schema drift, e lascia il resto al triage assistito. Automatizzare il raro prima del frequente è il modo più costoso di non imparare nulla.

Controlli che fermano gli errori silenziosi

I test a difesa della pipeline sono gli stessi con o senza agente; cambia chi li esegue e quando. L’agente li lancia a ogni triage, ma le soglie restano decise da umani e versionate nel repo. Quattro famiglie coprono quasi tutto.

I test di volume confrontano conteggi e tassi di scarto per partizione contro la baseline storica, con tolleranze diverse per giorno feriale e weekend. I test di schema bloccano deploy che rinominano o cambiano tipo senza migrazione esplicita, il caso coupon_code si ferma qui, prima di arrivare in produzione. I test di distribuzione guardano oltre i conteggi: quota di null, cardinalità delle chiavi, distribuzione di una colonna critica come order_status. Un join che perde il 40 per cento delle righe lascia quasi sempre una traccia in uno di questi tre. La quarta famiglia, i test di lignaggio, verifica che ogni colonna servita abbia una sorgente dichiarata e un owner: senza, l’agente non sa chi avvisare e il ticket gira a vuoto.

-- Controllo scarto per partizione: cuore del runbook orders_mart.
-- Confronta righe raw vs mart e alza un flag sopra la soglia umana.
SELECT
  ds,                          -- partizione giorno
  COUNT(*) AS righe_raw,       -- righe in ingresso
  SUM(CASE WHEN order_id IS NULL THEN 1 ELSE 0 END) AS righe_senza_chiave,
  -- Tasso di righe inutilizzabili: soglia decisa dal team, non dal modello
  SUM(CASE WHEN order_id IS NULL THEN 1 ELSE 0 END) * 1.0 / COUNT(*) AS tasso_scartato
FROM raw_orders
WHERE ds = CURRENT_DATE - INTERVAL '1 day'
GROUP BY ds
HAVING SUM(CASE WHEN order_id IS NULL THEN 1 ELSE 0 END) * 1.0 / COUNT(*) > 0.05;

Il risultato di questa query non è un numero: è una diramazione del runbook. Sotto il 5 per cento l’agente prosegue con gli altri controlli; sopra, apre l’incidente e allega il conteggio, la partizione e il confronto con i sette giorni precedenti. La soglia vive in una tabella di configurazione con owner e data di revisione. Quando il commerciale chiede perché l’alert non è scattato prima, la risposta è un link, non un ricordo.

Dare al modello solo gli accessi che servono

Il modo più rapido per trasformare un incidente dati in un incidente di sicurezza è dare all’agente una connessione warehouse con permessi da amministratore per semplicità. La configurazione corretta è noiosa e non negoziabile: ruolo di lettura su tabelle raw, mart e di monitoraggio; ruolo separato e più stretto su eventuali tabelle con dati personali, con mascheramento delle colonne sensibili; nessun diritto di scrittura in produzione, scrittura consentita solo in schema di staging o sandbox con quota e scadenza.

Tre accorgimenti pratici evitano la maggior parte dei guai. Primo, credenziali a breve scadenza con scope per pipeline: l’agente che cura orders_mart non legge le altre aree. Secondo, ogni query generata dal modello passa da un allowlist di pattern, letture con limite di righe e timeout, niente cancellazioni o grant fuori dai tool approvati. Terzo, tutto viene loggato: prompt, tool chiamati, query eseguite, righe lette, costo stimato. Quando un auditor chiede cosa ha fatto l’agente durante l’incidente del 14 marzo, il log risponde in minuti.

Il costo merita un controllo esplicito perché gli agenti interrogano molto. Un triage che scansiona tabelle raw da terabyte a ogni alert brucia budget in silenzio. Limiti di righe, partizioni obbligatorie nelle query, cache dei risultati recenti e un budget per incidente con alert oltre soglia tengono il sistema onesto. Un team che spende 30 euro di scansioni per diagnosticare un ritardo da 10 minuti sta automatizzando nel modo sbagliato.

L’approvazione umana che non diventa teatro

Il gate di approvazione è il punto dove molti workflow agentici falliscono in modo sottile: l’umano clicca approva senza leggere perché la proposta è lunga, generica e arriva nel momento peggiore. Un’approvazione che funziona si progetta come un’interfaccia, non come un pulsante.

La proposta deve stare in una schermata: cosa è successo in due righe, evidenze con link, azione proposta con comando esatto e piano di rollback, impatto stimato su downstream, costo e durata, rischi residui. Niente paragrafi generati di contorno. Il revisore deve poter rispondere in tre modi, approva, rifiuta, chiedi un controllo specifico, e ogni risposta deve avere un effetto reale: il rifiuto ferma la sequenza, la richiesta di controllo aggiunge un passo al runbook invece di perdersi in chat. Le approvazioni di emergenza fuori orario seguono un percorso separato con ambito ristretto e revisione retrospettiva obbligatoria entro 24 ore.

Un errore comune è chiedere approvazione per tutto, producendo fatigue e click automatici, o per niente, producendo autonomia non governata. La via di mezzo è calibrare sul blast radius: lettura e bozze senza gate, azioni reversibili su staging con notifica, qualsiasi tocco alla produzione con approvazione nominativa. Il log registra chi ha approvato cosa, su quali evidenze, a che ora. Quel record è parte del post-mortem, non burocrazia.

Misurare se il sistema migliora

Senza metriche, l’agente sembra utile perché risponde in fretta. Le misure che contano sono operative e scomode. Il tempo medio di rilevamento dice quanto passa dall’inizio del problema al primo alert con evidenze; il tempo medio di risoluzione dice quanto passa da lì al ripristino del contratto dati. Il tasso di falsi allarmi dice quante volte l’agente ha svegliato qualcuno per niente: sopra una certa soglia il team smette di fidarsi e il sistema muore anche se è preciso quando conta.

Altre due misure guardano la qualità: percentuale di incidenti con ticket completo di evidenze collegate, percentuale di post-mortem chiusi con un’azione sul runbook effettivamente implementata. Un post-mortem che finisce in un documento e non in un test o un passo di runbook è letteratura, non ingegneria. L’agente aiuta qui redigendo la prima bozza dal log del triage, sequenza, evidenze, decisione, tempi, ma la lezione appresa la scrive l’umano che ha approvato il fix.

Il confronto onesto è contro la baseline manuale: stessi tipi di incidente, stesso periodo stagionale, stessi owner. Se il triage assistito dimezza il rilevamento ma raddoppia i falsi allarmi, il guadagno netto può essere negativo. Meglio poche automazioni misurate che un cruscotto verde su metriche vanitose come il numero di query generate.

Cosa automatizzare per primo, cosa tenere in mano

L’ordine di adozione decide se il progetto sopravvive al primo trimestre. Prima settimana: agente in sola lettura su tre pipeline critiche, con runbook per ritardo e scarto righe, ticket automatici con evidenze, nessuna azione in scrittura. Primo mese: aggiunta del diff di schema e della ricerca incidenti simili, primo gate di approvazione su staging, misura di rilevamento e falsi allarmi contro baseline. Secondo trimestre: estensione ad altre pipeline solo se i falsi allarmi restano sotto la soglia concordata, backfill assistito con doppia approvazione, post-mortem generati dal log.

Restano in mano umana, sempre: la definizione delle soglie, la proprietà delle metriche, la decisione di comunicare all’esterno, qualsiasi azione su dati personali, il giudizio su trade-off tra velocità e accuratezza quando il runbook non copre il caso. L’agente propone, l’umano risponde del risultato. Scritto nel runbook, applicato nei permessi, verificato nei log.

Trappole che rompono questi sistemi

La prima è l’allucinazione di causa: l’agente produce una spiegazione coerente, per esempio il calo è dovuto alla campagna conclusa, senza aver confrontato segmenti né escluso il cambio di schema. La difesa è una regola semplice: ogni affermazione causale nel ticket deve puntare a una query o un diff. Senza link, è un’ipotesi e va etichettata come tale.

La seconda è il drift del runbook: il documento resta fermo mentre pipeline e schemi cambiano, e l’agente esegue passi obsoleti con sicurezza. La difesa è versionare il runbook nel repo, testarlo in staging a ogni deploy e misurare la copertura come metrica viva, non come voce di un audit annuale.

La terza è la remediation a catena: un fix automatico ne rompe un altro a valle, il backfill di una tabella invalida una tabella di attribuzione che nessuno aveva mappato. La difesa è il lignaggio dichiarato e il divieto di azioni su nodi con downstream non censiti. Se non sai cosa dipende da una tabella, non la tocchi in automatico.

Chi parte da qui ha un sistema che sbaglia in modo visibile e migliorabile, non in modo elegante e opaco. E quando il prossimo alert suona alle tre di notte, la differenza si sente: invece di una chat piena di ipotesi, un ticket con evidenze, un percorso proposto e un umano che decide con gli occhi aperti.

Verdetto: lettura e bozze sempre autonome, reversibili su staging con notifica, produzione e dati personali solo con approvazione nominativa e rollback pronto.

Il runbook in una frase

Il runbook agentico decide quali azioni operative l’agente esegue da solo e quali richiedono approvazione umana durante gli incidenti dati.

La sequenza operativa in cinque passi

  1. Apri il triage con stato dei task, ritardo dati, diff di schema e incidenti simili.
  2. Esegui i controlli di volume, schema, distribuzione e lignaggio contro soglie umane.
  3. Dirama il runbook sul tasso di scarto: sotto soglia prosegui, sopra apri l’incidente.
  4. Proponi patch e ticket con evidenze, comando esatto, rollback e impatto stimato.
  5. Misura rilevamento, risoluzione e falsi allarmi contro la baseline manuale.

Un caso reale: il deploy che non si ferma

Il 1 agosto 2012 Knight Capital ha perso circa 440 milioni di dollari in 45 minuti per un deploy difettoso del software di trading. Un modulo obsoleto è rimasto attivo sui server e ha generato milioni di ordini errati prima che qualcuno fermasse il sistema. La società non si è più ripresa ed è stata poi acquisita. Il caso mostra perché deploy, rollback e stop automatico vogliono gate umani e runbook provati: senza, un errore di routine diventa un incidente terminale.

Domande per chiudere la lezione

  1. Fin dove si spinge l’agente senza chiedere durante un incidente?
  2. Quali quattro domande segue un triage solido in ordine?
  3. Cosa trasforma un runbook narrativo in passi eseguibili da un agente?
  4. Quali metriche dicono se il sistema migliora davvero?
Serve una mano concreta?

Bloccato su questo argomento o vuoi applicarlo al tuo caso? Prenota una call di 15 minuti con un analista esperto.

Prenota una call