9.2 KiB
Prompt_t2live.md — Expria Backend
Spécification du prompt système T2 EO Live
Document de référence — Sprint 6 À lire conjointement avec PARCOURS_UTILISATEURS.md et PLANS_TARIFAIRES.md. Ce document doit être commité dans
expria-backend/docs/avant le démarrage du Sprint 6.
1. Contexte pédagogique
La Tâche 2 de l'Expression Orale TCF Canada est une interaction de service : le candidat joue le rôle d'une personne dans une situation concrète du quotidien 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
- La morphosyntaxe en situation d'interaction orale
- 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
2. Rôle de l'IA
L'IA joue le rôle de l'interlocuteur de la situation décrite dans le sujet (ex : un bailleur, un employeur, un vendeur, un agent de voyage, etc.).
Règles absolues du comportement de l'IA :
- Répondre uniquement en français — quelle que soit la langue utilisée par le candidat.
- Ne pas faciliter la tâche — ne pas reformuler les questions du candidat, ne pas anticiper ce qu'il veut savoir, ne pas lui souffler les mots.
- Répondre aux questions posées — réponses naturelles, réalistes, ni trop courtes (monosyllabiques) ni trop longues (monologues).
- Ne pas relancer au-delà de : "Avez-vous d'autres questions ?" si le candidat marque une pause prolongée ou semble avoir terminé.
- Ne pas évaluer le candidat pendant la conversation — aucun commentaire sur sa langue, ses erreurs, ou sa performance.
- Ne pas sortir du rôle — même si le candidat pose des questions hors sujet ou tente de changer de registre.
- Attendre que le candidat prenne la parole — c'est le candidat qui initie la conversation, comme à l'examen réel. L'IA ne parle pas en premier. Elle attend en silence et répond dès que le candidat s'adresse à elle.
3. Prompt système (à injecter dans geminiLive.ts)
Tu joues le rôle de {role} dans la situation suivante : {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.
Variables à substituer dynamiquement depuis le sujet :
{role}— ex : "un bailleur qui loue un appartement"{contexte}— la consigne + contexte du sujet issu de la tablesujets
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
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
emménager le mois prochain."
role : "un bailleur qui propose un appartement à louer"
Note : Le champ
roleexiste dans la tablesujetset a été alimenté pour les 9 sujets EO T2 (session 2026-04-26, script SQLupdate_sujets_t2.sql).
5. Structure du rapport T2
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 % |
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
entrée, avec tache: 'EO_T2'.
Rappel TD-08 (backend) : la phonologie est temporairement fixée à 0 pour les tâches EO live car l'évaluation nécessite l'audio brut. Applicable à T2 également — à résoudre post-MVP.
6. Flux technique complet Sprint 6
1. Candidat choisit un sujet T2 dans la liste → clic → page préparation
2. Page préparation : consigne affichée + bouton "Démarrer le dialogue"
3. Frontend ouvre WS : wss://api.expria.app/t2/live?token=<jwt>&sujet=<uuid>
4. Backend vérifie JWT + plan oral_t2_live (Premium)
5. Backend lit le sujet depuis Supabase (id sujet passé en query param)
6. Backend ouvre WS vers Gemini Live API avec prompt système construit
dynamiquement depuis {role} + {contexte} du sujet
7. Backend → Gemini : setup frame (modèle + prompt + responseModalities: AUDIO
+ VAD : endOfSpeechSensitivity LOW, silenceDurationMs 2000)
8. L'IA attend en silence — c'est le CANDIDAT qui prend la parole en premier
(conforme à l'examen réel TCF Canada)
9. Frontend → Backend → Gemini : audio candidat (PCM 16kHz base64) en continu
+ accumulation dans le buffer d'enregistrement chronologique (rééchantillonné 24kHz)
10. Gemini → Backend → Frontend : réponses audio (PCM 24kHz base64) en continu
+ accumulation dans le buffer d'enregistrement
11. Candidat clique "Terminer" → Frontend envoie signal de fin
12. Backend ferme WS Gemini, récupère transcript complet (inputTranscription
+ outputTranscription accumulés pendant la session)
13. Backend POST /corrections/eo avec transcript + tache='EO_T2'
→ rapport généré (même pipeline que T1/T3)
14. Backend sauvegarde production en base (tache='EO_T2_LIVE')
15. Backend envoie rapport au Frontend via WS (close code 1000 + payload rapport)
16. Frontend → state machine 'ended' → affichage rapport
17. Frontend propose bouton "Télécharger l'audio" (WAV mono 24kHz assemblé
depuis le buffer chronologique)
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 |
MIME type à envoyer à Gemini : audio/pcm;rate=16000
Côté frontend :
- Capture via
AudioContext+AudioWorklet(ouScriptProcessorNodeprovisoire) - Rééchantillonnage obligatoire : le navigateur capture à 44.1kHz ou 48kHz → downsampler à 16kHz
- Conversion Float32 → Int16 PCM avant envoi
- Lecture de l'audio reçu :
AudioContextà 24kHz +AudioBufferSourceNodepar chunk
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" |
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 |
10. Ce qui existe déjà (à ne pas recoder)
src/routes/t2live.ts— 101 lignes, route WS + auth + gating ✅src/lib/geminiLive.ts— 154 lignes, proxy bidirectionnel + setup frame ✅- Pipeline correction EO (
POST /corrections/eo) — réutilisable pour évaluation finale ✅ - 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.