llm_lab/analyse_projets.md
2025-03-26 15:02:58 +01:00

10 KiB

Analyse comparative des projets AIagent2 et llm_lab-test

1. Différences structurelles entre les deux projets

Structure de AIagent2 (ancien projet)

AIagent2/
├── llm_classes/
│   ├── __init__.py
│   ├── llm.py (classe abstraite de base)
│   ├── mistral.py
│   ├── ollama.py
│   ├── deepseek.py
│   ├── perplexity.py
│   ├── deepl.py
│   ├── rag.py
│   ├── llama_vision.py
│   ├── agents.py (classe Agent abstraite et implémentations)
│   ├── example.py
│   ├── example_vision.py
│   └── requirements.txt
├── images/
└── JSON/

Structure de llm_lab-test (nouveau projet)

llm_lab-test/
├── core/
│   ├── base_llm.py (classe abstraite de base)
│   ├── factory.py (pattern Factory pour instancier les LLM)
│   ├── mistral7b.py
│   └── llama_vision90b.py
├── agents/
│   └── roles.py (définition des rôles d'agents)
├── utils/
├── tests/
├── config/
├── prompts/
├── outputs/
└── logs/

Principales différences

  1. Organisation structurelle:

    • AIagent2: Organisation plus plate avec toutes les classes LLM et agents dans le même package
    • llm_lab-test: Structure plus modulaire avec séparation claire entre core (modèles) et agents (rôles)
  2. Patron de conception:

    • AIagent2: Utilise principalement l'héritage avec classes abstraites
    • llm_lab-test: Utilise le pattern Factory pour créer les instances LLM et séparation entre modèles et rôles
  3. Gestion des configurations:

    • AIagent2: Configuration intégrée dans les classes
    • llm_lab-test: Configuration externalisée dans un dossier dédié et séparation des rôles
  4. Logging et sorties:

    • AIagent2: Gestion interne dans les classes
    • llm_lab-test: Dossiers dédiés pour les logs et les sorties

2. Analyse de la classe abstraite Agent dans AIagent2

Structure de la classe Agent

Dans l'ancien projet AIagent2, une classe abstraite Agent a été définie comme base pour tous les agents spécialisés. Cette approche suit le principe de conception orienté objet où une classe de base définit l'interface commune et les comportements partagés.

class Agent:
    """
    Classe de base pour tous les agents
    """
    def __init__(self, nom: str = "Agent"):
        self.nom: str = nom
        self.historique: List[Dict[str, Any]] = []
        
    def ajouter_historique(self, action: str, input_data: Any, output_data: Any) -> None:
        # Implémentation commune
        
    def obtenir_historique(self) -> List[Dict[str, Any]]:
        # Implémentation commune
        
    def executer(self, *args, **kwargs) -> Any:
        # Méthode abstraite que chaque agent doit implémenter
        raise NotImplementedError("Chaque agent doit implémenter sa propre méthode executer()")

Agents spécialisés implémentés

Trois agents spécialisés héritent de cette classe abstraite :

  1. AgentAnalyseImage - Spécialisé dans l'analyse d'images avec LlamaVision
  2. AgentAnalyseJSON - Spécialisé dans l'analyse de données JSON
  3. AgentQuestionReponse - Spécialisé dans le processus de questions/réponses

Intérêt de cette approche

  1. Cohérence d'interface : Tous les agents partagent la même interface de base (executer())
  2. Code réutilisable : Les fonctionnalités communes comme la gestion de l'historique sont implémentées une seule fois
  3. Extensibilité : Facile d'ajouter de nouveaux types d'agents en héritant de la classe de base
  4. Polymorphisme : Possibilité de traiter différents agents de manière uniforme
  5. Traçabilité : Gestion unifiée de l'historique des actions et résultats

3. Analyse des classes LLM dans les deux projets

Classes LLM dans AIagent2

Le projet AIagent2 comporte plusieurs classes pour différents modèles LLM, toutes héritant d'une classe abstraite LLM :

  1. Mistral - Intégration avec l'API Mistral
  2. Ollama - Intégration avec Ollama pour les modèles locaux
  3. DeepSeek - Intégration avec l'API DeepSeek
  4. Perplexity - Intégration avec l'API Perplexity
  5. DeepL - Intégration avec l'API DeepL pour la traduction
  6. RAG - Système de Retrieval Augmented Generation
  7. LlamaVision - Intégration avec Llama Vision 3.2 pour l'analyse d'images

Toutes ces classes partagent une interface commune définie par la classe abstraite LLM, qui inclut des méthodes comme Interroger(), LLM_POST(), etc.

Classes LLM dans llm_lab-test

Le nouveau projet utilise une approche similaire mais plus simplifiée :

  1. BaseLLM - Classe de base abstraite
  2. Mistral7B - Implémentation pour Mistral 7B
  3. LlamaVision90B - Implémentation pour Llama Vision 90B

La différence principale est la séparation entre les modèles et les rôles (agents), qui sont définis dans un fichier séparé.

Comparaison des implémentations LlamaVision

LlamaVision dans AIagent2

  • Plus de paramètres configurables (température, top_k, top_p, mirostat, etc.)
  • Support intégré pour les images et données JSON
  • Méthodes pour la fusion des résultats avec JSON
  • Gestion détaillée des erreurs

LlamaVision90B dans llm_lab-test

  • Implémentation plus simple
  • Moins de paramètres configurables
  • Support pour la traduction automatique
  • Structure plus légère

4. Recommandations pour le nouveau projet

Intégration de la classe Agent dans llm_lab-test

L'approche avec une classe abstraite Agent présente des avantages significatifs qui pourraient être bénéfiques pour le nouveau projet sans perturber son fonctionnement actuel.

Voici comment elle pourrait être implémentée :

# Proposition pour agents/base_agent.py
from datetime import datetime
from typing import Dict, List, Any, Optional

class Agent:
    """Classe de base pour tous les agents d'analyse"""
    
    def __init__(self, nom: str = "Agent"):
        self.nom = nom
        self.historique = []
        
    def ajouter_historique(self, action: str, input_data: Any, output_data: Any) -> None:
        """Ajoute une entrée dans l'historique de l'agent"""
        self.historique.append({
            "timestamp": datetime.now().isoformat(),
            "action": action,
            "input": str(input_data)[:500],
            "output": str(output_data)[:500]
        })
    
    def obtenir_historique(self) -> List[Dict[str, Any]]:
        """Retourne l'historique complet de l'agent"""
        return self.historique
    
    def executer(self, *args, **kwargs) -> Any:
        """Méthode abstraite à implémenter dans les classes dérivées"""
        raise NotImplementedError("Chaque agent doit implémenter sa propre méthode executer()")

Adaptation de LlamaVision90B avec plus de paramètres

Le modèle LlamaVision90B du nouveau projet pourrait bénéficier des paramètres supplémentaires disponibles dans l'ancien projet :

# Proposition de mise à jour pour core/llama_vision90b.py
class LlamaVision90B(BaseLLM):
    def __init__(self):
        model_name = "llama3.2-vision:90b"
        engine = "Ollama"
        
        self.api_url = "http://217.182.105.173:11434/api/chat"
        
        default_params = {
            # Paramètres existants
            "temperature": 0.3,
            "top_p": 1.0,
            "top_k": 40,
            "repeat_penalty": 1.1,
            "num_predict": 512,
            "num_ctx": 4096,
            
            # Nouveaux paramètres inspirés de l'ancien projet
            "mirostat": 0,
            "mirostat_eta": 0.1,
            "mirostat_tau": 5.0,
            "seed": 0,
            "stop": [],
            "min_p": 0.0,
            
            # Paramètres existants
            "format": "json",
            "stream": False,
            "raw": False,
            "keep_alive": "5m"
        }
        
        super().__init__(model_name=model_name, engine=engine, base_params=default_params)
        
        # Support pour les données JSON associées
        self.json_data = {}
        
    def set_json_data(self, json_data: Dict[str, Any]) -> bool:
        """Définit les données JSON à associer à l'image"""
        try:
            self.json_data = json_data
            return True
        except Exception as e:
            print(f"Erreur lors de la définition des données JSON: {e}")
            return False
        
    # [...] Reste de l'implémentation 

Création d'une classe Mistral compatible avec l'ancien projet

# Proposition pour core/mistral_api.py
from core.base_llm import BaseLLM
import requests
import json

class MistralAPI(BaseLLM):
    """Intégration avec l'API Mistral (similaire à la classe Mistral de l'ancien projet)"""
    
    def __init__(self):
        model_name = "mistral-large-latest"
        engine = "MistralAPI"
        
        self.api_url = "https://api.mistral.ai/v1/chat/completions"
        self.api_key = "VOTRE_CLE_API"  # À remplacer par la clé réelle ou une variable d'environnement
        
        default_params = {
            "temperature": 0.7,
            "top_p": 0.9,
            "max_tokens": 1024,
            "presence_penalty": 0,
            "frequency_penalty": 0,
            "stop": []
        }
        
        super().__init__(model_name=model_name, engine=engine, base_params=default_params)
        
    def generate(self, user_prompt):
        prompt = self._format_prompt(user_prompt)
        
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self.api_key}"
        }
        
        payload = {
            "model": self.model,
            "messages": [
                {"role": "system", "content": self.system_prompt},
                {"role": "user", "content": user_prompt}
            ],
            "temperature": self.params.get("temperature", 0.7),
            "top_p": self.params.get("top_p", 0.9),
            "max_tokens": self.params.get("max_tokens", 1024)
        }
        
        response = requests.post(self.api_url, headers=headers, json=payload)
        
        if not response.ok:
            raise Exception(f"Erreur API Mistral: {response.status_code} - {response.text}")
        
        result_data = response.json()
        result_text = result_data.get("choices", [{}])[0].get("message", {}).get("content", "")
        
        return self._log_result(user_prompt, result_text)