Files
rpa_vision_v3/.kiro/specs/rpa-vision-excellence/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

15 KiB

Document de Conception : RPA Vision Excellence

Vue d'ensemble

Cette conception transforme RPA Vision V3 en un système RPA 100% Vision de niveau production en ajoutant quatre composants majeurs :

  1. Validateur de Qualité d'Entraînement - Validation et métriques de qualité d'entraînement
  2. Matcher Hiérarchique - Matching multi-niveau robuste
  3. Apprenant Continu - Apprentissage continu et adaptation
  4. Gestionnaire de Variantes - Gestion des variantes et états dynamiques

L'architecture s'intègre aux composants existants (GraphBuilder, WorkflowPipeline, ExecutionLoop) sans les remplacer.

Architecture

┌─────────────────────────────────────────────────────────────────────┐
│                        RPA Vision Excellence                        │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌──────────────────┐    ┌──────────────────┐    ┌────────────────┐ │
│  │ Training Quality │    │   Hierarchical   │    │   Continuous   │ │
│  │    Validator     │    │     Matcher      │    │    Learner     │ │
│  └────────┬─────────┘    └────────┬─────────┘    └───────┬────────┘ │
│           │                       │                       │         │
│           ▼                       ▼                       ▼         │
│  ┌──────────────────────────────────────────────────────────────┐   │
│  │                      Variant Manager                         │   │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐   │   │
│  │  │   Variant   │  │    State    │  │   Drift Detector    │   │   │
│  │  │   Cluster   │  │   Tracker   │  │                     │   │   │
│  │  └─────────────┘  └─────────────┘  └─────────────────────┘   │   │
│  └──────────────────────────────────────────────────────────────┘   │
│                                                                     │
├─────────────────────────────────────────────────────────────────────┤
│                     Existing Components                             │
│  ┌────────────┐  ┌────────────┐  ┌────────────┐  ┌────────────┐     | 
│  │   Graph    │  │  Workflow  │  │  Execution │  │    FAISS   │     │   
│  │  Builder   │  │  Pipeline  │  │    Loop    │  │   Manager  │     │  
│  └────────────┘  └────────────┘  └────────────┘  └────────────┘     │
└─────────────────────────────────────────────────────────────────────┘

Composants et Interfaces

1. Validateur de Qualité d'Entraînement

class TrainingQualityValidator:
    """Valide la qualité des workflows entraînés"""
    
    def validate_workflow(self, workflow: Workflow, 
                         observations: List[ScreenState]) -> QualityReport
    
    def compute_cluster_metrics(self, embeddings: np.ndarray, 
                                labels: np.ndarray) -> ClusterMetrics
    
    def detect_outliers(self, embeddings: np.ndarray) -> List[int]
    
    def cross_validate(self, workflow: Workflow, 
                      observations: List[ScreenState],
                      holdout_ratio: float = 0.2) -> ValidationResult

@dataclass
class QualityReport:
    overall_score: float  # 0.0 - 1.0
    cluster_metrics: Dict[str, ClusterMetrics]
    outlier_indices: List[int]
    validation_accuracy: float
    recommendations: List[str]
    is_production_ready: bool

@dataclass
class ClusterMetrics:
    silhouette_score: float  # Score de silhouette
    cohesion: float          # Cohésion intra-cluster
    separation: float        # Séparation inter-cluster
    sample_count: int        # Nombre d'échantillons
    is_sufficient: bool      # Données suffisantes

2. Matcher Hiérarchique

class HierarchicalMatcher:
    """Système de matching multi-niveau"""
    
    def match(self, screenshot: Image, 
              workflow: Workflow,
              temporal_context: Optional[TemporalContext] = None) -> MatchResult
    
    def match_window_level(self, window_info: WindowContext,
                          node: WorkflowNode) -> float
    
    def match_region_level(self, regions: List[UIRegion],
                          template_regions: List[UIRegion]) -> float
    
    def match_element_level(self, elements: List[UIElement],
                           template_elements: List[UIElement]) -> float

@dataclass
class MatchResult:
    node_id: str
    confidence: float              # Confiance globale
    window_confidence: float       # Confiance niveau fenêtre
    region_confidence: float       # Confiance niveau région
    element_confidence: float      # Confiance niveau élément
    temporal_boost: float          # Bonus temporel
    matched_variant: Optional[str] # Variante matchée
    alternatives: List[AlternativeMatch]

@dataclass
class TemporalContext:
    previous_nodes: List[str]       # N derniers nodes matchés
    previous_confidences: List[float]
    time_since_last_match: float    # Temps depuis dernier match

3. Apprenant Continu

class ContinuousLearner:
    """Apprentissage continu et adaptation"""
    
    def update_prototype(self, node_id: str, 
                        new_embedding: np.ndarray,
                        execution_success: bool) -> None
    
    def detect_drift(self, node_id: str,
                    recent_confidences: List[float]) -> DriftStatus
    
    def create_variant(self, node_id: str,
                      variant_embedding: np.ndarray) -> str
    
    def consolidate_variants(self, node_id: str) -> None
    
    def rollback_prototype(self, node_id: str, version: int) -> None

@dataclass
class DriftStatus:
    is_drifting: bool                # Dérive détectée
    drift_severity: float            # Sévérité 0.0 - 1.0
    consecutive_low_confidence: int  # Matchs faibles consécutifs
    recommended_action: str          # "monitor", "create_variant", "retrain"

class PrototypeVersionManager:
    """Gère l'historique des versions de prototypes"""
    
    def save_version(self, node_id: str, embedding: np.ndarray) -> int
    def get_version(self, node_id: str, version: int) -> np.ndarray
    def list_versions(self, node_id: str) -> List[VersionInfo]

4. Gestionnaire de Variantes

class VariantManager:
    """Gère les variantes d'écran et états UI"""
    
    def detect_variants(self, embeddings: List[np.ndarray],
                       similarity_threshold: float = 0.7) -> List[VariantCluster]
    
    def match_with_variants(self, query_embedding: np.ndarray,
                           node_id: str) -> VariantMatchResult
    
    def add_variant(self, node_id: str, 
                   variant_embedding: np.ndarray,
                   metadata: Dict) -> str
    
    def detect_ui_states(self, elements: List[UIElement]) -> Dict[str, UIState]
    
    def detect_overlay(self, screenshot: Image,
                      baseline: Image) -> Optional[OverlayInfo]

@dataclass
class VariantCluster:
    variant_id: str
    prototype: np.ndarray
    member_count: int                # Nombre de membres
    similarity_to_primary: float     # Similarité avec prototype principal

@dataclass
class UIState(Enum):
    ENABLED = "enabled"      # Activé
    DISABLED = "disabled"    # Désactivé
    CHECKED = "checked"      # Coché
    UNCHECKED = "unchecked"  # Non coché
    LOADING = "loading"      # Chargement
    ERROR = "error"          # Erreur
    FOCUSED = "focused"      # Focus

@dataclass
class OverlayInfo:
    overlay_type: str  # "modal", "popup", "tooltip", "dropdown"
    bounds: Tuple[int, int, int, int]  # Coordonnées
    blocking: bool     # Bloquant

Modèles de Données

WorkflowNode Amélioré

@dataclass
class EnhancedWorkflowNode(WorkflowNode):
    # Champs existants hérités
    
    # Nouveaux champs pour variantes
    variants: List[NodeVariant] = field(default_factory=list)
    primary_variant_id: str = "primary"
    
    # Métriques de qualité
    quality_score: float = 0.0
    observation_count: int = 0
    
    # Versioning des prototypes
    prototype_version: int = 1
    prototype_history: List[str] = field(default_factory=list)

@dataclass
class NodeVariant:
    variant_id: str
    embedding_path: str
    similarity_to_primary: float  # Similarité avec prototype principal
    observation_count: int        # Nombre d'observations
    created_at: datetime
    metadata: Dict[str, Any]

Relations Spatiales

@dataclass
class SpatialRelation:
    source_element_id: str
    target_element_id: str
    relation_type: str  # "above", "below", "left_of", "right_of", "inside"
    distance: float     # Distance en pixels
    confidence: float   # Confiance de la relation

@dataclass
class SemanticContainer:
    container_id: str
    container_type: str  # "form", "menu", "toolbar", "dialog", "list"
    element_ids: List[str]  # IDs des éléments contenus
    bounds: Tuple[int, int, int, int]  # Coordonnées du conteneur

Propriétés de Correction

Une propriété est une caractéristique ou un comportement qui doit être vrai pour toutes les exécutions valides d'un système - essentiellement, une déclaration formelle de ce que le système doit faire. Les propriétés servent de pont entre les spécifications lisibles par l'humain et les garanties de correction vérifiables par machine.

Propriété 1 : Cohérence de la Qualité des Clusters

Pour tout ensemble d'embeddings assignés à un cluster, le score de silhouette calculé par Training_Quality_Validator DOIT être cohérent avec la fonction silhouette_score de sklearn avec une tolérance de 0.01 Valide : Exigences 1.1

Propriété 2 : Correction de la Détection d'Outliers

Pour tout ensemble d'embeddings, les outliers détectés par la méthode IQR DOIVENT avoir une distance au centroïde du cluster supérieure à Q3 + 1.5*IQR Valide : Exigences 1.3

Propriété 3 : Précision de la Validation Croisée

Pour tout workflow avec N observations, la validation croisée avec 20% de holdout DOIT correctement matcher au moins 80% des observations retenues vers leurs nodes originaux Valide : Exigences 1.5

Propriété 4 : Bornes de Confiance Hiérarchique

Pour tout résultat de match du Hierarchical_Matcher, la confiance finale DOIT être égale à 0.2fenêtre + 0.3région + 0.5*élément avec une tolérance de 0.001 Valide : Exigences 2.4

Propriété 5 : Correction du Boost Temporel

Pour tout match où le node matché est un successeur valide du node précédent, la confiance DOIT être augmentée de exactement 0.1 (plafonnée à 1.0) Valide : Exigences 2.5

Propriété 6 : Mise à Jour du Prototype par EMA

Pour toute mise à jour de prototype, le nouveau prototype DOIT être égal à (1-alpha)ancien_prototype + alphanouvel_embedding où alpha=0.1 Valide : Exigences 3.1

Propriété 7 : Seuil de Détection de Dérive

Pour toute séquence de 3 exécutions consécutives avec une confiance inférieure à 0.85, le Drift_Detector DOIT signaler une dérive potentielle Valide : Exigences 3.2

Propriété 8 : Seuil de Similarité des Variantes

Pour toute variante créée, sa similarité avec le prototype principal DOIT être inférieure à 0.7 (différence > 0.3) Valide : Exigences 4.2

Propriété 9 : Sélection de la Meilleure Variante

Pour tout match contre un node avec variantes, le match retourné DOIT avoir la plus haute similarité parmi toutes les variantes Valide : Exigences 4.3

Propriété 10 : Symétrie des Relations Spatiales

Pour toute relation spatiale "A à_gauche_de B", il DOIT exister une relation correspondante "B à_droite_de A" Valide : Exigences 5.1

Propriété 11 : Backoff Exponentiel des Retries

Pour toute action échouée avec retries, les temps d'attente DOIVENT suivre le pattern : temps_base * 2^(tentative-1) pour les tentatives 1, 2, 3 Valide : Exigences 7.1

Gestion des Erreurs

Erreurs d'Entraînement

  • InsufficientDataError : Levée quand un cluster a moins de 3 observations
  • LowQualityClusterError : Levée quand le score de silhouette < 0.5
  • OutlierDominanceError : Levée quand les outliers dépassent 30% des observations

Erreurs de Matching

  • NoMatchFoundError : Levée quand aucun node ne matche au-dessus du seuil
  • AmbiguousMatchError : Levée quand plusieurs nodes matchent avec confiance similaire
  • TemporalInconsistencyError : Levée quand le node matché n'est pas atteignable depuis le précédent

Erreurs d'Apprentissage

  • DriftConfirmedError : Levée quand la dérive est confirmée et nécessite action utilisateur
  • VariantLimitExceededError : Levée quand un node dépasse 5 variantes
  • PrototypeCorruptionError : Levée quand la mise à jour du prototype produit un embedding invalide

Stratégie de Tests

Tests Unitaires

  • Tester chaque composant isolément avec dépendances mockées
  • Tester les cas limites : entrées vides, observation unique, variantes maximum
  • Tester les conditions d'erreur et la gestion des exceptions

Tests Basés sur les Propriétés

  • Utiliser la bibliothèque Hypothesis pour les tests property-based en Python
  • Chaque propriété de correction DOIT avoir un test property correspondant
  • Configurer minimum 100 itérations par test property
  • Taguer chaque test avec : **Feature: rpa-vision-excellence, Property {N}: {description}**

Tests d'Intégration

  • Tester le pipeline complet : entraînement → validation → matching → exécution
  • Tester le cycle d'apprentissage continu avec changements UI simulés
  • Tester les workflows de création et consolidation de variantes

Tests de Performance

  • Latence de matching : < 100ms pour un screenshot
  • Validation d'entraînement : < 5s pour un workflow avec 100 observations
  • Mise à jour de prototype : < 10ms par mise à jour