| # 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 <token>` |
| 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 |
|
|
|
|