1. Qu’est-ce qu’un incident dans le monde des ChatGPT Apps
Dans le web classique, un incident est généralement quelque chose comme « le serveur est down », « les erreurs 500 ont fortement augmenté », « la latency a doublé ». Définition formelle selon ITIL : un incident est une interruption non planifiée du service ou une dégradation de sa qualité.
Dans le monde des ChatGPT Apps et de GiftGenius, le tableau est plus complexe. Nous avons une couche de modèles, qui peuvent :
- ne pas appeler l’outil requis, alors que tout est disponible ;
- appeler un tool avec des paramètres incorrects ;
- « halluciner » un résultat en ignorant votre MCP.
Ainsi, un incident peut être non seulement un HTTP 500, mais aussi une situation où toutes les métriques back‑end sont au vert alors que les utilisateurs se plaignent massivement : « le bot rame et n’affiche pas de cadeaux » — parce que le modèle a cessé d’appeler suggest_gifts ou mélange les arguments. C’est un incident de qualité (Quality incident).
Il est pratique de raisonner par catégories d’incidents :
| Catégorie | Exemple de symptôme | Exemple de métrique (SLI) |
|---|---|---|
| Availability | MCP ne répond pas, « Error talking to app » dans ChatGPT | % de réponses réussies /mcp |
| Latency | la sélection de cadeaux prend 10+ secondes | p95 du temps d’appel de suggest_gifts |
| Quality | le modèle n’appelle pas l’outil requis, confond la devise | part des requêtes sans appel d’outil lors d’une demande explicite |
| Commerce | le checkout ne passe plus, l’argent ne bouge pas | checkout_success_rate |
Un incident, c’est le moment où la métrique réelle sort du SLO convenu à l’avance. Par exemple :
- nous avons convenu : p95 de la sélection de cadeaux < 4 secondes. C’est passé à 9 secondes ;
- nous voulons que 99% des checkouts hebdomadaires réussissent, et c’est devenu 94% ;
- nous attendons que, dans les scénarios d’achat, le modèle appelle presque toujours create_checkout_session, et les logs montrent une forte hausse des « omissions ».
Important : un incident, ce n’est pas « quelqu’un s’est plaint dans le chat ». Une plainte est un déclencheur, mais la décision « oui, c’est un incident » se prend en s’appuyant sur les SLO/SLI et les tableaux de bord.
2. Comment les SLO/SLI se transforment en incidents
Dans le module sur l’observabilité, vous avez déjà défini les métriques clés : latency, availability, error‑rate, succès de checkout. Nous allons maintenant les utiliser comme « gardiens à la porte ».
Scénario le plus simple : nous avons un SLO sur checkout_success_rate. Nous tenons des logs structurés d’événements :
// Exemple d'événement de log checkout sur le serveur MCP
logger.info({
event: 'checkout_result',
request_id,
user_id,
checkout_session_id,
status: 'success', // ou 'failed'
error_code: null,
});
Sur ces logs, on calcule une métrique : la part de status = "success" parmi tous les checkout_result sur les N dernières minutes/heures. Quand cette part passe sous le seuil (par exemple, 95% sur 10 minutes), le monitoring envoie une alerte dans le canal on‑call. C’est la détection de l’incident : le SLI sort du SLO.
De même, des alertes peuvent se déclencher sur :
- la hausse de error_rate des outils suggest_gifts, search_products ;
- l’augmentation de la latency p95/p99 ;
- une chute anormale du nombre de workflow_completed (les gens n’aboutissent pas au bout du scénario) ;
- une hausse anormale du coût LLM sans hausse de trafic (incident économique).
Tout cela n’est possible que parce que nous journalisons de manière structurée, au lieu d’écrire dans les logs « quelque chose ne va pas avec le checkout ». Une fois les métriques et alertes en place, nous savons remarquer quand quelque chose se passe mal. Question suivante : que se passe‑t‑il après la détection, qui réagit et comment ?
3. Cycle de vie d’un incident : de la détection au post‑mortem
Pour éviter de vivre en mode incendie permanent, il est utile de décrire le pipeline standard d’un incident. Beaucoup d’équipes SRE le formalisent comme une chaîne :
flowchart TD
D["Detection (détection)"] --> T["Triage (évaluation de la gravité)"]
T --> M["Mitigation (endiguement rapide)"]
M --> R["Resolution (correction définitive)"]
R --> P["Post-mortem (analyse et améliorations)"]
Voyons les étapes sur l’exemple de GiftGenius.
Detection — comment comprendre que ça va mal
L’identification du problème peut être automatique ou manuelle.
Automatique — ce sont les alertes de monitoring basées sur les SLO/SLI :
- PagerDuty / Opsgenie / e‑mail / bot Slack hurle : SEV-1 : checkout_success_rate < 60% sur 10 minutes ;
- alerte sur la latency : p95(suggest_gifts) > 10 s ;
- anomalie de coût : « Les dépenses LLM ont doublé pour le même nombre de workflow_completed ».
Détection manuelle — quand le support (ou vous, en direct sur Telegram) reçoit un flot de messages « le paiement ne passe pas », « le widget tourne indéfiniment ». Parfois, c’est ce qui met le problème en lumière avant que le monitoring ne le rattrape.
Conclusion pratique : même si vous n’avez pas encore un monitoring idéal, prenez l’habitude d’examiner toute plainte massive d’utilisateurs à travers le prisme des métriques : « quelle métrique cela représente‑t‑il et comment la mesurer ? ».
Triage — classification et priorisation
Après la détection, il faut répondre à deux questions : à quel point c’est grave et qui va s’en charger.
Il est utile d’avoir une échelle simple de gravité :
- SEV-1 : critique — les utilisateurs ne peuvent pas acheter, l’App ne fonctionne pas sur le scénario clé (par exemple, checkout = 0 avec du trafic actif).
- SEV-2 : sérieux, mais en dégradation — une partie des utilisateurs ne peut pas terminer le scénario, la latency a fortement augmenté, mais pas jusqu’à l’arrêt complet.
- SEV-3 : bogues mineurs — l’un des tools additionnels plante parfois, seul un cas limite est cassé.
Pour GiftGenius, les incidents commerce sont presque toujours SEV-1 : si l’argent ne circule pas, ce n’est pas qu’un problème technique, c’est une perte directe de revenus et de confiance.
À cette étape, on nomme l’on‑call (ou vous-même si vous êtes une équipe d’une seule personne) et on prend la décision : « Oui, c’est un incident officiel SEV‑1, on suit le runbook n° N » (un runbook est une procédure pas‑à‑pas documentée ; on verra sa structure dans une section séparée).
Mitigation — arrêter l’« hémorragie »
La mitigation n’est pas la recherche de la cause profonde, mais des mesures rapides pour réduire l’impact sur les utilisateurs. Exemples :
- rollback de la dernière release MCP/Agents/ACP ;
- désactivation du feature flag problématique ;
- basculer GiftGenius en mode « consultation » : nous affichons des recommandations, mais n’autorisons pas l’achat ;
- réduction temporaire de la charge (rate limiting) ou désactivation des outils lourds.
Exemple typique de code pour un « mode dégradé » dans notre MCP :
// Pseudo-code : un drapeau global basculable rapidement
let checkoutDisabled = false;
export function setCheckoutDisabled(value: boolean) {
checkoutDisabled = value;
}
export async function createCheckoutSession(args: CheckoutArgs) {
if (checkoutDisabled) {
// Informer le modèle que l'achat est temporairement indisponible
return {
error: 'checkout_temporarily_disabled',
message: "Le paiement est temporairement indisponible, affiche une explication à l'utilisateur.",
};
}
// logique habituelle de création de session
}
Dans votre système de feature flags, vous pouvez basculer setCheckoutDisabled(true) dans le cadre de la mitigation : les utilisateurs ne recevront au moins pas de 500 ni de paiements bloqués, mais verront un message explicite.
Resolution — correction définitive
Quand « l’hémorragie est stoppée », vous avez du temps pour trouver la cause racine et la corriger :
- bogue dans le code MCP/ACP ;
- problème chez un fournisseur tiers (Stripe, passerelle de paiement) ;
- limites sur l’API OpenAI (429, surcharge) ;
- prompt cassé ou modèle changé qui n’appelle plus le tool.
La resolution comprend généralement :
- un correctif (patch/rollback/config) ;
- un déploiement sur staging, puis sur production ;
- la vérification de tous les SLI/SLO ;
- le retour des flags à l’état normal.
Post-mortem — apprendre de ses erreurs
Après un incident, en particulier SEV‑1/SEV‑2, on mène un post‑mortem : un document où vous répondez honnêtement aux questions :
- ce qui s’est passé (faits et frise chronologique) ;
- comment cela a été détecté ;
- comment vous avez réagi ;
- ce qui a bien fonctionné et ce qui n’a pas marché ;
- quels changements vous ferez pour éviter la répétition.
Le post‑mortem n’est pas une chasse aux coupables, mais une amélioration du système et du processus. Il sert de base pour mettre à jour les runbooks, les alertes, et parfois même l’architecture.
4. Rôles et responsabilités : même si vous êtes « seul à bord »
Pour que le pipeline d’incident décrit ci‑dessus fonctionne dans la vraie vie, il est important de convenir à l’avance de qui prend quelles décisions pendant l’incendie. Même si votre équipe tient dans un ascenseur, formaliser les rôles lors des incidents a du sens. Cela réduit le chaos.
On distingue généralement :
- Ingénieur on‑call — celui qui reçoit l’alerte en premier et prend les décisions techniques de stabilisation (rollback, feature flags, rustines temporaires).
- Incident commander — la personne qui pilote le processus : consigne la chronologie, arbitre les priorités, veille à ce que l’équipe ne s’éparpille pas. Dans une micro‑équipe, c’est souvent le même on‑call avec une autre « casquette ».
- Communication — responsable de la relation avec les utilisateurs et les parties prenantes business : messages dans Slack, sur la page de statut, dans l’interface de l’App (widget/chat), sur le store ChatGPT.
- Scribe — consigne les étapes et faits importants, puis ce compte rendu sert au post‑mortem.
Dans une équipe d’une seule personne, ces quatre rôles, c’est vous ; il est simplement utile de changer consciemment de mode : « maintenant je suis ingénieur et je répare », « maintenant je communique », « maintenant je note la chronologie ».
5. Runbook : la procédure plutôt que la mémoire
Un runbook est un document qui décrit pas à pas quoi faire pour un type d’incident donné : quels graphiques regarder, quels boutons cliquer, sur quoi on peut faire des compromis. Il réduit fortement l’improvisation et le niveau de stress.
Structure d’un runbook
Un runbook contient généralement :
- Une brève description de l’incident et comment il est détecté. Exemple : « Hausse des erreurs ACP checkout > 5% sur 5 minutes » ou « Error talking to app pour >20% des requêtes ».
- Scope — qui est impacté : tout le trafic, une région seulement, un tool spécifique seulement.
- Où regarder : liens vers les tableaux de bord (SLO sur le checkout, error‑rate MCP, logs avec tool_name = create_checkout_session), vers MCP Inspector, etc.
- Actions rapides de mitigation : « vérifier le statut Stripe », « rollback de la dernière release ACP », « activer le mode recommandations sans achat ».
- Étapes pour l’analyse définitive et le correctif.
- Ce qu’il faut mettre à jour à l’issue : alertes, code, documentation.
Mini‑exemple de runbook pour GiftGenius (le checkout échoue)
Décrivons‑le sous forme de données structurées, pour se rapprocher du code :
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: 'Hausse des erreurs de checkout dans GiftGenius',
severity: 'SEV-1',
detection: 'Alerte : checkout_success_rate < 60% sur 10 minutes',
steps: [
{
title: 'Vérifier les statuts externes',
description: "Ouvrir le statut Stripe et l'ACP backend, s'assurer qu'il n'y a pas de panne générale.",
},
{
title: 'Vérifier les derniers déploiements',
description: 'Vérifier s’il y a eu des déploiements MCP/ACP durant les 30 dernières minutes. Faire un rollback si nécessaire.',
},
],
};
Dans un runbook réel, vous ajouterez plus d’étapes : activer un feature flag read‑only, afficher une bannière dans le widget, collecter des logs pour le post‑mortem.
Exemple de texte pour le widget lors d’un incident commerce
Il est utile de prévoir à l’avance dans le runbook le texte destiné à l’utilisateur. Par exemple, le widget de GiftGenius peut afficher :
« Nous rencontrons actuellement des problèmes techniques temporaires avec le paiement. Vous pouvez quand même enregistrer les idées de cadeaux qui vous plaisent et finaliser l’achat un peu plus tard. »
Ainsi, ce texte peut être intégré dans l’état du composant UI :
// Pseudo-code de l'état du widget
const [checkoutAvailable, setCheckoutAvailable] = useState(true);
if (!checkoutAvailable) {
return (
<Alert>
Le paiement est temporairement indisponible. Vous pouvez toujours parcourir et enregistrer des idées de cadeaux.
</Alert>
);
}
6. Pratique sur GiftGenius : code autour des incidents
Pour que le sujet ne reste pas purement organisationnel, regardons quelques extraits de code qui aident directement à la gestion d’incidents.
Endpoint de health‑check pour MCP/Backend
Outil simple mais important : le health‑check. Avec Next.js 16, on peut le faire via un route handler :
// app/api/health/route.ts
import { NextRequest, NextResponse } from 'next/server';
export function GET(_req: NextRequest) {
// On peut ajouter des vérifications de base de données, de files, etc.
return NextResponse.json({
status: 'ok',
mcp: 'healthy',
timestamp: new Date().toISOString(),
});
}
Le système de monitoring va interroger périodiquement /api/health. Si, au lieu de 200 OK, on observe des timeouts ou des 5xx, c’est un signal clair d’un incident d’Availability (MCP non vivant).
Classification d’un incident selon les métriques
Côté service analytique ou script d’admin backend, on peut garder une logique simple de détermination de 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'; // l'argent ne circule pas
if (ctx.giftSearchErrorRate > 0.3 || ctx.p95GiftSearchMs > 8000) return 'SEV-2';
return null; // pas encore un incident
}
Ce bout de code peut être exécuté par cron ou déclenché par le monitoring : en cas de retour SEV‑1, un incident est créé automatiquement dans votre système et une notification part à l’on‑call.
Journalisation des événements clés d’un incident
Les incidents, ce ne sont pas que des métriques, mais aussi des événements : quand un incident est créé, modifié, clôturé. Il est pratique de les garder dans des logs dédiés.
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(),
});
}
Par exemple, lors de l’activation du mode « read‑only » pour GiftGenius :
setCheckoutDisabled(true);
logIncidentEvent({
incidentId: 'inc-2025-11-21-001',
type: 'mitigated',
severity: 'SEV-1',
message: 'Checkout disabled, app switched to recommendations-only mode',
});
On peut ensuite retrouver facilement ces événements et les corréler avec les séries temporelles des métriques.
7. Calendrier opérationnel : la vie après « youpi, tout est réparé »
La gestion d’incidents, ce n’est pas seulement éteindre des incendies, c’est aussi de la prévention régulière. Dans les pratiques SRE, le cycle opérationnel est souvent décrit comme un calendrier opérationnel avec des revues régulières des SLO, des coûts et de la sécurité.
On peut diviser les activités par périodicité.
Hebdomadaire
Une fois par semaine (ou toutes les deux), il est pertinent de :
- passer en revue les SLO principaux : latency, error‑rate, succès du checkout, part d’incidents par catégorie ;
- regarder s’il y a eu des alertes « auto‑résolues » et décider s’il faut renforcer/assouplir les seuils ;
- analyser brièvement au moins un incident (même SEV‑3) — cela entraîne le réflexe post‑mortem.
Mensuel
Une fois par mois, il est bon de :
- faire une revue des coûts (LLM, commissions ACP/Stripe, infrastructure) et les comparer au revenu — lien avec les thèmes 1–2 du module 19 ;
- examiner les métriques produit : activation, rétention, conversion workflow_completed → checkout_success — lien avec le module marketing et croissance ;
- parcourir les logs de sécurité pour détecter des anomalies : motifs de connexion étranges, erreurs d’autorisation, pics de requêtes inhabituels (pont vers le module sécurité).
Trimestriel
Une fois par trimestre, vous :
- faites une rotation des secrets : clés API OpenAI, Stripe, clients OAuth, etc. ;
- vérifiez si les SLO ne sont pas obsolètes : peut‑être que l’App a grandi et que désormais p95 à 2 secondes au lieu de 1 est la norme, ou au contraire que vous pouvez durcir les objectifs ;
- revoyez les runbooks : nouveaux types d’incidents, dépendances mises à jour (SDK, spéc MCP, etc.).
Le calendrier peut simplement vivre sous forme de page Wiki ou de README dans le dépôt GiftGenius : l’essentiel est qu’il soit « vivant » et maintenu à jour.
8. Incidents, argent et produit : pourquoi un incendie commerce est le plus brûlant
Le module 19 porte globalement sur l’économie et la « vie opérationnelle » d’une App, et les incidents y sont étroitement liés à l’argent. Les incidents commerce — quand le checkout échoue, que l’argent est bloqué ou débité deux fois — sont presque toujours plus prioritaires que, par exemple, un timeout ponctuel lors de la recherche de cadeaux.
Les raisons sont simples :
- pertes directes de revenus à l’instant T ;
- risque de perte de confiance (un utilisateur à qui l’on a débité de l’argent sans livrer aura du mal à revenir) ;
- conséquences potentielles juridiques et de réputation.
Ainsi, dans votre catalogue d’incidents GiftGenius, les incidents commerce doivent être explicitement marqués SEV‑1 avec des SLO stricts sur le temps de réaction (par exemple, « réaction on‑call en 15 minutes, mitigation en une heure »).
Les anomalies économiques (par exemple, un coût LLM qui grimpe sans hausse du revenu) sont aussi des incidents, mais en général de niveau SEV‑2 : elles ne cassent pas l’UX immédiatement, mais peuvent « manger » toute la marge si on ne les voit pas.
Côté produit, tout incident majeur est l’occasion de réfléchir :
- le workflow n’est‑il pas trop complexe (parfois plus simple = plus fiable) ;
- faut‑il ajouter un scénario de repli : par exemple, si MCP ne répond pas, le modèle donne au moins des conseils sans données externes ;
- faut‑il adapter l’UX pour annoncer honnêtement les problèmes plutôt que de les masquer.
9. Mini‑exercices (travail autonome)
Même si la leçon n’est pas un atelier, je recommande vivement d’effectuer réellement les étapes suivantes sur votre GiftGenius :
- Décrire dans un même document au moins deux runbooks :
- « Erreurs massives lors du paiement (checkout) » ;
- « MCP ne répond pas / ChatGPT affiche Error talking to app ».
- Établir un calendrier opérationnel pour un mois :
- quels SLO vous examinerez chaque semaine ;
- quel bilan de coûts vous ferez en fin de mois ;
- quelles vérifications de sécurité vous inclurez (au moins basiques).
Cela prendra quelques heures, mais changera radicalement votre regard sur votre application : elle cessera d’être seulement du code et deviendra un service vivant.
Erreurs typiques dans la gestion d’incidents des ChatGPT Apps
Erreur n° 1 : « Un incident, c’est seulement quand tout est down »
Beaucoup considèrent par habitude qu’un incident n’est que la panne totale du MCP ou de la base. Dans les AI‑Apps, les incidents « doux » de qualité sont souvent plus douloureux : le modèle n’appelle plus l’outil requis, le flux de checkout devient confus, les utilisateurs n’arrivent pas au bout alors que les métriques HTTP sont au vert. Si vous ne considérez pas ces situations comme des incidents et ne les analysez pas, la qualité de l’App se dégradera insidieusement.
Erreur n° 2 : absence de SLO clairs et de frontières du « fonctionnement normal »
Sans SLO formels, tout débat sur un incident se transforme en « j’ai l’impression que c’est lent » vs « chez moi c’est rapide ». C’est précisément pour cela que les SLO sont la base de la gestion d’incidents : ils rendent la gravité du problème objective.
Erreur n° 3 : improviser au lieu d’utiliser des runbooks
Scénario courant : alerte, tout le monde panique en prod, quelqu’un rollback, quelqu’un modifie des configs, une heure plus tard « on dirait que c’est réparé », mais personne ne se souvient de ce qui a vraiment aidé. Sans runbooks, chaque incident est un mini‑chaos, et l’équipe n’apprend pas. Même un simple runbook pour un incident de checkout réduit fortement le stress.
Erreur n° 4 : ignorer la communication avec les utilisateurs
Parfois, les ingénieurs réparent en silence, et les utilisateurs ne voient qu’un « spinner » et un « quelque chose s’est mal passé ». Pour les scénarios commerce, c’est particulièrement toxique : les gens s’inquiètent pour leur argent. Il est important d’avoir des modèles de messages prêts dans le widget, la description de l’App et, si nécessaire, des canaux externes, pour indiquer honnêtement le problème et le délai attendu de correction.
Erreur n° 5 : accuser « c’est la faute d’OpenAI » sans examiner sa propre partie
Il est facile de tout mettre sur « OpenAI est instable », mais l’expérience montre que même avec des problèmes upstream, on peut faire beaucoup de choses de son côté : gérer correctement les timeouts et erreurs, basculer en mode sans MCP, réduire le nombre de tentatives afin de ne pas aggraver la situation. La notion de responsabilité partagée implique que vous êtes responsable de votre maillon de la chaîne, même si l’un des fournisseurs est instable.
Erreur n° 6 : pas de post‑mortems ni de cycle opérationnel
Si un incident se termine par « bon, on y va », sans qu’aucun document, alerte ou code ne change, le système est condamné à répéter les mêmes erreurs. Les post‑mortems, les revues régulières des SLO, des coûts et de la sécurité — ce n’est pas de la bureaucratie, c’est une façon de passer un accord avec votre vous futur et votre équipe, pour qu’à l’horizon d’un an GiftGenius soit plus fiable, et non plus fragile.
GO TO FULL VERSION