moteur_ia.py — v2 (logs, erreurs gérées, recherche branchée)

Bienvenue sur CFTPfr.fr Forums moteur_ia.py — v2 (logs, erreurs gérées, recherche branchée)

  • Ce sujet est vide.
Affichage de 1 message (sur 1 au total)
  • Auteur
    Messages
  • #266
    Mario Da Conceicao
    Maître des clés

    Version corrigée du 01/08/2026, après relecture critique. Retenu : gestion des erreurs (try/except), journal (logging), recherche sémantique enfin branchée. Refusé : cache des réponses (lru_cache — défaut connu de fuite mémoire sur une méthode d’objet, en plus de figer artificiellement les réponses), et le chargement de plusieurs modèles en parallèle (contraire à l’adaptation à la RAM disponible).

    import sys
    import logging
    from pathlib import Path
    
    sys.path.append(str(Path(__file__).resolve().parent))
    
    from detecteur_materiel import choisir_palier_modele, modele_deja_present, obtenir_ram_disponible_go, obtenir_espace_disque_go
    from gestionnaire_specialites import GestionnaireSpecialites
    from recherche_semantique import RechercheSemantique
    
    BASE_DIR = Path(__file__).resolve().parent
    MODELES_DIR = BASE_DIR / "modeles"
    LOGS_DIR = BASE_DIR / "logs"
    LOGS_DIR.mkdir(parents=True, exist_ok=True)
    
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s - %(levelname)s - %(message)s",
        filename=str(LOGS_DIR / "mira.log"),
    )
    
    PROMPT_SYSTEME = """Tu es MIRA, une intelligence artificielle locale et autonome.
    
    Tes principes, non négociables :
    1. PRÉCISION avant vitesse. Tu prends le temps de vérifier avant de répondre.
       Tu ne devines jamais quand tu peux vérifier dans tes spécialités.
    2. RÉPONSES COURTES ET JUSTES. Jamais de remplissage, jamais de blabla.
    3. HONNÊTETÉ. Si tu ne sais pas, tu le dis clairement, tu ne bluffes jamais.
    4. AUCUNE ACTION SANS VALIDATION. Tu ne modifies jamais de fichier système,
       ne télécharges rien, n'actives aucune spécialité sans l'accord explicite
       de l'utilisateur.
    5. Tu restes toi-même : conçue et façonnée par Mario ANTARES.
    """
    
    class MoteurMira:
        def __init__(self):
            self.ram_go = obtenir_ram_disponible_go()
            self.espace_disque_go = obtenir_espace_disque_go()
            self.palier = choisir_palier_modele(self.ram_go, self.espace_disque_go)
            self.specialites = GestionnaireSpecialites()
            self.modele_charge = None
            self.recherche = None  # branché une fois un moteur d'embeddings disponible
    
        def demarrer(self):
            """NOUVEAU : entouré de try/except + journalisation des erreurs."""
            try:
                if not modele_deja_present(self.palier):
                    logging.warning(f"Modèle {self.palier['nom']} non installé.")
                    return {
                        "statut": "attente_validation",
                        "message": (
                            f"Le modèle recommandé ({self.palier['nom']}, {self.palier['parametres']}) "
                            f"n'est pas installé. Fichier attendu : modeles/{self.palier['fichier']}. "
                            "Aucun téléchargement automatique — validation nécessaire."
                        )
                    }
    
                self._charger_modele()
                logging.info(f"Moteur démarré avec {self.palier['nom']}.")
                return {"statut": "pret", "message": self.rapport_demarrage()}
    
            except Exception as e:
                logging.error(f"Erreur au démarrage : {e}")
                return {"statut": "erreur", "message": f"Erreur au démarrage : {e}"}
    
        def _charger_modele(self):
            try:
                from llama_cpp import Llama
                self.modele_charge = Llama(
                    model_path=str(MODELES_DIR / self.palier["fichier"]),
                    n_ctx=4096,
                    verbose=False,
                )
            except ImportError:
                logging.warning("llama-cpp-python non installé.")
                self.modele_charge = None
    
        def rapport_demarrage(self):
            return (
                f"RAM détectée : {self.ram_go} Go\n"
                f"Espace disque : {self.espace_disque_go} Go\n"
                f"Modèle chargé : {self.palier['nom']} ({self.palier['parametres']})\n"
                f"Spécialités actives : {len(self.specialites.lister_actives())}"
            )
    
        def repondre(self, question):
            """NOUVEAU : gestion des erreurs, pas de cache (chaque question est
            vraiment retraitée, cohérent avec 'précision avant vitesse')."""
            if self.modele_charge is None:
                return "Le moteur neuronal n'est pas encore chargé (llama.cpp manquant ou modèle absent)."
    
            try:
                contexte = self._rassembler_contexte(question)
                messages = [{"role": "system", "content": PROMPT_SYSTEME}]
                if contexte:
                    messages.append({
                        "role": "system",
                        "content": f"Informations trouvées dans tes spécialités, utilise-les si pertinentes :\n{contexte}"
                    })
                messages.append({"role": "user", "content": question})
    
                resultat = self.modele_charge.create_chat_completion(
                    messages=messages,
                    max_tokens=400,
                    temperature=0.3,
                )
                return resultat["choices"][0]["message"]["content"].strip()
    
            except Exception as e:
                logging.error(f"Erreur lors de la réponse : {e}")
                return f"Erreur lors de la génération de la réponse : {e}"
    
        def _rassembler_contexte(self, question):
            """MODIFIÉ : utilise la vraie recherche sémantique si un index existe
            pour la spécialité, sinon retombe sur la recherche simple."""
            extraits = []
            for specialite in self.specialites.lister_actives():
                nom = specialite["nom"]
                fichier_index = MODELES_DIR.parent / "specialites" / nom / "index.json"
                if self.recherche and fichier_index.exists():
                    resultats = self.recherche.chercher(question, fichier_index, top_n=2)
                    extraits.extend(r["texte"] for r in resultats)
                else:
                    resultats = self.specialites.consulter_specialite(nom, mot_cle=None)
                    if resultats:
                        extraits.extend(r["extrait"] for r in resultats[:1])
            return "\n---\n".join(extraits) if extraits else None
    
    if __name__ == "__main__":
        moteur = MoteurMira()
        etat = moteur.demarrer()
        print(etat["message"])
Affichage de 1 message (sur 1 au total)
  • Vous devez être connecté pour répondre à ce sujet.
Retour en haut