feat(corrections): Sprint 3.6a — nouveaux prompts + taxonomie erreurs + génération parallèle

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hermann_Kitio 2026-04-22 17:27:29 +03:00
parent df7ef2cc31
commit 63bc43ddcf
14 changed files with 2319 additions and 282 deletions

View file

@ -0,0 +1,164 @@
# Prompt Maître — Génération de la Production Modèle TCF Canada
> **Source :** `app/api/modele/route.ts` → handler `POST` (ligne 115)
> **Modèle :** DeepSeek Chat (`deepseek-chat`) · `temperature: 0.3` · `max_tokens: 2200`
---
## Principe de fonctionnement
Le prompt **réécrit la production du candidat** un niveau NCLC au-dessus de son score obtenu, en conservant intégralement ses idées et arguments. Il ne génère pas un texte de zéro.
```
nclcModele = min(nclcObtenu + 1, 10)
```
---
## Variables dynamiques
| Variable | Description | Exemple |
|---|---|---|
| `sujet` | Consigne ou sujet donné au candidat | `"Écrivez un mail à votre voisin..."` |
| `taskDescription` | Description officielle de la tâche (voir ci-dessous) | — |
| `texte` | Production originale du candidat | — |
| `nclcObtenu` | Niveau NCLC réellement atteint par le candidat (710) | `8` |
| `nclcModele` | Niveau NCLC cible de la production modèle (`nclcObtenu + 1`) | `9` |
| `scoreModele` | Score minimum requis pour atteindre `nclcModele` | `14` |
### Barème NCLC → score minimum
| NCLC | Score minimum /20 |
|---|---|
| 7 | 10 |
| 8 | 12 |
| 9 | 14 |
| 10 | 16 |
---
## Descriptions des tâches
### Tâche 1
> Expression écrite — Tâche 1 : Message / mail / annonce **(60-120 mots)**. Respect du registre (formel ou informel), salutation, corps du message, formule de clôture et signature.
### Tâche 2
> Expression écrite — Tâche 2 : Article de blog ou forum **(120-150 mots)**. Accroche, récit personnel à la 1re personne, opinion argumentée, conseil au lecteur.
### Tâche 3
> Expression écrite — Tâche 3 : Texte comparatif **(120-180 mots)**. Partie 1 (40-60 mots) : présentation neutre des deux documents. Partie 2 (80-120 mots) : prise de position personnelle argumentée.
---
## Prompt envoyé au modèle
```
Tu es un correcteur expert TCF Canada.
Le candidat a rédigé cette production sur le sujet suivant :
SUJET : {sujet}
TÂCHE : {taskDescription}
PRODUCTION DU CANDIDAT :
{texte}
Le candidat a obtenu NCLC {nclcObtenu}. Ta mission est de lui montrer comment atteindre NCLC {nclcModele} (score minimum {scoreModele}/20).
Ta mission : réécrire cette production EN CONSERVANT le fond, les idées, le positionnement et les arguments du candidat — mais en appliquant parfaitement les 4 critères officiels TCF Canada :
1. Réalisation de la tâche — respecter le format, les limites de mots, la consigne, le registre
2. Cohérence / Structure — paragraphes clairs, connecteurs logiques variés, progression cohérente
3. Étendue du lexique — vocabulaire riche et précis, zéro répétition, registre adapté
4. Maîtrise grammaticale — structures complexes, subjonctif, passif, subordination
RÈGLES ABSOLUES :
- Conserver les idées et arguments du candidat — ne pas inventer
- Respecter STRICTEMENT les limites de mots ci-dessous pour le champ production_modele_propre (ne jamais dépasser le maximum)
- Viser exactement le niveau NCLC {nclcModele}
- Le texte d'examen ne contient AUCUNE note : pas de [NOTE:], pas de commentaire entre parenthèses dans production_modele_propre
- Proposer exactement 3 entrées dans notes_pedagogiques (passage court + explication)
- Répondre en JSON valide sans markdown
COMPTAGE DES MOTS (TCF Canada, Expression écrite) :
- Un mot = segment séparé par des espaces (ou fins de ligne) ; l'apostrophe (' ou ') et le tiret (-) ne créent pas un mot supplémentaire.
- Exemples : « c'est », « l'eau », « aujourd'hui », « c'est-à-dire », « vas-y » comptent chacun pour un seul mot.
LONGUEUR production_modele_propre pour cette tâche (respecter min conseillé et max STRICT) :
- Tâche 1 : 60 à 120 mots — ne pas dépasser 120 mots
- Tâche 2 : 120 à 150 mots — ne pas dépasser 150 mots
- Tâche 3 : 120 à 180 mots — ne pas dépasser 180 mots
FORMAT JSON :
{
"production_modele_propre": "texte final seul, prêt pour l'examen, sans aucune annotation",
"notes_pedagogiques": [
{"passage": "extrait court du texte modèle", "explication": "pourquoi ce passage est efficace au TCF"}
],
"transformations": [
{"original": "extrait original du candidat", "ameliore": "version améliorée", "explication": "pourquoi c'est mieux"}
],
"message": "phrase courte encourageante sur les idées du candidat"
}
```
---
## Structure de la réponse JSON attendue
```json
{
"production_modele_propre": "<texte final réécrit, prêt pour l'examen, sans annotation>",
"notes_pedagogiques": [
{
"passage": "<extrait court du texte modèle>",
"explication": "<pourquoi ce passage est efficace au TCF>"
},
{
"passage": "<extrait court du texte modèle>",
"explication": "<pourquoi ce passage est efficace au TCF>"
},
{
"passage": "<extrait court du texte modèle>",
"explication": "<pourquoi ce passage est efficace au TCF>"
}
],
"transformations": [
{
"original": "<extrait original du candidat>",
"ameliore": "<version améliorée>",
"explication": "<pourquoi c'est mieux>"
}
],
"message": "<phrase courte encourageante sur les idées du candidat>"
}
```
---
## Champs expliqués
| Champ | Rôle |
|---|---|
| `production_modele_propre` | Texte final réécrit au niveau NCLC cible, sans aucune annotation, prêt pour l'examen |
| `notes_pedagogiques` | Exactement **3** passages du texte modèle commentés pédagogiquement |
| `notes_pedagogiques[].passage` | Extrait court tiré du texte modèle |
| `notes_pedagogiques[].explication` | Raison pour laquelle ce passage est efficace au TCF |
| `transformations` | Liste des améliorations appliquées sur des extraits précis |
| `transformations[].original` | Extrait original du candidat |
| `transformations[].ameliore` | Version améliorée de cet extrait |
| `transformations[].explication` | Justification pédagogique de l'amélioration |
| `message` | Message court et encourageant adressé au candidat |
---
## Post-traitement côté serveur
Après réception de la réponse du modèle, le serveur applique les traitements suivants :
1. **Nettoyage** — suppression de toutes les annotations entre crochets `[NOTE: ...]` ou parenthèses dans `production_modele_propre` via `stripModelAnnotations()`
2. **Vérification du nombre de mots** — comptage TCF via `wordCount()` (apostrophes et tirets ne créent pas de mots supplémentaires)
3. **Troncature automatique** — si le texte dépasse le maximum de mots autorisé, il est tronqué via `truncateToMaxWords()` et le flag `tcf_truncated: true` est retourné
4. **Enrichissement de la réponse** — ajout des métadonnées : `nclcModele`, `nclcObtenu`, `scoreCible`, `tcf_word_count`, `tcf_word_min`, `tcf_word_max`, `tcf_truncated`
5. **Persistance** — enregistrement dans la table `productions` avec `record_kind: "production_modele"` et lien vers le rapport parent via `parent_production_id`