Saltar para o conteúdo principal
OpenAI

23 de fevereiro de 2026

InvestigaçãoPublicação

Porque é que o SWE-bench Verified deixou de medir as capacidades de programação de ponta

SWE-bench Verified está cada vez mais contaminado. Recomendamos o SWE-bench Pro.

A carregar…

Desde que publicámos pela primeira vez o SWE-bench Verified, em agosto de 2024, a indústria tem utilizado amplamente este benchmark para medir o progresso dos modelos em tarefas de engenharia de software autónoma. Após o seu lançamento, o SWE-bench Verified forneceu um sinal forte de progresso nas capacidades e tornou-se uma métrica padrão reportada nos lançamentos de modelos de ponta. Acompanhar e prever o progresso destas capacidades é também uma parte importante do trabalho do Preparedness Framework da OpenAI. Quando criámos inicialmente o benchmark Verified, procurámos resolver problemas na avaliação original que tornavam certas tarefas impossíveis de realizar no conjunto de dados SWE-bench(abre numa nova janela).

Após os avanços iniciais, o progresso de ponta no SWE-bench Verified abrandou, melhorando(abre numa nova janela) de 74,9% para 80,9% nos últimos 6 meses. Isto levanta a questão: as falhas restantes refletem limitações do modelo ou características do próprio conjunto de dados?

Numa nova análise, identificámos dois problemas principais no conjunto Verified que indicam que o benchmark já não é adequado para medir o progresso nas capacidades autónomas de engenharia de software em lançamentos de modelos de ponta, aos níveis de desempenho atuais:

  1. Os testes rejeitam soluções corretas: auditámos 27,6% do conjunto de dados que os modelos frequentemente não conseguiam resolver e verificámos que, pelo menos, 59,4% dos problemas auditados apresentam casos de teste defeituosos que rejeitam submissões funcionalmente corretas, apesar dos nossos esforços em melhorar isto durante a criação inicial do SWE-bench Verified.
  2. Treino com soluções: como os grandes modelos de ponta podem aprender informações durante o treino, é importante que nunca sejam treinados com problemas e soluções sobre os quais vão ser avaliados. Isto é semelhante a partilhar problemas e soluções de um teste futuro com os alunos antes do teste — eles podem não memorizar a resposta, mas os alunos que já viram as respostas certamente terão um desempenho melhor do que aqueles que não as viram. Os problemas do SWE-bench são provenientes de repositórios open-source que muitos fornecedores de modelos utilizam para fins de treino. Na nossa análise, verificámos que todos os modelos de ponta que testámos conseguiram reproduzir a correção de bug original escrita por humanos, utilizada como referência de verdade fundamental (gold patch), ou detalhes literais do enunciado do problema para certas tarefas, indicando que todos eles tiveram contacto, pelo menos com alguns dos problemas e soluções durante o treino.

Verificámos igualmente que os modelos expostos aos problemas durante o treino apresentam maior taxa de sucesso, por beneficiarem de informação adicional indispensável para satisfazer testes com especificação insuficiente.

Isto significa que as melhorias no SWE-bench Verified já não refletem melhorias significativas nas capacidades reais dos modelos em desenvolvimento de software. Em vez disso, refletem cada vez mais o grau de exposição do modelo ao benchmark durante o treino. É por isso que deixámos de reportar resultados no SWE-bench Verified e recomendamos que outros programadores de modelos façam o mesmo.

Estamos a desenvolver novas avaliações, livres de contaminação, para acompanhar de forma mais fiável as capacidades de programação, e acreditamos que este é um domínio importante em que a comunidade de investigação em geral deve concentrar-se. Enquanto não as tivermos, a OpenAI recomenda divulgar os resultados do SWE-bench Pro.

Fundo

A avaliação original SWE-bench(abre numa nova janela) foi lançada em 2023. Cada problema provém de um issue resolvido no GitHub, em um dos 12 repositórios open-source de Python, e está associado ao pull request (PR) correspondente. Para determinar se uma alteração de código gerada por um modelo está correta, cada problema inclui dois conjuntos de testes:

  • Testes que falham na base de código não modificada, mas passam se o problema for corrigido corretamente
  • Testes de regressão que passam tanto antes como depois da correção, para garantir que funcionalidades não relacionadas se mantêm intactas.

O modelo não vê os testes. Tem de produzir uma alteração de código com base apenas no texto do problema original e no estado do repositório antes da correção. Um problema é considerado resolvido apenas se, depois de aplicada a modificação de código, todos os testes forem bem-sucedidos.

Identificámos vários problemas nessa avaliação que podem levar a uma subestimação das capacidades dos modelos.

  • Alguns testes unitários eram demasiado específicos ou estavam desalinhados com a tarefa, pelo que correções corretas poderiam ser rejeitadas.
  • Muitas descrições de tarefas estavam insuficientemente especificadas, o que podia levar a múltiplas interpretações válidas — enquanto os testes apenas cobriam uma interpretação específica.
  • Dependendo da configuração do ambiente (por exemplo, Linux vs Windows, ou a versão do python), alguns testes podiam apresentar falhas indevidas

Criámos o SWE-bench Verified em 2024 para resolver estes problemas. Trabalhámos com engenheiros de software especialistas para rever 1.699 problemas do SWE-bench e filtrar aqueles que apresentavam estes problemas. Cada problema foi revisto por três especialistas de forma independente. Este processo de revisão resultou no SWE-bench Verified, um conjunto selecionado de 500 problemas.

Testes demasiado restritivos e demasiado permissivos

Embora o SWE-bench Verified seja uma grande melhoria em relação à versão inicial, ainda persistem problemas residuais. Realizámos uma auditoria a 138 problemas do SWE-bench Verified que a OpenAI o3 não conseguiu resolver de forma consistente em 64 execuções independentes. Cada caso foi revisto de forma independente por, pelo menos, seis engenheiros de software experientes. Se um especialista sinalizou um problema, este foi verificado novamente por uma equipa adicional.

Verificámos que 59,4% dos 138 problemas continham problemas significativos no desenho dos testes e/ou na descrição das tarefas, tornando-os extremamente difíceis ou mesmo impossíveis de resolver, mesmo para o modelo ou humano mais capaz. 

  • 35,5% das tarefas auditadas possuem casos de teste rigorosos que impõem detalhes específicos de implementação, invalidando muitas submissões funcionalmente corretas, aos quais chamamos casos de teste restritivos.
  • 18,8% das tarefas auditadas possuem testes que verificam funcionalidades adicionais que não estavam especificadas na descrição do problema, aos quais chamamos casos de teste abrangentes.
  • Os restantes 5,1% das tarefas apresentavam problemas diversos que não se enquadravam bem nesta taxonomia.

Um exemplo ilustrativo do primeiro modo de falha é pylint-dev__pylint-4551(abre numa nova janela), em que o PR introduz uma nova função `get_annotation` como parte da solução global. Este nome de função não é mencionado na descrição do problema, mas é importado diretamente pelos testes. Embora alguns modelos possam intuir a necessidade de criar tal função, não é estritamente necessário implementar uma função com este nome específico para resolver corretamente o problema. Muitas soluções válidas falham nos testes devido a erros de importação.

Descrição do problema

Texto simples

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

Excerto de teste de PR

Python

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

Falhas de testes de PR (truncado para facilitar a leitura)

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)

Um exemplo de casos de teste demasiado abrangentes é sympy__sympy-18199(abre numa nova janela). Esta tarefa teve origem num PR que abordou três problemas distintos com a função `nthroot_mod`, especificamente #17373(abre numa nova janela), #17377(abre numa nova janela) e #18212(abre numa nova janela). A descrição da tarefa SWE-bench Verified, no entanto, abrange apenas o problema final #18212(abre numa nova janela). Isto cria uma discrepância: os testes do PR abrangem os três problemas, enquanto a descrição detalha apenas um. Nas nossas execuções, os modelos frequentemente implementam corretamente a correção descrita e depois falham nos testes que abrangem a implementação das outras duas questões.

Descrição original do PR (do PR do GitHub)

Texto simples

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

Descrição do problema para #18212

Texto simples

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.

Descrição do problema para a tarefa SWE-bench Verified (retirada apenas de #18212):

Texto simples

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.

Contaminação

O SWE-bench Verified e os repositórios (bases de código e notas de lançamento) são ambos open-source e amplamente utilizados e discutidos, o que torna difícil evitar a contaminação para os desenvolvedores de modelos.

Encontrámos pela primeira vez sinais de contaminação nos nossos próprios modelos. Por exemplo, quando o GPT‑5.2 resolveu 31 tarefas que identificámos como quase impossíveis de resolver. Em django__django-14725(abre numa nova janela) os testes exigem um novo parâmetro específico `edit_only` que não é explicitamente exigido pelo enunciado do problema. Ao resolver o problema, o GPT‑5.2 demonstra na sua cadeia de raciocínio que possui informações sobre as notas de versão que detalham alterações na base de código, e identifica corretamente que o parâmetro `edit_only` foi introduzido no Django 4.1.

GPT‑5.2 CoT

Texto simples

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 avaliar quão significativa é a contaminação de forma mais ampla, criámos uma configuração automatizada de red-teaming. Para cada questão do SWE-bench Verified, incumbimos o GPT‑5 de sondar um GPT‑5.2‑Chat, Claude Opus 4.5 e Gemini 3 Flash Preview para contaminação. Estes modelos foram escolhidos para excluir modelos de raciocínio, mas reconhecemos que provavelmente existe uma diferença de capacidades significativa entre eles.

Para investigar a contaminação, o GPT‑5 recebeu: o ID da tarefa do SWE-bench Verified, a descrição, a correção de referência (gold patch) e os testes do PR. Ao longo de 15 interações, permitimos que o GPT‑5 variasse o system/developer prompt, o user prompt, o preenchimento inicial do assistente (assistant prefill) e diferentes estratégias de elicitação. Após cada turno, um modelo juiz avaliou a quantidade de informação nova e específica da tarefa que apareceu, e cada resposta foi classificada quanto à gravidade da contaminação, de “nenhuma” a “forte”. O GPT‑5 teve permissão para adaptar a sua estratégia com base em vezes anteriores para recuperar iterativamente detalhes específicos da tarefa. Para cada exemplo de contaminação forte, verificámos com outro juiz que o GPT‑5 não divulgou demasiada informação ao modelo de destino. Por fim, revimos manualmente os exemplos “fortes” que constituem as transcrições desta publicação.

Abaixo estão exemplos de forte contaminação entre diferentes fornecedores de modelos.

GPT‑5.2 

Dado um pequeno excerto da descrição da tarefa, o GPT‑5.2 gera a correção de referência exata. Em particular, ele sabe o nome exato da classe e do método, e a nova condição de retorno antecipado `se o nome de utilizador é Nenhum ou a palavra-passe é Nenhum` que é introduzida.

Deteção de contaminação

Enunciado do problema

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

prompt do utilizador

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"

Resposta do 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.

Correção de referência

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 

O Opus consegue não só recordar a alteração funcional de 4 linhas que o PR introduziu, juntamente com o ficheiro e o método específicos que foram afetados, como também cita literalmente o comentário inline que fazia parte do diff. 

Deteção de contaminação

Prompt do utilizador

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.

Preencher automaticamente

1
Let me be precise about the location and wording.

Resposta do 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

Correção de referência

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 

O Gemini 3 Flash, quando não recebe qualquer informação adicional sobre a tarefa além do ID, consegue reproduzir literalmente detalhes da descrição da tarefa e da correção de referência. Isto inclui a nova expressão regular para validação de nomes de utilizador e os números exatos das linhas da alteração.

Deteção de contaminação

Enunciado do problema

1
UsernameValidator allows trailing newline in usernames

prompt do utilizador

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.

Preencher automaticamente

1
Let me be precise about the wording.

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

Correção de referência

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

Discussão

A partir desta auditoria ao SWE-bench Verified, retiramos duas lições mais amplas sobre o desenho de avaliações. Em primeiro lugar, os benchmarks obtidos a partir de material publicamente disponível apresentam risco de contaminação, uma vez que a exposição aos dados de treino pode inflacionar os resultados de forma silenciosa. Se forem utilizados dados recolhidos publicamente na construção do benchmark, os desenvolvedores de modelos devem realizar testes adicionais para deteção de contaminação. Os benchmarks, e até as suas soluções, quando publicados publicamente, podem acabar por integrar os dados de treino. Deve ser prestada especial atenção tanto à forma como os conjuntos de dados são publicados (por exemplo, protegidos por palavra-passe) como à filtragem dos dados de treino (i.e. cumprimento rigoroso de canary strings). 

Em segundo lugar, a pontuação automática é difícil de acertar; os testes ideais devem verificar totalmente a funcionalidade correta, sendo ao mesmo tempo independentes de detalhes de implementação irrelevantes e resistentes a soluções de atalho. Estes problemas são inerentemente complexos e difíceis de resolver. Identificar estes problemas exigiu várias campanhas extensas de anotação humana. 

Incorporámos estas conclusões nos nossos esforços de avaliação mais recentes. Nos últimos meses, optámos por reportar os resultados da divisão pública do SWE-Bench Pro. Recomendamos que outros programadores de modelos façam o mesmo. O SWE-bench Pro não é perfeito, mas empiricamente parece apresentar menos problemas de contaminação. O nosso sistema de deteção de contaminação identificou alguns casos, mas estes eram significativamente mais raros e menos graves do que no SWE-bench Verified, e nenhum modelo conseguiu produzir uma correção de referência completa e literal.

Continuaremos a investir em benchmarks originais, de autoria privada, e a pedir ajuda à indústria e à academia para fazerem o mesmo. No GDPVal, as tarefas são elaboradas de forma privada por especialistas da área, reduzindo o risco de exposição, e as soluções são avaliadas de forma holística por revisores treinados. Esta abordagem exige muitos recursos, mas é cada vez mais necessária para medir as verdadeiras melhorias de capacidade.

Autor

OpenAI