# Swe Exp Experience Driven Bug Resolution

> Framework that distills reusable experience from prior agent trajectories enabling continuous learning across issues. Achieves 73% resolution on SWE-Bench by leveraging multi-level experience banks capturing both successful and failed repair attempts.

- Skill: `adu2021/swe-exp-experience-driven-bug-resolution` (Agent Skill)
- Install (CLI): `npx skillmds@latest add adu2021/swe-exp-experience-driven-bug-resolution`
- Raw SKILL.md: https://api.skillmd.com/api/skills/adu2021/swe-exp-experience-driven-bug-resolution/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- License: MIT
- Author: adu2021 (https://skillmd.com/u/adu2021)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/adu2021/swe-exp-experience-driven-bug-resolution

---


## SWE-Exp: Experience-Driven Software Issue Resolution

SWE-Exp addresses a critical limitation in LLM-based software agents: they lack memory between tasks, treating each bug independently. This framework systematically extracts and reuses experience from prior repairs, enabling agents to learn progressively and achieve state-of-the-art performance on real-world software engineering tasks.

### Core Concept

The key insight is that software bugs often share patterns across issues—similar code structures, failure modes, and repair strategies. Rather than solving each independently, SWE-Exp:

- **Distills experience** from successful and failed repair attempts
- **Organizes experience** at multiple abstraction levels (problem type, code patterns, specific fixes)
- **Retrieves relevant experience** when encountering new issues
- **Applies learned strategies** to new problems with task-specific adaptation

This achieves 73.0% resolution on SWE-Bench Verified, demonstrating the power of accumulated expertise.

### Architecture Overview

The framework consists of:

- **Trajectory Recorder**: Captures complete agent execution paths
- **Experience Extractor**: Distills key insights from trajectories (at high, medium, low levels)
- **Multi-Level Experience Bank**: Organizes knowledge by abstraction level
- **Experience Retriever**: Finds relevant prior experience for new issues
- **Adaptive Application**: Applies learned experience while handling task-specific differences
- **Feedback Loop**: Updates experience bank based on success/failure

### Implementation Steps

**Step 1: Record and parse agent trajectories**

Capture complete execution traces from repair attempts:

```python
from typing import List, Dict, Any, Tuple
from dataclasses import dataclass
import json
from datetime import datetime

@dataclass
class ActionStep:
    """Single step in agent trajectory"""
    action_type: str  # 'edit', 'test', 'search', 'run_command'
    target: str  # file/location affected
    content: str  # action content
    timestamp: float
    outcome: str  # 'success', 'error', 'info'

@dataclass
class TrajectoryRecord:
    """Complete execution trace for a repair attempt"""
    issue_id: str
    repo_name: str
    initial_problem: str
    steps: List[ActionStep]
    final_status: str  # 'resolved', 'failed', 'partial'
    test_results: Dict[str, bool]  # test_name -> pass/fail

class TrajectoryRecorder:
    """Records agent trajectories for experience extraction"""

    def __init__(self):
        self.current_trajectory: TrajectoryRecord = None
        self.all_trajectories: List[TrajectoryRecord] = []

    def start_trajectory(self, issue_id: str, repo_name: str, problem: str):
        """Initialize trajectory recording for new issue"""
        self.current_trajectory = TrajectoryRecord(
            issue_id=issue_id,
            repo_name=repo_name,
            initial_problem=problem,
            steps=[],
            final_status='in_progress',
            test_results={}
        )

    def record_action(self, action_type: str, target: str,
                     content: str, outcome: str = 'info'):
        """Log a single action"""
        if self.current_trajectory is None:
            return

        step = ActionStep(
            action_type=action_type,
            target=target,
            content=content,
            timestamp=datetime.now().timestamp(),
            outcome=outcome
        )

        self.current_trajectory.steps.append(step)

    def record_test_result(self, test_name: str, passed: bool):
        """Log test execution result"""
        if self.current_trajectory:
            self.current_trajectory.test_results[test_name] = passed

    def finalize_trajectory(self, status: str = 'completed'):
        """Complete trajectory recording"""
        if self.current_trajectory:
            self.current_trajectory.final_status = status
            self.all_trajectories.append(self.current_trajectory)

    def to_dict(self) -> Dict:
        """Serialize trajectory for storage"""
        return {
            'issue_id': self.current_trajectory.issue_id,
            'repo': self.current_trajectory.repo_name,
            'problem': self.current_trajectory.initial_problem,
            'steps': [
                {
                    'type': s.action_type,
                    'target': s.target,
                    'content': s.content[:200],  # Truncate for storage
                    'outcome': s.outcome
                }
                for s in self.current_trajectory.steps
            ],
            'status': self.current_trajectory.final_status,
            'tests': self.current_trajectory.test_results
        }
```

This creates a detailed record of the agent's problem-solving process.

**Step 2: Extract experience at multiple abstraction levels**

Distill trajectories into reusable patterns at different levels:

```python
class ExperienceExtractor:
    """Distills experience from trajectories at multiple levels"""

    def __init__(self):
        self.high_level_patterns = {}  # Problem type -> strategies
        self.mid_level_patterns = {}   # Code pattern -> fixes
        self.low_level_patterns = {}   # Specific changes

    def extract_high_level_strategy(self, trajectory: TrajectoryRecord) -> Dict:
        """
        Extract high-level problem-solving strategy.

        Identifies: problem classification, overall approach, key decisions
        """
        problem = trajectory.initial_problem

        # Classify problem type
        problem_type = self._classify_problem(problem)

        # Identify high-level approach sequence
        approach_sequence = []
        for step in trajectory.steps:
            if step.action_type in ['run_command', 'test']:
                if step.outcome == 'success':
                    approach_sequence.append(step.action_type)

        # Extract decision points
        decisions = self._extract_decisions(trajectory)

        return {
            'problem_type': problem_type,
            'approach': approach_sequence,
            'key_decisions': decisions,
            'success': trajectory.final_status == 'resolved'
        }

    def extract_mid_level_pattern(self, trajectory: TrajectoryRecord) -> List[Dict]:
        """
        Extract medium-level code patterns and fixes.

        Identifies: file types modified, code patterns, repair techniques
        """
        patterns = []

        for step in trajectory.steps:
            if step.action_type == 'edit':
                pattern = {
                    'file': step.target,
                    'file_type': self._get_file_type(step.target),
                    'action': self._parse_edit_action(step.content),
                    'outcome': step.outcome
                }
                patterns.append(pattern)

        return patterns

    def extract_low_level_fix(self, trajectory: TrajectoryRecord) -> List[Dict]:
        """
        Extract specific low-level changes and their effects.

        Identifies: exact modifications, test responses, error corrections
        """
        fixes = []

        for i, step in enumerate(trajectory.steps):
            if step.action_type == 'edit':
                # Find associated test results
                subsequent_tests = [
                    s for s in trajectory.steps[i+1:i+5]
                    if s.action_type == 'test'
                ]

                fix = {
                    'change': step.content[:500],
                    'file': step.target,
                    'test_impact': [
                        {
                            'test': t.target,
                            'result': t.outcome
                        }
                        for t in subsequent_tests
                    ]
                }
                fixes.append(fix)

        return fixes

    def _classify_problem(self, problem: str) -> str:
        """Classify bug type: logic error, syntax, missing feature, etc."""
        keywords = {
            'syntax': ['SyntaxError', 'IndentationError', 'TypeError'],
            'logic': ['assert', 'expected', 'got', 'incorrect'],
            'import': ['ImportError', 'ModuleNotFoundError', 'cannot import'],
            'missing': ['AttributeError', 'NameError', 'not defined']
        }

        for category, keywords_list in keywords.items():
            if any(kw in problem for kw in keywords_list):
                return category

        return 'unknown'

    def _extract_decisions(self, trajectory: TrajectoryRecord) -> List[str]:
        """Extract key decision points in trajectory"""
        decisions = []

        for i, step in enumerate(trajectory.steps):
            if step.outcome == 'error' and i + 1 < len(trajectory.steps):
                # Decision point: recovered from error
                next_step = trajectory.steps[i + 1]
                if next_step.action_type != step.action_type:
                    decisions.append(
                        f"Error in {step.action_type} → Tried {next_step.action_type}"
                    )

        return decisions

    def _get_file_type(self, filepath: str) -> str:
        """Extract file extension"""
        return filepath.split('.')[-1] if '.' in filepath else 'unknown'

    def _parse_edit_action(self, content: str) -> str:
        """Simplify edit content to action description"""
        lines = content.split('\n')
        return f"{len(lines)} lines changed"
```

This creates a three-level experience hierarchy from fine to coarse.

**Step 3: Implement multi-level experience bank**

Store and organize extracted experience:

```python
from collections import defaultdict

class ExperienceBank:
    """Stores experience at multiple abstraction levels"""

    def __init__(self):
        # High-level: problem type -> list of strategies
        self.high_level = defaultdict(list)

        # Mid-level: code pattern -> list of applicable fixes
        self.mid_level = defaultdict(list)

        # Low-level: specific changes and their outcomes
        self.low_level = []

        # Index for fast retrieval
        self.problem_type_index = defaultdict(list)

    def add_experience(self, trajectory: TrajectoryRecord,
                       extractor: ExperienceExtractor):
        """Add extracted experience from trajectory to bank"""

        # High-level experience
        high_exp = extractor.extract_high_level_strategy(trajectory)
        problem_type = high_exp['problem_type']
        self.high_level[problem_type].append(high_exp)
        self.problem_type_index[problem_type].append(trajectory.issue_id)

        # Mid-level experience
        mid_exps = extractor.extract_mid_level_pattern(trajectory)
        for mid_exp in mid_exps:
            pattern_key = (mid_exp['file_type'], mid_exp['action'])
            self.mid_level[pattern_key].append(mid_exp)

        # Low-level experience
        low_exps = extractor.extract_low_level_fix(trajectory)
        self.low_level.extend(low_exps)

    def get_relevant_high_level(self, problem_type: str,
                               k: int = 3) -> List[Dict]:
        """Retrieve high-level strategies for problem type"""
        strategies = self.high_level.get(problem_type, [])

        # Sort by success rate
        sorted_strategies = sorted(
            strategies,
            key=lambda s: 1.0 if s['success'] else 0.0,
            reverse=True
        )

        return sorted_strategies[:k]

    def get_relevant_mid_level(self, file_type: str, k: int = 5) -> List[Dict]:
        """Retrieve mid-level patterns for file type"""
        patterns = []

        for (ftype, action), pattern_list in self.mid_level.items():
            if ftype == file_type:
                patterns.extend(pattern_list)

        return patterns[:k]

    def get_successful_low_level_fixes(self, k: int = 10) -> List[Dict]:
        """Retrieve low-level fixes that worked"""
        successful = [f for f in self.low_level if f['test_impact']]

        return successful[:k]

    def get_statistics(self) -> Dict:
        """Get experience bank statistics"""
        return {
            'problem_types': len(self.high_level),
            'total_strategies': sum(len(v) for v in self.high_level.values()),
            'patterns': len(self.mid_level),
            'specific_fixes': len(self.low_level)
        }
```

This enables organized retrieval of experience at appropriate abstraction levels.

**Step 4: Implement experience-aware agent prompting**

Use retrieved experience to guide new repair attempts:

```python
class ExperienceAwareAgent:
    """Software agent that leverages experience bank"""

    def __init__(self, llm, experience_bank: ExperienceBank):
        self.llm = llm
        self.experience_bank = experience_bank
        self.recorder = TrajectoryRecorder()

    def plan_repair(self, issue: Dict) -> str:
        """Generate repair plan informed by experience"""

        problem = issue['description']
        repo = issue['repo']

        # Classify problem and retrieve relevant experience
        problem_type = self._classify(problem)
        relevant_strategies = self.experience_bank.get_relevant_high_level(
            problem_type, k=3
        )

        # Build context-aware prompt
        prompt = f"""You are fixing a bug in repository {repo}.

Issue: {problem}

Based on similar issues resolved before:
"""

        for i, strategy in enumerate(relevant_strategies, 1):
            prompt += f"\nApproach {i}: {strategy['approach']}"
            if strategy['key_decisions']:
                prompt += f"\nKey decisions: {strategy['key_decisions']}"

        prompt += """\n
Analyze the issue and generate a step-by-step repair plan. Consider the strategies above but adapt to the specific issue."""

        plan = self.llm.generate(prompt, max_tokens=1000)

        return plan

    def execute_repair_step(self, step: str, target_file: str = None) -> Tuple[bool, str]:
        """
        Execute a single repair step and record it.

        Args:
            step: Description or command for repair action
            target_file: File being modified

        Returns:
            (success, output/error_message)
        """

        # Parse action from step
        action_type, content = self._parse_step(step)

        # Record action
        self.recorder.record_action(action_type, target_file or 'unknown', content)

        # Execute action (simplified)
        success, output = self._execute_action(action_type, content, target_file)

        self.recorder.record_action(action_type, target_file, content,
                                    outcome='success' if success else 'error')

        return success, output

    def _classify(self, problem: str) -> str:
        """Simple problem classification"""
        if 'ImportError' in problem or 'ModuleNotFoundError' in problem:
            return 'import'
        elif 'AssertionError' in problem:
            return 'logic'
        elif 'AttributeError' in problem:
            return 'missing'
        else:
            return 'unknown'

    def _parse_step(self, step: str) -> Tuple[str, str]:
        """Parse action from generated step"""
        if step.startswith('Edit'):
            return 'edit', step[5:]
        elif step.startswith('Run'):
            return 'test', step[4:]
        else:
            return 'search', step

    def _execute_action(self, action_type: str, content: str,
                       target: str) -> Tuple[bool, str]:
        """Execute action (simplified; real version would interact with filesystem)"""
        # Placeholder
        return True, "Action executed"

    def repair_issue(self, issue: Dict) -> bool:
        """
        Full repair workflow: plan, execute, learn.

        Returns:
            True if issue resolved, False otherwise
        """

        self.recorder.start_trajectory(issue['id'], issue['repo'], issue['description'])

        # Plan repair informed by experience
        plan = self.plan_repair(issue)

        # Execute planned steps
        for step in plan.split('\n'):
            if step.strip():
                success, output = self.execute_repair_step(step)

                if not success and 'test' in step.lower():
                    self.recorder.record_test_result(step, False)

        # Record outcome
        resolved = self._verify_resolution(issue)
        self.recorder.finalize_trajectory(
            'resolved' if resolved else 'failed'
        )

        return resolved

    def _verify_resolution(self, issue: Dict) -> bool:
        """Check if issue is resolved"""
        # Simplified: real version would run tests
        return True
```

This enables agents to leverage accumulated experience when planning repairs.

**Step 5: Implement feedback loop for experience refinement**

Update experience bank based on outcomes:

```python
class ExperienceLearner:
    """Continuously refines experience bank"""

    def __init__(self, experience_bank: ExperienceBank):
        self.experience_bank = experience_bank
        self.success_log = []
        self.failure_log = []

    def process_outcome(self, trajectory: TrajectoryRecord,
                       agent: ExperienceAwareAgent,
                       extractor: ExperienceExtractor):
        """
        Process trajectory outcome and update experience.

        Args:
            trajectory: Completed repair attempt
            agent: Agent that performed repair
            extractor: Experience extractor
        """

        # Add to appropriate log
        if trajectory.final_status == 'resolved':
            self.success_log.append(trajectory)
        else:
            self.failure_log.append(trajectory)

        # Update experience bank
        self.experience_bank.add_experience(trajectory, extractor)

        # Analyze patterns in successes vs failures
        self._update_strategy_success_rates()

    def _update_strategy_success_rates(self):
        """Compute success rates for each strategy"""

        for problem_type in self.experience_bank.high_level:
            strategies = self.experience_bank.high_level[problem_type]

            # Recompute success rate
            successful_count = sum(1 for s in strategies if s['success'])
            success_rate = successful_count / len(strategies) if strategies else 0

            # Mark strategies below threshold as low confidence
            for strategy in strategies:
                strategy['confidence'] = success_rate

    def get_learning_summary(self) -> Dict:
        """Summarize learning progress"""
        return {
            'successes': len(self.success_log),
            'failures': len(self.failure_log),
            'success_rate': (len(self.success_log) /
                           (len(self.success_log) + len(self.failure_log) + 1e-8)),
            'bank_stats': self.experience_bank.get_statistics()
        }
```

This creates a continuous learning loop that improves the agent over time.

### Practical Guidance

**When to use SWE-Exp:**
- Software engineering with many similar issues (web frameworks, libraries)
- Teams with repetitive bug patterns across codebases
- Long-running bug fix systems where learning is valuable
- Repos with clear problem taxonomies
- When multiple related issues exist

**When NOT to use SWE-Exp:**
- One-off problem solving with no similar prior cases
- Real-time systems where experience building overhead matters
- Completely novel problem domains with no experience base
- Static, unchanging codebases with few repairs

**Key hyperparameters:**

- `k_high_level`: Number of high-level strategies to retrieve (2-5)
- `k_mid_level`: Number of code patterns to include (3-8)
- `success_threshold`: Confidence threshold for strategy application (0.5-0.7)
- Experience bank size: Typically 100-500 trajectories for good coverage

**Performance characteristics:**

- Experience helps on similar issues: 15-25% improvement on previously-seen patterns
- Problem classification accuracy: 80-90% on main categories
- Experience retrieval time: <100ms for standard banks
- Storage: ~10KB per trajectory

### Reference

SWE-Exp: Experience-Driven Software Issue Resolution. arXiv:2507.23361

