Spaces:
Running
Running
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 LLMagent_service.py: Exécution des agentstranscription_service.py: Transcription audiosecurity.py: Authentification JWT
2. Open/Closed Principle (OCP)
Extensible sans modification:
# 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:
def get_llm(...) -> BaseChatModel:
# Peut retourner ChatOpenAI ou ChatMistralAI
# Les deux sont interchangeables
4. Interface Segregation Principle (ISP)
Interfaces spécifiques et minimales:
- Route
/completionne dépend que deAgentService - Route
/transcriptionne dépend que deTranscriptionService
5. Dependency Inversion Principle (DIP)
Les dépendances pointent vers les abstractions:
# 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:
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:
builder = agent_registry.get_builder(AgentType.SIMPLE)
graph = builder(llm)
Dependency Injection
FastAPI injecte les dépendances:
async def route(current_user: dict = Depends(CurrentUser)):
# current_user est injecté automatiquement
Singleton Pattern
Services instanciés une seule fois:
llm_service = LLMService() # Singleton
agent_registry = AgentRegistry() # Singleton
Sécurité
Authentification JWT
- Client demande un token:
POST /auth/token - Serveur génère un JWT signé
- Client inclut le token dans chaque requête:
Authorization: Bearer <token> - Middleware vérifie et décode le token
- Si valide, la requête est traitée
Validation des entrées
Tous les inputs sont validés par Pydantic:
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
- Ajouter dans
domain/enums.py:
class ModelName(str, Enum):
NEW_MODEL = "new-model-name"
- Ajouter dans
services/llm_service.py:
def list_available_models():
# Ajouter les métadonnées
Ajouter un nouveau type d'agent
- Créer le graphe dans
graphs/:
def create_custom_graph(llm):
# Votre graphe
return workflow.compile()
- Enregistrer dans
services/agent_registry.py:
agent_registry.register_agent(
AgentType.CUSTOM,
create_custom_graph,
"Description"
)
- Utiliser directement via l'API!
Ajouter une nouvelle route API
- Créer le fichier dans
api/routes/:
router = APIRouter(prefix="/custom", tags=["Custom"])
@router.get("/")
async def custom_route():
return {"message": "Custom"}
- Inclure dans
app.py:
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:
LANGCHAIN_TRACING_V2=true
LANGCHAIN_API_KEY=...
Logs
Logging structuré avec Python logging:
logger.info(f"Request: {method} {path}")
logger.error(f"Error: {error}", exc_info=True)
Déploiement
Docker
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