Spaces:
Sleeping
Sleeping
from typing import List, Literal | |
import json | |
from langchain_openai import ChatOpenAI | |
from langchain.prompts import ChatPromptTemplate | |
from app.core.config import settings | |
from app.models.quiz import Question | |
import logging | |
logger = logging.getLogger(__name__) | |
class QuizGenerator: | |
def __init__(self, provider: Literal["openai", "deepseek"] = "openai"): | |
# Configuration selon le provider | |
if provider == "deepseek": | |
self.llm = ChatOpenAI( | |
model_name="deepseek-chat", | |
temperature=0.7, | |
openai_api_key=settings.DEEPSEEK_API_KEY, | |
base_url="https://api.deepseek.com" | |
) | |
else: # openai | |
self.llm = ChatOpenAI( | |
model_name=settings.MODEL_NAME, | |
temperature=0.7, | |
openai_api_key=settings.OPENAI_API_KEY | |
) | |
def clean_json_response(self, response_text: str) -> str: | |
"""Nettoie la réponse du LLM pour obtenir un JSON valide.""" | |
cleaned = response_text.replace('```json', '').replace('```', '').strip() | |
return cleaned.strip() | |
async def generate_quiz(self, theme: str, num_questions: int = 5) -> List[Question]: | |
logger.debug(f"Génération de quiz - Thème: {theme}, Nb questions: {num_questions}") | |
try: | |
# Template pour la génération de questions | |
prompt = ChatPromptTemplate.from_template(""" | |
Tu es un générateur de quiz intelligent. | |
Génère {num_questions} questions de quiz sur le thème: {theme} | |
IMPORTANT: Réponds UNIQUEMENT avec un JSON valide sans backticks ni formatage markdown. | |
Format exact attendu: | |
{{ | |
"questions": [ | |
{{ | |
"question": "La question", | |
"options": ["Option A", "Option B", "Option C"], | |
"correct_answer": "La bonne réponse (qui doit être une des options)" | |
}} | |
] | |
}} | |
""") | |
# Générer les questions | |
response = await self.llm.agenerate([ | |
prompt.format_messages( | |
theme=theme, | |
num_questions=num_questions | |
) | |
]) | |
# Parser le JSON et créer les objets Question | |
response_text = response.generations[0][0].text | |
cleaned_response = self.clean_json_response(response_text) | |
try: | |
response_json = json.loads(cleaned_response) | |
except json.JSONDecodeError as e: | |
logger.error(f"Réponse brute: {response_text}") | |
logger.error(f"Réponse nettoyée: {cleaned_response}") | |
raise Exception(f"Erreur de parsing JSON: {str(e)}") | |
questions = [] | |
for q in response_json["questions"]: | |
questions.append(Question( | |
question=q["question"], | |
options=q["options"], | |
correct_answer=q["correct_answer"] | |
)) | |
return questions | |
except Exception as e: | |
print(f"Erreur dans generate_quiz: {str(e)}") | |
raise e |