Spaces:
Running
Running
| # utils/config.py | |
| import os | |
| from dotenv import load_dotenv | |
| # Charger les variables d'environnement du fichier .env | |
| load_dotenv() | |
| # --- Clé API LLM + Embedding --- | |
| MISTRAL_API_KEY = os.getenv("MISTRAL_API_KEY") | |
| if not MISTRAL_API_KEY: | |
| print("⚠️ Attention: La clé API Mistral (MISTRAL_API_KEY) n'est pas définie dans le fichier .env") | |
| # Vous pouvez choisir de lever une exception ici ou de continuer avec des fonctionnalités limitées | |
| # raise ValueError("Clé API Mistral manquante. Veuillez la définir dans le fichier .env") | |
| # --- Clé API Write Pydantic Logfire --- | |
| LOGFIRE_TOKEN = os.getenv("LOGFIRE_TOKEN") # Si vous souhaitez envoyer des logs à Logfire, sinon laissez vide ou ne pas utiliser | |
| # --- Configuration de l'Application --- | |
| APP_TITLE = "NBA Analyst AI" | |
| NAME = "NBA" # Nom à personnaliser dans l'interface | |
| # ====================================================== | |
| # LLM | |
| # ====================================================== | |
| # --- Modèles Mistral --- | |
| EMBEDDING_MODEL = "mistral-embed" | |
| MODEL_NAME = "mistral-small-latest" # mistral-small-latest mistral-small-2506 | |
| # --- Paramètres du LLM Mistral --- | |
| # Note : les paramètres 'Presence Penalty' et 'Frequency Penalty' ne sont pas définis dans ce projet car ils sont plus adaptés à des tâches de génération créative ou de conversation prolongée. | |
| TEMPERATURE = 0.03 # Température basse pour des réponses factuelles basées sur le contexte | |
| TOP_P = 0.9 # Nucleus sampling (Une température de 0 est déterministe, rendant ainsi la valeur Top P sans importance) | |
| # Note : Si on souhaite des réponses plus créatives, on peut augmenter la température et/ou réduire le top_p. | |
| # Mistral ne supporte pas Temperature et Top_p simultanément. C'est l'un ou l'autre. Décommenter top_p dans le code si nécessaire. | |
| LLM_CALL_DELAY = 0.7 # Délai en secondes entre les appels au LLM (rate limiting) | |
| # ====================================================== | |
| # Vectorisation + RAG | |
| # ====================================================== | |
| # --- Racine du projet (dossier parent de utils/) --- | |
| _PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
| # --- Configuration de l'Indexation --- | |
| # INPUT_DATA_URL = os.getenv("INPUT_DATA_URL") # Décommentez si vous utilisez une URL | |
| INPUT_DIR = os.path.join(_PROJECT_ROOT, "inputs") | |
| VECTOR_DB_DIR = os.path.join(_PROJECT_ROOT, "vector_db") | |
| FAISS_INDEX_FILE = os.path.join(VECTOR_DB_DIR, "faiss_index.idx") | |
| DOCUMENT_CHUNKS_FILE = os.path.join(VECTOR_DB_DIR, "document_chunks.pkl") | |
| CHUNK_SIZE = 1500 # Taille des chunks en caractères | |
| CHUNK_OVERLAP = 150 # Chevauchement en caractères | |
| EMBEDDING_BATCH_SIZE = 8 # Taille des lots pour l'API d'embedding (réduire pour éviter les erreurs brotli) | |
| # --- Configuration de la Recherche --- | |
| SEARCH_K = 5 # Nombre de documents à récupérer par défaut | |
| # --- Fichier source Excel à charger en Vector DB / Rag --- | |
| EXCEL_INPUTS_FOR_RAG = os.path.join(INPUT_DIR, "regular NBA_Corr_Rag.xlsx") | |
| # --- Prompt Système RAG --- | |
| RAG_SYSTEM_PROMT = """Tu es 'NBA Analyst AI', un assistant expert sur la ligue de basketball NBA. | |
| Ta mission est de répondre aux questions des entraîneurs, analystes et préparateurs physiques de manière structurée, mais pas trop verbeuse. | |
| N'invente jamais d'informations : si tu n'es pas sûr de la réponse, dis-le clairement et suggère de consulter une source externe. | |
| --- | |
| {context_str} | |
| --- | |
| QUESTION DE L'UTILISATEUR: | |
| {question} | |
| RÉPONSE DE L'ANALYSTE NBA:""" | |
| # ====================================================== | |
| # RAGAS | |
| # ====================================================== | |
| # --- Configuration des questions/réponses pour RAGAS --- | |
| QUESTIONS_TEST = [ | |
| "Quelle équipe à comme code MIA ?", | |
| "Combien de joueurs contient l’équipe des Philadelphia 76ers ?", | |
| "Quelle est la moyenne d’âge des joueurs d’Atlanta à un chiffre après la virgule ?", | |
| "Quelle est l’équipe qui a inscrit le plus de points ?", | |
| "Comment se rendre à San Antonio ?" | |
| ] | |
| GROUND_TRUTHS= [ | |
| "L’équipe ayant le code MIA est l’équipe des Miami Heat.", | |
| "L’équipe des Philadelphia 76ers contient 23 joueurs.", | |
| "La moyenne d’âge des joueurs d’Atlanta est de 25,6.", | |
| "L’équipe des Detroit Pistons a inscrit le plus de points avec un total de 10292.", | |
| "Le système ne peut pas guider l’utilisateur et suggère de consulter une source externe." | |
| ] | |
| # ====================================================== | |
| # SQL | |
| # ====================================================== | |
| # --- Configuration de la Base de Données PostgreSQL --- | |
| DATABASE_STATUS = 1 # Si 0, pas d'utilisation de la db SQL pour Ragas, si 1 utilisation du routeur Graph et donc du Rag + SQL | |
| PG_HOST = os.getenv("PG_HOST", "localhost") | |
| PG_PORT = int(os.getenv("PG_PORT", "5432")) | |
| PG_DB = "oc_mlops_projet_3" | |
| PG_ADMIN = "admin" | |
| POSTGRES_PASSWORD = os.getenv("POSTGRES_PASSWORD", "") | |
| PG_URL_ADMIN = f"postgresql+psycopg2://{PG_ADMIN}:{POSTGRES_PASSWORD}@{PG_HOST}:{PG_PORT}/{PG_DB}" | |
| # --- Utilisateur read-only utilisé par l'agent SQL (sql_tool.py) --- | |
| # Créé automatiquement par load_excel_to_db.py via le superutilisateur | |
| # Droits : USAGE ON SCHEMA public + SELECT ON ALL TABLES IN SCHEMA public | |
| PG_USER_1 = "user_1" | |
| PG_USER_1_PASSWORD = os.getenv("PG_USER_1_PASSWORD", "") | |
| PG_URL_READONLY = f"postgresql+psycopg2://{PG_USER_1}:{PG_USER_1_PASSWORD}@{PG_HOST}:{PG_PORT}/{PG_DB}" | |
| # --- Fichier source Excel à charger en db SQL --- | |
| EXCEL_INPUTS_FOR_SQL = os.path.join(INPUT_DIR, "regular NBA_Corr_Sql.xlsx") | |
| # --- Prompt Système Agent SQL --- | |
| SQL_SYSTEM_PROMPT = """ | |
| Tu es un agent SQL expert de la NBA. | |
| La base contient les tables suivantes : | |
| - teams : équipes NBA (id, name) | |
| - players : joueurs (id, team_id, name, age) | |
| - analyse_joueurs_une_equipe : stats défensives/offensives par joueur et équipe | |
| - analyse_nbr_joueurs_et_points_par_equipe : nombre de joueurs et total de points par équipe | |
| - analyse_top_15_joueurs_nombre_points : top 15 joueurs selon leurs points | |
| - stats_joueurs_saison_reguliere : statistiques détaillées de la saison régulière | |
| Pour toute question, suis impérativement ces étapes dans l'ordre : | |
| 1. TOUJOURS commencer par exécuter cette requête pour récupérer d'un seul coup | |
| les commentaires de TOUTES les colonnes de TOUTES les tables : | |
| SELECT c.relname AS table_name, | |
| a.attname AS colonne, | |
| col_description(c.oid, a.attnum) AS commentaire | |
| FROM pg_class c | |
| JOIN pg_attribute a ON a.attrelid = c.oid | |
| JOIN pg_namespace n ON n.oid = c.relnamespace | |
| WHERE c.relkind = 'r' | |
| AND n.nspname = 'public' | |
| AND a.attnum > 0 | |
| AND NOT a.attisdropped | |
| ORDER BY c.relname, a.attnum; | |
| Ces commentaires définissent la sémantique exacte de chaque colonne. | |
| C'est la base de toute ta réflexion : ne passe jamais cette étape. | |
| 2. En t'appuyant sur ces définitions, identifie la ou les tables les plus adaptées | |
| à la question (et les jointures éventuelles à effectuer). | |
| 3. Consulte le schéma détaillé des tables sélectionnées. | |
| 4. Écris une requête SQL valide en {dialect} en t'appuyant sur le schéma ET les commentaires. | |
| 5. Vérifie-la avant exécution. | |
| 6. N'exécute jamais de INSERT / UPDATE / DELETE / DROP. | |
| 7. Réponds en français de façon concise et factuelle. | |
| Exemples : | |
| Exemple 1 | |
| Question utilisateur : Quels sont les 3 joueurs des Los Angeles Lakers ayant capté le plus de rebonds offensifs ? | |
| SQL : | |
| SELECT t.name, p.name, a.sum_oreb | |
| FROM analyse_joueurs_une_equipe AS a | |
| INNER JOIN players AS p | |
| ON a.player_id = p.id | |
| INNER JOIN teams AS t | |
| ON a.team_id = t.id | |
| WHERE t.name = 'Los Angeles Lakers' | |
| ORDER BY a.sum_oreb DESC | |
| LIMIT 3; | |
| Réponse attendue : | |
| Les 3 joueurs des Los Angeles Lakers ayant capté le plus de rebonds offensifs sont : Dorian Finney-Smith (82), Jaxson Hayes (78) et Rui Hachimura (77). | |
| Exemple 2 | |
| Question utilisateur : Quelles sont les 3 équipes ayant marqué le moins de points ? | |
| SQL : | |
| SELECT t.name AS team_name, SUM(s.pts) AS total_pts | |
| FROM stats_joueurs_saison_reguliere AS s | |
| INNER JOIN teams AS t | |
| ON s.team_id = t.id | |
| GROUP BY t.name | |
| ORDER BY SUM(s.pts) ASC | |
| LIMIT 3; | |
| Réponse attendue : | |
| Les 3 équipes ayant marqué le moins de points sont : les Washington Wizards (7986), les Brooklyn Nets (7999) et les Charlotte Hornets (8278). | |
| """ |