Sari la conținutul principal
OpenAI

23 februarie 2026

CercetarePublicare

De ce SWE-bench Verified nu mai măsoară capabilitățile de programare de vârf

SWE-bench Verified este din ce în ce mai contaminat. Recomandăm SWE-bench Pro.

Se încarcă…

De când am publicat pentru prima dată SWE-bench Verified în august 2024, a fost folosit pe scară largă pentru a măsura progresul modelelor în sarcini autonome de inginerie software. După lansarea sa, SWE-bench Verified a oferit un semnal puternic al progresului capacităților și a devenit un indicator standard raportat în lansările de modele de vârf. Urmărirea și prognozarea progresului acestor capacități reprezintă, de asemenea, o parte importantă a Cadrului de pregătire OpenAI. Când am creat inițial testul de performanță Verified, am încercat să rezolvăm problemele din evaluarea originală care făceau ca anumite sarcini să fie imposibil de realizat în setul de date SWE-bench(se deschide într-o fereastră nouă).

După salturile inițiale, progresul de ultimă generație în cazul SWE-bench Verified a încetinit, îmbunătățindu-se(se deschide într-o fereastră nouă) de la 74.9% la 80.9% în ultimele 6 luni. Rezultă întrebarea: eșecurile rămase reflectă limitările modelului sau proprietățile setului de date în sine?

Într-o nouă analiză, am identificat două probleme majore cu setul Verified care indică faptul că acest test de performanță nu mai este potrivit pentru măsurarea progresului în ceea ce privește capacitățile de inginerie software autonomă pentru lansări de vârf la nivelurile de performanță de astăzi:

  1. Testele resping soluțiile corecte: am auditat un subset de 27.6% din setul de date pe care modelele adesea nu reușeau să-l rezolve și am constatat că cel puțin 59.4% dintre problemele auditate au cazuri de testare defectuoase care resping trimiteri funcțional corecte, în ciuda eforturilor noastre de a îmbunătăți acest aspect în crearea inițială a SWE-bench Verified.
  2. Instruire pe soluții: deoarece modelele de vârf pot învăța informații din instruirea lor, este important ca acestea să nu fie niciodată instruite pe problemele și soluțiile pe care sunt evaluate. Este ca și cum le-ai dezvălui elevilor problemele și soluțiile unui test înainte de a-l susține: poate că nu vor memora răspunsurile, dar elevii care le-au văzut înainte vor obține cu siguranță rezultate mai bune decât cei care nu le-au văzut. Problemele SWE-bench provin din depozite open-source pe care mulți furnizori de modele le folosesc în scopuri de instruire. În analiza noastră, am constatat că toate modelele de vârf pe care le-am testat au fost capabile să reproducă remedierea originală a bugului, scrisă de un om, folosită ca referință ground-truth, cunoscută drept patch-ul gold sau detalii specifice ale enunțului problemei, cuvânt cu cuvânt, pentru anumite sarcini, ceea ce indică faptul că toate au văzut cel puțin o parte dintre probleme și soluții în timpul instruirii.

Am găsit, de asemenea, dovezi că modelele care au observat problemele în timpul instruirii au șanse mai mari să reușească, deoarece au informații suplimentare necesare pentru a trece testele insuficient de bine definite.

Aceasta înseamnă că îmbunătățirile aduse testului SWE-bench Verified nu mai reflectă îmbunătățiri semnificative ale capacităților de dezvoltare software ale modelelor în condiții reale. În schimb, ele reflectă din ce în ce mai mult cât de mult a fost expus modelul la respectivul test de performanță în timpul instruirii. De aceea am încetat să mai raportăm scorurile SWE-bench Verified și recomandăm ca și alți dezvoltatori de modele să facă la fel.

Construim evaluări noi, necontaminate, pentru a urmări mai bine capacitățile de programare și considerăm că acesta este un domeniu important pe care să ne concentrăm pentru comunitatea de cercetare în ansamblu. Până când le vom avea, OpenAI recomandă raportarea rezultatelor pentru SWE-bench Pro.

Fundal

Evaluarea originală SWE-bench(se deschide într-o fereastră nouă) a fost lansată în 2023. Fiecare problemă provine dintr-o problemă GitHub rezolvată din unul dintre cele 12 depozite Python open-source și este asociată cu pull requestul (PR) corespunzător. Pentru a determina dacă o modificare de cod generată de un model este corectă, fiecare problemă vine cu două seturi de teste:

  • Teste care eșuează în cazul bazei de cod nemodificate, dar trec dacă problema este remediată corect
  • Teste de regresie care trec atât înainte, cât și după remediere, pentru a asigura că funcționalitatea fără legătură rămâne intactă.

Modelul nu vede testele. Trebuie să producă o modificare de cod având la dispoziție doar textul original al problemei și starea depozitului înainte de remediere. O problemă trece numai dacă toate testele trec după aplicarea modificării de cod.

Am descoperit numeroase probleme legate de evaluarea respectivă, care ar putea duce la subraportarea capacității modelelor.

  • Unele teste unitare erau prea specifice sau nealiniate cu sarcina, așa că remedierile corecte puteau fi respinse.
  • Multe dintre sarcinile de lucru erau insuficient definite, ceea ce putea duce la multiple interpretări valide, în timp ce testele acopereau doar una dintre ele.
  • În funcție de configurarea mediului (de exemplu Linux vs Windows sau versiunea de Python), unele teste ar putea eșua în mod fals

Am creat SWE-bench Verified în 2024 pentru a aborda aceste probleme. Am colaborat cu ingineri software experți pentru a analiza 1.699 de probleme SWE-bench și a filtra problemele care prezentau aceste probleme. Fiecare problemă a fost revizuită de trei experți, în mod independent. Acest proces de revizuire a dus la SWE-bench Verified, un set selectat de 500 de probleme.

Teste prea restrânse și teste prea extinse

Deși SWE-bench Verified este o îmbunătățire majoră față de versiunea inițială, persistă probleme reziduale. Am efectuat un audit al 138 de probleme SWE-bench Verified pe care OpenAI o3 nu le-a rezolvat în mod consecvent pe parcursul a 64 de rulări independente. Fiecare caz a fost revizuit independent de cel puțin șase ingineri software cu experiență. Dacă un expert a semnalat o problemă, aceasta a fost reverificată de o echipă suplimentară.

Am constatat că 59.4% dintre cele 138 de probleme conțineau probleme materiale în proiectarea testului și/sau descrierea problemei, ceea ce le făcea extrem de dificil sau imposibil de rezolvat chiar și de către cel mai capabil model sau om. 

  • 35.5% dintre sarcinile auditate au cazuri de testare stricte care impun detalii specifice de implementare, invalidând multe trimiteri corecte din punct de vedere funcțional, pe care le numim cazuri de testare restrictive.
  • 18.8% dintre sarcinile auditate prezintă teste care verifică funcționalități suplimentare care nu au fost specificate în descrierea problemei, pe care le numim cazuri de testare extinse.
  • Restul de 5.1% dintre sarcini au avut probleme diverse care nu au fost bine grupate în această taxonomie.

Un exemplu ilustrativ al primului mod de eșec este pylint-dev__pylint-4551(se deschide într-o fereastră nouă), unde PR-ul introduce o funcție nouă `get_annotation` ca parte a soluției generale. Numele acestei funcții nu este menționat în descrierea problemei, dar este importat direct de teste. Deși unele modele ar putea intui să creeze o astfel de funcție, nu este strict necesar să implementezi o funcție cu acest nume specific pentru a aborda corect problema. Multe soluții valide eșuează la teste din cauza erorilor de import.

Descrierea problemei

Text simplu

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

Fragment de test PR

Python

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

Eșecuri ale testelor PR (trunchiate pentru lizibilitate)

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 exemplu de cazuri de testare prea extinse este sympy__sympy-18199(se deschide într-o fereastră nouă). Această sarcină a fost preluată dintr-un PR care a abordat trei probleme distincte ale funcției `nthroot_mod`, mai exact #17373(se deschide într-o fereastră nouă), #17377(se deschide într-o fereastră nouă) și #18212(se deschide într-o fereastră nouă). Descrierea pentru sarcina SWE-bench Verified, însă, acoperă doar problema finală #18212(se deschide într-o fereastră nouă). Acest lucru creează o neconcordanță: testele din PR acoperă toate cele trei probleme, în timp ce descrierea detaliază doar una. În rulările noastre, modelele implementează adesea corect remedierea descrisă și apoi eșuează la testele care acoperă implementarea pentru celelalte două probleme.

Descrierea originală a PR-ului (din PR-ul GitHub)

Text simplu

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

Descrierea problemei pentru #18212

Text simplu

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.

Descrierea problemei pentru sarcina SWE-bench Verified (preluată doar din #18212):

Text simplu

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.

Contaminare

SWE-bench Verified și depozitele (bazele de cod și notele de lansare) sunt ambele open-source și utilizate și discutate pe scară largă, ceea ce face dificilă evitarea contaminării pentru dezvoltatorii de modele.

Am întâlnit pentru prima dată semne de contaminare în propriile noastre modele. De exemplu, când GPT‑5.2 a rezolvat 31 de sarcini pe care le-am identificat ca fiind aproape imposibil de rezolvat. În cazul django__django-14725(se deschide într-o fereastră nouă), testele necesită un nou parametru specific `edit_only` care nu este cerut în mod explicit de enunțul problemei. În timp ce rezolvă problema, GPT‑5.2 arată în lanțul de gândire că are informații despre notele de lansare care detaliază modificările aduse bazei de cod și identifică corect faptul că parametrul `edit_only` a fost introdus în Django 4.1.

GPT‑5.2 CoT

Text simplu

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.

Pentru a evalua cât de semnificativă este contaminarea la scară mai largă, am creat o configurație automatizată de „red teaming”. Pentru fiecare întrebare SWE-bench Verified, i-am cerut lui GPT‑5 să sondeze GPT‑5.2‑Chat, Claude Opus 4.5 și Gemini 3 Flash Preview pentru contaminare. Aceste modele au fost alese pentru a exclude modelele de raţionament, dar recunoaștem că există probabil un decalaj de capacitate deloc neglijabil între ele.

Pentru a verifica contaminarea, GPT‑5 a primit: ID-ul, descrierea, patch-ul gold și testele PR ale sarcinii SWE-bench Verified. Pe parcursul a 15 runde, am permis ca GPT‑5 să varieze solicitarea sistemului/dezvoltatorului, solicitarea utilizatorului, completarea automată a asistentului și diferite strategii de declanșare. După fiecare rundă, un model evaluator a etichetat cât de multe informații noi specifice sarcinii au apărut, iar fiecare răspuns a fost etichetat în funcție de severitatea contaminării de la „deloc” la „pronunțat.” GPT‑5 a avut permisiunea să-și adapteze strategia pe baza rundelor anterioare pentru a recupera iterativ detalii specifice sarcinii. Pentru fiecare exemplu de contaminare pronunțată, am verificat cu un alt evaluator că GPT‑5 nu a divulgat prea multe informații către modelul țintă. În cele din urmă, am revizuit manual exemplele „pronunțate” care alcătuiesc transcrierile din această postare.

Mai jos sunt exemple de contaminare puternică de la diferiți furnizori de modele.

GPT‑5.2 

Având un fragment scurt din descrierea sarcinii, GPT‑5.2 produce exact patch-ul gold. Mai ales, cunoaște numele exact al clasei și al metodei, precum și noua condiție de returnare timpurie `if username is None or password is None` care este introdusă.

Declanșarea contaminării

Enunțul problemei

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

Solicitarea utilizatorului

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"

Răspunsul modelului

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.

Patch-ul Gold

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 este capabil nu numai să rețină exact modificarea funcțională pe 4 rânduri introdusă de PR, împreună cu numele fișierului și metoda specifică pe care le-a abordat, dar și să citeze ad litteram comentariul în linie care făcea parte din diferență. 

Declanșarea contaminării

Solicitarea utilizatorului

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.

Precompletare

1
Let me be precise about the location and wording.

Răspunsul asistentului

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

Patch-ul Gold

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, atunci când nu i se oferă nicio informație suplimentară despre sarcină în afară de ID, este capabil să redea textual detalii din descrierea sarcinii și din patch-ul gold. Aceasta include noua formulă regex pentru validarea numelui de utilizator și numerele exacte de linie pentru modificare.

Declanșarea contaminării

Enunțul problemei

1
UsernameValidator allows trailing newline in usernames

Solicitarea utilizatorului

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.

Precompletare

1
Let me be precise about the wording.

Răspunsul modelului

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
```

Patch-ul Gold

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

Discuție

Din acest audit al SWE-bench Verified, observăm două lecții mai generale pentru proiectarea evaluărilor. În primul rând, testele de performanță provenite din materiale disponibile public prezintă un risc de contaminare, deoarece expunerea la datele de instruire poate umfla în mod discret scorurile. Dacă datele colectate prin crawling public sunt utilizate în crearea testului de performanță, dezvoltatorii de modele ar trebui să efectueze teste suplimentare pentru contaminare. Testele de performanță, și chiar soluțiile lor, postate public pot ajunge în datele de instruire. Ar trebui acordată o atenție sporită atât modului în care sunt postate seturile de date (de ex., protejat prin parolă) și filtrarea datelor de antrenament (de ex., respectarea strictă a șirurilor canary). 

În al doilea rând, scoringul automatizat este dificil de realizat corect; cazurile de testare perfecte ar trebui să verifice pe deplin funcționalitatea corectă, fiind atât agnostice față de detalii specifice de implementare neimportante, cât și robuste față de soluții de tip scurtătură. Aceste probleme sunt în mod inerent complexe și dificil de rezolvat. Identificarea acestor probleme a necesitat mai multe campanii extinse de etichetare realizate de oameni. 

Am integrat aceste constatări în eforturile noastre recente de evaluare. În ultimele luni am ales să raportăm rezultatele divizării publice a SWE-Bench Pro. Recomandăm ca și alți dezvoltatori de modele să facă la fel. SWE-bench Pro nu este perfect, dar, empiric, pare să prezinte mai puține probleme de contaminare. Canalul nostru de contaminare a descoperit câteva cazuri de contaminare, dar acestea au fost semnificativ mai rare și mai puțin flagrante decât cele verificate prin SWE-bench, și niciun model nu a reușit să producă un patch gold complet și exact pentru a demonstra contaminarea.

Vom continua să investim în teste de performanță originale, create pe plan privat, și vom solicita din partea domeniului nostru și mediului universitar aceeași abordare. În cazul GDPVal, sarcinile sunt redactate în mod privat de experți în domeniu, reducând riscul de expunere, iar soluțiile sunt evaluate holistic de evaluatori instruiți. Această abordare necesită multe resurse, dar este din ce în ce mai necesară pentru a măsura îmbunătățirile reale ale capacităților.

Autor

OpenAI