1. Che cos’è un incidente nel mondo delle ChatGPT Apps
Nel web classico un incidente è di solito qualcosa come «il server è giù», «le 500 sono aumentate notevolmente», «la latenza è raddoppiata». La definizione formale da ITIL: un incidente è un’interruzione non pianificata del servizio o un degrado della qualità del servizio.
Nel mondo delle ChatGPT Apps e di GiftGenius il quadro è più complesso. Compare uno strato di modelli che possono:
- non chiamare il tool necessario, anche se tutto è disponibile;
- chiamare il tool con parametri errati;
- «allucinare» un risultato ignorando il tuo MCP.
Perciò un incidente può non essere solo un HTTP 500, ma anche una situazione in cui tutte le metriche del backend sono verdi e gli utenti si lamentano in massa: «il bot è ottuso e non mostra i regali» — perché il modello ha smesso di chiamare suggest_gifts o confonde gli argomenti. Questo è un incidente di qualità (Quality incident).
È comodo pensare agli incidenti per categorie:
| Categoria | Esempio di sintomo | Esempio di metrica (SLI) |
|---|---|---|
| Disponibilità | MCP non risponde, «Error talking to app» in ChatGPT | % di risposte riuscite su /mcp |
| Latenza | la selezione dei regali richiede 10+ secondi | p95 del tempo di chiamata di suggest_gifts |
| Qualità | il modello non chiama il tool necessario, confonde la valuta | quota di richieste senza tool‑call a fronte di richiesta esplicita |
| Commerce | il checkout ha smesso di passare, i soldi non vengono elaborati | checkout_success_rate |
Un incidente è il momento in cui la metrica effettiva esce dai limiti del SLO concordato in precedenza. Per esempio:
- abbiamo concordato: p95 della selezione dei regali < 4 secondi. È diventato 9 secondi;
- vogliamo che il 99% dei checkout in una settimana abbia successo, ma è diventato 94%;
- ci aspettiamo che negli scenari con acquisto il modello quasi sempre chiami create_checkout_session, ma dai log vediamo un aumento brusco di «mancate chiamate».
Importante: un incidente non è «qualcuno in chat si è lamentato». La lamentela è un trigger, ma la decisione «sì, è un incidente» la prendiamo basandoci su SLO/SLI e dashboard.
2. Come SLO/SLI si trasformano in incidenti
Nel modulo sull’osservabilità hai già definito le metriche chiave: latenza, disponibilità, error‑rate, successo del checkout. Ora usiamole come «guardiani alla porta».
Lo scenario più semplice: abbiamo uno SLO su checkout_success_rate. Teniamo log strutturati degli eventi:
// Esempio di evento di log di checkout nel server MCP
logger.info({
event: 'checkout_result',
request_id,
user_id,
checkout_session_id,
status: 'success', // oppure 'failed'
error_code: null,
});
Su questi log si costruisce la metrica: quota di status = "success" tra tutti i checkout_result negli ultimi N minuti/ore. Quando questa quota scende sotto la soglia (per esempio, 95% su 10 minuti), il monitoring invia un alert al canale on‑call. Questa è la rilevazione dell’incidente: l’SLI è uscita dai limiti dello SLO.
Allo stesso modo possono scattare alert per:
- crescita di error_rate degli strumenti suggest_gifts, search_products;
- crescita di p95/p99 della latenza;
- calo anomalo del numero di workflow_completed (le persone non arrivano a fine percorso);
- crescita anomala dei costi LLM senza crescita del traffico (incidente economico).
Tutto questo è possibile solo perché registriamo in modo strutturato, e non scriviamo nei log «qualcosa non va di nuovo con il checkout». Quando le metriche e gli alert sono configurati, impariamo a notare che qualcosa è andato storto. La domanda successiva: cosa succede dopo la detection, chi e come reagisce?
3. Ciclo di vita di un incidente: dalla detection al post‑mortem
Per non vivere in modalità incendio perpetuo, è utile descrivere un pipeline standard dell’incidente. Molti team SRE lo formalizzano come una catena:
flowchart TD
D["Detection (rilevamento)"] --> T["Triage (valutazione della gravità)"]
T --> M["Mitigation (mitigazione rapida)"]
M --> R["Resolution (correzione definitiva)"]
R --> P["Post-mortem (analisi e miglioramenti)"]
Analizziamo le fasi con l’esempio di GiftGenius.
Detection — come capire che le cose vanno male
L’individuazione del problema può essere automatica o manuale.
Automatica — sono gli alert dal monitoring basati su SLO/SLI:
- PagerDuty / Opsgenie / email / bot Slack segnala: SEV-1: checkout_success_rate < 60% su 10 minuti;
- alert sulla latenza: p95(suggest_gifts) > 10 s;
- anomalia sui costi: «i costi LLM sono raddoppiati con lo stesso numero di workflow_completed».
Manuale — quando al supporto (o direttamente a te su Telegram) arriva un’ondata di messaggi «il pagamento non va a buon fine», «il widget ruota all’infinito». A volte è proprio questo a mettere in luce il problema prima che il monitoring lo recuperi.
Conclusione pratica: anche se ancora non hai un monitoring perfetto, abitua a guardare qualsiasi lamentela di massa degli utenti attraverso la lente delle metriche: «quale metrica c’è dietro e come la misuriamo?».
Triage — classificazione e prioritizzazione
Dopo la detection bisogna rispondere a due domande: quanto è grave e chi si metterà a intervenire.
È utile avere una scala di gravità semplice:
- SEV-1: critico — gli utenti non possono acquistare, l’App non funziona sul percorso chiave (per esempio, checkout=0 con traffico attivo).
- SEV-2: serio ma con degradazione — parte degli utenti non riesce a completare il percorso, la latenza è aumentata sensibilmente ma non fino allo zero.
- SEV-3: bug minori — uno dei tool aggiuntivi a volte cade, si rompe solo un edge case.
Per GiftGenius gli incidenti di commerce sono quasi sempre SEV-1: se i soldi non circolano, non è solo un problema tecnico, ma un danno diretto a ricavi e fiducia.
In questo stesso passaggio si assegna l’on‑call (o tu stesso, se il team è di una persona) e si prende la decisione: «Sì, è un incidente ufficiale SEV‑1, lavoriamo secondo il runbook N» (il runbook è un’istruzione passo‑passo definita in anticipo; ne analizzeremo la struttura in una sezione separata).
Mitigation — fermare l’«emorragia»
La mitigation non è la ricerca della causa radice, ma misure rapide affinché gli utenti soffrano meno. Esempi:
- rollback dell’ultimo rilascio MCP/Agents/ACP;
- disattivazione del feature flag problematico;
- passare GiftGenius alla modalità «solo visualizzazione»: mostriamo raccomandazioni ma non permettiamo l’acquisto;
- riduzione temporanea del carico (rate limiting) o disattivazione degli strumenti pesanti.
Esempio tipico di codice per la «modalità degradata» nel nostro MCP:
// Pseudo-codice: flag globale che si può commutare rapidamente
let checkoutDisabled = false;
export function setCheckoutDisabled(value: boolean) {
checkoutDisabled = value;
}
export async function createCheckoutSession(args: CheckoutArgs) {
if (checkoutDisabled) {
// Comunichiamo al modello che l'acquisto è temporaneamente non disponibile
return {
error: 'checkout_temporarily_disabled',
message: 'Il pagamento non è temporaneamente disponibile, mostra una spiegazione all’utente.',
};
}
// logica normale di creazione della sessione
}
Nel sistema di feature flag puoi attivare setCheckoutDisabled(true) come parte della mitigation: almeno gli utenti non riceveranno 500 o pagamenti bloccati, ma vedranno un messaggio onesto.
Resolution — correzione definitiva
Quando «l’emorragia è stata fermata», hai il tempo di trovare la causa radice e correggerla:
- bug nel codice MCP/ACP;
- problemi con un provider esterno (Stripe, gateway di pagamento);
- limiti su OpenAI API (429, sovraccarico);
- prompt rotto o cambio di modello che ha smesso di chiamare il tool.
La resolution in genere include:
- fix (patch/rollback/configurazione);
- deploy su staging, poi su produzione;
- verifica di tutte le SLI/SLO;
- riportare i flag allo stato normale.
Post-mortem — imparare dagli errori
Dopo l’incidente, soprattutto SEV‑1/SEV‑2, si esegue un post‑mortem: un documento in cui rispondi onestamente alle domande:
- cosa è successo (fatti e timeline);
- come è stato rilevato;
- come si è reagito;
- cosa ha funzionato bene e cosa no;
- quali cambiamenti farai per evitare che si ripeta.
Il post‑mortem non serve a trovare colpevoli, ma a migliorare sistema e processo. Sulla sua base si aggiornano runbook, alert e talvolta anche l’architettura.
4. Ruoli e responsabilità: anche se sei «solo»
Per far funzionare nella pratica il pipeline di incidenti descritto sopra, è importante concordare in anticipo chi prende quali decisioni durante l’emergenza. Anche se il tuo team sta in un solo ascensore, ha senso formalizzare i ruoli negli incidenti. Questo riduce il caos.
Di solito si distinguono:
- Ingegnere on‑call — a cui arriva per primo l’alert e che prende decisioni tecniche per stabilizzare (rollback, feature flag, placeholder temporanei).
- Incident commander — la persona che guida il processo: registra la timeline, decide le priorità, vigila che il team non si disperda. In un micro‑team è lo stesso on‑call, ma con un «cappello» diverso.
- Comunicazione — responsabile della comunicazione con utenti e stakeholder: messaggi in Slack, sulla status page, nell’interfaccia dell’App (widget/chat), nello store di ChatGPT.
- Scribe — annota passi e fatti importanti; su questi appunti si scrive poi il post‑mortem.
In un team di una sola persona i quattro ruoli sei tu; è solo utile passare consapevolmente tra le modalità: «ora sono l’ingegnere e riparo», «ora comunico», «ora registro la timeline».
5. Runbook: un manuale al posto della memoria
Un runbook è un documento che descrive passo‑passo cosa fare per un determinato tipo di incidente: quali grafici guardare, quali pulsanti premere, a cosa si può rinunciare. Riduce molto l’improvvisazione e lo stress.
Struttura di un runbook
Di solito un runbook contiene:
- Breve descrizione dell’incidente e di come viene rilevato. Esempio: «Aumento degli errori ACP checkout > 5% in 5 minuti» oppure «Error talking to app per >20% delle richieste».
- Ambito (scope) — chi è impattato: tutto il traffico, solo una regione, solo un tool specifico.
- Dove guardare: link ai dashboard (SLO sul checkout, error‑rate MCP, log con tool_name = create_checkout_session), a MCP Inspector ecc.
- Passi rapidi di mitigation: «controllare lo status di Stripe», «fare rollback dell’ultimo rilascio ACP», «attivare la modalità raccomandazioni senza acquisto».
- Passi per l’analisi definitiva e il fix.
- Cosa aggiornare a valle: alert, codice, documentazione.
Mini‑esempio di runbook per GiftGenius (il checkout fallisce)
Descriviamolo come dati strutturati, per avvicinarlo al codice:
type Severity = 'SEV-1' | 'SEV-2' | 'SEV-3';
interface RunbookStep {
title: string;
description: string;
}
interface Runbook {
id: string;
title: string;
severity: Severity;
detection: string;
steps: RunbookStep[];
}
export const checkoutFailureRunbook: Runbook = {
id: 'rb-checkout-failure',
title: 'Aumento degli errori di checkout in GiftGenius',
severity: 'SEV-1',
detection: 'Alert: checkout_success_rate < 60% su 10 minuti',
steps: [
{
title: 'Verificare gli stati esterni',
description: 'Aprire lo status di Stripe e dell’ACP backend, assicurarsi che non ci sia un outage globale.',
},
{
title: 'Verificare i rilasci recenti',
description: 'Controllare se ci sono stati deploy MCP/ACP negli ultimi 30 minuti. Se necessario, fare rollback.',
},
],
};
In un runbook reale aggiungerai altri passi: attivare il flag di «sola lettura», mostrare un banner nel widget, raccogliere log per il post‑mortem.
Esempio di testo per il widget in caso di incidente di commerce
Nel runbook è utile pensare in anticipo anche al testo per l’utente. Per esempio, nel widget di GiftGenius si può mostrare:
«Al momento stiamo riscontrando problemi tecnici temporanei con i pagamenti. Puoi comunque salvare le idee regalo che ti piacciono e completare l’acquisto più tardi.»
Questo testo poi può essere cablato in uno stato dell’UI:
// Pseudocodice dello stato del widget
const [checkoutAvailable, setCheckoutAvailable] = useState(true);
if (!checkoutAvailable) {
return (
<Alert>
Il pagamento non è temporaneamente disponibile. Puoi comunque esplorare e salvare idee regalo.
</Alert>
);
}
6. Pratica su GiftGenius: codice intorno agli incidenti
Per non lasciare il tema puramente organizzativo, guardiamo un paio di pezzi di codice che aiutano direttamente nell’incident management.
Endpoint di health‑check per MCP/Backend
Uno strumento semplice ma importante — l’health‑check. In Next.js 16 si può creare tramite un route handler:
// app/api/health/route.ts
import { NextRequest, NextResponse } from 'next/server';
export function GET(_req: NextRequest) {
// Si possono aggiungere controlli su DB, code, ecc.
return NextResponse.json({
status: 'ok',
mcp: 'healthy',
timestamp: new Date().toISOString(),
});
}
Il sistema di monitoring interrogherà periodicamente /api/health. Se invece di 200 OK arrivano timeout o 5xx, è un segnale evidente di un incidente di disponibilità (MCP non è vivo).
Classificazione dell’incidente in base alle metriche
Dal lato del servizio analitico o di uno script backend admin si può mantenere una logica semplice per determinare la gravità:
type Severity = 'SEV-1' | 'SEV-2' | 'SEV-3';
interface IncidentContext {
checkoutSuccessRate: number; // 0..1
giftSearchErrorRate: number; // 0..1
p95GiftSearchMs: number;
}
export function classifyIncident(ctx: IncidentContext): Severity | null {
if (ctx.checkoutSuccessRate < 0.6) return 'SEV-1'; // i soldi non circolano
if (ctx.giftSearchErrorRate > 0.3 || ctx.p95GiftSearchMs > 8000) return 'SEV-2';
return null; // non ancora un incidente
}
Questo pezzo può essere eseguito in cron o innescato dal monitoring: al ritorno di SEV‑1 si crea automaticamente un incidente nel tuo sistema e parte la notifica all’on‑call.
Logging degli eventi chiave dell’incidente
Gli incidenti non sono solo metriche ma anche eventi: quando l’incidente è creato, modificato, chiuso. È utile tenerli in log separati.
function logIncidentEvent(event: {
incidentId: string;
type: 'created' | 'mitigated' | 'resolved';
severity: Severity;
requestId?: string;
message: string;
}) {
logger.warn({
level: 'WARN',
service: 'incident-manager',
...event,
timestamp: new Date().toISOString(),
});
}
Per esempio, quando si abilita la modalità «read‑only» per GiftGenius:
setCheckoutDisabled(true);
logIncidentEvent({
incidentId: 'inc-2025-11-21-001',
type: 'mitigated',
severity: 'SEV-1',
message: 'Checkout disabled, app switched to recommendations-only mode',
});
Questi eventi sono poi facili da trovare e collegare alle serie temporali delle metriche.
7. Calendario operativo: la vita dopo «evviva, è tutto sistemato»
L’incident management non è solo spegnere incendi, ma anche prevenzione regolare. Nelle pratiche SRE il ciclo operativo è spesso descritto come un calendario operativo con revisioni periodiche di SLO, costi e sicurezza.
Possiamo dividere le attività per periodicità.
Settimanale
Una volta a settimana (o ogni due) ha senso:
- rivedere gli SLO principali: latenza, error‑rate, successo del checkout, quota di incidenti per categoria;
- verificare se ci sono stati alert «spenti da soli» e decidere se inasprire/allentare le soglie;
- analizzare brevemente almeno un incidente (anche SEV‑3) — allena il muscolo del post‑mortem.
Mensile
Una volta al mese è bene:
- rivedere i costi (LLM, commissioni ACP/Stripe, infrastruttura) e confrontarli con i ricavi — collegato ai temi 1–2 del modulo 19;
- guardare le metriche di prodotto: activation, retention, conversione workflow_completed → checkout_success — collegato al modulo su marketing e crescita;
- passare in rassegna i log di sicurezza alla ricerca di anomalie: pattern di login strani, errori di autorizzazione, picchi inusuali di richieste (ponte verso il modulo sulla sicurezza).
Trimestrale
Una volta a trimestre si:
- ruotano i segreti: chiavi API di OpenAI, Stripe, client OAuth ecc.;
- verifica se gli SLO sono obsoleti: magari l’App è cresciuta e ora un p95 di 2 secondi invece di 1 è la norma, oppure al contrario puoi inasprire gli obiettivi;
- rivedono i runbook: nuovi tipi di incidenti, dipendenze aggiornate (SDK, specifica MCP, ecc.).
Il calendario può essere mantenuto semplicemente come pagina Wiki o README nel repository di GiftGenius: l’importante è che sia «vivo» e aggiornato.
8. Incidenti, denaro e prodotto: perché un incendio commerce è il più «rovente»
Il modulo 19 riguarda in generale l’economia e la «vita operativa» dell’App, e gli incidenti qui sono strettamente legati al denaro. Gli incidenti di commerce — quando il checkout non passa, i soldi vengono bloccati o addebitati due volte — hanno quasi sempre priorità più alta rispetto, ad esempio, a un timeout occasionale nella ricerca dei regali.
Le ragioni sono semplici:
- perdite dirette di ricavi nel momento attuale;
- rischio di perdita di fiducia (un utente a cui sono stati addebitati soldi senza ricevere il prodotto difficilmente tornerà);
- potenziali conseguenze legali e reputazionali.
Perciò nel tuo catalogo degli incidenti di GiftGenius quelli di commerce devono essere chiaramente contrassegnati come SEV‑1 con SLO rigorosi sul tempo di reazione (ad esempio, «reazione dell’on‑call entro 15 minuti, mitigation entro un’ora»).
Le anomalie economiche (per esempio, il costo dell’LLM cresce bruscamente senza crescita dei ricavi) sono anch’esse incidenti, ma di solito di livello SEV‑2: non rompono l’UX immediatamente, ma possono «mangiare» tutto il margine se non notate.
Dal punto di vista di prodotto, ogni incidente importante è un’occasione per riflettere:
- il workflow è troppo complesso (magari più semplice = più affidabile);
- conviene aggiungere uno scenario di fallback: ad esempio, se l’MCP non risponde, il modello restituisce comunque suggerimenti senza dati esterni;
- serve modificare l’UX per comunicare onestamente i problemi invece di nasconderli.
9. Mini‑esercizi (per lavoro autonomo)
Anche se la lezione non è un laboratorio pratico, consiglio vivamente di eseguire davvero i passi seguenti sul tuo GiftGenius:
- Descrivere in un documento almeno due runbook:
- «Errori massivi durante il pagamento (checkout)»;
- «MCP non risponde / ChatGPT mostra Error talking to app».
- Creare un calendario operativo per un mese:
- quali SLO controllerai ogni settimana;
- quale review dei costi farai a fine mese;
- quali controlli di sicurezza includerai (almeno di base).
Questo richiederà un paio d’ore, ma cambierà molto il tuo modo di guardare la tua applicazione: smetterà di essere solo codice e diventerà un servizio vivo.
Errori tipici nell’incident management delle ChatGPT Apps
Errore n. 1: «Un incidente è solo quando tutto è giù»
Molti per abitudine considerano incidente solo il crollo totale di MCP o del database. Nelle AI‑App spesso sono più dolorosi gli incidenti «morbidi» di qualità: il modello ha smesso di chiamare il tool giusto, il flusso di checkout è diventato confuso, gli utenti non arrivano alla fine anche se le metriche HTTP sono verdi. Se non consideri tali situazioni come incidenti e non le analizzi, la qualità dell’App degraderà in modo silenzioso.
Errore n. 2: Mancanza di SLO chiari e di confini della «normale operatività»
Senza SLO formali qualsiasi discussione su un incidente diventa «a me sembra lento» vs «in locale è veloce». È proprio per questo che gli SLO sono la base dell’incident management: rendono oggettiva la gravità del problema.
Errore n. 3: Improvvisazione al posto dei runbook
Scenario diffuso: alert, tutti corrono nel prod nel panico, qualcuno fa rollback del rilascio, qualcuno modifica i config; dopo un’ora «sembra risolto», ma nessuno ricorda cosa abbia aiutato. Senza runbook ogni incidente è un mini‑caos e il team non impara. Anche un singolo runbook semplice per il checkout riduce molto lo stress.
Errore n. 4: Ignorare la comunicazione con gli utenti
Talvolta gli ingegneri sistemano in silenzio, mentre gli utenti vedono solo la «rotellina» e l’errore «qualcosa è andato storto». Per gli scenari di commerce questo è particolarmente tossico: le persone sono preoccupate per i soldi. È importante avere in anticipo template di messaggi nel widget, nella descrizione dell’App e, se necessario, in canali esterni, per indicare onestamente il problema e il tempo stimato di risoluzione.
Errore n. 5: Dare la colpa a «OpenAI» senza analizzare la propria parte
È facile attribuire tutto a «OpenAI non funziona», ma la pratica mostra che anche con problemi upstream si può fare molto dal proprio lato: gestire correttamente timeout ed errori, passare alla modalità senza MCP, ridurre il numero di retry per non peggiorare la situazione. Il concetto di responsabilità condivisa implica che tu risponda della tua parte della catena, anche se uno dei provider è instabile.
Errore n. 6: Niente post‑mortem e ciclo operativo
Se l’incidente si chiude con «ok, sembra a posto, andiamo avanti» e nessun documento, alert o codice cambia — il sistema è destinato a ripetere gli stessi errori. Post‑mortem, revisioni regolari di SLO, costi e sicurezza — non sono burocrazia, ma un modo per mettersi d’accordo con il proprio io futuro e con il team, affinché tra un anno GiftGenius sia più affidabile e non più fragile.
GO TO FULL VERSION