Prompt d’évaluation automatique (FR/MG) + un schéma JSON de sortie pour scorer chaque réponse du bot

Voici un prompt d’évaluation automatique (FR/MG) + un schéma JSON de sortie pour scorer chaque réponse du bot et, si besoin, demander une réécriture guidée.

1) Prompt “Évaluateur RAG” (FR + MG)

À utiliser comme system prompt d’un second appel LLM (judge). Il évalue une réponse du bot au regard de la question étudiante et des extraits RAG fournis au bot.

Vous êtes un évaluateur pédagogique pour une licence d’agronomie (3 ans). Votre tâche : noter la réponse du bot selon les extraits RAG fournis. Langue : - Si la question est en Français → privilégiez vos commentaires en Français. - Si la question est en Malgache → privilégiez vos commentaires en Malgache. - Vous pouvez insérer de courtes clarifications bilingues si utile. Entrées que vous recevez : - question_utilisateur (FR ou MG) - reponse_bot (FR ou MG) - extraits_RAG: liste d’objets {text, title, page, section, url} Règles : 1) Évaluez la réponse UNIQUEMENT par rapport aux extraits_RAG. 2) S’il manque l’information dans les extraits, la bonne conduite du bot est de l’admettre. 3) Vérifiez la présence et la justesse des citations (Titre + page/section). 4) Notation par critères (0–5). Donnez des justifications BRÈVES et actionnables. 5) Produisez un JSON strict suivant le schéma fourni (pas d’autre texte). Critères (0–5 chacun) : - relevance : Pertinence par rapport à la question. - grounding : Appui réel sur les extraits (pas d’invention). - citations : Qualité et exactitude des sources (format, correspondance contenu). - clarity : Clarté, pédagogie, structure (niveau licence). - language : Adéquation de la langue (FR/MG), ton académique. - completeness : Couverture suffisante de la question au regard des extraits. - concision : Droit au but, sans digressions inutiles. - safety_privacy : Respect RGPD, pas de PII inutile, pas de propos déplacés. - hallucination_check : 5 = aucune hallucination détectée ; 0 = inventé. Calcul : - overall_score = moyenne pondérée : relevance 20%, grounding 20%, citations 10%, clarity 10%, language 10%, completeness 15%, concision 5%, safety_privacy 5%, hallucination_check 5%. - decision : - "accept" si overall_score ≥ 4.0 - "revise" si 3.0 ≤ overall_score < 4.0 - "reject" si overall_score < 3.0 Conseils de réécriture (si revise/reject) : - Donnez des directives concrètes et courtes pour améliorer la réponse, en citant les extraits exacts à renforcer et les erreurs à corriger. Sortie : - JSON strict selon le schema ci-après.

2) Schéma JSON attendu (copiez tel quel)

{ "scores": { "relevance": 0, "grounding": 0, "citations": 0, "clarity": 0, "language": 0, "completeness": 0, "concision": 0, "safety_privacy": 0, "hallucination_check": 0 }, "overall_score": 0, "decision": "accept | revise | reject", "justifications": { "relevance": "…", "grounding": "…", "citations": "…", "clarity": "…", "language": "…", "completeness": "…", "concision": "…", "safety_privacy": "…", "hallucination_check": "…" }, "rewrite_guidance": [ "Instruction 1 courte et actionnable…", "Instruction 2…" ], "spot_citations_to_fix": [ { "current": "Source : [Titre, p.X]", "issue": "page incorrecte / titre absent / format", "suggested_fix": "Source : [Titre correct, p.Y / section Z]" } ] }

3) Gabarit de “réécriture forcée” (si revise/reject)

Utilisez ce prompt système pour un appel de réécriture : le modèle reçoit la question, les extraits_RAG, et la réponse initiale + rewrite_guidance venant du juge.

Vous êtes un assistant pédagogique. Réécrivez la réponse en suivant STRICTEMENT : - Les extraits_RAG fournis (ne rien inventer). - La même langue que la question (FR ou MG). - Les consignes "rewrite_guidance" (priorité haute). - Incluez des citations correctes (Titre + page/section). - Réponse concise, structurée (puces / courts paragraphes), niveau licence. Si un point n’est pas couvert par les extraits_RAG, dites-le explicitement.

4) Exemple d’appel (pseudo-Node)

// 1) Appel "judge" const judge = await openai.chat.completions.create({ model: "gpt-4o-mini", temperature: 0, messages: [ { role:"system", content: EVALUATOR_SYSTEM_PROMPT }, { role:"user", content: JSON.stringify({ question_utilisateur, reponse_bot, extraits_RAG }) } ] }); const evalJson = JSON.parse(judge.choices[0].message.content); // 2) Si revise/reject → réécriture if (evalJson.decision !== "accept") { const rewrite = await openai.chat.completions.create({ model: "gpt-4o-mini", temperature: 0.2, messages: [ { role:"system", content: REWRITE_SYSTEM_PROMPT }, { role:"user", content: JSON.stringify({ question_utilisateur, extraits_RAG, reponse_initiale: reponse_bot, rewrite_guidance: evalJson.rewrite_guidance }) } ] }); const reponse_finale = rewrite.choices[0].message.content; }

5) Conseils pratiques

  • Stockez overall_score, decision, et les guidances pour suivre la qualité dans le temps.
  • Déclenchez la réécriture auto si overall_score < 4.0.
  • Logguez aussi un court rationale (extraits utilisés) pour l’audit qualité.
  • Pour MG/FR, vous pouvez forcer la langue en ajoutant la langue détectée au message user (champ lang).

Souhaitez-vous une version prête à copier en Python des deux prompts (évaluateur + réécriture) avec un mini stub de fonction ?

Vous avez dit :

Oui

ChatGPT a dit :

Excellent 🙌

Voici la version Python prête à copier avec les deux prompts (évaluateur + réécriture) et un stub de fonctions que vous pouvez intégrer dans votre backend (FastAPI ou autre).

1) Prompt Évaluateur (Judge)

EVALUATOR_PROMPT = """ Vous êtes un évaluateur pédagogique pour une licence d’agronomie (3 ans). Votre tâche : noter la réponse du bot selon les extraits RAG fournis. Langue : - Si la question est en Français → commentez en Français. - Si la question est en Malgache → commentez en Malgache. Entrées que vous recevez : - question_utilisateur (FR ou MG) - reponse_bot (FR ou MG) - extraits_RAG: liste d’objets {text, title, page, section, url} Règles : 1) Évaluez la réponse UNIQUEMENT par rapport aux extraits_RAG. 2) Si info manquante dans les extraits, la bonne conduite est de l’admettre. 3) Vérifiez la présence et la justesse des citations (Titre + page/section). 4) Notation par critères (0–5). Justifications brèves et actionnables. 5) Produisez un JSON strict (sans texte supplémentaire). Critères (0–5 chacun) : - relevance - grounding - citations - clarity - language - completeness - concision - safety_privacy - hallucination_check Calcul : - overall_score = moyenne pondérée : relevance 20%, grounding 20%, citations 10%, clarity 10%, language 10%, completeness 15%, concision 5%, safety_privacy 5%, hallucination_check 5%. - decision : "accept" si overall_score ≥ 4.0 "revise" si 3.0 ≤ overall_score < 4.0 "reject" si overall_score < 3.0 Conseils de réécriture (si revise/reject) : - Donnez des directives concrètes et courtes pour améliorer la réponse. Sortie JSON : { "scores": {...}, "overall_score": 0, "decision": "accept|revise|reject", "justifications": {...}, "rewrite_guidance": [...], "spot_citations_to_fix": [...] } """

2) Prompt Réécriture (Rewrite)

REWRITE_PROMPT = """ Vous êtes un assistant pédagogique. Réécrivez la réponse du bot en suivant STRICTEMENT : - Les extraits_RAG fournis (ne rien inventer). - La même langue que la question (FR ou MG). - Les consignes "rewrite_guidance" données par l’évaluateur. - Incluez des citations correctes (Titre + page/section). - Réponse concise, structurée (puces ou courts paragraphes), niveau licence. Si un point n’est pas couvert par les extraits_RAG, dites-le explicitement. """

3) Fonctions Python complètes

import json from openai import OpenAI client = OpenAI() def evaluate_response(question, reponse_bot, extraits_RAG): """ Évalue automatiquement la réponse du bot selon les critères RAG. Retourne un dict Python conforme au schéma JSON. """ completion = client.chat.completions.create( model="gpt-4o-mini", temperature=0, messages=[ {"role": "system", "content": EVALUATOR_PROMPT}, {"role": "user", "content": json.dumps({ "question_utilisateur": question, "reponse_bot": reponse_bot, "extraits_RAG": extraits_RAG }, ensure_ascii=False)} ] ) content = completion.choices[0].message.content try: result = json.loads(content) except Exception: # fallback si sortie mal formatée result = {"decision":"reject","overall_score":0,"error":"invalid JSON","raw":content} return result def rewrite_response(question, reponse_initiale, extraits_RAG, rewrite_guidance): """ Réécrit la réponse si l’évaluateur demande "revise" ou "reject". """ completion = client.chat.completions.create( model="gpt-4o-mini", temperature=0.2, messages=[ {"role": "system", "content": REWRITE_PROMPT}, {"role": "user", "content": json.dumps({ "question_utilisateur": question, "extraits_RAG": extraits_RAG, "reponse_initiale": reponse_initiale, "rewrite_guidance": rewrite_guidance }, ensure_ascii=False)} ] ) return completion.choices[0].message.content # ---- Exemple d’utilisation ---- if __name__ == "__main__": question = "Quels sont les avantages de la permaculture ?" reponse_bot = "La permaculture est bonne pour la nature." extraits_RAG = [ {"text":"La permaculture réduit l’usage de produits chimiques et favorise la biodiversité.", "title":"Cours de permaculture UE5", "page":"p.12", "section":"2.1", "url":"https://example.com"} ] # 1) Évaluer evaluation = evaluate_response(question, reponse_bot, extraits_RAG) print("Évaluation :", evaluation) # 2) Réécrire si besoin if evaluation.get("decision") in ["revise","reject"]: nouvelle = rewrite_response( question, reponse_bot, extraits_RAG, evaluation.get("rewrite_guidance", []) ) print("Réécriture :", nouvelle)

Voulez-vous que je vous propose aussi un tableau de pondération ajustable (au format dict Python) pour pouvoir modifier facilement les poids des critères (par exemple si vous voulez insister plus sur la clarté ou sur les citations) ?

Vous avez dit :

Oui

ChatGPT a dit :

Parfait 👌

Voici un tableau de pondération ajustable (Python dict) que vous pouvez intégrer dans votre pipeline d’évaluation.

Il vous permettra de recalculer overall_score selon vos priorités (par ex. donner plus de poids à la clarté ou aux citations).

1) Pondérations par défaut (Licence Agro)

# Pondérations par défaut (% total = 100) WEIGHTS = { "relevance": 0.20, # Pertinence vis-à-vis de la question "grounding": 0.20, # Appui réel sur les extraits RAG "citations": 0.10, # Qualité des références "clarity": 0.10, # Pédagogie / structure "language": 0.10, # Respect FR/MG "completeness": 0.15, # Couverture de la question "concision": 0.05, # Pas de digressions inutiles "safety_privacy": 0.05, # Pas de PII / RGPD "hallucination_check": 0.05 # Vérif anti-invention }

2) Fonction de calcul du score pondéré

def compute_overall_score(scores: dict, weights: dict = WEIGHTS) -> float: """ Calcule la note globale pondérée à partir des scores (0-5). - scores : dict {critère: note} - weights : dict {critère: poids entre 0 et 1} Retourne une note sur 5. """ total = 0 for critere, poids in weights.items(): note = scores.get(critere, 0) total += note * poids return round(total, 2)

3) Exemple d’utilisation

scores_exemple = { "relevance": 5, "grounding": 4, "citations": 3, "clarity": 4, "language": 5, "completeness": 4, "concision": 5, "safety_privacy": 5, "hallucination_check": 5 } overall = compute_overall_score(scores_exemple) print("Score global :", overall) # => Score global : 4.4

4) Ajustement rapide des pondérations

👉 Si vous voulez insister davantage sur la clarté pédagogique :

WEIGHTS["clarity"] = 0.20 WEIGHTS["citations"] = 0.05

👉 Si vous voulez pénaliser fortement les hallucinations :

WEIGHTS["hallucination_check"] = 0.15 WEIGHTS["concision"] = 0.02

⚡ Avantage :

Vous pouvez modifier ce dict WEIGHTS par matière (UE1 vs UE5), par année (L1 vs L3), ou même par type d’examen (questions de cours vs projets appliqués).

Voulez-vous que je vous prépare aussi un tableau FR/MG avec la description pédagogique de chaque critère (utile pour partager avec les enseignants comme guide qualité) ?

Vous avez dit :

Oui

ChatGPT a dit :

Parfait 🙌

Voici un tableau bilingue FR/MG décrivant chaque critère pédagogique. Vous pouvez le partager avec vos enseignants ou l’intégrer dans un guide qualité pour le bot.

📊 Tableau des critères d’évaluation – Licence Agronomie (FR / MG)

CritèreDescription (FR)Famaritana (MG)
Relevance (Pertinence)La réponse correspond directement à la question posée, sans digressions.Mifanaraka tsara amin’ny fanontaniana ny valiny, tsy misy resaka ivelany.
Grounding (Ancrage)La réponse s’appuie bien sur les extraits RAG fournis et ne rajoute pas d’éléments inventés.Miorina amin’ireo tahirin-kevitra RAG nomena ny valiny, tsy misy zavatra noforonina.
Citations (Loharano)Les sources sont mentionnées correctement (Titre + page/section).Voatanisa mazava ny loharano (Lohateny + pejy/fizarana).
Clarity (Fahazavana)La réponse est claire, bien structurée (puces, courts paragraphes), niveau licence.Mazava sy voalamina tsara ny valiny (lisitra, andininy fohy), ambaratonga licence.
Language (Fiteny)Respect de la langue de la question (FR ou MG) avec un ton académique.Mampiasa ny fiteny mitovy amin’ny fanontaniana (FR na MG) amin’ny fomba akademika.
Completeness (Fahafenoana)La réponse couvre les points essentiels de la question, selon les extraits disponibles.Mandrakotra ireo hevitra lehibe mifandraika amin’ny fanontaniana, araka ny loharano misy.
Concision (Fohy & Mahitsy)La réponse va droit au but, sans redondance inutile.Tsy miverimberina tsy ilaina ny valiny, mandeha mivantana amin’ny zava-dehibe.
Safety & Privacy (Fiarovana & Fiarovana ny tsiambaratelo)Pas de données personnelles inutiles, respect du RGPD, pas de propos déplacés.Tsy misy mombamomba manokana tsy ilaina, manaja ny tsiambaratelo, tsy misy teny tsy mety.
Hallucination Check (Fanaraha-maso ny noforonina)Vérifie que la réponse n’invente rien en dehors des extraits fournis.Manamarina fa tsy mamorona zavatra tsy hita ao amin’ny tahirin-kevitra ny valiny.

🛠 Usage pratique

  • Pour les enseignants : se servir de ce tableau comme grille de lecture des réponses générées par le bot.
  • Pour les étudiants : comprendre comment le bot formule ses réponses et pourquoi parfois il dit “je ne sais pas”.
  • Pour l’équipe technique : ajuster les pondérations (poids par critère) selon l’importance pédagogique.