Vai al contenuto principale
OpenAI

23 febbraio 2026

RicercaPubblicazione

Perché SWE-bench Verified non misura più le capacità di programmazione di frontiera

SWE-bench Verified è sempre più contaminato. Consigliamo SWE-bench Pro.

Caricamento in corso...

Da quando abbiamo pubblicato per la prima volta SWE-bench Verified nell’agosto 2024, il settore lo ha ampiamente utilizzato per misurare i progressi dei modelli nelle attività di ingegneria software autonoma. Dopo la sua pubblicazione, SWE-bench Verified ha fornito un forte segnale dei progressi nelle capacità ed è diventato una metrica standard riportata nelle release dei modelli di frontiera. Monitorare e prevedere i progressi di queste capacità è anche una parte importante del Preparedness Framework di OpenAI. Quando abbiamo creato inizialmente il benchmark Verified, abbiamo cercato di risolvere i problemi nella valutazione originale che rendevano impossibile portare a termine determinate attività nel set di dati SWE-bench(si apre in una nuova finestra).

Dopo i primi notevoli progressi, i miglioramenti nelle performance su SWE-bench Verified sono rallentati, passando(si apre in una nuova finestra) dal 74,9% all’80,9% negli ultimi sei mesi. Ci si chiede quindi: i fallimenti rimanenti riflettono i limiti del modello o le proprietà del set di dati stesso?

In una nuova analisi, abbiamo individuato due problemi principali nel set Verified che indicano come il benchmark non sia più adatto a misurare i progressi nelle capacità di ingegneria software autonoma per lanci di frontiera ai livelli di performance attuali:

  1. I test rifiutano soluzioni corrette: abbiamo esaminato un sottoinsieme del 27,6% del set di dati, composto da problemi che i modelli spesso non riuscivano a risolvere, e abbiamo riscontrato che almeno il 59,4% dei problemi analizzati contiene test difettosi che respingono soluzioni funzionalmente corrette, nonostante i nostri sforzi iniziali nella creazione di SWE-bench Verified per migliorarne l’accuratezza.
  2. Addestramento sulle soluzioni: poiché i grandi modelli di frontiera possono apprendere informazioni dal loro addestramento, è importante che non vengano mai addestrati su problemi e soluzioni su cui vengono valutati. È come condividere con gli studenti, prima del test, problemi e soluzioni per un test imminente: potrebbero non memorizzare la risposta, ma gli studenti che hanno già visto le risposte andranno certamente meglio di quelli che non le hanno viste. I problemi di SWE-bench provengono da repository open source che molti fornitori di modelli utilizzano a scopo di addestramento. Nella nostra analisi abbiamo riscontrato che tutti i modelli di frontiera che abbiamo testato erano in grado di riprodurre la correzione del bug originale, scritta da un essere umano, usata come riferimento di ground truth, nota come gold patch, oppure i dettagli testuali della descrizione del problema per determinate attività. Ciò indica che tutti i modelli hanno avuto accesso ad almeno alcuni dei problemi e delle soluzioni durante l’addestramento.

Abbiamo inoltre trovato prove che i modelli che hanno già incontrato i problemi durante l’addestramento hanno maggiori probabilità di successo, poiché possiedono informazioni aggiuntive necessarie per superare i test insufficientemente specificati.

Ciò significa che i miglioramenti su SWE-bench Verified non riflettono più progressi significativi nelle reali capacità di sviluppo software dei modelli. Al contrario, riflettono sempre più quanto il modello sia stato esposto al benchmark durante l’addestramento. Per questo motivo abbiamo cessato di riportare i punteggi di SWE-bench Verified e raccomandiamo ad altri sviluppatori di modelli di fare lo stesso.

Stiamo sviluppando nuove valutazioni non contaminate per monitorare meglio le capacità di programmazione e riteniamo che questa sia un’area importante su cui concentrarsi per la comunità di ricerca più ampia. Fino a quando non saranno disponibili, OpenAI raccomanda di riportare i risultati per SWE-bench Pro.

Sfondo

La valutazione originale SWE-bench(si apre in una nuova finestra) è stata rilasciata nel 2023. Ogni problema proviene da un issue risolto su GitHub in uno dei 12 repository open-source Python ed è associato alla corrispondente pull request (PR). Per verificare se una modifica di codice generata dal modello sia corretta, ogni problema include due set di test:

  • Test che falliscono sul codice sorgente non modificato, ma che vengono superati se il problema è stato risolto correttamente
  • Test di regressione che vengono superati sia prima che dopo la correzione per garantire che le funzionalità non correlate rimangano intatte.

Il modello non ha accesso ai test. Deve produrre una modifica al codice basandosi esclusivamente sul testo originale dell’issue e sullo stato del repository prima della correzione. Un problema è considerato risolto solo se tutti i test risultano superati dopo l’applicazione della modifica.

Abbiamo riscontrato molti problemi in quella valutazione che potrebbero portare a sottostimare le capacità dei modelli.

  • Alcuni test unitari erano troppo specifici o non allineati all’attività, quindi le correzioni corrette potevano essere respinte.
  • Molte descrizioni delle attività erano insufficientemente dettagliate, il che poteva portare a più interpretazioni valide, mentre i test coprivano solo una di esse.
  • A seconda della configurazione dell’ambiente (ad esempio Linux vs Windows, o la versione di Python), alcuni test potevano fallire senza un motivo reale

Abbiamo creato SWE-bench Verified nel 2024 per affrontare questi problemi. Abbiamo collaborato con ingegneri del software esperti per esaminare 1.699 problemi di SWE-bench ed escludere quelli che presentavano questi problemi. Ogni problema è stato esaminato in modo indipendente da tre esperti. Questo processo di revisione ha portato a SWE-bench Verified, un insieme curato di 500 problemi.

Test troppo restrittivi e troppo ampi

Sebbene SWE-bench Verified rappresenti un grande miglioramento rispetto alla versione iniziale, permangono problemi residui. Abbiamo condotto un audit di 138 problemi SWE-bench Verified che OpenAI o3 non ha risolto in modo coerente in 64 esecuzioni indipendenti. Ogni caso è stato esaminato in modo indipendente da almeno sei ingegneri esperti di software. Se un esperto segnalava un problema, questo veniva nuovamente verificato da un team aggiuntivo.

Abbiamo riscontrato che il 59,4% dei 138 problemi conteneva criticità sostanziali nella progettazione dei test e/o nella descrizione del problema, rendendoli estremamente difficili o impossibili da risolvere anche per il modello o l’essere umano più capace. 

  • Il 35,5% delle attività sottoposte ad audit presenta casi di test rigidi che impongono dettagli specifici di implementazione, invalidando molte soluzioni funzionalmente corrette, che chiamiamo casi di test restrittivi.
  • Il 18,8% delle attività sottoposte ad audit ha test che verificano funzionalità aggiuntive non specificate nella descrizione del problema, che chiamiamo casi di test ampi.
  • Il restante 5,1% delle attività presentava problemi vari che non erano ben raggruppati in questa tassonomia.

Un esempio illustrativo della prima modalità di errore è pylint-dev__pylint-4551(si apre in una nuova finestra), in cui la PR introduce una nuova funzione `get_annotation` come parte della soluzione complessiva. Questo nome di funzione non è menzionato nella descrizione del problema, ma viene importato direttamente dai test. Sebbene alcuni modelli possano intuire di creare una funzione di questo tipo, non è strettamente necessario implementare una funzione con questo nome specifico per affrontare correttamente il problema. Molte soluzioni valide non superano i test a causa di errori di importazione.

Descrizione del problema

Testo semplice

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)]

Snippet di test della PR

Python

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

Errori dei test della PR (troncati per una migliore leggibilità)

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)

Un esempio di casi di test troppo ampi è sympy__sympy-18199(si apre in una nuova finestra). Questa attività è stata ricavata da una PR che ha affrontato tre problemi distinti con la funzione `nthroot_mod`, nello specifico #17373(si apre in una nuova finestra), #17377(si apre in una nuova finestra) e #18212(si apre in una nuova finestra). La descrizione per l’attività SWE-bench Verified, tuttavia, copre solo il problema finale #18212(si apre in una nuova finestra). Questo crea una discrepanza: i test della PR coprono tutti e tre i problemi, mentre la descrizione ne dettaglia solo uno. Nelle nostre esecuzioni, i modelli spesso implementano correttamente la correzione descritta e poi non superano i test che coprono l’implementazione degli altri due problemi.

Descrizione originale della PR (dalla PR di GitHub)

Testo semplice

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

Descrizione del problema per #18212

Testo semplice

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.

Descrizione del problema per l’attività SWE-bench Verified (presa solo da #18212):

Testo semplice

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.

Contaminazione

SWE-bench Verified e i repository (codici sorgente e note di rilascio) sono entrambi open source e ampiamente utilizzati e discussi, il che rende difficile evitare la contaminazione per gli sviluppatori di modelli.

Abbiamo riscontrato per la prima volta segni di contaminazione nei nostri stessi modelli. Ad esempio, quando GPT‑5.2 ha risolto 31 attività che avevamo identificato come quasi impossibili da risolvere. In django__django-14725(si apre in una nuova finestra) i test richiedono un nuovo parametro specifico `edit_only` che non è esplicitamente richiesto dalla descrizione del problema. Durante la risoluzione del problema, GPT‑5.2 mostra nel suo chain of thought di avere informazioni sulle note di rilascio che descrivono in dettaglio le modifiche al codice sorgente e identifica correttamente che il parametro `edit_only` è stato introdotto in Django 4.1.

GPT‑5.2 CoT

Testo semplice

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.

Per valutare quanto sia significativa la contaminazione in senso più ampio, abbiamo creato una configurazione automatizzata di red teaming. Per ogni domanda di SWE-bench Verified, abbiamo incaricato GPT‑5 di mettere alla prova un GPT‑5.2‑Chat, Claude Opus 4.5 e Gemini 3 Flash Preview per la contaminazione. Questi modelli sono stati scelti per escludere i modelli di ragionamento, ma riconosciamo che probabilmente esiste un divario di capacità non trascurabile tra di essi.

Per verificare la contaminazione, GPT‑5 ha ricevuto: l’ID dell’attività di SWE-bench Verified, la descrizione, la gold patch e i test della PR. In oltre 15 turni, abbiamo consentito a GPT‑5 di variare il prompt di sistema/sviluppatore, il prompt dell’utente e la precompilazione dell’assistente e diverse strategie di individuazione. Dopo ogni turno, un modello giudice ha etichettato quante nuove informazioni specifiche del compito apparivano e ogni risposta è stata etichettata per gravità della contaminazione da “nessuna” a “elevata”. A GPT‑5 è stato consentito di adattare la propria strategia in base ai turni precedenti per recuperare in modo iterativo dettagli specifici dell’attività. Per ogni esempio di contaminazione elevata, abbiamo verificato con un altro giudice che GPT‑5 non avesse divulgato troppe informazioni al modello di destinazione. Infine, abbiamo poi esaminato manualmente gli esempi “elevati” che compongono le trascrizioni in questo post.

Di seguito sono riportati esempi di contaminazione elevata tra diversi fornitori di modelli.

GPT‑5.2 

Dato un breve estratto della descrizione dell’attività, GPT‑5.2 produce esattamente la gold patch. In particolare, conosce il nome esatto della classe e del metodo, e la nuova condizione di early return `if username is None or password is None` che viene introdotta.

Individuazione della contaminazione

Descrizione del problema

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

Prompt dell'utente

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"

Risposta del modello

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 è in grado non solo di richiamare esattamente le 4 righe di modifica funzionale introdotte dalla PR, insieme al nome del file e al metodo interessati, ma anche di riportare testualmente il commento inline presente nella differenza di codice. 

Individuazione della contaminazione

Prompt dell’utente

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.

Precompilazione

1
Let me be precise about the location and wording.

Risposta dell’assistente

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 

Gemini 3 Flash, quando non riceve alcuna informazione aggiuntiva sull’attività se non l’ID, è in grado di fornire dettagli testuali esatti dalla descrizione dell’attività e dalla gold patch. Ciò include la nuova formula regex per la validazione del nome utente e i numeri di riga esatti della modifica.

Individuazione della contaminazione

Descrizione del problema

1
UsernameValidator allows trailing newline in usernames

Prompt dell'utente

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.

Precompilazione

1
Let me be precise about the wording.

Risposta del modello

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.'

Discussione

Da questo audit di SWE-bench Verified, emergono due lezioni più ampie per la progettazione delle valutazioni. Innanzitutto, i benchmark provenienti da materiale pubblicamente disponibile comportano un rischio di contaminazione, in cui l’esposizione ai dati di addestramento può gonfiare silenziosamente i punteggi. Se i dati sottoposti a crawling pubblico vengono utilizzati nella costruzione dei benchmark, gli sviluppatori di modelli dovrebbero eseguire test aggiuntivi per verificare la contaminazione. I benchmark, e persino le loro soluzioni, pubblicati possono finire nei dati di addestramento. È necessario prestare particolare attenzione sia al modo in cui i set di dati vengono pubblicati (ad esempio, tramite protezione con password) sia al filtraggio dei dati di addestramento (ad esempio, rispettando rigorosamente le stringhe di monitoraggio). 

In secondo luogo, la valutazione automatica è complessa da fare correttamente; i casi di test perfetti dovrebbero verificare pienamente la corretta funzionalità, rimanendo agnostici rispetto a dettagli implementativi irrilevanti e allo stesso tempo robusti rispetto a soluzioni scorciatoia. Questi problemi sono intrinsecamente complessi e difficili da risolvere. Individuare questi problemi ha richiesto molteplici campagne estese di etichettatura manuale. 

Abbiamo incorporato questi risultati nei nostri recenti sforzi di valutazione. Negli ultimi mesi abbiamo scelto di riportare i risultati dello split pubblico di SWE-Bench Pro. Consigliamo ad altri sviluppatori di modelli di fare lo stesso. SWE-bench Pro non è perfetto, ma empiricamente sembra soffrire meno di problemi di contaminazione. La nostra pipeline di contaminazione ha rilevato alcuni casi di contaminazione, ma questi casi erano significativamente più rari e meno gravi rispetto a SWE-bench Verified, e nessun modello è stato in grado di produrre una gold patch completa e testuale.

Continueremo a investire in benchmark originali, redatti privatamente, e chiederemo il supporto del settore e del mondo accademico affinché facciano lo stesso. In GDPVal, le attività sono redatte privatamente da esperti del settore, riducendo il rischio di esposizione, e le soluzioni vengono valutate in modo olistico da revisori formati. Questo approccio richiede molte risorse, ma è sempre più necessario per misurare miglioramenti reali delle capacità.

Autore

OpenAI