Files
rpa_vision_v3/.kiro/specs/rpa-precision-enhancement/design.md
Dom a7de6a488b feat: replay E2E fonctionnel — 25/25 actions, 0 retries, SomEngine via serveur
Validé sur PC Windows (DESKTOP-58D5CAC, 2560x1600) :
- 8 clics résolus visuellement (1 anchor_template, 1 som_text_match, 6 som_vlm)
- Score moyen 0.75, temps moyen 1.6s
- Texte tapé correctement (bonjour, test word, date, email)
- 0 retries, 2 actions non vérifiées (OK)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 14:04:41 +02:00

23 KiB

RPA Precision Enhancement - Document de Design

Auteur: Dom, Alice Kiro
Date: 15 décembre 2024
Version: 1.0
Statut: Design Initial

🏗️ Architecture Générale

Vue d'Ensemble du Système

┌─────────────────────────────────────────────────────────────────┐
│                    RPA Precision Enhancement                    │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐ │
│  │   Monitoring    │  │   Performance   │  │   Robustness    │ │
│  │   Dashboard     │  │   Optimizer     │  │   Manager       │ │
│  └─────────────────┘  └─────────────────┘  └─────────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐ │
│  │  Precision      │  │   Adaptive      │  │   Cache         │ │
│  │  Metrics        │  │   Calibrator    │  │   Manager       │ │
│  └─────────────────┘  └─────────────────┘  └─────────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│                    Core RPA Vision V3                          │
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐ │
│  │ Target Resolver │  │ Action Executor │  │ Screen Capturer │ │
│  │   (Enhanced)    │  │   (Enhanced)    │  │   (Enhanced)    │ │
│  └─────────────────┘  └─────────────────┘  └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘

Composants Principaux

1. Precision Metrics Engine

  • Responsabilité: Collecte et analyse métriques précision temps réel
  • Interface: PrecisionMetricsCollector, MetricsAnalyzer
  • Stockage: TimeSeries DB (InfluxDB/Prometheus)

2. Adaptive Calibrator

  • Responsabilité: Ajustement automatique seuils et paramètres
  • Interface: ThresholdCalibrator, EnvironmentDetector
  • Algorithmes: ML adaptatif, A/B testing

3. Robustness Manager

  • Responsabilité: Gestion multi-environnements et récupération
  • Interface: EnvironmentNormalizer, UIChangeDetector
  • Stratégies: DPI normalization, fallback chains

4. Performance Optimizer

  • Responsabilité: Optimisation latence et throughput
  • Interface: ParallelResolver, CacheOptimizer
  • Techniques: Parallel processing, intelligent caching

5. Monitoring Dashboard

  • Responsabilité: Visualisation temps réel et alertes
  • Interface: Web dashboard, REST API
  • Technologies: React/TypeScript, WebSocket

🔧 Design Détaillé par Composant

1. Precision Metrics Engine

Architecture

class PrecisionMetricsEngine:
    """
    Moteur de collecte et analyse des métriques de précision.
    
    Collecte en temps réel:
    - Latence résolution par stratégie
    - Taux de succès par environnement
    - Confiance moyenne par type d'élément
    - Patterns d'échec et récupération
    """
    
    def __init__(self):
        self.collectors: List[MetricsCollector] = []
        self.analyzers: List[MetricsAnalyzer] = []
        self.storage: TimeSeriesStorage = None
        self.alerting: AlertManager = None
    
    async def collect_resolution_metrics(
        self, 
        target_spec: TargetSpec,
        result: Optional[ResolvedTarget],
        latency_ms: float,
        environment_info: EnvironmentInfo
    ) -> None:
        """Collecter métriques d'une résolution"""
        
    async def analyze_trends(
        self, 
        time_window: timedelta
    ) -> PrecisionAnalysis:
        """Analyser tendances sur période donnée"""
        
    async def detect_anomalies(self) -> List[Anomaly]:
        """Détecter anomalies dans métriques"""

Métriques Collectées

@dataclass
class ResolutionMetrics:
    """Métriques d'une résolution individuelle"""
    timestamp: datetime
    target_spec: TargetSpec
    success: bool
    latency_ms: float
    confidence: float
    strategy_used: str
    fallback_applied: bool
    environment_hash: str
    screen_resolution: Tuple[int, int]
    dpi_scale: float
    error_type: Optional[str] = None
    recovery_time_ms: Optional[float] = None

@dataclass
class AggregatedMetrics:
    """Métriques agrégées par période"""
    time_window: timedelta
    total_resolutions: int
    success_rate: float
    avg_latency_ms: float
    p95_latency_ms: float
    p99_latency_ms: float
    strategy_distribution: Dict[str, int]
    environment_success_rates: Dict[str, float]
    top_failure_patterns: List[FailurePattern]

2. Adaptive Calibrator

Architecture

class AdaptiveCalibrator:
    """
    Calibrateur adaptatif pour optimisation automatique des paramètres.
    
    Fonctionnalités:
    - Détection automatique environnement (DPI, résolution, thème)
    - Ajustement seuils de confiance par contexte
    - A/B testing configurations
    - Rollback automatique si dégradation
    """
    
    def __init__(self):
        self.environment_detector = EnvironmentDetector()
        self.threshold_optimizer = ThresholdOptimizer()
        self.ab_tester = ABTester()
        self.config_manager = ConfigurationManager()
    
    async def detect_environment_change(
        self, 
        screen_state: ScreenState
    ) -> Optional[EnvironmentChange]:
        """Détecter changement d'environnement"""
        
    async def calibrate_thresholds(
        self, 
        environment: EnvironmentInfo,
        historical_metrics: List[ResolutionMetrics]
    ) -> CalibrationResult:
        """Calibrer seuils pour environnement donné"""
        
    async def test_configuration(
        self, 
        config_a: Configuration,
        config_b: Configuration,
        test_duration: timedelta
    ) -> ABTestResult:
        """Tester deux configurations en A/B"""

Détection d'Environnement

@dataclass
class EnvironmentInfo:
    """Information sur l'environnement d'exécution"""
    screen_resolution: Tuple[int, int]
    dpi_scale: float
    color_depth: int
    os_version: str
    browser_info: Optional[BrowserInfo]
    ui_theme: str  # "light", "dark", "high_contrast"
    accessibility_mode: bool
    zoom_level: float
    
    def compute_hash(self) -> str:
        """Hash unique pour cet environnement"""
        return hashlib.md5(
            f"{self.screen_resolution}_{self.dpi_scale}_{self.ui_theme}_{self.zoom_level}"
            .encode()
        ).hexdigest()

class EnvironmentDetector:
    """Détecteur d'environnement et changements"""
    
    def detect_current_environment(self) -> EnvironmentInfo:
        """Détecter environnement actuel"""
        
    def detect_ui_changes(
        self, 
        previous_state: ScreenState,
        current_state: ScreenState
    ) -> List[UIChange]:
        """Détecter changements UI entre deux états"""
        
    def normalize_coordinates(
        self, 
        bbox: Tuple[int, int, int, int],
        source_env: EnvironmentInfo,
        target_env: EnvironmentInfo
    ) -> Tuple[int, int, int, int]:
        """Normaliser coordonnées entre environnements"""

3. Robustness Manager

Architecture

class RobustnessManager:
    """
    Gestionnaire de robustesse multi-environnements.
    
    Responsabilités:
    - Normalisation DPI/résolution
    - Adaptation zoom/échelle
    - Stratégies de récupération
    - Fallback intelligent
    """
    
    def __init__(self):
        self.normalizer = CoordinateNormalizer()
        self.scale_adapter = ScaleAdapter()
        self.recovery_strategies = RecoveryStrategyManager()
        self.fallback_chains = FallbackChainManager()
    
    async def resolve_with_robustness(
        self, 
        target_spec: TargetSpec,
        screen_state: ScreenState,
        environment: EnvironmentInfo
    ) -> Optional[ResolvedTarget]:
        """Résolution robuste avec fallbacks"""
        
    async def adapt_to_scale_change(
        self, 
        original_elements: List[UIElement],
        scale_factor: float
    ) -> List[UIElement]:
        """Adapter éléments à changement d'échelle"""

Stratégies de Récupération

class RecoveryStrategy(ABC):
    """Stratégie de récupération abstraite"""
    
    @abstractmethod
    async def can_recover(
        self, 
        failure: ResolutionFailure,
        context: RecoveryContext
    ) -> bool:
        """Vérifier si cette stratégie peut récupérer"""
        
    @abstractmethod
    async def attempt_recovery(
        self, 
        failure: ResolutionFailure,
        context: RecoveryContext
    ) -> Optional[ResolvedTarget]:
        """Tenter récupération"""

class SpatialRecoveryStrategy(RecoveryStrategy):
    """Récupération par relations spatiales"""
    
class SemanticRecoveryStrategy(RecoveryStrategy):
    """Récupération par similarité sémantique"""
    
class TemplateRecoveryStrategy(RecoveryStrategy):
    """Récupération par matching de templates"""

4. Performance Optimizer

Architecture

class PerformanceOptimizer:
    """
    Optimiseur de performance pour résolution parallèle et cache intelligent.
    
    Fonctionnalités:
    - Résolution batch/parallèle
    - Cache multi-niveaux
    - Pool de workers
    - Optimisation GPU/CPU
    """
    
    def __init__(self):
        self.parallel_resolver = ParallelResolver()
        self.cache_manager = IntelligentCacheManager()
        self.worker_pool = WorkerPoolManager()
        self.resource_optimizer = ResourceOptimizer()
    
    async def resolve_batch(
        self, 
        target_specs: List[TargetSpec],
        screen_state: ScreenState,
        max_parallelism: int = 4
    ) -> List[Optional[ResolvedTarget]]:
        """Résoudre plusieurs cibles en parallèle"""
        
    async def optimize_cache_strategy(
        self, 
        usage_patterns: List[CacheUsagePattern]
    ) -> CacheConfiguration:
        """Optimiser stratégie de cache"""

Cache Multi-Niveaux

class IntelligentCacheManager:
    """
    Gestionnaire de cache intelligent multi-niveaux.
    
    Niveaux:
    1. L1: Résolutions récentes (LRU, 100 entrées)
    2. L2: Embeddings par session (TTL 1h)
    3. L3: Relations spatiales (TTL 30min)
    4. L4: Configurations environnement (TTL 24h)
    """
    
    def __init__(self):
        self.l1_cache = LRUCache(maxsize=100)  # Résolutions
        self.l2_cache = TTLCache(maxsize=1000, ttl=3600)  # Embeddings
        self.l3_cache = TTLCache(maxsize=500, ttl=1800)  # Relations
        self.l4_cache = TTLCache(maxsize=50, ttl=86400)  # Configs
        
    async def get_cached_resolution(
        self, 
        cache_key: str
    ) -> Optional[ResolvedTarget]:
        """Récupérer résolution du cache"""
        
    async def cache_resolution(
        self, 
        cache_key: str,
        result: ResolvedTarget,
        cache_level: int = 1
    ) -> None:
        """Mettre en cache une résolution"""
        
    async def invalidate_on_ui_change(
        self, 
        ui_change: UIChange
    ) -> None:
        """Invalider cache suite à changement UI"""

5. Monitoring Dashboard

Architecture Frontend (React/TypeScript)

// Components principaux
interface MonitoringDashboardProps {
  metricsEngine: PrecisionMetricsEngine;
  realTimeUpdates: boolean;
}

const MonitoringDashboard: React.FC<MonitoringDashboardProps> = ({
  metricsEngine,
  realTimeUpdates
}) => {
  return (
    <div className="monitoring-dashboard">
      <MetricsOverview />
      <PrecisionTrends />
      <EnvironmentComparison />
      <AlertsPanel />
      <PerformanceCharts />
    </div>
  );
};

// Hooks pour données temps réel
const useRealTimeMetrics = (refreshInterval: number = 5000) => {
  const [metrics, setMetrics] = useState<AggregatedMetrics | null>(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    const ws = new WebSocket('/api/metrics/stream');
    ws.onmessage = (event) => {
      const newMetrics = JSON.parse(event.data);
      setMetrics(newMetrics);
      setLoading(false);
    };
    
    return () => ws.close();
  }, []);
  
  return { metrics, loading };
};

API Backend (FastAPI)

from fastapi import FastAPI, WebSocket
from fastapi.responses import HTMLResponse

app = FastAPI(title="RPA Precision Monitoring API")

@app.websocket("/api/metrics/stream")
async def metrics_websocket(websocket: WebSocket):
    """Stream temps réel des métriques"""
    await websocket.accept()
    
    async for metrics in metrics_engine.stream_metrics():
        await websocket.send_json(metrics.dict())

@app.get("/api/metrics/summary")
async def get_metrics_summary(
    time_window: str = "1h"
) -> AggregatedMetrics:
    """Résumé des métriques sur période"""
    
@app.get("/api/environments")
async def get_environments() -> List[EnvironmentInfo]:
    """Liste des environnements détectés"""
    
@app.post("/api/calibration/trigger")
async def trigger_calibration(
    environment_id: str
) -> CalibrationResult:
    """Déclencher calibration pour environnement"""

🔄 Flux de Données et Intégrations

Flux Principal de Résolution Améliorée

sequenceDiagram
    participant Client
    participant RobustnessManager
    participant TargetResolver
    participant MetricsEngine
    participant AdaptiveCalibrator
    participant CacheManager
    
    Client->>RobustnessManager: resolve_target(spec, screen_state)
    RobustnessManager->>CacheManager: check_cache(cache_key)
    
    alt Cache Hit
        CacheManager-->>RobustnessManager: cached_result
        RobustnessManager-->>Client: result
    else Cache Miss
        RobustnessManager->>AdaptiveCalibrator: get_optimized_config(environment)
        AdaptiveCalibrator-->>RobustnessManager: config
        
        RobustnessManager->>TargetResolver: resolve_with_config(spec, config)
        TargetResolver-->>RobustnessManager: result
        
        RobustnessManager->>CacheManager: cache_result(key, result)
        RobustnessManager->>MetricsEngine: record_metrics(spec, result, latency)
        
        RobustnessManager-->>Client: result
    end
    
    MetricsEngine->>AdaptiveCalibrator: update_calibration_data(metrics)

Intégration avec Composants Existants

Enhanced Target Resolver

class EnhancedTargetResolver(TargetResolver):
    """
    Version améliorée du TargetResolver avec support précision avancée.
    
    Nouvelles fonctionnalités:
    - Métriques intégrées
    - Cache intelligent
    - Adaptation environnement
    - Récupération robuste
    """
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.metrics_engine = PrecisionMetricsEngine()
        self.robustness_manager = RobustnessManager()
        self.performance_optimizer = PerformanceOptimizer()
    
    async def resolve_target(
        self,
        target_spec: TargetSpec,
        screen_state: ScreenState,
        context: Optional[ResolutionContext] = None
    ) -> Optional[ResolvedTarget]:
        """Résolution avec améliorations précision"""
        
        start_time = time.time()
        environment = self.robustness_manager.detect_environment()
        
        try:
            # Tentative résolution robuste
            result = await self.robustness_manager.resolve_with_robustness(
                target_spec, screen_state, environment
            )
            
            # Enregistrer métriques succès
            latency_ms = (time.time() - start_time) * 1000
            await self.metrics_engine.collect_resolution_metrics(
                target_spec, result, latency_ms, environment
            )
            
            return result
            
        except Exception as e:
            # Enregistrer métriques échec
            latency_ms = (time.time() - start_time) * 1000
            await self.metrics_engine.collect_resolution_metrics(
                target_spec, None, latency_ms, environment
            )
            raise

📊 Modèles de Données

Configuration et Calibration

@dataclass
class PrecisionConfiguration:
    """Configuration de précision par environnement"""
    environment_hash: str
    similarity_threshold: float
    position_tolerance: int
    text_fuzzy_threshold: float
    confidence_boost_factors: Dict[str, float]
    cache_ttl_seconds: int
    parallel_workers: int
    
    # Seuils adaptatifs
    adaptive_thresholds: Dict[str, AdaptiveThreshold]
    
    # Stratégies de fallback
    fallback_strategies: List[str]
    
    # Métriques cibles
    target_precision: float = 0.98
    target_latency_ms: float = 50.0

@dataclass
class AdaptiveThreshold:
    """Seuil adaptatif avec historique"""
    current_value: float
    min_value: float
    max_value: float
    adjustment_history: List[ThresholdAdjustment]
    last_calibration: datetime
    
@dataclass
class ThresholdAdjustment:
    """Ajustement de seuil"""
    timestamp: datetime
    old_value: float
    new_value: float
    reason: str
    performance_impact: float

Métriques et Alertes

@dataclass
class Alert:
    """Alerte système"""
    id: str
    severity: AlertSeverity
    title: str
    description: str
    timestamp: datetime
    environment_hash: Optional[str]
    metrics_snapshot: Dict[str, Any]
    suggested_actions: List[str]
    auto_resolution_attempted: bool = False

class AlertSeverity(Enum):
    INFO = "info"
    WARNING = "warning"
    ERROR = "error"
    CRITICAL = "critical"

@dataclass
class PerformanceBenchmark:
    """Benchmark de performance"""
    test_name: str
    environment: EnvironmentInfo
    target_specs: List[TargetSpec]
    results: List[BenchmarkResult]
    summary_stats: BenchmarkSummary
    timestamp: datetime

@dataclass
class BenchmarkResult:
    """Résultat individuel de benchmark"""
    target_spec: TargetSpec
    success: bool
    latency_ms: float
    confidence: float
    strategy_used: str
    memory_usage_mb: float
    cpu_usage_percent: float

🧪 Stratégie de Tests

Tests de Performance

class TestPrecisionPerformance:
    """Tests de performance pour précision améliorée"""
    
    @pytest.mark.performance
    async def test_resolution_latency_targets(self):
        """Vérifier latences cibles respectées"""
        resolver = EnhancedTargetResolver()
        
        # Test résolution simple
        simple_spec = TargetSpec(by_role="button")
        start = time.time()
        result = await resolver.resolve_target(simple_spec, mock_screen_state)
        latency_ms = (time.time() - start) * 1000
        
        assert latency_ms < 50, f"Simple resolution too slow: {latency_ms}ms"
        assert result is not None, "Should find target"
    
    @pytest.mark.performance
    async def test_batch_resolution_throughput(self):
        """Vérifier throughput résolution batch"""
        optimizer = PerformanceOptimizer()
        
        specs = [TargetSpec(by_role=f"button_{i}") for i in range(10)]
        start = time.time()
        results = await optimizer.resolve_batch(specs, mock_screen_state)
        duration = time.time() - start
        
        throughput = len(specs) / duration
        assert throughput > 20, f"Batch throughput too low: {throughput} res/s"

### Tests Multi-Environnements
```python
class TestMultiEnvironmentRobustness:
    """Tests robustesse multi-environnements"""
    
    @pytest.mark.parametrize("resolution,dpi", [
        ((1920, 1080), 1.0),
        ((2560, 1440), 1.25),
        ((3840, 2160), 1.5),
    ])
    async def test_resolution_consistency(self, resolution, dpi):
        """Vérifier cohérence sur différentes résolutions"""
        env = EnvironmentInfo(
            screen_resolution=resolution,
            dpi_scale=dpi,
            ui_theme="light",
            zoom_level=1.0
        )
        
        manager = RobustnessManager()
        result = await manager.resolve_with_robustness(
            target_spec, screen_state, env
        )
        
        assert result is not None, f"Should resolve on {resolution}@{dpi}x"
        assert result.confidence > 0.9, "High confidence expected"

Tests d'Intégration

class TestPrecisionIntegration:
    """Tests d'intégration système complet"""
    
    async def test_end_to_end_precision_workflow(self):
        """Test workflow complet avec métriques"""
        # Setup
        metrics_engine = PrecisionMetricsEngine()
        calibrator = AdaptiveCalibrator()
        resolver = EnhancedTargetResolver()
        
        # Exécution
        results = []
        for i in range(100):
            result = await resolver.resolve_target(
                random_target_spec(), random_screen_state()
            )
            results.append(result)
        
        # Vérifications
        success_rate = sum(1 for r in results if r is not None) / len(results)
        assert success_rate > 0.95, f"Success rate too low: {success_rate}"
        
        # Vérifier métriques collectées
        metrics = await metrics_engine.get_recent_metrics(timedelta(minutes=5))
        assert len(metrics) == 100, "All resolutions should be tracked"

🚀 Plan de Déploiement

Phase 1: Infrastructure (Semaines 1-2)

  1. Setup métriques: InfluxDB + Grafana
  2. Cache Redis: Configuration multi-niveaux
  3. API monitoring: FastAPI + WebSocket
  4. Tests baseline: Benchmarks performance actuels

Phase 2: Robustesse (Semaines 3-4)

  1. Détection environnement: DPI, résolution, thème
  2. Normalisation coordonnées: Cross-environment
  3. Stratégies récupération: Spatial, sémantique, template
  4. Tests multi-env: Validation 3+ environnements

Phase 3: Performance (Semaines 5-6)

  1. Résolution parallèle: Worker pool + batch API
  2. Cache intelligent: Invalidation + optimisation
  3. Profiling: Identification goulots d'étranglement
  4. Optimisation: GPU/CPU, mémoire

Phase 4: Monitoring (Semaines 7-8)

  1. Dashboard React: Interface temps réel
  2. Alertes intelligentes: Seuils adaptatifs
  3. Diagnostic auto: Suggestions amélioration
  4. Documentation: Guides utilisateur + API

Prochaine étape: Création du fichier de tâches détaillées pour l'implémentation.