diff --git a/_portfolio/cedd-hackathon-emotional-drift-detection.md b/_portfolio/cedd-hackathon-emotional-drift-detection.md index eb6e95e..9b97dce 100644 --- a/_portfolio/cedd-hackathon-emotional-drift-detection.md +++ b/_portfolio/cedd-hackathon-emotional-drift-detection.md @@ -11,12 +11,18 @@ description: >- modulation - 90% CV accuracy and 36/36 adversarial tests passing. translation_url: /portfolio/hackathon-cedd-derive-emotionnelle/ translation_label: "🇫🇷 Lire cet article en français" +image: /assets/img/cedd/conversation-demo-en.png --- A single message rarely tells you a young person is in trouble. Twelve messages that get shorter, darker, and further apart do. That shift - from "instant risk in one message" to "drift across a whole conversation" - is the idea behind **CEDD** (*Conversational Emotional Drift Detection*), the second system our team *404HarmNotFound* built at the March 2026 AI safety hackathon organized by [Mila](https://mila.quebec) with Bell and Kids Help Phone. Where our [bilingual input guardrail](/portfolio/mila-hackathon-bilingual-guardrail/) classifies each conversation snapshot as `low_risk` or `high_risk` before it reaches the LLM, CEDD is the orthogonal layer: it monitors the **trajectory** of the user's messages in real time - length, tone, semantic drift, behavioral withdrawal - and adapts the chatbot's behavior *as the conversation degrades*, from warm support all the way to a crisis protocol with a warm handoff to a human. +
+ CEDD Streamlit interface at the end of the 9-message demo: chat on the left, dashboard with Orange alert gauge, class probabilities and active signals on the right +
The CEDD interface at the end of the 9-message demo: the conversation has drifted, the gauge sits at Orange, and the dashboard shows class probabilities and the active signals behind the alert.
+
+ ## The problem: gradual deterioration is invisible to per-message classifiers Emotional support chatbots for youth (the target population here is 16-22) can miss a slow slide into distress: no single message contains a crisis keyword, yet the conversation as a whole is unmistakably drifting. The signals are behavioral as much as lexical - messages getting shorter, hope vocabulary disappearing, topics being avoided, replies coming slower. CEDD turns that intuition into a feature space. @@ -37,6 +43,11 @@ flowchart TD **Classification with a safety-first contract.** A `StandardScaler → GradientBoostingClassifier` pipeline maps the 67D vector to one of four alert levels - Green, Yellow, Orange, Red. But the ML never has the last word: **7 safety gates** wrap it. Crisis keywords force Red instantly at any point; low ML confidence defaults to Yellow (precautionary principle); short conversations cap the ML at Orange; a lexical safety floor guarantees the prediction can never go *below* what keyword rules detected; and long response delays bump the level up. The design rule we kept from the guardrail project applies here too: safety rules can never be overridden by ML. +
+ Emotional flow streamgraph: stacked class probabilities per message, green giving way to yellow then orange, above the session statistics +
The "emotional flow" streamgraph: class probabilities evolving message by message — green gives way to yellow and orange as the drift unfolds.
+
+ **Adaptive response modulation.** The alert level selects one of four system prompts (in the user's language) injected into the conversational LLM: standard warmth at Green, enhanced emotional validation at Yellow, active support with resources at Orange, and at Red a **5-step warm handoff** - empathetic validation, permission-based transition, resources (Kids Help Phone 1-800-668-6868, text 686868, 9-8-8, 911), encouragement to connect, continued presence - plus an optional switch to "Alex", a simulated counselor persona using ASIST active-listening techniques. The LLM layer itself is resilient: a fallback chain (Cohere → Llama 3.3 70B via Groq → Gemini 2.5 Flash → Claude Haiku → static text) with per-model timeouts, so the UI never freezes on a slow provider. **Longitudinal tracking.** A SQLite session tracker follows users *across* sessions: weighted risk score over the last 7 sessions, improving/stable/worsening trend, consecutive high-alert sessions, and withdrawal detection when a user disappears for more than 24 hours after a session without closure. @@ -64,8 +75,18 @@ The adversarial suite is the part I would defend in front of a clinician: 36 han **Explainability is a safety feature.** Every alert ships with its top-5 contributing features (model importance × scaled value), displayed as a bar chart in the bilingual Streamlit dashboard. In a mental-health context, "the system raised an alert because messages shortened 60% and finality vocabulary appeared" is actionable for a counselor; a bare probability is not. +
+ Feature radar comparing message 1 and message 9, with the alert level history chart showing the escalation from Green to Orange +
The feature radar compares message 1 with message 9, and the alert level history traces the Green → Yellow → Orange escalation a counselor can act on.
+
+ **Document your failure modes.** The known-gaps table is part of the deliverable: conjugated crisis forms ("killing myself" vs "kill myself") that slip past the keyword gate, phrase-based identity detection, threshold-based withdrawal detection. In safety work, an honest limitation list is worth more than an inflated metric. +
+ CEDD dashboard in dark mode: alert level evolution, LLM fallback chain selector and active response mode +
The dashboard in dark mode: alert level evolution, the LLM fallback chain selector (Cohere → Groq → Gemini → Claude → static) and the active response mode.
+
+ ## Full cedd-hackathon GitHub project [CEDD Hackathon](https://github.com/dapiced/cedd-hackathon) diff --git a/_portfolio/hackathon-cedd-derive-emotionnelle.md b/_portfolio/hackathon-cedd-derive-emotionnelle.md index ab1b15b..8cf5e11 100644 --- a/_portfolio/hackathon-cedd-derive-emotionnelle.md +++ b/_portfolio/hackathon-cedd-derive-emotionnelle.md @@ -12,12 +12,18 @@ description: >- validation croisée et 36/36 tests adversariaux réussis. translation_url: /portfolio/cedd-hackathon-emotional-drift-detection/ translation_label: "🇬🇧 Read this article in English" +image: /assets/img/cedd/conversation-demo-fr.png --- Un seul message dit rarement qu'un jeune va mal. Douze messages qui deviennent plus courts, plus sombres et plus espacés, oui. Ce déplacement - du « risque instantané dans un message » vers la « dérive sur l'ensemble d'une conversation » - est l'idée derrière **CEDD** (*Conversational Emotional Drift Detection*), le deuxième système que notre équipe *404HarmNotFound* a construit au hackathon sécurité de l'IA de mars 2026, organisé par [Mila](https://mila.quebec/fr) avec Bell et Jeunesse, J'écoute. Là où notre [garde-fou d'entrée bilingue](/portfolio/hackathon-mila-garde-fou-bilingue/) classe chaque instantané de conversation en `low_risk` ou `high_risk` avant qu'il n'atteigne le LLM, CEDD est la couche orthogonale : il surveille en temps réel la **trajectoire** des messages de l'utilisateur - longueur, ton, dérive sémantique, retrait comportemental - et adapte le comportement du chatbot *au fur et à mesure que la conversation se dégrade*, du soutien chaleureux jusqu'au protocole de crise avec transfert accompagné vers un humain. +
+ Interface Streamlit de CEDD à la fin de la démo de 9 messages : conversation à gauche, tableau de bord avec jauge d'alerte Orange, probabilités par classe et signaux actifs à droite +
L'interface CEDD à la fin de la démo de 9 messages (Félix, 18 ans, CÉGEP) : la conversation a dérivé, la jauge est à l'Orange, et le tableau de bord montre les probabilités par classe et les signaux actifs derrière l'alerte.
+
+ ## Le problème : la détérioration graduelle est invisible pour un classifieur par message Les chatbots de soutien émotionnel pour les jeunes (la population cible ici : 16-22 ans) peuvent manquer un glissement lent vers la détresse : aucun message pris isolément ne contient de mot-clé de crise, et pourtant la conversation dans son ensemble dérive de façon manifeste. Les signaux sont autant comportementaux que lexicaux - des messages qui raccourcissent, le vocabulaire d'espoir qui disparaît, des sujets évités, des réponses qui tardent. CEDD transforme cette intuition en espace de features. @@ -38,6 +44,11 @@ flowchart TD **Une classification sous contrat de sécurité.** Un pipeline `StandardScaler → GradientBoostingClassifier` projette le vecteur 67D sur quatre niveaux d'alerte - Vert, Jaune, Orange, Rouge. Mais le ML n'a jamais le dernier mot : **7 portes de sécurité** l'encadrent. Un mot-clé de crise force le Rouge instantanément à tout moment ; une confiance ML faible retombe par défaut sur Jaune (principe de précaution) ; les conversations courtes plafonnent le ML à Orange ; un plancher de sécurité lexical garantit que la prédiction ne peut jamais descendre *sous* ce que les règles à mots-clés ont détecté ; et un long délai de réponse fait monter le niveau d'un cran. La règle de conception héritée du projet garde-fou s'applique ici aussi : les règles de sécurité ne peuvent jamais être outrepassées par le ML. +
+ Streamgraph du flux émotionnel : probabilités par classe empilées message par message, le vert cédant la place au jaune puis à l'orange, au-dessus des statistiques de session +
Le streamgraph du « flux émotionnel » : les probabilités par classe évoluent message par message — le vert cède la place au jaune puis à l'orange au fil de la dérive.
+
+ **Modulation adaptative de la réponse.** Le niveau d'alerte sélectionne l'un des quatre prompts système (dans la langue de l'utilisateur) injectés dans le LLM conversationnel : chaleur standard au Vert, validation émotionnelle renforcée au Jaune, soutien actif avec ressources à l'Orange, et au Rouge un **transfert accompagné en 5 étapes** - validation empathique, transition avec demande de permission, présentation des ressources (Jeunesse, J'écoute 1-800-668-6868, texto 686868, 9-8-8, 911), encouragement à se connecter, présence continue - plus une bascule optionnelle vers « Alex », un·e intervenant·e simulé·e utilisant les techniques d'écoute active ASIST. La couche LLM elle-même est résiliente : une chaîne de fallback (Cohere → Llama 3.3 70B via Groq → Gemini 2.5 Flash → Claude Haiku → texte statique) avec timeout par modèle, pour que l'interface ne gèle jamais sur un fournisseur lent. **Suivi longitudinal.** Un session tracker SQLite suit les utilisateurs *entre* les sessions : score de risque pondéré sur les 7 dernières sessions, tendance (amélioration / stable / aggravation), sessions consécutives à niveau élevé, et détection de retrait quand un utilisateur disparaît plus de 24 heures après une session restée sans clôture. @@ -65,8 +76,18 @@ La suite adversariale est la partie que je défendrais devant un clinicien : 36 **L'explicabilité est une fonctionnalité de sécurité.** Chaque alerte est livrée avec son top 5 de features contributives (importance du modèle × valeur normalisée), affiché en barres dans le tableau de bord Streamlit bilingue. En contexte de santé mentale, « le système a levé une alerte parce que les messages ont raccourci de 60 % et que le vocabulaire de finalité est apparu » est actionnable pour un intervenant ; une probabilité nue ne l'est pas. +
+ Radar des features comparant le message 1 et le message 9, avec l'historique des niveaux d'alerte montrant l'escalade du Vert Ă  l'Orange +
Le radar des features compare le message 1 au message 9, et l'historique des niveaux d'alerte trace l'escalade Vert → Jaune → Orange sur laquelle un intervenant peut agir.
+
+ **Documenter ses modes de défaillance.** Le tableau des lacunes connues fait partie du livrable : formes de crise conjuguées (« killing myself » vs « kill myself ») qui échappent à la porte à mots-clés, détection identitaire par phrases plutôt que par contexte, détection de retrait par seuil. En sécurité, une liste de limites honnête vaut plus qu'une métrique gonflée. +
+ Interface CEDD en mode sombre : conversation en français québécois avec badges de niveau d'alerte, jauge Orange et probabilités par classe +
L'interface en mode sombre : chaque réponse du bot porte son badge de niveau d'alerte, et les ressources de Jeunesse, J'écoute apparaissent dès l'Orange.
+
+ ## Projet Github cedd-hackathon complet [CEDD Hackathon](https://github.com/dapiced/cedd-hackathon) diff --git a/assets/img/cedd/accueil-en.png b/assets/img/cedd/accueil-en.png new file mode 100644 index 0000000..45af462 Binary files /dev/null and b/assets/img/cedd/accueil-en.png differ diff --git a/assets/img/cedd/accueil-fr.png b/assets/img/cedd/accueil-fr.png new file mode 100644 index 0000000..f4ffc0c Binary files /dev/null and b/assets/img/cedd/accueil-fr.png differ diff --git a/assets/img/cedd/conversation-demo-en.png b/assets/img/cedd/conversation-demo-en.png new file mode 100644 index 0000000..b9ab0d3 Binary files /dev/null and b/assets/img/cedd/conversation-demo-en.png differ diff --git a/assets/img/cedd/conversation-demo-fr-sombre.png b/assets/img/cedd/conversation-demo-fr-sombre.png new file mode 100644 index 0000000..4875798 Binary files /dev/null and b/assets/img/cedd/conversation-demo-fr-sombre.png differ diff --git a/assets/img/cedd/conversation-demo-fr.png b/assets/img/cedd/conversation-demo-fr.png new file mode 100644 index 0000000..4b14101 Binary files /dev/null and b/assets/img/cedd/conversation-demo-fr.png differ diff --git a/assets/img/cedd/dashboard-radar-en.png b/assets/img/cedd/dashboard-radar-en.png new file mode 100644 index 0000000..9ab24ba Binary files /dev/null and b/assets/img/cedd/dashboard-radar-en.png differ diff --git a/assets/img/cedd/dashboard-sombre.png b/assets/img/cedd/dashboard-sombre.png new file mode 100644 index 0000000..f549152 Binary files /dev/null and b/assets/img/cedd/dashboard-sombre.png differ diff --git a/assets/img/cedd/dashboard-streamgraph-en.png b/assets/img/cedd/dashboard-streamgraph-en.png new file mode 100644 index 0000000..37e8195 Binary files /dev/null and b/assets/img/cedd/dashboard-streamgraph-en.png differ