Skip to content
Back to skills

Seagent Self Evolving Computer Use

ASecurity

Vision-based computer use agent that self-improves through experiential learning, curriculum generation, and reward-based RL on diverse software.

  • 6 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 9, 2026
ai-agentspythongo

Works with

  • cli

Security analysis

A100/100

Scanned September 9, 2026

npx -y skills add ADu2021/skillXiv --skill seagent-self-evolving-computer-use --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Seagent Self Evolving Computer Use?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Seagent Self Evolving Computer Use
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/adu2021-seagent-self-evolving-computer-use/badge)](https://www.skillsdirectory.com/skills/adu2021-seagent-self-evolving-computer-use)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: seagent-self-evolving-computer-use
title: SEAgent - Self-Evolving Computer Use Agent
version: 0.0.2
engine: skillxiv-v0.0.2-claude-opus-4.6
license: MIT
url: https://arxiv.org/abs/2508.04700
keywords: [computer-use, reinforcement-learning, self-improvement, curriculum-learning]
description: "Vision-based computer use agent that self-improves through experiential learning, curriculum generation, and reward-based RL on diverse software."
---

## SEAgent: Self-Evolving Computer Use Through Experience

SEAgent enables autonomous agents to master unfamiliar software through trial-and-error learning without human annotations. The framework combines curriculum learning (progressively harder tasks), dual RL (success rewards + failure penalties), and specialist-to-generalist knowledge distillation, achieving 34.5% success on professional software applications.

### Core Concept

Learning to use computer interfaces requires understanding visual elements, interpreting their meanings, and planning appropriate actions. Rather than human-annotated demonstrations, SEAgent learns from raw experience: attempt tasks, receive feedback, refine understanding. A curriculum generator creates progressively harder challenges; a world state model provides step-level rewards; specialists trained on individual software distill knowledge into a generalist agent.

### Architecture Overview

- **World State Model**: Vision-language model providing step-level reward signals by evaluating full action trajectories
- **Curriculum Generator**: LLM-based system maintaining "software guidebook" and generating increasingly complex tasks
- **Actor Model**: Policy network (initialized from UI-TARS) refined via RL
- **Specialist-to-Generalist**: Train per-software specialists, distill into multi-software generalist
- **Dual RL**: Group Relative Policy Optimization (GRPO) for successes; adversarial loss for failures

### Implementation Steps

**Step 1: Implement World State Model (Reward Judge)**

```python
import torch
import torch.nn as nn
from typing import List, Tuple, Dict
from PIL import Image

class WorldStateModel(nn.Module):
    """
    Vision-language model that evaluates action trajectories.
    Provides step-level rewards based on progress evaluation.
    """

    def __init__(self, vision_model_name: str = 'openai/clip-vit-base-patch32',
                 language_model_name: str = 'gpt2'):
        super().__init__()

        # Vision encoder
        self.vision_model = load_vision_model(vision_model_name)

        # Language model for reasoning
        self.language_model = load_language_model(language_model_name)

        # Reward head
        self.reward_head = nn.Linear(768, 1)  # Output scalar reward

    def forward(self, trajectory: List[Tuple[Image.Image, str]]) -> List[float]:
        """
        Evaluate trajectory and produce step-level rewards.

        Args:
            trajectory: List of (screenshot, action_text) pairs

        Returns:
            step_rewards: List of rewards for each action
        """
        step_rewards = []

        # Process each step
        for t, (screenshot, action) in enumerate(trajectory):
            # Encode screenshot with vision model
            image_features = self.vision_model.encode_image(screenshot)

            # Encode action text
            action_features = self.vision_model.encode_text(f"Action: {action}")

            # Evaluate this step's progress
            # Check: Did action advance toward goal?
            goal_progress = self._assess_progress(screenshot, action)

            # Check: Is action valid for current screen?
            action_validity = self._assess_validity(image_features, action_features)

            # Combine signals
            step_reward = 0.7 * goal_progress + 0.3 * action_validity
            step_rewards.append(step_reward)

        return step_rewards

    def _assess_progress(self, screenshot: Image.Image, action: str) -> float:
        """Estimate if action advanced toward goal."""
        # Prompt: "Does this action advance the task?"
        prompt = f"""Screenshot of software with task description.
Action taken: {action}

Did this action make progress toward completing the task? (0-1)"""

        # Vision-language reasoning
        reasoning = self.language_model.generate(prompt, max_tokens=10)
        score = self._parse_score(reasoning)
        return score

    def _assess_validity(self, image_features, action_features) -> float:
        """Check if action is valid for this screen state."""
        # High cosine similarity = action appropriate for screen
        similarity = torch.nn.functional.cosine_similarity(
            image_features.unsqueeze(0),
            action_features.unsqueeze(0)
        ).item()

        return (similarity + 1) / 2  # Normalize to [0, 1]

    def _parse_score(self, text: str) -> float:
        """Extract numeric score from model output."""
        import re
        match = re.search(r'(\d+(?:\.\d+)?)', text)
        if match:
            return float(match.group(1)) / 100
        return 0.5
```

**Step 2: Implement Curriculum Generator**

```python
class CurriculumGenerator:
    """
    Dynamically generate progressively harder tasks.
    Maintains "software guidebook" of available operations.
    """

    def __init__(self, language_model):
        self.llm = language_model
        self.software_guidebooks = {}
        self.task_difficulty = {}

    def build_guidebook(self, software_name: str, interface_screenshots: List[Image.Image]):
        """
        Extract available operations from software interface.
        Store for task generation.
        """
        operations = []

        for screenshot in interface_screenshots:
            # Analyze screenshot with vision model
            prompt = f"""Software: {software_name}

Analyze this screenshot and list all interactive elements visible.
What actions can the user take?"""

            elements = self.llm.generate(prompt, max_tokens=500)
            operations.extend(self._parse_elements(elements))

        self.software_guidebooks[software_name] = {
            'operations': operations,
            'difficulty_distribution': {}
        }

    def generate_task(self, software_name: str, difficulty: int = 5) -> str:
        """
        Generate a task for given software at specified difficulty.
        Difficulty: 1-10 (1=simple, 10=complex).
        """
        guidebook = self.software_guidebooks.get(software_name, {})
        operations = guidebook.get('operations', [])

        # Use operations to ground task generation
        operations_str = ', '.join(operations[:5])

        prompt = f"""Software: {software_name}
Available operations: {operations_str}
Task difficulty: {difficulty}/10

Generate a single specific task for a user to complete.
Make it realistic and achievable but at the specified difficulty level.

Task:"""

        task = self.llm.generate(prompt, max_tokens=100)
        return task.strip()

    def update_guidebook_from_feedback(self, software_name: str, trajectory: List[Dict],
                                      success: bool):
        """
        Update guidebook based on learning from trajectories.
        Track which operations are most useful.
        """
        if not success:
            # Failed trajectory: maybe operations weren't applicable
            pass

        # Track operation success rates
        guidebook = self.software_guidebooks[software_name]
        if 'operation_success_rates' not in guidebook:
            guidebook['operation_success_rates'] = {}

        for step in trajectory:
            action = step.get('action', '')
            # Update success rate for this action type
            if action not in guidebook['operation_success_rates']:
                guidebook['operation_success_rates'][action] = {'successes': 0, 'attempts': 0}

            guidebook['operation_success_rates'][action]['attempts'] += 1
            if success:
                guidebook['operation_success_rates'][action]['successes'] += 1

    def _parse_elements(self, text: str) -> List[str]:
        """Extract interactive elements from model output."""
        lines = text.split('\n')
        elements = [line.strip('- ') for line in lines if line.strip().startswith('-')]
        return elements
```

**Step 3: Implement Dual RL (GRPO + Adversarial)**

```python
class DualRL:
    """
    Train via Group Relative Policy Optimization (GRPO) for successes
    and adversarial imitation loss for failures.
    """

    def __init__(self, actor_model):
        self.actor = actor_model
        self.optimizer = torch.optim.Adam(actor_model.parameters(), lr=1e-5)

    def compute_grpo_loss(self, trajectory: List[Dict], trajectory_reward: float):
        """
        Group Relative Policy Optimization: reward successful actions.
        Treats trajectory as a group; relative ranking within group.
        """
        action_logps = []

        for step in trajectory:
            action = step['action']
            screen_features = step['screen_features']

            # Get log probability of action
            logp = self.actor.compute_action_logp(screen_features, action)
            action_logps.append(logp)

        # GRPO: advantage = trajectory_reward - baseline
        baseline = trajectory_reward * 0.9  # Conservative baseline
        advantage = trajectory_reward - baseline

        # Policy gradient: sum(log_pi * advantage)
        grpo_loss = -torch.sum(torch.stack(action_logps)) * advantage

        return grpo_loss

    def compute_adversarial_loss(self, failed_trajectory: List[Dict],
                                successful_trajectory: List[Dict]):
        """
        Penalize failure patterns through adversarial imitation.
        Learn to diverge from failure trajectories.
        """
        failed_logps = []
        success_logps = []

        for step in failed_trajectory:
            action = step['action']
            screen_features = step['screen_features']
            logp = self.actor.compute_action_logp(screen_features, action)
            failed_logps.append(logp)

        for step in successful_trajectory:
            action = step['action']
            screen_features = step['screen_features']
            logp = self.actor.compute_action_logp(screen_features, action)
            success_logps.append(logp)

        # Loss: maximize divergence between failure and success distributions
        # DKL(success || failure) = sum(log_success - log_failure)
        adversarial_loss = -torch.sum(torch.stack(success_logps)) + torch.sum(torch.stack(failed_logps))

        return adversarial_loss

    def train_step(self, successful_trajectories: List[List[Dict]],
                  failed_trajectories: List[List[Dict]]):
        """
        One training step combining GRPO and adversarial loss.
        """
        total_loss = 0.0

        # GRPO on successes
        for trajectory in successful_trajectories:
            reward = 1.0  # Successful
            loss = self.compute_grpo_loss(trajectory, reward)
            total_loss += loss

        # Adversarial on failures paired with successes
        for failed_traj, success_traj in zip(failed_trajectories, successful_trajectories):
            adv_loss = self.compute_adversarial_loss(failed_traj, success_traj)
            total_loss += 0.5 * adv_loss  # Weight adversarial less

        # Update
        self.optimizer.zero_grad()
        total_loss.backward()
        self.optimizer.step()

        return total_loss.item()
```

**Step 4: Specialist-to-Generalist Distillation**

```python
class SpecialistToGeneralist:
    """
    Train specialists on individual software, distill to generalist.
    """

    def __init__(self):
        self.specialists = {}  # software_name -> model
        self.generalist = None

    def train_specialist(self, software_name: str, trajectories: List[List[Dict]],
                        num_epochs: int = 10):
        """Train specialist agent for one software."""
        specialist_model = create_model()
        specialist_rl = DualRL(specialist_model)

        for epoch in range(num_epochs):
            # Sample trajectories
            successful = [t for t in trajectories if t[-1]['success']]
            failed = [t for t in trajectories if not t[-1]['success']]

            loss = specialist_rl.train_step(successful, failed[:len(successful)])

            if epoch % 2 == 0:
                print(f"Specialist {software_name}, epoch {epoch}: loss={loss:.3f}")

        self.specialists[software_name] = specialist_model

    def distill_to_generalist(self, num_epochs: int = 5):
        """
        Distill knowledge from all specialists to single generalist.
        """
        # Initialize generalist
        self.generalist = create_model()

        # KL divergence loss: minimize divergence between specialist and generalist
        for epoch in range(num_epochs):
            for software_name, specialist in self.specialists.items():
                # Sample task for this software
                task = f"Interact with {software_name}"

                # Get actions from specialist
                specialist_actions = specialist.generate_actions(task, num_actions=5)

                # Train generalist to match specialist
                for action in specialist_actions:
                    generalist_logp = self.generalist.compute_action_logp(task, action)
                    specialist_logp = specialist.compute_action_logp(task, action)

                    # KL divergence (reverse)
                    kl_loss = torch.nn.functional.kl_div(
                        generalist_logp.exp(),
                        specialist_logp.exp(),
                        reduction='batchmean'
                    )

                    kl_loss.backward()

                self.generalist.optimizer.step()

    def evaluate_generalist(self, test_tasks: Dict[str, List[str]]) -> Dict:
        """Evaluate generalist on multiple software."""
        results = {}

        for software, tasks in test_tasks.items():
            successes = 0
            for task in tasks:
                success = self.generalist.attempt_task(software, task)
                if success:
                    successes += 1

            results[software] = successes / len(tasks)

        return results
```

**Step 5: Full Self-Improving Loop**

```python
def self_evolving_agent_training(initial_software_list: List[str],
                                num_rounds: int = 5):
    """
    Complete self-improving loop:
    1. Train specialist per software
    2. Distill to generalist
    3. Evaluate and expand
    """

    curriculum = CurriculumGenerator(llm_model)
    specialist_distiller = SpecialistToGeneralist()

    for round_num in range(num_rounds):
        print(f"\n=== Round {round_num} ===")

        # Round: Train specialists on each software
        for software in initial_software_list:
            print(f"Training specialist for {software}...")

            # Generate tasks via curriculum
            tasks = [curriculum.generate_task(software, difficulty=i)
                    for i in range(1, 6)]  # Difficulties 1-5

            # Execute tasks and collect trajectories
            trajectories = []
            for task in tasks:
                trajectory = run_agent_on_task(software, task)
                trajectories.append(trajectory)

            # Train specialist
            specialist_distiller.train_specialist(software, trajectories)

            # Update curriculum guidebook
            for trajectory in trajectories:
                success = trajectory[-1].get('success', False)
                curriculum.update_guidebook_from_feedback(software, trajectory, success)

        # Distill specialists to generalist
        print("Distilling specialists to generalist...")
        specialist_distiller.distill_to_generalist()

        # Evaluate generalist on harder tasks
        print("Evaluating generalist...")
        test_tasks = {software: [curriculum.generate_task(software, difficulty=8)]
                     for software in initial_software_list}

        results = specialist_distiller.evaluate_generalist(test_tasks)

        for software, success_rate in results.items():
            print(f"  {software}: {success_rate:.1%}")

    return specialist_distiller.generalist
```

### Practical Guidance

**When to Use:**
- Computer use automation on unfamiliar software
- Scenarios with diverse interfaces requiring flexible learning
- Applications where human demonstrations are expensive
- Long-horizon tasks (multi-step interactions)

**When NOT to Use:**
- Real-time systems (RL training is slow)
- Highly specialized software with few users
- Scenarios requiring formal correctness guarantees
- Systems where mistakes have high consequences

**Hyperparameters:**

| Parameter | Default | Impact |
|-----------|---------|--------|
| `specialist_epochs` | 10 | More training per specialist for deeper learning |
| `curriculum_difficulty_range` | 1-10 | Range of task difficulties generated |
| `success_weight_grpo` | 1.0 | Weight of successful trajectory rewards |
| `failure_weight_adversarial` | 0.5 | Weight of failure pattern penalties |

### Reference

**Paper**: SEAgent: Self-Evolving Computer Use Agent (2508.04700)
- 34.5% success on OSWorld professional software (from 11.3% baseline UI-TARS)
- Specialist-to-generalist approach outperforms direct multi-software training
- World State Model provides 71.6% precision trajectory evaluation

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.