Skip to content

20.3 Self-Play SWE-RL ​

So far, we have discussed the three pillars of SWE-RL:

  • Data: SWE-bench (real PRs) + SWE-smith (synthetic bugs)
  • Algorithm: GRPO + binary reward in Meta SWE-RL
  • Long-horizon training: CWM learns from environment trajectories, while DeepSWE scales pure RL in real R2E-Gym environments

However, these methods all rely on pre-collected training data — SWE-bench or SWE-smith. Data collection itself is expensive and limited.

This section discusses a new direction: Self-play SWE-RL (SSR) — letting the model generate its own training data, forming a "data flywheel."

Suppose we have only an open-source repository whose dependencies can be installed and whose tests can run—no human issue and no gold patch. The model first edits the code to make a newly added test fail. It then sees only the test patch and current repository and tries to repair the defect. A successful inject-and-repair round becomes a new training experience.

A self-play loop alternates between injecting a verifiable defect and repairing it

20.3.1 Core Idea of Self-play ​

The inspiration for self-play comes from AlphaGo Zero — the model plays against itself, learning from the outcomes of the games. SSR applies this idea to SWE:

text
┌──────────────────────────────────────────────────────────┐
│ Player A (Bug Generator):                                │
│   - Injects a bug into a repository                      │
│   - Generates corresponding tests (to verify the bug)    │
│   - Generates corresponding issue descriptions          │
├──────────────────────────────────────────────────────────┤
│ Player B (Bug Fixer):                                    │
│   - Sees the issue description                           │
│   - Tries to fix it                                      │
│   - Runs tests to verify                                  │
├──────────────────────────────────────────────────────────┤
│ RL Update:                                               │
│   - Player A learns to "generate harder bugs" (Player B can't fix them) │
│   - Player B learns to "fix more complex bugs"          │
│   - Forming adversarial improvement                      │
└──────────────────────────────────────────────────────────┘

Difference from SWE-smith ​

Section 20.1 SWE-smith is offline synthetic data — 50K data is generated all at once, then training is performed.

SSR is online synthetic data — the model continuously generates data during training, and the data quality improves as the model's capability increases.

DimensionSWE-smith (Offline)SSR (Online)
Data GenerationOne-timeContinuous during training
Data DifficultyFixedAdjusted with model capability
Data QualityIndependent of generator capabilityImproved with model capability
Applicable StageEarly trainingEntire training process

Data Flywheel of SSR ​

The core value of SSR is the data flywheel — the stronger the model, the better the generated data; the better the data, the stronger the model.

text
Strong model → Generate hard bugs + excellent fixes → High-quality training data → Model becomes stronger → ...

This positive feedback loop makes SSR particularly effective in the later stages of training — the "hard problems" explored by the model itself can break through the model's capability limits more effectively than those designed by humans.

20.3.2 Algorithm Details of SSR ​

The specific design of the Self-play SWE-RL (SSR) from Tsinghua University SSR:

Bug Generator (Player A) ​

The Bug Generator is a Large Language Model (LLM) that takes a code repository as input and outputs "bug-injected code + test case + issue description".

python
def generate_bug(generator_model, repo, file_path):
    # 1. Select a file
    original_code = repo.read(file_path)

    # 2. Let the generator inject a bug
    prompt = f"""
    Here is the code in {file_path}:
    {original_code}

    Please:
    1. Choose a function to modify
    2. Inject a subtle bug (logic error, not syntax error)
    3. Generate a test that would fail with the bug
    4. Generate an issue description (without revealing the bug)
    """

    response = generator_model.generate(prompt)
    bug_code, test, issue = parse_response(response)

    # 3. Validate the bug (the test fails on the bug code, passes on the original code)
    if not validate_bug(original_code, bug_code, test):
        return None  # Invalid bug, discard

    return {
        "original_code": original_Code,
        "bug_code": bug_code,
        "test": test,
        "issue": issue
    }

Bug Fixer (Player B) ​

Bug Fixer is the trained policy model, which takes an issue and bug code as input and outputs a patch to fix the bug.

python
def fix_bug(fixer_model, task):
    # 1. Show the fixer the issue and bug code (without the original code)
    prompt = f"""
    Issue: {task['issue']}

    Current code: {task['bug_code']}

    Please fix the bug.
    """

    # 2. Fixer fixes the bug in an agentic manner
    trajectory = []
    while not done:
        action = fixer_model.act(prompt)
        trajectory.append(action)

        if action.type == "edit":
            apply_edit(action)
        elif action.type == "test":
            result = run_tests()
            if result.all_passed:
                done = True

    # 3. Calculate the reward
    reward = 1.0 if tests_passed else 0.0

    return trajectory, reward

Adversarial Training ​

python
def ssr_training(generator_model, fixer_model, repo):
    for epoch in range(N_EPOCHS):
        # 1. Generator generates bugs
        task = generate_bug(generator_model, repo, random_file())

        # 2. Fixer attempts to fix
        trajectory, reward = fix_bug(fixer_model, task)

        # 3. Adversarial reward
        generator_reward = -reward  # Fixer fails to fix → Generator wins
        fixer_reward = reward       # Fixer succeeds in fixing → Fixer wins

        # 4. Update both models
        update_generator(generator_model, task, generator_reward)
        update_fixer(fixer_model, trajectory, fixer_reward)

Curriculum Learning ​

SSR naturally generates a curriculum — the Generator initially creates simple bugs, which the Fixer can easily fix; as the Fixer becomes stronger, the Generator must produce more complex bugs to win.

text
Epoch 0-100:  Generator generates simple typos / single-line bugs
Epoch 100-500: Generator generates multi-file, cross-function bugs
Epoch 500-2000: Generator generates subtle logic errors, cross-module impacts

This curriculum is adaptive — it does not require manual design of difficulty gradients.

20.3.3 Experimental Results of SSR ​

Experimental results of SSR on SWE-bench Verified:

Training MethodData SourceSWE-bench Verified
Meta SWE-RLReal PR + SWE-smith41.0%
DeepSWEReal PR + SWE-smith + world model50.0%
SSRReal PR + self-play generated data47.5%
SSR + DeepSWEAll data53.2%

SSR achieves 47.5% performance with training alone (without relying on SWE-smith) — this demonstrates the effectiveness of self-play generated data. Combining it with DeepSWE's world model further improves performance to 53.2%.

Comparison of Data Efficiency ​

MethodTraining Data SizeAchieved Accuracy
SWE-smith (one-time)50K41%
SSR (self-play)5K seeds + 50K self-play47%
SSR + curriculum5K seeds + 100K self-play53%

Self-play improves data efficiency — with the same amount of training data, self-play achieves 6 percentage points higher accuracy than static data.

20.3.4 Limitations and Future of SSR ​

Generator May Generate Invalid Bugs ​

If the Generator learns to "generate syntactically incorrect" bugs (which Fixer finds hard to fix), this is actually ineffective training — syntactic errors are rare in real SWE tasks.

Mitigation: Add a "bug authenticity" reward to the Generator's reward — use an LLM judge to determine whether a bug resembles a real bug.

Imbalance Between Generator and Fixer ​

If the Generator is much stronger than the Fixer, the Fixer will never be able to fix the issues — training has no signal. If the Fixer is much stronger than the Generator, the Generator will be unable to generate effective challenges — the curriculum stagnates.

Mitigation: Dynamically adjust the training frequency of both — maintain balance.

Domain Shift ​

The bugs generated by self-play may differ from the real-world bug distribution — for example, the Generator may focus on a particular type of bug (e.g., typos), while real-world bugs are diverse in type.

Mitigation: Use real PRs as seeds, allowing the Generator to mutate based on real bug patterns.

20.3.5 Industrial Deployment of RL-based SWE ​

As of mid-2026, RL-based SWE has been deployed in multiple products:

Cursor ​

Cursor is one of the most popular AI code editors. Its core capabilities include:

  • Multi-file Understanding: Using RAG to let the model see the entire project
  • Agentic Fixing: The model can autonomously read, edit, and test
  • Based on Claude Opus + Tool Invocation

Cursor does not publicly disclose its training methods, but it is speculated that it uses training data similar to SWE-RL (GitHub PRs + internal code).

Cognition Devin ​

Devin is the "AI Software Engineer" developed by Cognition — capable of independently completing full development tasks (planning, writing code, testing, and deployment).

Devin's training details are not publicly disclosed, but Cognition mentioned in a blog post: "Our RL training enables Devin to learn the full process from planning to implementation."

Byte Trae ​

Trae is the AI IDE from Byte, based on the research findings of DeepSWE. It is actively operating in the domestic market.

OpenAI Codex (2025+) ​

OpenAI has re-released Codex — a code agent based on o3. Its features include:

  • Using o3's reasoning capabilities for complex planning
  • Integration with ChatGPT to handle multiple tasks in parallel
  • Achieving approximately 53% on SWE-bench Verified

Anthropic Claude Code ​

Claude Code is the CLI tool from Anthropic, based on Claude Opus 4.6/4.7. Its features include:

  • Reasoning model + agentic tools
  • Long context (200K-1M)
  • Achieving 65%+ on SWE-bench Verified

20.3.6 Multi-Language and Multi-Repository Extensions ​

Currently, SWE-RL is primarily focused on Python. Future directions for expansion include:

Multi-Language ​

  • JavaScript/TypeScript: Jest and Mocha testing frameworks are mature and can be handled similarly to Python.
  • Java: JUnit testing is mature, but the code style is strict, requiring stronger KL constraints.
  • C/C++: Compiled languages, with slow test execution, and a greater need for a world model.
  • Go/Rust: Modern languages with generally high test coverage, making them suitable for S0-RL.

Multi-Repository ​

  • Enterprise Internal Code: Each company has its own code style, dependencies, and testing standards.
  • Microservices Architecture: Cross-repository modifications and API compatibility.
  • Legacy Systems: Old code, lack of tests, and incomplete documentation.

Expanding to multiple repositories requires:

  • Fast Environment Setup: Dependency management for each repository.
  • Domain-Specific Rewards: Different "good code" standards for different repositories.
  • Cross-Repository Reasoning: Understanding the dependencies between repositories.

20.3.7 Multi-Agent Collaboration ​

Complex SWE tasks may require multiple agents to collaborate:

text
Planner Agent: Analyze the issue and develop a repair plan
  ↓
Explorer Agent: Locate relevant files in the repository
  ↓
Editor Agent: Implement the changes
  ↓
Tester Agent: Run tests and provide feedback
  ↓
Reviewer Agent: Check code quality

This type of multi-agent collaboration has already appeared in systems like Claude Opus 4.7, Cursor, and Devin. Training such systems requires:

  • Multi-Agent RL: Joint training of multiple policies.
  • Communication Protocol: How agents pass information to each other.
  • Shared Value Model: Evaluating the overall quality of a trajectory.

This is a specific application of the Chapter 19 on Agentic RL Multi-Agent Systems in the domain of SWE.

Chapter Summary ​

In this chapter, we have reviewed the full picture of RL-based Software Engineering (SWE):

  • Section 20.1: SWE-bench and the RLVR paradigm — why SWE is an ideal battlefield for RLVR
  • Section 20.1: Meta SWE-RL — open-source SOTA, GRPO + simple reward
  • Section 20.2: Code World Model + DeepSWE — accelerating training + handling long horizons
  • Section 20.3: Self-play SSR — data flywheel, industrial deployment

Key Takeaways:

  1. SWE is one of the most successful industrial applications of RLVR — clear answers, automated verification, and massive data
  2. Simple reward > complex shaping — binary test pass rates are more effective than continuous rewards
  3. Long horizons require stronger algorithms — value models, world models, and test-time search
  4. Self-play is key to data expansion — models generate their own data, with quality improving as capability increases
  5. Industrial deployment is already mature — Cursor, Devin, and Claude Code all use RL-based SWE

Next Chapters:

Hands-on Modern Reinforcement Learning