Pasar al contenido principal
OpenAI

23 de febrero de 2026

InvestigaciónPublicación

Por qué SWE-bench Verified ya no mide las capacidades de programación de vanguardia

SWE-bench Verified está cada vez más contaminado. Recomendamos SWE-bench Pro.

Cargando...

Desde que publicamos por primera vez SWE-bench Verified en agosto de 2024, la industria lo ha utilizado ampliamente para medir el progreso de los modelos en tareas de ingeniería de software autónoma. Tras su lanzamiento, SWE-bench Verified proporcionó una señal sólida del progreso de las capacidades y se convirtió en una métrica estándar informada en los lanzamientos de modelos de vanguardia. El seguimiento y la previsión del progreso de estas capacidades también es una parte importante del Marco de preparación de OpenAI. Cuando creamos inicialmente la prueba de referencia de Verified, intentamos resolver problemas en la evaluación original que hacían que ciertas tareas fueran imposibles de realizar en el conjunto de datos de SWE-bench(se abre en una nueva ventana).

Tras los avances iniciales, el progreso de vanguardia en SWE-bench Verified se ha ralentizado, con una mejora(se abre en una nueva ventana) del 74,9 % al 80,9 % en los últimos 6 meses. Esto plantea la siguiente pregunta: ¿Los fallos restantes reflejan limitaciones del modelo o propiedades del propio conjunto de datos?

En un nuevo análisis, descubrimos dos problemas importantes con el conjunto Verified que indican que la prueba de referencia ya no es adecuada para medir el progreso en capacidades de ingeniería de software autónoma para lanzamientos de vanguardia en los niveles de rendimiento actuales:

  1. Las pruebas rechazan soluciones correctas: Auditamos un subconjunto del 27,6 % del conjunto de datos que los modelos a menudo no lograban resolver y descubrimos que al menos el 59,4 % de los problemas auditados tienen casos de prueba defectuosos que rechazan envíos funcionalmente correctos, a pesar de nuestro máximo esfuerzo por mejorarlo en la creación inicial de SWE-bench Verified.
  2. Entrenamiento sobre soluciones: Debido a que los modelos de vanguardia grandes pueden aprender información a partir de su entrenamiento, es importante que nunca se entrenen con los problemas y las soluciones con los que se evalúan. Esto es similar a compartir problemas y soluciones de un examen próximo con los estudiantes antes del examen: quizá no memoricen la respuesta, pero los estudiantes que ya han visto las respuestas sin duda lo harán mejor que quienes no. Los problemas de SWE-bench provienen de repositorios de código abierto que muchos proveedores de modelos utilizan con fines de entrenamiento. En nuestro análisis, descubrimos que todos los modelos de vanguardia que probamos pudieron reproducir la corrección de error original escrita por humanos utilizada como valor de referencia real, conocido como el parche de referencia, o los detalles textuales del planteamiento del problema para ciertas tareas, lo que indica que todos han visto al menos algunos de los problemas y soluciones durante el entrenamiento.

También encontramos evidencia de que los modelos que detectaron los problemas durante el entrenamiento tienen más probabilidades de tener éxito, porque cuentan con información adicional necesaria para superar las pruebas poco específicas.

Esto significa que las mejoras en SWE-bench Verified ya no reflejan mejoras significativas en las capacidades reales de desarrollo de software de los modelos. En cambio, cada vez reflejan más cuánto estuvo expuesto el modelo a la prueba de referencia durante el entrenamiento. Por eso hemos dejado de informar las puntuaciones de SWE-bench Verified y recomendamos que otros desarrolladores de modelos hagan lo mismo.

Estamos desarrollando evaluaciones nuevas sin contaminación para realizar un mejor seguimiento de las capacidades de programación y creemos que es un área importante en la que enfocarse para la comunidad de investigación en general. Hasta que lo logremos, OpenAI recomienda informar los resultados de SWE-bench Pro.

Antecedentes

La evaluación original de SWE-bench(se abre en una nueva ventana) se publicó en 2023. Cada problema proviene de uno resuelto de GitHub en uno de los 12 repositorios de Python de código abierto y se empareja con la pull request (PR) correspondiente. Para determinar si un cambio de código generado por un modelo es correcto, cada problema incluye dos conjuntos de pruebas:

  • Pruebas que fallan en el código base sin modificar, pero se superan si el problema se corrige correctamente
  • Pruebas de regresión que se superan tanto antes como después de la corrección para asegurar que la funcionalidad no relacionada se mantenga intacta.

El modelo no ve las pruebas. Tiene que producir un cambio de código dado solo el texto original del problema y el estado del repositorio antes de la corrección. Solo se aprueba un problema si se superan todas las pruebas después de aplicar el cambio de código.

Encontramos muchos problemas con esa evaluación que podrían llevar a subestimar la capacidad de los modelos.

  • Algunas pruebas unitarias eran demasiado específicas o estaban desalineadas con la tarea, por lo que se podían rechazar correcciones correctas.
  • Muchos planteos de tareas estaban poco especificados, lo que podría dar lugar a múltiples interpretaciones válidas, mientras que las pruebas solo cubrían una específica.
  • Según la configuración del entorno (por ejemplo, Linux vs. Windows o la versión de Python), algunas pruebas podrían fallar de forma engañosa.

Creamos SWE-bench Verified en 2024 para abordar estos problemas. Trabajamos con ingenieros de software expertos para revisar 1699 problemas de SWE-bench y filtrar los problemas que tenían estos inconvenientes. Cada problema fue revisado de forma independiente por tres expertos. Este proceso de revisión dio como resultado SWE-bench Verified, un conjunto curado de 500 problemas.

Pruebas de mucha estrechez y mucha amplitud

Si bien SWE-bench Verified es una gran mejora con respecto a la versión inicial, persisten problemas residuales. Realizamos una auditoría de 138 problemas de SWE-bench Verified que OpenAI o3 no resolvió de manera consistente en 64 ejecuciones independientes. Cada caso fue revisado de forma independiente por al menos seis ingenieros de software experimentados. Si un experto señalaba un problema, un equipo adicional lo volvía a verificar.

Descubrimos que el 59,4 % de los 138 problemas contenían problemas materiales en el diseño de la prueba o la descripción del problema, lo que los hacía extremadamente difíciles o imposibles de resolver incluso para el modelo o humano más capaz.

  • El 35,5 % de las tareas auditadas tienen casos de prueba estrictos que imponen detalles específicos de implementación, lo que invalida muchos envíos funcionalmente correctos, a los que llamamos casos de prueba estrechos.
  • El 18,8 % de las tareas auditadas tienen pruebas que verifican una funcionalidad adicional que no se especificó en la descripción del problema, a lo que llamamos casos de prueba amplios.
  • El 5,1 % restante de las tareas presentaba problemas diversos que no se combinaron bien con esta taxonomía.

Un ejemplo ilustrativo del primer modo de falla es pylint-dev__pylint-4551(se abre en una nueva ventana), donde la PR introduce una nueva función `get_annotation` como parte de la solución general. Este nombre de función no se menciona en la descripción del problema, pero las pruebas lo importan directamente. Si bien algunos modelos podrían intuir crear una función de este tipo, no es estrictamente necesario implementar una función con este nombre específico para abordar correctamente el problema. Muchas soluciones válidas no superan las pruebas debido a errores de importación.

Descripción del problema

Texto plano

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

Fragmento de prueba de PR

Python

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

Fallos de pruebas de PR (truncados para facilitar la lectura)

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 ejemplo de casos de prueba demasiado amplios es sympy__sympy-18199(se abre en una nueva ventana). Esta tarea se originó a partir de una PR que abordó tres problemas distintos con la función `nthroot_mod`, específicamente #17373(se abre en una nueva ventana), #17377(se abre en una nueva ventana) y #18212(se abre en una nueva ventana). Sin embargo, la descripción de la tarea SWE-bench Verified solo cubre el problema final #18212(se abre en una nueva ventana). Esto crea una discrepancia: las pruebas de la PR cubren los tres problemas, mientras que la descripción detalla solo uno. En nuestras ejecuciones, los modelos a menudo implementan correctamente la corrección descrita y, luego, fallan las pruebas que cubren la implementación de los otros dos problemas.

Descripción original de la PR (de la PR de GitHub)

Texto plano

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

Descripción del problema de #18212

Texto plano

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.

Descripción del problema para la tarea de SWE-bench Verified (solo tomada de #18212):

Texto plano

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.

Contaminación

SWE-bench Verified y los repositorios (bases de código y notas de la versión) son de código abierto, y se usan y se discuten ampliamente, lo que dificulta evitar la contaminación de los desarrolladores de modelos.

Primero encontramos señales de contaminación en nuestros propios modelos. Por ejemplo, cuando GPT‑5.2 resolvió 31 tareas que identificamos como casi imposibles de resolver. En django__django-14725(se abre en una nueva ventana) las pruebas requieren un nuevo parámetro específico `edit_only` que no es explícitamente requerido por el planteo del problema. Mientras resolvía el problema, GPT‑5.2 muestra en su cadena de pensamiento que tiene información sobre las notas de la versión que detallan cambios en la base de código e identifica correctamente que el parámetro `edit_only` se introdujo en Django 4.1.

GPT‑5.2 CoT

Texto plano

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.

Para evaluar qué tan significativa es la contaminación de manera más amplia, creamos una configuración automatizada de red teaming. Para cada pregunta de SWE-bench Verified, le pedimos a GPT‑5 que analizara un GPT‑5.2‑Chat, Claude Opus 4.5 y Gemini 3 Flash Preview para detectar contaminación. Estos modelos se eligieron para excluir los modelos de razonamiento, pero reconocemos que probablemente exista una brecha de capacidad no trivial entre ellos.

Para analizar la contaminación, GPT‑5 recibió el ID de la tarea de SWE-bench Verified, la descripción, el parche de referencia y las pruebas de PR. A lo largo de 15 turnos, permitimos que GPT‑5 variara el prompt del sistema/desarrollador, el prompt del usuario, el prellenado del asistente y diferentes estrategias de obtención. Después de cada turno, un modelo juez etiquetó cuánta información novedosa específica de la tarea apareció y cada respuesta se etiquetó según la gravedad de la contaminación, de “ninguna” a “mucha”. Se permitió que GPT‑5 adaptara su estrategia en función de los turnos anteriores para recuperar de forma iterativa detalles específicos de la tarea. Para cada ejemplo de mucha contaminación, verificamos con otro juez que GPT‑5 no filtrara demasiada información al modelo objetivo. Por último, revisamos manualmente los ejemplos “de mucha contaminación” que conforman las transcripciones en esta publicación.

A continuación, se muestran ejemplos de gran contaminación en diferentes proveedores de modelos.

GPT‑5.2 

Dado un fragmento breve de la descripción de la tarea, GPT‑5.2 genera el parche exacto de referencia. En particular, conoce el nombre exacto de la clase y del método, así como la nueva condición de retorno anticipado `if username is None or password is None` que se introduce.

Obtención de contaminación

Planteo del problema

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

Consulta del usuario

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"

Respuesta del modelo

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.

Parche de referencia

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 no solo puede recordar el cambio funcional exacto de 4 líneas que introdujo la PR, junto con el nombre de archivo y el método específicos que tocó, sino que también cita textualmente el comentario en línea que formaba parte de la diferencia. 

Obtención de contaminación

Consulta del usuario

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.

Prellenado

1
Let me be precise about the location and wording.

Respuesta del asistente

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

Parche de referencia

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, cuando no se le proporciona más información sobre la tarea además del ID, es capaz de reproducir textualmente detalles de la descripción de la tarea y del parche de referencia. Esto incluye la nueva fórmula de regex para la validación del nombre de usuario y los números de línea exactos del cambio.

Obtención de contaminación

Planteo del problema

1
UsernameValidator allows trailing newline in usernames

Consulta del usuario

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.

Prellenado

1
Let me be precise about the wording.

Respuesta del modelo

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

Parche de referencia

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

Discusión

A partir de esta auditoría de SWE-bench Verified, observamos dos lecciones más amplias para el diseño de evaluaciones. Primero, las pruebas de referencia obtenidas de material disponible al público conllevan un riesgo de contaminación, donde la exposición a los datos de entrenamiento puede inflar silenciosamente las puntuaciones. Si se utilizan datos rastreados públicamente en la creación de una prueba de referencia, los desarrolladores de modelos deben realizar pruebas adicionales para detectar contaminación. Las pruebas de referencias, e incluso sus soluciones, publicadas públicamente pueden derivar en datos de entrenamiento. Se debe tener especial cuidado tanto en cómo se publican los conjuntos de datos (es decir, protegidos con contraseña) y en cómo se filtran los datos de entrenamiento (es decir, estricto cumplimiento de cadenas canario). 

En segundo lugar, la calificación automatizada correcta resulta complicada; los casos de prueba perfectos deberían verificar plenamente la funcionalidad correcta, siendo tanto agnósticos a detalles específicos e irrelevantes de la implementación como también robustos frente a soluciones de atajo. Estos problemas son inherentemente complejos y difíciles de resolver. Detectar estos problemas requirió múltiples campañas extensas de etiquetado humano. 

Hemos incorporado estos hallazgos en nuestras iniciativas recientes de evaluación. En los últimos meses hemos optado por informar resultados de la división pública de SWE-Bench Pro. Recomendamos que otros desarrolladores de modelos hagan lo mismo. SWE-bench Pro no es perfecto, pero empíricamente parece presentar menos problemas de contaminación. Nuestro proceso de detección de contaminación encontró algunos casos de contaminación, pero dichos casos fueron mucho menos frecuentes y menos graves que en SWE-bench Verified, y ningún modelo pudo producir un parche de referencia completo y literal.

Seguiremos invirtiendo en pruebas de referencia originales, de autoría privada, y pediremos ayuda a la industria y al mundo académico para que hagan lo mismo. En GDPVal, las tareas son creadas de forma privada por expertos en la materia, lo que reduce el riesgo de exposición, y las soluciones se evalúan de manera integral por revisores capacitados. Este enfoque requiere muchos recursos, pero es cada vez más necesario para medir mejoras genuinas en las capacidades.

Autor

OpenAI