expria-backend/docs/Prompt_t2live.md
2026-04-26 03:09:13 +03:00

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 :

  1. Répondre uniquement en français — quelle que soit la langue utilisée par le candidat.
  2. 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.
  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 ?" 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.
  6. Ne pas sortir du rôle — même si le candidat pose des questions hors sujet ou tente de changer de registre.
  7. 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 table sujets

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 role existe dans la table sujets et a été alimenté pour les 9 sujets EO T2 (session 2026-04-26, script SQL update_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 (ou ScriptProcessorNode provisoire)
  • 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 + AudioBufferSourceNode par 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.