# Architecture du Projet ## Vue d'ensemble Ce projet suit les principes de **Clean Architecture** et **SOLID** pour garantir: - Maintenabilité - Testabilité - Extensibilité - Séparation des responsabilités ## Structure des dossiers ``` routeur_ia_api/ │ ├── config/ # Configuration │ ├── __init__.py │ └── settings.py # Settings avec pydantic-settings │ ├── core/ # Noyau de l'application │ ├── __init__.py │ ├── security.py # Authentification JWT │ └── dependencies.py # Dépendances FastAPI │ ├── domain/ # Couche domaine (modèles métier) │ ├── __init__.py │ ├── enums.py # Enums (ModelName, AgentType, etc.) │ └── models.py # Modèles Pydantic (DTO) │ ├── services/ # Couche service (logique métier) │ ├── __init__.py │ ├── llm_service.py # Factory LLM multi-providers │ ├── agent_service.py # Orchestration des agents │ ├── agent_registry.py # Registre des agents disponibles │ └── transcription_service.py # Service Whisper │ ├── graphs/ # Graphes LangGraph │ ├── __init__.py │ ├── base_graph.py # Graphe conversationnel simple │ └── README.md # Doc pour créer des graphes │ ├── api/ # Couche présentation (API) │ ├── __init__.py │ ├── routes/ │ │ ├── __init__.py │ │ ├── auth.py # Routes authentification │ │ ├── completion.py # Routes completion │ │ ├── transcription.py # Routes transcription │ │ ├── models.py # Routes liste modèles/agents │ │ └── realtime.py # Routes WebSocket/WebRTC │ └── middleware.py # Middleware personnalisé │ └── app.py # Point d'entrée FastAPI ``` ## Flux de données ``` ┌─────────────┐ │ Client │ └──────┬──────┘ │ HTTP Request + JWT ▼ ┌─────────────────────────────────┐ │ FastAPI App │ │ ┌──────────────────────────┐ │ │ │ Security Middleware │ │ │ └──────────┬───────────────┘ │ │ ▼ │ │ ┌──────────────────────────┐ │ │ │ API Routes Layer │ │ │ │ (auth, completion, etc) │ │ │ └──────────┬───────────────┘ │ └─────────────┼───────────────────┘ ▼ ┌─────────────────────────────────┐ │ Services Layer │ │ ┌─────────────────────────┐ │ │ │ Agent Service │ │ │ │ LLM Service │ │ │ │ Transcription Service │ │ │ └──────────┬──────────────┘ │ └─────────────┼───────────────────┘ ▼ ┌─────────────────────────────────┐ │ External Services │ │ - OpenAI API │ │ - Mistral AI API │ │ - LangChain/LangGraph │ └─────────────────────────────────┘ ``` ## Principes SOLID appliqués ### 1. Single Responsibility Principle (SRP) Chaque module a une seule responsabilité: - `llm_service.py`: Gestion des LLM - `agent_service.py`: Exécution des agents - `transcription_service.py`: Transcription audio - `security.py`: Authentification JWT ### 2. Open/Closed Principle (OCP) **Extensible sans modification:** ```python # Ajouter un nouvel agent sans toucher au code existant agent_registry.register_agent( AgentType.NEW_AGENT, create_new_graph, "Description" ) ``` ### 3. Liskov Substitution Principle (LSP) Tous les LLM respectent l'interface `BaseChatModel` de LangChain: ```python def get_llm(...) -> BaseChatModel: # Peut retourner ChatOpenAI ou ChatMistralAI # Les deux sont interchangeables ``` ### 4. Interface Segregation Principle (ISP) Interfaces spécifiques et minimales: - Route `/completion` ne dépend que de `AgentService` - Route `/transcription` ne dépend que de `TranscriptionService` ### 5. Dependency Inversion Principle (DIP) Les dépendances pointent vers les abstractions: ```python # AgentService dépend de l'abstraction BaseChatModel # pas d'une implémentation concrète class AgentService: def invoke(self, ..., model_name: ModelName): llm: BaseChatModel = llm_service.get_llm(model_name) # llm peut être n'importe quelle implémentation ``` ## Patterns utilisés ### Factory Pattern `LLMService` est un factory pour créer les bons LLM: ```python llm = llm_service.get_llm(ModelName.GPT_4) # ou llm = llm_service.get_llm(ModelName.MISTRAL_LARGE) ``` ### Registry Pattern `AgentRegistry` gère les agents disponibles: ```python builder = agent_registry.get_builder(AgentType.SIMPLE) graph = builder(llm) ``` ### Dependency Injection FastAPI injecte les dépendances: ```python async def route(current_user: dict = Depends(CurrentUser)): # current_user est injecté automatiquement ``` ### Singleton Pattern Services instanciés une seule fois: ```python llm_service = LLMService() # Singleton agent_registry = AgentRegistry() # Singleton ``` ## Sécurité ### Authentification JWT 1. Client demande un token: `POST /auth/token` 2. Serveur génère un JWT signé 3. Client inclut le token dans chaque requête: `Authorization: Bearer ` 4. Middleware vérifie et décode le token 5. Si valide, la requête est traitée ### Validation des entrées Tous les inputs sont validés par Pydantic: ```python class CompletionRequest(BaseModel): message: str = Field(...) model: ModelName = Field(...) # Enum validation temperature: float = Field(ge=0.0, le=2.0) # Range validation ``` ## Extensibilité ### Ajouter un nouveau modèle LLM 1. Ajouter dans `domain/enums.py`: ```python class ModelName(str, Enum): NEW_MODEL = "new-model-name" ``` 2. Ajouter dans `services/llm_service.py`: ```python def list_available_models(): # Ajouter les métadonnées ``` ### Ajouter un nouveau type d'agent 1. Créer le graphe dans `graphs/`: ```python def create_custom_graph(llm): # Votre graphe return workflow.compile() ``` 2. Enregistrer dans `services/agent_registry.py`: ```python agent_registry.register_agent( AgentType.CUSTOM, create_custom_graph, "Description" ) ``` 3. Utiliser directement via l'API! ### Ajouter une nouvelle route API 1. Créer le fichier dans `api/routes/`: ```python router = APIRouter(prefix="/custom", tags=["Custom"]) @router.get("/") async def custom_route(): return {"message": "Custom"} ``` 2. Inclure dans `app.py`: ```python from api.routes import custom app.include_router(custom.router) ``` ## Tests (à implémenter) Structure recommandée: ``` tests/ ├── unit/ │ ├── test_llm_service.py │ ├── test_agent_service.py │ └── test_security.py ├── integration/ │ ├── test_completion_api.py │ ├── test_transcription_api.py │ └── test_auth_flow.py └── e2e/ └── test_full_workflow.py ``` ## Performance ### Asynchronicité Toutes les opérations I/O sont async: - Appels API externes (OpenAI, Mistral) - Requêtes base de données (futures) - Opérations fichiers (transcription) ### Streaming Support du streaming pour réduire la latence perçue: - Server-Sent Events (SSE) pour completion - WebSocket pour communication temps réel ## Monitoring ### LangSmith Intégration optionnelle pour tracer les agents LangChain: ```env LANGCHAIN_TRACING_V2=true LANGCHAIN_API_KEY=... ``` ### Logs Logging structuré avec Python logging: ```python logger.info(f"Request: {method} {path}") logger.error(f"Error: {error}", exc_info=True) ``` ## Déploiement ### Docker ```dockerfile FROM python:3.12 # Configuration sécurisée # Installation dépendances # Lancement uvicorn ``` ### Production Recommandations: - Uvicorn avec workers multiples - Reverse proxy (nginx, traefik) - HTTPS obligatoire - Variables d'environnement sécurisées - Rate limiting - Monitoring (Prometheus, Grafana) ## Évolutions futures - [ ] Cache Redis pour réponses fréquentes - [ ] Base vectorielle pour RAG - [ ] Queue Celery pour tâches longues - [ ] Métriques Prometheus - [ ] Tests automatisés - [ ] CI/CD pipeline