Преминаване към основното съдържание
OpenAI

23 февруари 2026 г.

ПроучванеПубликация

Защо SWE-bench Verified вече не измерва авангардните способности за кодиране

SWE-bench Verified е все по-компрометиран. Препоръчваме SWE-bench Pro.

Зареждане…

Откакто за първи път публикувахме SWE-bench Verified през август 2024 г., индустрията го използва широко, за да измерва напредъка на моделите при автономни задачи по софтуерно инженерство. След пускането си SWE-bench Verified се утвърди като надежден индикатор за напредък в способностите и се превърна в стандартен показател, докладван при представянето на авангардни модели. Проследяването и прогнозирането на напредъка на тези способности също е важна част от Рамката за готовност на OpenAI. Когато първоначално създадохме еталона Verified, се опитахме да решим проблеми в първоначалното оценяване, които правеха определени задачи невъзможни за изпълнение в набора от данни SWE-bench(отваря се в нов прозорец).

След първоначалните скокове, най-съвременният напредък по SWE-bench Verified се е забавил, подобрявайки(отваря се в нов прозорец) се от 74,9% до 80,9% през последните 6 месеца. Това повдига въпроса: отразяват ли останалите неуспехи ограничения на модела или свойства на самия набор от данни?

В нов анализ установихме два основни проблема с набора Verified, които показват, че еталонът вече не е подходящ за измерване на напредъка в автономните способности за софтуерно инженерство при авангардните модели при днешните нива на производителност:

  1. Тестовете отхвърлят правилни решения: Одитирахме 27.6% подмножество от набори от данни, което моделите често не успяваха да решат, и установихме, че поне 59.4% от одитираните задачи имат дефектни тестови случаи, които отхвърлят функционално правилни решения, въпреки най-добрите ни усилия да подобрим това при първоначалното създаване на SWE-bench Verified.
  2. Обучение върху решения: Тъй като големите авангардни модели могат да усвояват информация от обучението си, е важно никога да не се обучават върху задачите и решенията, по които се оценяват. Това е подобно на това да споделиш с учениците задачи и решения за предстоящ тест преди самия тест – може и да не запомнят отговора, но учениците, които са виждали отговорите преди, със сигурност ще се справят по-добре от тези, които не са. Задачите за SWE-bench са взети от хранилища с отворен код, които много доставчици на модели използват за целите на обучението. В нашия анализ установихме, че всички авангардни модели, които тествахме, са били в състояние да възпроизведат оригиналната, написана от човек корекция на бъг, използвана като достоверна отправна точка, известна като златната корекция, или дословни специфики от формулировката на проблема за определени задачи, което показва, че всички те са виждали поне част от проблемите и решенията по време на обучението.

Също така открихме доказателства, че моделите, които са виждали задачите по време на обучението, е по-вероятно да успеят, защото разполагат с допълнителната информация, необходима за преминаване на недостатъчно конкретизираните тестове.

Това означава, че подобренията в SWE-bench Verified вече не отразяват значими подобрения в реалните способности на моделите за разработка на софтуер. Вместо това те все повече отразяват доколко моделът е бил изложен на еталона по време на обучението. Ето защо спряхме да отчитаме резултатите на SWE-bench Verified и препоръчваме и на други разработчици на модели да направят същото.

Изграждаме нови, некомпроментирани начини за оценяване, за да проследяваме по-добре уменията за програмиране и смятаме, че това е важна област, върху която по-широката изследователска общност да се съсредоточи. Докато не разполагаме с тях, OpenAI препоръчва да се отчитат резултатите от SWE-bench Pro.

Фон

Оригиналната оценка SWE-bench(отваря се в нов прозорец) беше публикувана през 2023 г. Всяка задача е взета от разрешен проблем в GitHub в едно от 12 хранилища с отворен код на Python и е сдвоена със съответната pull заявка(PR). За да се определи дали промяна в кода, генерирана от модел, е правилна, всяка задача идва с два набора от тестове:

  • Тестове, които се провалят при непроменената кодова база, но преминават, ако проблемът е коректно отстранен
  • Регресионни тестове, които преминават успешно както преди, така и след поправката, за да се гарантира, че оставащата функционалност остава непокътната.

Моделът не вижда тестовете. Той трябва да промени кода, като разполага само с оригиналния текст на задачата и състоянието на хранилището преди поправката. Той преминава задача само ако всички тестове преминат успешно след прилагане на промяната в кода.

Открихме много проблеми с тази оценка, които биха могли да доведат до подценяване на способностите на моделите.

  • Някои единични тестове бяха твърде конкретни или не съответстваха на задачата, затова правилните поправки можеха да бъдат отхвърлени.
  • Много от формулировките на задачите не бяха достатъчно конкретизирани, което можеше да доведе до множество валидни интерпретации – докато тестовете обхващаха само една конкретна.
  • В зависимост от настройката на средата (например Linux спрямо Windows или версията на Python), някои тестове може да се провалят погрешно

Създадохме SWE-bench Verified през 2024 г., за да се справим с тези проблеми. Работихме с експертни софтуерни инженери, за да прегледаме 1699 задачи от SWE-bench и да отсеем задачите, които имаха тези проблеми. Всеки проблем беше прегледан от трима експерти независимо. Този процес на преглед доведе до SWE-bench Verified, подбран набор от 500 проблема.

Твърде конкретни и твърде общи тестове

Въпреки че SWE-bench Verified е голямо подобрение спрямо първоначалната версия, остават остатъчни проблеми. Проведохме одит на 138 задачи от SWE-bench Verified, на които OpenAI o3 се проваляше постоянно в рамките на 64 независими изпълнения. Всеки случай беше прегледан независимо от поне шестима опитни софтуерни инженери. Ако задачата бе отбелязана от експерт, тя беше повторно проверена от допълнителен екип.

Установихме, че 59,4% от 138-те задачи съдържат съществени проблеми в дизайна на теста и/или описанието на задачата, което ги прави изключително трудни или невъзможни за решаване дори за най-способния модел или човек. 

  • 35,5% от проверените задачи включват прекалено строги тестови случаи, изискващи специфични детайли на реализацията, което води до отхвърляне на множество функционално правилни решения – т.нар. тесни тестови случаи.
  • 18,8% от одитираните задачи имат тестове, които проверяват за допълнителна функционалност, която не е посочена в описанието на задачата и която наричаме широки тестови случаи.
  • Останалите 5,1% от задачите съдържаха разнородни проблеми, които не бяха добре групирани в тази класификация.

Илюстративен пример за първия режим на отказ е pylint-dev__pylint-4551(отваря се в нов прозорец), където pull заявката въвежда нова функция `get_annotation` като част от цялостното решение. Това име на функция не е споменато в описанието на задачата, но се импортира директно от тестовете. Въпреки че някои модели може интуитивно да създадат такава функция, не е строго необходимо да се внедри функция с това конкретно име, за да се адресира правилно проблемът. Много валидни решения не преминават тестовете поради грешки при импортиране.

Описание на задачата

Обикновен текст

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

Тестов фрагмент за pull заявка

Python

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

Неуспехи при PR тестовете (съкратено за по-лесно четене)

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)

Пример за твърде широки тестови случаи е sympy__sympy-18199(отваря се в нов прозорец). Тази задача беше извлечена от PR, която адресира три отделни проблема с функцията `nthroot_mod`, по-специално #17373(отваря се в нов прозорец), #17377(отваря се в нов прозорец) и #18212(отваря се в нов прозорец). Описанието за задачата SWE-bench Verified обаче обхваща само последния проблем #18212(отваря се в нов прозорец). Това създава несъответствие: тестовете в PR обхващат и трите проблема, докато описанието описва подробно само един. В нашите изпълнения моделите често правилно прилагат описаната корекция и след това не преминават тестовете, които покриват имплементацията за другите два проблема.

Оригинално описание на pull заявката (от pull заявката в GitHub)

Обикновен текст

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

Описание на задачата за #18212

Обикновен текст

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.

Описание на задачата за задача SWE-bench Verified (взето само от #18212):

Обикновен текст

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.

Компрометираност

SWE-bench Verified е проверен и хранилищата (кодови бази и бележки по изданието) са както с отворен код, така и широко използвани и обсъждани, което прави избягването на компрометиране трудно за разработчиците на модел.

Първо срещнахме признаци на компроментиране в собствените си модели. Например, когато GPT‑5.2 реши 31 задачи, които бяхме идентифицирали като почти невъзможни за решаване. В django__django-14725(отваря се в нов прозорец) тестовете изискват конкретен нов параметър `edit_only`, който не е изрично изискан от формулировката на проблема. Докато решава проблема, GPT‑5.2 показва в своето логическо мислене, че разполага с информация за бележките към изданието, които описват промените в кодовата база, и правилно идентифицира, че параметърът `edit_only` е въведен в Django 4.1.

GPT‑5.2 CoT

Обикновен текст

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.

За да оценим колко значимо е компроментирането в по-широк план, създадохме автоматизирана настройка за стрес тест. За всеки въпрос от SWE-bench Verified възложихме на GPT‑5 да тества GPT‑5.2‑Chat, Claude Opus 4.5 и Gemini 3 Flash Preview за замърсяване. Тези модели бяха избрани, за да се изключат модели със структурирано анализиране, но признаваме, че между тях вероятно има нетривиална разлика в способностите.

За да се провери за компроментиране, GPT‑5 получи: ID на задачата в SWE-bench Verified, описание, gold patch и PR tests. В рамките на над 15 хода позволихме на GPT‑5 да варира системната/разработчическата подкана, потребителската подкана и предварителното попълване на асистента, както и различни стратегии за извличане. След всеки ход, модел съдия обозначаваше колко нова специфична за задачата информация се е появила и всеки отговор беше оценяван за тежест на компроментирането от „няма“ до „силно“. На GPT‑5 беше позволено да адаптира стратегията си въз основа на предишни ходове, за да възстановява итеративно специфични за задачата подробности. За всеки пример за силно компроментиране проверихме с друг съдия, че GPT‑5 не е изтекъл твърде много информация към целевия модел. Накрая ръчно прегледахме „силните“ примери, които съставляват транскрипциите в тази публикация.

По-долу са дадени примери за силно компрометиране при различни доставчици на модели.

GPT‑5.2 

Като се даде кратък откъс от описанието на задачата, GPT‑5.2 извежда точния златен пач. По-конкретно, то знае точното име на класа и метода, както и новото условие за ранно връщане `if username is None or password is None`, което се въвежда.

Идентифициране на компрометираност

Описание на задачата

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

Потребителска подкана

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"

Отговор на модела

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.

Златен пач

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 е в състояние не само да си припомни точната 4-редова функционална промяна, която PR въведе, заедно с конкретното име на файла и метода, които е засегнал, но също така цитира дословно коментара, който беше част от разликата. 

Идентифициране на компрометираност

Потребителска подкана

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.

Предварително попълване

1
Let me be precise about the location and wording.

Отговор на асистента

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

Златен пач

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 е в състояние да изведе дословно подробности от описанието на задачата и златния пач. Това включва новата формула за регулярно изразяване за валидиране на потребителско име и точните номера на редовете за промяната.

Идентифициране на компрометираност

Описание на задачата

1
UsernameValidator allows trailing newline in usernames

Потребителска подкана

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.

Предварително попълване

1
Let me be precise about the wording.

Отговор на модела

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

Златен пач

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

Дискусия

От този одит на SWE-bench Verified виждаме два по-общи извода за дизайна на оценяването. Първо, еталоните, извлечени от публично достъпни материали, носят риск от компроментиране, при който излагането на данни за обучение може незабелязано да завиши резултатите. Ако при изграждането на еталона се използват публично обходени данни, разработчиците на моделите трябва да проведат допълнителни тестове за компроментиране. Публично публикуваните еталони, и дори и техните решения, могат да попаднат в данни за обучение. Трябва да се полагат допълнителни грижи както за начина, по който се публикуват наборите от данни (т.е. защитено с парола), така и за филтриране на данните за обучение (i.e. стриктно придържане към канарски низове). 

Второ, автоматизираното оценяване е трудно да се направи правилно; перфектните тестови случаи трябва напълно да проверяват коректната функционалност, като са едновременно независими от конкретни маловажни детайли на прилагането и също така устойчиви на решения с преки пътища. Тези проблеми са по своята същност сложни и трудни за решаване. Засичането на тези проблеми изискваше множество обширни кампании за човешко анотиране. 

Включихме тези констатации в нашите скорошни усилия за оценка. През последните месеци избрахме да докладваме резултати от публичното разделение на SWE-Bench Pro. Препоръчваме и на други разработчици на модели да направят същото. SWE-bench Pro не е перфектен, но емпирично изглежда да има по-малко проблеми с компроментиране. Нашият метод за откриване на компроментиране установи някои случаи, но те бяха значително по-редки и по-малко фрапиращи от SWE-bench Verified, и нито един модел не успя да произведе пълен дословен златен пач.

Ще продължим да инвестираме в оригинални, частно разработени еталони и ще търсим помощ от индустрията и академичните среди, за да правят същото. В GDPVal задачите се създават поверително от експерти в областта, което намалява риска от излагане, а решенията се оценяват цялостно от обучени рецензенти. Този подход е ресурсоемък, но все по-необходим за измерване на реални подобрения във възможностите.

Автор

OpenAI