import os import threading from datetime import datetime from modules.logger import log_event # IMPORT DE NOTRE MOTEUR FAISS (Le nouveau cerveau) from modules.vector_rag import rechercher_contexte_global, indexer_dossier_thematique # Définition du chemin racine sécurisé sur ton RAID RAG_BASE_DIR = "/DATA/AppData/MULTI-IA-AETHAS38/RAG" # Les thématiques pour organiser l'apprentissage THEMATIQUES_RAG = [ "Minecraft_KubeJS", "Juridique_Loi_Francaise", "Serveur_Debian", "Bureautique_Excel", "Regles_Aethas38", "Education_Nationale", "Connaissances_Generales" ] def initialiser_arborescence_rag(): """Crée les dossiers RAG physiques sur le disque s'ils n'existent pas.""" try: if not os.path.exists(RAG_BASE_DIR): os.makedirs(RAG_BASE_DIR) log_event("INFO", "RAG", "Création du dossier racine RAG.") for theme in THEMATIQUES_RAG: chemin_theme = os.path.join(RAG_BASE_DIR, theme) if not os.path.exists(chemin_theme): os.makedirs(chemin_theme) log_event("INFO", "RAG", f"Création du sous-dossier thématique : {theme}") except Exception as e: log_event("ERROR", "RAG", f"Erreur lors de l'initialisation de l'arborescence : {e}") def rechercher_contexte_rag(prompt, categorie="general"): """ Récupère le contenu des fichiers via la recherche sémantique FAISS + Ollama. (Remplace l'ancienne méthode d'extraction basique). """ try: # On fouille dans toute la base de connaissances et on récupère les 3 meilleurs blocs contexte = rechercher_contexte_global(prompt, top_k=3) return contexte except Exception as e: log_event("ERROR", "RAG_MANAGER", f"Erreur lors de la recherche FAISS : {e}") return "" def auto_apprendre_rag(prompt, reponse, thematique_simplifiee): """ Sauvegarde systématiquement la réponse en Markdown, puis déclenche l'indexation FAISS pour auto-incrémenter le RAG. """ # Mapping élargi mapping = { "minecraft": "Minecraft_KubeJS", "droit": "Juridique_Loi_Francaise", "serveur": "Serveur_Debian", "excel": "Bureautique_Excel", "regles": "Regles_Aethas38", "education_nationale": "Education_Nationale" } theme_reel = mapping.get(thematique_simplifiee.lower(), "Connaissances_Generales") try: chemin_theme = os.path.join(RAG_BASE_DIR, theme_reel) os.makedirs(chemin_theme, exist_ok=True) # On raccourcit le prompt pour créer un nom de fichier propre sujet_court = "".join(c for c in prompt[:15] if c.isalnum() or c == " ").strip().replace(" ", "_") nom_fichier = f"rag_{sujet_court}_{datetime.now().strftime('%H%M%S')}.md" chemin_fichier = os.path.join(chemin_theme, nom_fichier) contenu = f"## Question utilisateur\n{prompt}\n\n## Réponse de l'IA (Contexte validé)\n{reponse}\n" # 1. Sauvegarde physique du fichier with open(chemin_fichier, 'w', encoding='utf-8') as f: f.write(contenu) log_event("INFO", "RAG_MANAGER", f"Connaissance sauvegardée dans {theme_reel} ({nom_fichier}).") # 2. AUTO-INCRÉMENTATION : Lancement de l'indexation FAISS # On utilise un Thread (processus en arrière-plan) pour que l'indexation via Ollama # se fasse silencieusement sans bloquer l'interface web de l'utilisateur. tache_indexation = threading.Thread(target=indexer_dossier_thematique, args=(theme_reel,)) tache_indexation.start() log_event("INFO", "RAG_MANAGER", f"Indexation vectorielle lancée en tâche de fond pour {theme_reel}.") except Exception as e: log_event("ERROR", "RAG_MANAGER", f"Erreur lors de l'auto-apprentissage : {e}") # On s'assure que les dossiers existent dès l'import du module initialiser_arborescence_rag()