stephane000 commited on
Commit
5774769
·
verified ·
1 Parent(s): 496be72

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +19 -37
main.py CHANGED
@@ -6,17 +6,15 @@ from fastapi import FastAPI
6
  from fastapi.middleware.cors import CORSMiddleware
7
  from huggingface_hub import InferenceClient
8
 
9
- # Configuration pour Qwen 3 (Albert API)
10
- # L'identifiant 32B est le compromis idéal entre raisonnement complexe et rapidité.
11
  MODEL_ID = "Qwen/Qwen2.5-Coder-32B-Instruct"
12
 
13
- # Récupération du jeton d'accès Hugging Face (à configurer dans les Secrets du Space)
14
  token = os.getenv("HF_TOKEN")
15
  client = InferenceClient(api_key=token)
16
 
17
  app = FastAPI()
18
 
19
- # Configuration CORS pour permettre la communication avec la Forge
20
  app.add_middleware(
21
  CORSMiddleware,
22
  allow_origins=["*"],
@@ -26,73 +24,57 @@ app.add_middleware(
26
 
27
  @app.post("/verify")
28
  async def verify(data: dict):
29
- # Récupération des entrées utilisateur
30
  question_eleve = data.get("userLatex", "")
31
  ville_etudiee = data.get("expectedLatex", "Toulouse")
32
 
33
- # --- LOGIQUE MÉTIER ET INSTRUCTIONS SYSTÈME ---
34
  if ville_etudiee == "Toulouse":
35
  system_instruction = """
36
- TON RÔLE : Tu es Albert, tuteur de SVT expert. Tu corriges l'exercice sur TOULOUSE.
37
-
38
- TES CRITÈRES DE RÉUSSITE STRICTS :
39
- 1. Longueur : Minimum 15 mots.
40
- 2. Mots-clés présents : ALÉA (ou FAILLE), ENJEU, RISQUE.
41
- 3. Contenu : Expliquer que le risque est faible car l'aléa (la faille) est loin de la ville.
42
-
43
- MÉTHODE SOCRATIQUE (OBLIGATOIRE) :
44
- - Si un critère manque, NE DONNE PAS la réponse. Pose une question pour faire réfléchir.
45
- - Si < 15 mots : "Ton analyse commence bien. Peux-tu détailler davantage ton raisonnement scientifique ?"
46
- - Si mot 'FAILLE' absent : "Regarde bien la carte de Toulouse : vois-tu des zones de rupture (failles) sous la ville ?"
47
- - Si mot 'ENJEU' absent : "Toulouse est une grande métropole. Comment appelle-t-on ce facteur de vulnérabilité en SVT ?"
48
  """
49
  else:
50
  system_instruction = """
51
- TON RÔLE : Albert, tuteur expert en sismologie. Cas final de PONT-SAINT-ESPRIT.
52
- MÉTHODE : Demande à l'élève de comparer avec le cas de Toulouse.
53
- Il doit expliquer pourquoi ici le risque est plus élevé (proximité de la faille active du Teil).
54
  """
55
 
56
- # Format de prompt optimisé pour Qwen 3 (ChatML)
57
  prompt = f"""<|im_start|>system
58
  {system_instruction}
59
- IMPORTANT : Réponds EXCLUSIVEMENT sous ce format JSON strict :
60
  {{
61
  "isCorrect": boolean,
62
- "feedback": "ton message ici"
63
  }}
64
  <|im_end|>
65
  <|im_start|>user
66
- Réponse de l'élève : "{question_eleve}"
67
  <|im_end|>
68
  <|im_start|>assistant
69
  """
70
 
71
  try:
72
- # Appel à l'Inference API de Hugging Face
73
  response = client.chat_completion(
74
  model=MODEL_ID,
75
  messages=[{"role": "user", "content": prompt}],
76
- max_tokens=300,
77
- temperature=0.1 # Très bas pour garantir la structure JSON et la précision
78
  )
79
-
80
  content = response.choices[0].message.content
81
 
82
- # Extraction du JSON par Regex (protection contre le texte superflu de l'IA)
83
  match = re.search(r'\{.*\}', content, re.DOTALL)
84
  if match:
85
  return json.loads(match.group())
86
-
87
  return json.loads(content)
88
 
89
  except Exception as e:
90
- print(f"Erreur backend : {e}")
91
- return {
92
- "isCorrect": False,
93
- "feedback": "Albert 3 est momentanément indisponible. Réessaie dans quelques secondes."
94
- }
95
 
96
  if __name__ == "__main__":
97
- # Port 7860 standard pour Hugging Face Spaces
98
  uvicorn.run(app, host="0.0.0.0", port=7860)
 
6
  from fastapi.middleware.cors import CORSMiddleware
7
  from huggingface_hub import InferenceClient
8
 
9
+ # Configuration Qwen 3 (Moteur Coder 32B)
 
10
  MODEL_ID = "Qwen/Qwen2.5-Coder-32B-Instruct"
11
 
 
12
  token = os.getenv("HF_TOKEN")
13
  client = InferenceClient(api_key=token)
14
 
15
  app = FastAPI()
16
 
17
+ # Autoriser la Forge (CORS)
18
  app.add_middleware(
19
  CORSMiddleware,
20
  allow_origins=["*"],
 
24
 
25
  @app.post("/verify")
26
  async def verify(data: dict):
 
27
  question_eleve = data.get("userLatex", "")
28
  ville_etudiee = data.get("expectedLatex", "Toulouse")
29
 
30
+ # Instructions système
31
  if ville_etudiee == "Toulouse":
32
  system_instruction = """
33
+ TON RÔLE : Tu es Albert, tuteur de SVT. Tu corriges l'exercice sur TOULOUSE.
34
+ CRITÈRES :
35
+ 1. Mots-clés : ALÉA (ou FAILLE), ENJEU, RISQUE.
36
+ 2. Logique : Risque faible car l'aléa est LOIN (peu importe les enjeux).
37
+ MÉTHODE : Si incomplet, pose une question (Socratique). Ne donne pas la réponse.
 
 
 
 
 
 
 
38
  """
39
  else:
40
  system_instruction = """
41
+ TON RÔLE : Albert, tuteur expert. Cas PONT-SAINT-ESPRIT.
42
+ MÉTHODE : Demande de comparer avec Toulouse. Ici risque plus fort car faille proche.
 
43
  """
44
 
45
+ # Prompt ChatML pour Qwen 3
46
  prompt = f"""<|im_start|>system
47
  {system_instruction}
48
+ RÉPONDRE UNIQUEMENT EN JSON STRICT :
49
  {{
50
  "isCorrect": boolean,
51
+ "feedback": "string"
52
  }}
53
  <|im_end|>
54
  <|im_start|>user
55
+ Réponse élève : "{question_eleve}"
56
  <|im_end|>
57
  <|im_start|>assistant
58
  """
59
 
60
  try:
 
61
  response = client.chat_completion(
62
  model=MODEL_ID,
63
  messages=[{"role": "user", "content": prompt}],
64
+ max_tokens=350,
65
+ temperature=0.1
66
  )
 
67
  content = response.choices[0].message.content
68
 
69
+ # Nettoyage Regex (Protection anti-bug)
70
  match = re.search(r'\{.*\}', content, re.DOTALL)
71
  if match:
72
  return json.loads(match.group())
 
73
  return json.loads(content)
74
 
75
  except Exception as e:
76
+ print(f"Erreur: {e}")
77
+ return {"isCorrect": False, "feedback": "Albert 3 redémarre ses circuits... Réessaie !"}
 
 
 
78
 
79
  if __name__ == "__main__":
 
80
  uvicorn.run(app, host="0.0.0.0", port=7860)