docs(t2live): MAJ prompt §3, TD-22, CHANGELOG Sprint 6d
Some checks failed
CI / quality (push) Has been cancelled

- Prompt_t2live.md §3 réécrit (13 règles) + encadré spécificité T2 (règle 7
  non propageable au prompt T1).
- TECH_DEBT-backend.md: TD-22 (contournement prompt engineering Flash Live).
- CHANGELOG-backend.md: bloc Sprint 6d.
This commit is contained in:
Hermann_Kitio 2026-06-28 11:49:45 +03:00
parent 94387a71db
commit 5f7e52d88a
3 changed files with 89 additions and 46 deletions

View file

@ -6,6 +6,26 @@ Format basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/).
---
## [Unreleased] — 2026-06-28 — Sprint 6d — T2 Live : durcissement prompt + VAD + cleanup SDK
### Changed
- `buildT2SystemPrompt` (`geminiLive.ts`) — prompt système T2 durci : 13 règles absolues (Bug 1). Interdiction stricte de poser des questions (aucun point d'interrogation), rôle passif/inerte, silence total après réponse, aucune formule de politesse de fin. Objectif : stopper la relance systématique de l'examinateur IA. Réf TD-22. ⚠ Spécifique T2 — l'interdiction du « ? » ne doit pas être propagée au prompt T1 (Sprint 7).
- `buildSetupFrame` (`geminiLive.ts`) — `realtimeInputConfig.automaticActivityDetection` (VAD) réintégré dans le setup frame Gemini (Bug 2), 4 champs : `disabled:false`, `startOfSpeechSensitivity:START_SENSITIVITY_LOW`, `endOfSpeechSensitivity:END_SENSITIVITY_LOW`, `silenceDurationMs:2000`.
- `geminiLive.test.ts` — assertion VAD mise à jour (`realtimeInputConfig` : `toBeUndefined` → présence + valeurs des 4 champs).
### Removed
- Dépendance `@google/genai` retirée de `package.json` / `package-lock.json` et script de debug `test-gemini-live.js` supprimé (Bug 8) — SDK abandonné au profit du WebSocket brut (`ws`).
### Notes
- Tests backend : 292/292 verts (0 échec).
- Validé au test manuel Golden Dataset Groupe D — Bug 1 (plus de relance systématique) et Bug 2 (VAD, pauses de réflexion respectées) confirmés en conditions réelles.
- **TD-22 (🟡 ouvert)** — comportement T2 garanti uniquement par prompt engineering ; pas de garantie déterministe sur modèle Flash Live. À revisiter si la relance persiste.
---
## [Unreleased] — 2026-04-26 — Sprint 6a — Backend T2 Live
### Added

View file

@ -1,4 +1,5 @@
# Prompt_t2live.md — Expria Backend
# Spécification du prompt système T2 EO Live
> **Document de référence — Sprint 6**
@ -15,6 +16,7 @@ qui a besoin d'informations pour prendre une décision. Il pose des questions à
un interlocuteur (joué par l'IA) qui détient ces informations.
**Ce que cette tâche évalue :**
- La capacité à initier et maintenir une conversation en français
- La formulation de questions claires et adaptées au registre
- Le lexique lié à la vie quotidienne
@ -22,6 +24,7 @@ un interlocuteur (joué par l'IA) qui détient ces informations.
- La phonologie (évaluée sur l'audio)
**Ce que cette tâche n'est pas :**
- Un débat d'opinions
- Un exposé monologique
- Un jeu de questions-réponses guidé par l'examinateur
@ -41,7 +44,7 @@ L'IA joue le rôle de l'interlocuteur de la situation décrite dans le sujet
ne pas anticiper ce qu'il veut savoir, ne pas lui souffler les mots.
3. **Répondre aux questions posées** — réponses naturelles, réalistes,
ni trop courtes (monosyllabiques) ni trop longues (monologues).
4. **Ne pas relancer au-delà de** : *"Avez-vous d'autres questions ?"*
4. **Ne pas relancer au-delà de** : _"Avez-vous d'autres questions ?"_
si le candidat marque une pause prolongée ou semble avoir terminé.
5. **Ne pas évaluer le candidat** pendant la conversation — aucun commentaire
sur sa langue, ses erreurs, ou sa performance.
@ -56,28 +59,34 @@ L'IA joue le rôle de l'interlocuteur de la situation décrite dans le sujet
## 3. Prompt système (à injecter dans `geminiLive.ts`)
```
Tu joues le rôle de {role} dans la situation suivante : {contexte}
RÔLE : Tu incarnes {role}.
CONTEXTE : {contexte}
Règles à respecter impérativement :
- Tu réponds uniquement en français, quelle que soit la langue de ton interlocuteur.
- Tu joues ton rôle de façon naturelle et réaliste. Tu n'es pas un examinateur —
tu es {role}.
- Tu réponds aux questions qu'on te pose de façon honnête et naturelle,
comme le ferait une vraie personne dans cette situation.
- Tu ne facilites pas la tâche : tu ne reformules pas les questions,
tu n'anticipes pas ce que l'interlocuteur veut savoir,
tu ne lui suggères pas quoi demander.
- Si ton interlocuteur marque une longue pause ou semble avoir terminé,
tu peux dire : "Avez-vous d'autres questions ?" — c'est la seule relance autorisée.
- Tu ne fais aucun commentaire sur la langue, les erreurs ou le niveau de français
de ton interlocuteur.
- Tu ne sors jamais de ton rôle.
- Tu ne prends PAS la parole en premier. Tu attends que ton interlocuteur
s'adresse à toi, puis tu réponds naturellement dans ton rôle.
- Tes réponses sont concises et naturelles : ni monosyllabiques, ni des monologues.
RÈGLES ABSOLUES :
1. Tu parles TOUJOURS en français naturel et courant, niveau B2-C1.
2. Tu NE corriges JAMAIS les erreurs du candidat. Tu continues naturellement.
3. Tu attends que le candidat finisse sa question avant de répondre.
4. Tes réponses sont courtes (15 à 25 mots maximum) pour laisser la place au dialogue.
5. Ne donne pas toutes les informations d'un coup. Force le candidat à poser des questions précises.
6. Si le candidat est vague, réponds brièvement sans chercher à compléter — c'est à lui de reformuler.
7. STRICTE INTERDICTION DE POSER DES QUESTIONS. Tu n'as pas le droit d'utiliser de point d'interrogation. Tes phrases se terminent par un point.
8. SILENCE TOTAL APRÈS LA RÉPONSE. Réponds de manière factuelle, puis arrête-toi immédiatement. Ne suggère rien, ne relance pas, ne dis pas "et vous ?".
9. RÔLE PASSIF : tu es une source d'information inerte. Tu n'aides pas le candidat à tenir la conversation. S'il ne parle plus, le silence s'installe.
10. AUCUNE FORMULE DE POLITESSE DE FIN : bannis "n'hésitez pas", "j'espère que ça vous aide", "qu'en pensez-vous ?".
11. JAMAIS de listes ni de structure numérotée — parle naturellement.
12. Ne mentionne jamais que tu es une IA ou un modèle.
13. Tu ne prends PAS la parole en premier. Tu attends que le candidat s'adresse à toi.
```
> **⚠ Spécificité T2 — règle 7 :** l'interdiction absolue de poser des questions
> (et du point d'interrogation) est **propre à la Tâche 2** (interaction de service
> où le candidat doit mener l'échange). Elle ne doit **jamais** être propagée au
> prompt T1 (Sprint 7), où l'examinateur doit au contraire relancer le candidat.
> Voir aussi TD-22 (TECH_DEBT-backend.md) : contournement par prompt engineering,
> sans garantie déterministe sur modèle Flash Live.
**Variables à substituer dynamiquement depuis le sujet :**
- `{role}` — ex : "un bailleur qui loue un appartement"
- `{contexte}` — la consigne + contexte du sujet issu de la table `sujets`
@ -86,18 +95,20 @@ Règles à respecter impérativement :
## 4. Format du sujet T2 en base
Les sujets T2 sont stockés dans la table `sujets` avec les champs :
- `consigne` — la situation décrite au candidat (ce qu'il doit faire)
- `contexte` — les informations de cadrage (lieu, situation, interlocuteur)
- `tache` — valeur `'EO_T2'`
- `mode` — valeur `'entrainement'`
**Exemple de sujet :**
```
consigne : "Vous avez vu une annonce pour un appartement à louer.
Appelez le bailleur pour obtenir les informations
consigne : "Vous avez vu une annonce pour un appartement à louer.
Appelez le bailleur pour obtenir les informations
nécessaires avant de prendre votre décision."
contexte : "Vous cherchez un appartement de 2 pièces dans le
centre-ville, votre budget est limité et vous souhaitez
contexte : "Vous cherchez un appartement de 2 pièces dans le
centre-ville, votre budget est limité et vous souhaitez
emménager le mois prochain."
role : "un bailleur qui propose un appartement à louer"
```
@ -113,12 +124,12 @@ role : "un bailleur qui propose un appartement à louer"
Le rapport T2 suit **exactement la même structure** que les rapports EO T1 et T3 :
4 critères officiels TCF Canada :
| Critère | Pondération |
|---|---|
| Cohérence et cohésion | 25 % |
| Étendue et maîtrise du lexique | 25 % |
| Maîtrise morphosyntaxique | 25 % |
| Phonologie | 25 % |
| Critère | Pondération |
| ------------------------------ | ----------- |
| Cohérence et cohésion | 25 % |
| Étendue et maîtrise du lexique | 25 % |
| Maîtrise morphosyntaxique | 25 % |
| Phonologie | 25 % |
**Conséquence :** l'évaluation finale peut réutiliser le prompt de correction EO
existant (`POST /corrections/eo`) en passant le transcript de la session comme
@ -164,14 +175,15 @@ entrée, avec `tache: 'EO_T2'`.
## 7. Spécifications audio
| Direction | Format | Sample rate | Encoding |
|---|---|---|---|
| Frontend → Gemini | PCM brut | 16kHz | 16 bits, little-endian, mono |
| Gemini → Frontend | PCM brut | 24kHz | 16 bits, little-endian, mono |
| Direction | Format | Sample rate | Encoding |
| ----------------- | -------- | ----------- | ---------------------------- |
| Frontend → Gemini | PCM brut | 16kHz | 16 bits, little-endian, mono |
| Gemini → Frontend | PCM brut | 24kHz | 16 bits, little-endian, mono |
**MIME type à envoyer à Gemini :** `audio/pcm;rate=16000`
**Côté frontend :**
- Capture via `AudioContext` + `AudioWorklet` (ou `ScriptProcessorNode` provisoire)
- Rééchantillonnage obligatoire : le navigateur capture à 44.1kHz ou 48kHz → downsampler à 16kHz
- Conversion Float32 → Int16 PCM avant envoi
@ -181,23 +193,23 @@ entrée, avec `tache: 'EO_T2'`.
## 8. Gestion des erreurs WebSocket
| Close code | Cause | Action frontend |
|---|---|---|
| 1000 | Fin normale + rapport prêt | State → 'ended', afficher rapport |
| 4001 | AUTH_REQUIRED | State → 'error', redirect /login |
| 4003 | PLAN_INSUFFICIENT | State → 'error', PaywallModal Premium |
| 4004 | SUJET_NOT_FOUND | State → 'error', retour liste sujets |
| Autre | Erreur réseau / Gemini | State → 'error', bouton "Réessayer" |
| Close code | Cause | Action frontend |
| ---------- | -------------------------- | ------------------------------------- |
| 1000 | Fin normale + rapport prêt | State → 'ended', afficher rapport |
| 4001 | AUTH_REQUIRED | State → 'error', redirect /login |
| 4003 | PLAN_INSUFFICIENT | State → 'error', PaywallModal Premium |
| 4004 | SUJET_NOT_FOUND | State → 'error', retour liste sujets |
| Autre | Erreur réseau / Gemini | State → 'error', bouton "Réessayer" |
---
## 9. Questions ouvertes à trancher au Sprint 6
| # | Question | Impact |
|---|---|---|
| Q1 | Le champ `role` existe-t-il dans la table `sujets` ou faut-il le dériver du `contexte` ? | Migration SQL ou prompt engineering |
| Q2 | L'id du sujet est-il passé en query param WS (`?token=jwt&sujet=uuid`) ou via le premier message WS ? | Protocole de connexion |
| Q3 | Le transcript est-il accumulé côté backend pendant la session ou demandé à Gemini en fin de session ? | Architecture geminiLive.ts |
| # | Question | Impact |
| --- | ----------------------------------------------------------------------------------------------------- | ----------------------------------- |
| Q1 | Le champ `role` existe-t-il dans la table `sujets` ou faut-il le dériver du `contexte` ? | Migration SQL ou prompt engineering |
| Q2 | L'id du sujet est-il passé en query param WS (`?token=jwt&sujet=uuid`) ou via le premier message WS ? | Protocole de connexion |
| Q3 | Le transcript est-il accumulé côté backend pendant la session ou demandé à Gemini en fin de session ? | Architecture geminiLive.ts |
---
@ -209,7 +221,7 @@ entrée, avec `tache: 'EO_T2'`.
- Modèle `gemini-live-2.5-flash-native-audio` — accès confirmé ✅
**À modifier :**
- `src/lib/geminiLive.ts` — remplacer le prompt agent immobilier par le prompt
dynamique §3, brancher la récupération du sujet depuis Supabase,
accumuler le transcript, déclencher l'évaluation finale.

View file

@ -245,6 +245,17 @@ Gate de qualité actuel : npm run test.
---
### TD-22 — Comportement T2 Live garanti uniquement par prompt engineering
**Priorité :** 🟡 Important
**Statut :** Ouvert — introduit au Sprint 6d
**Description :** Le respect du rôle passif de l'examinateur T2 (réponses courtes, aucune question posée, aucune relance, silence après réponse) repose entièrement sur le durcissement du prompt système dans `buildT2SystemPrompt` (`src/lib/geminiLive.ts`, cf. `docs/Prompt_t2live.md §3`). Le modèle Gemini Flash Live n'offre **aucune garantie déterministe** : il peut malgré tout poser une question, ajouter une formule de politesse de fin ou relancer le candidat.
**À faire :** Revisiter si la relance persiste en tests manuels — pistes : reformulation/renforcement du prompt, post-filtrage des sorties, ou évaluation d'un modèle Live plus dirigeable.
**⚠ Spécificité T2 :** l'interdiction de poser des questions (et du point d'interrogation, règle 7) est **propre à la Tâche 2**. Ne jamais la propager au prompt T1 (Sprint 7), où l'examinateur doit relancer le candidat.
**Session concernée :** T2 Live — Sprint 6d.
---
## 5. Historique des résolutions
| ID | Description | Résolu le | Comment |