Overslaan naar hoofdinhoud
OpenAI

23 februari 2026

OnderzoekPublicatie

Waarom SWE-bench Verified niet langer geschikt is om de codeervaardigheden van grensverleggende modellen te meten

SWE-bench Verified raakt steeds meer vervuild. Wij raden daarom het gebruik van SWE-bench Pro aan.

Bezig met laden...

Sinds we SWE-bench Verified in augustus 2024 publiceerden, wordt deze door de sector breed ingezet om de voortgang van modellen op het gebied van autonome software-engineeringtaken te meten.e-engineeringtaken te meten. Na de release vormde SWE-bench Verified een sterke graadmeter voor de vooruitgang in capaciteiten en werd het een standaardmaatstaf bij de lancering van grensverleggende modellen. Het monitoren en voorspellen van de voortgang van deze vaardigheden is ook een belangrijk onderdeel van OpenAI's Preparedness Framework. Bij het creëren van de Verified-benchmark probeerden we problemen in de oorspronkelijke evaluatie op te lossen die bepaalde taken in de SWE-bench-dataset(opent in een nieuw venster) onmogelijk maakten.

Na grote sprongen in het begin is de vooruitgang van de best presterende modellen op SWE-bench Verified vertraagd, met een stijging(opent in een nieuw venster) van 74,9% naar 80,9% in de afgelopen zes maanden. Dit roept de vraag op: weerspiegelen de resterende fouten de beperkingen van het model, of eigenschappen van de dataset zelf?

Uit een nieuwe analyse blijken twee grote problemen met de Verified-set, die erop wijzen dat de benchmark (gezien de huidige prestatieniveaus) niet langer geschikt is om de voortgang op het gebied van autonome software-engineeringcapaciteiten te meten bij de lancering van grensverleggende modellen:

  1. Tests keuren correcte oplossingen af: We hebben een subset van 27,6% van de dataset onderzocht die modellen vaak niet konden oplossen. We ontdekten dat bij ten minste 59,4% van de onderzochte problemen sprake is van gebrekkige testcases die functioneel correcte inzendingen afkeuren, ondanks onze uiterste inspanningen om dit te verbeteren bij de creatie van SWE-bench Verified.
  2. Trainen op oplossingen: Omdat grote, geavanceerde modellen informatie kunnen leren uit hun training, is het belangrijk dat ze nooit worden getraind op de problemen en oplossingen waarop ze worden geëvalueerd. Dit is vergelijkbaar met het vooraf delen van toetsvragen en antwoorden met studenten: ze onthouden het antwoord misschien niet letterlijk, maar studenten die de antwoorden hebben gezien, zullen het zeker beter doen dan studenten die dat niet hebben. SWE-bench-problemen zijn afkomstig uit open-source repositories die door veel modelaanbieders worden gebruikt voor trainingsdoeleinden. Uit onze analyse bleek dat alle geteste geavanceerde modellen in staat waren om de oorspronkelijke, door mensen geschreven bugfix (de referentieoplossing, oftewel de 'gold patch') te reproduceren, of woordelijke details van de probleemstelling voor bepaalde taken te genereren. Dit wijst erop dat ze allemaal tijdens de training ten minste een deel van de problemen en oplossingen hebben gezien.

We hebben ook bewijs gevonden dat modellen die de problemen tijdens de training hebben gezien, een grotere slagingskans hebben. Ze beschikken namelijk over de extra informatie die nodig is om voor de onvoldoende gespecificeerde tests te slagen.

Dit betekent dat hogere scores op SWE-bench Verified niet langer een betekenisvolle afspiegeling zijn van de daadwerkelijke softwareontwikkelingsvaardigheden van modellen. In plaats daarvan laten ze in toenemende mate zien in hoeverre het model tijdens de training is blootgesteld aan de benchmark. Daarom zijn wij gestopt met het rapporteren van SWE-bench Verified-scores, en we raden andere modelontwikkelaars aan dit ook te doen.

We bouwen aan nieuwe, onvervuilde evaluaties om codeervaardigheden beter te kunnen volgen. We vinden dit een belangrijk aandachtsgebied voor de bredere onderzoeksgemeenschap. Tot die tijd raadt OpenAI aan om resultaten van SWE-bench Pro te rapporteren.

Achtergrond

De oorspronkelijke SWE-bench(opent in een nieuw venster)-evaluatie werd in 2023 uitgebracht. Elk probleem is afkomstig van een opgelost GitHub-issue in een van de 12 open-source Python-repository's en is gekoppeld aan de bijbehorende pull request (PR). Om te bepalen of een door het model gegenereerde codewijziging correct is, bevat elk probleem twee sets tests:

  • Tests die falen op de ongewijzigde codebase, maar slagen als het probleem correct is opgelost
  • Regressietests die zowel voor als na de fix slagen, om te garanderen dat niet-gerelateerde functionaliteit intact blijft.

Het model krijgt de tests niet te zien. Het moet een codewijziging doorvoeren op basis van alleen de oorspronkelijke probleembeschrijving en de staat van de repository vóór de fix. Een probleem geldt pas als 'opgelost' als alle tests slagen nadat de codewijziging is toegepast.

We hebben veel problemen gevonden met die evaluatie, wat kan leiden tot onderapportage van de capaciteiten van modellen.

  • Sommige unit tests waren te specifiek of sloten niet goed aan bij de taak, waardoor correcte oplossingen ten onrechte werden afgekeurd.
  • Veel taakomschrijvingen waren onvoldoende gespecificeerd. Dit kon leiden tot meerdere geldige interpretaties, terwijl de tests slechts één specifieke interpretatie dekten.
  • Afhankelijk van de omgevingsinstellingen (bijvoorbeeld Linux vs. Windows, of de Python-versie) konden sommige tests onterecht falen.

We hebben in 2024 SWE-bench Verified gecreëerd om deze problemen aan te pakken. We hebben samengewerkt met deskundige software-engineers om 1.699 SWE-bench-problemen te beoordelen en de problemen met deze gebreken eruit te filteren. Elk probleem is onafhankelijk beoordeeld door drie experts. Dit beoordelingsproces resulteerde in SWE-bench Verified, een gecureerde set van 500 problemen.

Tests die te eng of juist te breed zijn

Hoewel SWE-bench Verified een grote verbetering is ten opzichte van de oorspronkelijke versie, blijven er restproblemen bestaan. We hebben een audit uitgevoerd op 138 SWE-bench Verified-problemen die OpenAI o3 niet consistent kon oplossen in 64 onafhankelijke runs. Elk geval is onafhankelijk beoordeeld door ten minste zes ervaren software-engineers. Als een expert een probleem signaleerde, werd dit door een extra team opnieuw geverifieerd.

We ontdekten dat 59,4% van de 138 problemen significante fouten bevatte in het testontwerp en/of de probleembeschrijving. Hierdoor waren ze extreem moeilijk of onmogelijk op te lossen, zelfs voor de meest bekwame modellen of mensen. 

  • 35,5% van de onderzochte taken heeft strikte testcases die specifieke implementatiedetails afdwingen, waardoor veel functioneel correcte inzendingen ongeldig worden verklaard. Dit noemen we 'narrow test cases' (te enge tests).
  • 18,8% van de onderzochte taken heeft tests die controleren op extra functionaliteit die niet in de probleembeschrijving stond vermeld. Dit noemen we 'wide test cases' (te brede tests).
  • De overige 5,1% van de taken had diverse problemen die niet goed in deze taxonomie pasten.

Een illustratief voorbeeld van de eerste faalwijze is pylint-dev__pylint-4551(opent in een nieuw venster), waarbij de PR een nieuwe functie get_annotation introduceert als onderdeel van de totale oplossing. Deze functienaam wordt niet genoemd in de probleembeschrijving, maar wordt wel direct door de tests geïmporteerd. Hoewel sommige modellen intuïtief zouden kunnen besluiten zo'n functie aan te maken, is het strikt genomen niet noodzakelijk om een functie met deze specifieke naam te implementeren om het probleem correct op te lossen. Veel geldige oplossingen falen voor de tests vanwege importfouten.

Probleembeschrijving

Platte tekst

1
Use Python type hints for UML generation
2
It seems that pyreverse does not read python type hints (as defined by [PEP 484](https://www.python.org/dev/peps/pep-0484/)), and this does not help when you use `None` as a default value :
3
### Code example
4
`
5
class C(object):
6
def __init__(self, a: str = None):
7
self.a = a
8
`
9
### Current behavior
10
Output of pyreverse :
11
![classes_test](https://user-images.githubusercontent.com/22218701/27432305-f10fe03e-574f-11e7-81fa-e2b59e493360.png)
12
### Expected behavior
13
I would like to see something like : `a : String` in the output.
14
### pylint --version output
15
pylint-script.py 1.6.5,
16
astroid 1.4.9
17
Python 3.6.0 |Anaconda custom (64-bit)| (default, Dec 23 2016, 11:57:41) [MSC v.1900 64 bit (AMD64)]

PR-testfragment

Python

1
+from pylint.pyreverse.utils import get_annotation, get_visibility, infer_node

PR-testfouten (ingekort voor de leesbaarheid)

Python

1
==================================== ERRORS ====================================
2
_____________ ERROR collecting tests/unittest_pyreverse_writer.py ______________
3
ImportError while importing test module '/testbed/tests/unittest_pyreverse_writer.py'.
4
Hint: make sure your test modules/packages have valid Python names.
5
Traceback:
6
/opt/miniconda3/envs/testbed/lib/python3.9/importlib/__init__.py:127: in import_module
7
return _bootstrap._gcd_import(name[level:], package, level)
8
tests/unittest_pyreverse_writer.py:32: in <module>
9
from pylint.pyreverse.utils import get_annotation, get_visibility, infer_node
10
E ImportError: cannot import name 'get_annotation' from 'pylint.pyreverse.utils' (/testbed/pylint/pyreverse/utils.py)

Een voorbeeld van te brede testcases is sympy__sympy-18199(opent in een nieuw venster). Deze taak is afkomstig van een PR die drie verschillende problemen met de nthroot_mod-functie aanpakte, specifiek #17373(opent in een nieuw venster), #17377(opent in een nieuw venster) en #18212(opent in een nieuw venster). De beschrijving voor de SWE-bench Verified-taak behandelt echter alleen het laatste probleem, #18212(opent in een nieuw venster). Dit creëert een discrepantie: de PR-tests dekken alle drie de problemen, terwijl de beschrijving er slechts één detailleert. In onze runs implementeren modellen vaak correct de beschreven oplossing, maar falen ze vervolgens op tests die de implementatie voor de andere twee problemen dekken.

Originele PR-beschrijving (uit de GitHub PR)

Platte tekst

1
Fixes #17373
2
Fixes #17377
3
Fixes #18212
4
- ntheory
5
- `nthroot_mod` now supports composite moduli

Probleembeschrijving voor #18212

Platte tekst

1
nthroot_mod function misses one root of x = 0 mod p.
2

3
When in the equation x**n = a mod p , when a % p == 0. Then x = 0 mod p is also a root of this equation. But right now `nthroot_mod` does not check for this condition. `nthroot_mod(17*17, 5 , 17)` has a root `0 mod 17`. But it does not return it.

Probleembeschrijving voor SWE-bench Verified-taak (alleen overgenomen van #18212):

Platte tekst

1
nthroot_mod function misses one root of x = 0 mod p.
2

3
When in the equation x**n = a mod p , when a % p == 0. Then x = 0 mod p is also a root of this equation. But right now `nthroot_mod` does not check for this condition. `nthroot_mod(17*17, 5 , 17)` has a root `0 mod 17`. But it does not return it.

Contaminatie

Zowel SWE-bench Verified als de repository's (codebases en release notes) zijn open-source en worden op grote schaal gebruikt en besproken. Dit maakt het voor modelontwikkelaars moeilijk om contaminatie te voorkomen.

We kwamen de eerste tekenen van contaminatie tegen in onze eigen modellen. Bijvoorbeeld toen GPT‑5.2 31 taken oploste die wij als nagenoeg onmogelijk hadden bestempeld. In django__django-14725(opent in een nieuw venster) vereisen de tests een specifieke nieuwe parameter edit_only, die niet expliciet wordt vereist in de probleemstelling. Tijdens het oplossen van het probleem laat GPT‑5.2 in zijn 'chain of thought' (denkproces) zien dat het beschikt over informatie uit de release notes die wijzigingen in de codebase beschrijven. Het identificeert correct dat de parameter edit_only werd geïntroduceerd in Django 4.1.

GPT‑5.2 CoT

Platte tekst

1
There is also `edit_only` parameter maybe added around 4.1 or 4.2. Since this is 4.1 dev 2022, the code might be before introduction. We will implement now. Hidden tests will check new behavior.

Om te beoordelen hoe significant de contaminatie in bredere zin is, hebben we een geautomatiseerde 'red-teaming'-opzet gecreëerd. Voor elke SWE-bench Verified-vraag gaven we GPT‑5 de opdracht om GPT‑5.2‑Chat, Claude Opus 4.5 en Gemini 3 Flash Preview te testen op contaminatie Deze modellen werden gekozen om redenerende modellen uit te sluiten, maar we erkennen dat er waarschijnlijk een niet-triviaal verschil in capaciteiten tussen de modellen bestaat.

Om te testen op contaminatie ontving GPT‑5: de ID van de SWE-bench Verified-taak, de beschrijving, de gold patch en de PR-tests. Gedurende 15 beurten stonden we GPT‑5 toe om de systeem-/ontwikkelaarsprompt, de gebruikersprompt, de assistent-prefill en verschillende ontlokkingsstrategieën te variëren. Na elke beurt labelde een jury-model hoeveel nieuwe taakspecifieke informatie er verscheen en werd elk antwoord gelabeld op de ernst van de contaminatie, variërend van 'geen' tot 'sterk'. GPT‑5 mocht zijn strategie aanpassen op basis van eerdere beurten om iteratief taakspecifieke details te achterhalen. Voor elk voorbeeld van sterke contaminatie verifieerden we met een ander beoordelingsmodel of GPT‑5 niet te veel informatie naar het doelmodel had gelekt. Ten slotte hebben we de 'sterke' voorbeelden die de transcripties in dit bericht vormen, handmatig beoordeeld.

Hieronder staan voorbeelden van sterke contaminatie bij verschillende modelaanbieders.

GPT‑5.2 

Op basis van een kort fragment uit de taakomschrijving genereert GPT‑5.2 de exacte gold patch. In het bijzonder kent het de exacte klasse- en methodenaam, en de nieuwe 'early return'-voorwaarde if username is None or password is None die wordt geïntroduceerd.

Uitlokken van contaminatie

Probleemstelling

1
ModelBackend.authenticate() shouldn't make a database query when username is None

Gebruikersprompt

1
We're playing a SWE-bench Verified memory game.
2
Please give your best guess of the full sentence of the task description based on the hint, and the corresponding code change introduced in the fix. Bonus points if you remember the exact diff.
3
The task ID is django__django-11451.
4
Hint: Part of the description was "... shouldn't make a database query when username is None"

Antwoord van het model

1
Task (best-guess full sentence)
2
- “`ModelBackend.authenticate()` shouldn’t make a database query when `username` is `None`.”
3

4
What the fix changed (corresponding code change)
5
- Location: `django/contrib/auth/backends.py`
6
- Function: `ModelBackend.authenticate(...)`
7
- Change: add an early-return guard so that if `username` is `None` (and similarly if `password` is `None`), Django returns `None` immediately instead of calling `UserModel._default_manager.get_by_natural_key(username)` (which would hit the DB and/or error).
8

9
Best-guess diff (approximate, from memory)
10

11
```diff
12
diff --git a/django/contrib/auth/backends.py b/django/contrib/auth/backends.py
13
index XXXXXXX..YYYYYYY 100644
14
--- a/django/contrib/auth/backends.py
15
+++ b/django/contrib/auth/backends.py
16
@@ -1,6 +1,7 @@
17
class ModelBackend(BaseBackend):
18
def authenticate(self, request, username=None, password=None, **kwargs):
19
+ if username is None or password is None:
20
+ return
21
UserModel = get_user_model()
22
if username is None:
23
username = kwargs.get(UserModel.USERNAME_FIELD)
24
try:
25
user = UserModel._default_manager.get_by_natural_key(username)
26
except UserModel.DoesNotExist:
27
UserModel().set_password(password)
28
else:
29
if user.check_password(password) and self.user_can_authenticate(user):
30
return user
31
```
32

33
If I had to be stricter about matching what actually shipped, the key behavioral point is: **don’t attempt `get_by_natural_key()` (DB query) when `username` is `None`**; the fix is an early `return None` before any lookup.

Gold patch

Python

1
diff --git a/django/contrib/auth/backends.py b/django/contrib/auth/backends.py
2
--- a/django/contrib/auth/backends.py
3
+++ b/django/contrib/auth/backends.py
4
@@ -39,6 +39,8 @@ class ModelBackend(BaseBackend):
5
def authenticate(self, request, username=None, password=None, **kwargs):
6
if username is None:
7
username = kwargs.get(UserModel.USERNAME_FIELD)
8
+ if username is None or password is None:
9
+ return
10
try:
11
user = UserModel._default_manager.get_by_natural_key(username)
12
except UserModel.DoesNotExist:

Claude Opus 4.5 

Opus weet niet alleen de exacte functionele wijziging van vier regels die de PR introduceerde te reproduceren (inclusief de specifieke bestandsnaam en de aangepaste methode), maar citeert ook woordelijk het inline-commentaar uit de diff. 

Uitlokken van contaminatie

Gebruikersprompt

1
Quick memory check on the Astropy issue about stopping the automatic conversion of structured ndarrays into a mixin. Without seeing the patch, can you: 1) name the exact file path and function where that conditional lived, and quote the inline comment immediately above it word-for-word, and 2) quote verbatim the content that was beneath the inline comment that was changed by the PR? Please be exact on punctuation and paths. Context: astropy__astropy-13236.

Prefill

1
Let me be precise about the location and wording.

Antwoord van assistent

1
**1) File path and function:**
2
`astropy/table/table.py` in the `_convert_data_to_col` method (which is inside the `Table` class).
3

4
**2) The inline comment immediately above the conditional:**
5

6
```python
7
# Structured ndarray gets viewed as a mixin unless already a valid
8
# mixin class
9
```
10

11
**3) The content beneath that comment that was changed:**
12

13
The original code was:
14
```python
15
if (not isinstance(data, Column) and not data_is_mixin
16
and isinstance(data, np.ndarray) and len(data.dtype) > 1):
17
data = data.view(NdarrayMixin)
18
data_is_mixin = True
19
```
20

21
This was the code that automatically converted structured ndarrays to `NdarrayMixin`, which the PR removed/changed to stop that automatic conversion behavior.
22

Gold patch

Python

1
diff --git a/astropy/table/table.py b/astropy/table/table.py
2
--- a/astropy/table/table.py
3
+++ b/astropy/table/table.py
4
@@ -1239,13 +1239,6 @@ def _convert_data_to_col(self, data, copy=True, default_name=None, dtype=None, n
5
f'{fully_qualified_name} '
6
'did not return a valid mixin column')
7
8
- # Structured ndarray gets viewed as a mixin unless already a valid
9
- # mixin class
10
- if (not isinstance(data, Column) and not data_is_mixin
11
- and isinstance(data, np.ndarray) and len(data.dtype) > 1):
12
- data = data.view(NdarrayMixin)
13
- data_is_mixin = True
14
-
15
# Get the final column name using precedence. Some objects may not
16
# have an info attribute. Also avoid creating info as a side effect.
17
if not name:

Gemini 3 Flash 

Wanneer Gemini 3 Flash geen andere informatie over de taak krijgt dan de ID, kan het woordelijke details uit de taakomschrijving en de gold patch genereren. Dit omvat onder andere de nieuwe regex-formule voor gebruikersnaamvalidatie en de exacte regelnummers voor de wijziging.

Uitlokken van contaminatie

Probleemstelling

1
UsernameValidator allows trailing newline in usernames

Gebruikersprompt

1
Please provide the exact task text for the SWE-Bench Verified item django__django-11099: first the single-line summary, then the full detailed description that follows, character-for-character. After that, reproduce the complete gold patch as a unified diff, with exact file paths, hunk headers, and line content. Do not paraphrase; quote verbatim.

Prefill

1
Let me be precise about the wording.

Antwoord van het model

1
### Task Text
2
UsernameValidator allows trailing newlines.
3

4
ASCIIUsernameValidator and UnicodeUsernameValidator use the regex r'^[\w.@+-]+$'. This allows a trailing newline if it's there. The regex should be r'^[\w.@+-]+\Z'.
5

6
### Gold Patch
7
```diff
8
--- a/django/contrib/auth/validators.py
9
+++ b/django/contrib/auth/validators.py
10
@@ -7,7 +7,7 @@ from django.utils.translation import gettext_lazy as _
11
@deconstructible
12
class ASCIIUsernameValidator(validators.RegexValidator):
13
- regex = r'^[\w.@+-]+$'
14
+ regex = r'^[\w.@+-]+\Z'
15
message = _(
16
'Enter a valid username. This value may contain only English letters, '
17
'numbers, and @/./+/-/_ characters.'
18
@@ -17,7 +17,7 @@ class ASCIIUsernameValidator(validators.RegexValidator):
19
@deconstructible
20
class UnicodeUsernameValidator(validators.RegexValidator):
21
- regex = r'^[\w.@+-]+$'
22
+ regex = r'^[\w.@+-]+\Z'
23
message = _(
24
'Enter a valid username. This value may contain only letters, '
25
'numbers, and @/./+/-/_ characters.'
26
```

Gold patch

Python

1
diff --git a/django/contrib/auth/validators.py b/django/contrib/auth/validators.py
2
--- a/django/contrib/auth/validators.py
3
+++ b/django/contrib/auth/validators.py
4
@@ -7,7 +7,7 @@
5
6
@deconstructible
7
class ASCIIUsernameValidator(validators.RegexValidator):
8
- regex = r'^[\w.@+-]+$'
9
+ regex = r'^[\w.@+-]+\Z'
10
message = _(
11
'Enter a valid username. This value may contain only English letters, '
12
'numbers, and @/./+/-/_ characters.'
13
@@ -17,7 +17,7 @@ class ASCIIUsernameValidator(validators.RegexValidator):
14
15
@deconstructible
16
class UnicodeUsernameValidator(validators.RegexValidator):
17
- regex = r'^[\w.@+-]+$'
18
+ regex = r'^[\w.@+-]+\Z'
19
message = _(
20
'Enter a valid username. This value may contain only letters, '
21
'numbers, and @/./+/-/_ characters.'

Discussie

Uit deze audit van SWE-bench Verified trekken we twee bredere lessen voor het ontwerp van evaluaties. Ten eerste brengen benchmarks die gebaseerd zijn op openbaar beschikbaar materiaal een risico op contaminatie met zich mee, waarbij blootstelling aan trainingsdata de scores ongemerkt kan opblazen. Als er voor het samenstellen van benchmarks gebruik wordt gemaakt van data die openbaar van internet is gehaald, moeten modelontwikkelaars extra tests uitvoeren op contaminatie. Benchmarks, en zelfs de oplossingen daarvan, die openbaar worden geplaatst, kunnen in de trainingsdata terechtkomen. Extra zorgvuldigheid is vereist bij de manier waarop datasets worden gepubliceerd (beveiligd met een wachtwoord) én bij het filteren van trainingsdata (strikte naleving van 'canary strings'). 

Ten tweede is geautomatiseerde scoring lastig goed te krijgen: perfecte testcases moeten de juiste functionaliteit volledig verifiëren, onafhankelijk zijn van onbelangrijke implementatiedetails en robuust zijn tegen 'shortcut'-oplossingen. Deze problemen zijn inherent complex en moeilijk op te lossen. Het opsporen van deze problemen vergde meerdere uitgebreide menselijke beoordelingsrondes. 

We hebben deze bevindingen verwerkt in onze recente evaluatie-inspanningen. De afgelopen maanden hebben we ervoor gekozen om resultaten te rapporteren van de publieke deelverzameling van SWE-bench Pro. We raden andere modelontwikkelaars aan hetzelfde te doen. SWE-bench Pro is niet perfect, maar lijkt empirisch gezien minder last te hebben van contaminatieproblemen. Onze contaminatie-pipeline vond enkele gevallen van vervuiling, maar deze waren aanzienlijk zeldzamer en minder ernstig dan bij SWE-bench Verified. Bovendien was geen enkel model in staat een volledige, woordelijke gold patch te produceren.

We blijven investeren in originele, privé opgestelde benchmarks en vragen we de industrie en de academische wereld om hierbij te helpen. In GDPVal worden taken privé opgesteld door domeinexperts, wat het risico op blootstelling (exposure) vermindert, en oplossingen worden holistisch beoordeeld door getrainde beoordelaars. Deze aanpak is tijd- en arbeidsintensief, maar steeds noodzakelijker om echte verbeteringen in capaciteiten te meten.

Auteur

OpenAI