CheckerBench: sintetizar checkers de análisis estático sigue siendo trabajo largo — 32,30% de Pass@1 medio y 45,33% el mejor de 21 configuraciones
TL;DR
- Verificado (abstract y §5.2 del paper): CheckerBench mide si un agente de código sabe sintetizar un checker de análisis estático reutilizable a partir de un CVE real. En 21 configuraciones (7 modelos × 3 harnesses, 3 repeticiones por configuración), el Pass@1 medio es 32,30%; la mejor configuración, Claude Opus 4.8 con OpenCode, llega al 45,33%. Con la mejor combinación sobre la mesa, más de la mitad de las tareas sigue fallando.
- Verificado (§5.2, Tabla 2): compilar no es pasar. La pirámide media es 78,25% de builds correctos → 73,65% de diffs válidos → 32,30% de pases completos. El caso extremo: GPT-5.6 con Hermes Agent consigue 100% de builds y 64% de diffs válidos, y pasa el 23% de las tareas.
- Verificado (§5.2): el harness pesa hasta 10,81 puntos entre extremos (medias de 36,95% en OpenCode, 33,81% en Claude Code y 26,14% en Hermes Agent) y 14,34 puntos para Kimi-K3 entre su mejor y su peor combinación. El modelo solo no explica el resultado.
- Verificado (§5.7): sobre 4.360 runs fallidos, las causas dominantes son agotar el presupuesto de tiempo (25,32%), proceso de síntesis deficiente (22,96%), modelado semántico insuficiente (21,15%) y exceso de falsos positivos (15,96%).
- La lectura práctica: sintetizar una herramienta reutilizable con feedback de compilación es trabajo largo-horizonte que los coding agents actuales no resuelven. Y el criterio que casi ningún benchmark mide — no inundar de falsos positivos — aquí forma parte de la aceptación.
Qué es CheckerBench: de CVE a checker reutilizable
CheckerBench (arXiv 2610.07557, v1 del 06-oct-2026, Hang He et al.; preprint sin revisión por pares en el momento de escribir esto) es un benchmark ejecutable con una pregunta concreta: ¿puede un agente de código escribir, sin intervención humana, un checker de análisis estático que detecte la clase de defecto de un CVE real?
Cada tarea entrega al agente dos revisiones de un repositorio (vulnerable y corregida), un entorno de análisis pineado y un scaffold del checker. La salida no es un patch: es una herramienta reutilizable — un checker de Clang Static Analyzer para C/C++ o una query de CodeQL para Java, Python, JavaScript y Go — que debe señalar el defecto en la revisión vulnerable, callarse en la corregida y no llenar de alertas el resto del repositorio. En palabras del abstract: “an executable benchmark of 300 tasks derived from 297 CVEs across 167 repositories, 85 CWEs, and five language ecosystems”. El reparto: 159 tareas de CSA en C/C++ y 141 de CodeQL (51 de Python, 30 de Java, 30 de JavaScript y 30 de Go).
La diferencia con SWE-bench y derivados no es cosmética. Un patch cierra un incidente; un checker es un activo que se queda en tu CI vigilando esa clase de defecto para siempre. Los autores sitúan el benchmark contra cuatro huecos de los evals existentes (Fig. 2): no centran la tarea en el checker, el horizonte de interacción es corto, el scaffold depende del sistema analizado y las señales de corrección están fragmentadas. Aquí la tarea es larga (inspeccionar el repo, entender el defecto, implementar, refinar con feedback de compilación y análisis) y la aceptación es ejecutable.
Cómo evalúa: reconstrucción independiente y un juez con validación humana
El framework de evaluación, CheckerLab, separa la síntesis interactiva de la verificación: congela el código del checker que envía el agente junto con su traza de ejecución, y después lo reconstruye desde cero en un workspace limpio con el entorno pineado. Pasa solo si hay contraste de diagnóstico entre la revisión vulnerable y la corregida, si la alerta se localiza en el patch y si un escaneo más amplio del repositorio no dispara falsos positivos por encima del umbral.
Un juez LLM (Claude Opus 5) triaja falsos positivos y puntúa calidad de proceso y semántica de la vulnerabilidad. La validación frente a humanos da un κ de Cohen pooled de 0,85, cifra razonable pero que no elimina lo que contaré en limitaciones: el juez comparte familia con uno de los modelos evaluados.
El protocolo: 7 modelos (GPT-5.6-Sol, Claude Opus 4.8, Qwen3.8-Max, DeepSeek-V4-Pro-0813, GLM-5.2, Kimi-K3 e HY4-Preview) × 3 harnesses (OpenCode, Claude Code, Hermes Agent), con sandbox E2B aislada y un presupuesto de 50 minutos de generación activa por run. Pass@1 significa pasar todos los filtros a la primera: semántica, proceso, falsos positivos y terminación normal incluidos.
Los números, verificados
Cifras contrastadas contra el HTML v1 del paper el 09-oct-2026 (secciones entre paréntesis):
| Dato | Valor | Dónde |
|---|---|---|
| Tareas | 300 (297 CVEs, 167 repos, 85 CWEs, 5 ecosistemas) | abstract |
| Reparto | 159 CSA (C/C++) + 141 CodeQL (Py 51, Java 30, JS 30, Go 30) | Apéndice D.1 |
| Configuraciones | 21 = 7 modelos × 3 harnesses, 3 repeticiones | §5.1 |
| Pass@1 medio | 32,30% | abstract, §5.2 |
| Mejor configuración | 45,33% — Claude Opus 4.8 + OpenCode | §5.2 |
| Build medio / diff válido medio | 78,25% / 73,65% | §5.2, Tabla 2 |
| Media por harness | OpenCode 36,95% > Claude Code 33,81% > Hermes Agent 26,14% (Δ 10,81 pp) | §5.2 |
| Falsos positivos (FP_pass) | OpenCode 6,63% vs Claude Code 1,97% | §5.2 |
| Causas de fallo (4.360 runs) | presupuesto 25,32%, proceso 22,96%, semántica 21,15%, FP 15,96% | §5.7 |
| Ablation (DeepSeek-V4-Pro, OpenCode) | Full 39,67% → sin skills 8,33% → sin feedback de ejecución 13,33% → one-shot 0,33% | §5.4 |
| Presupuesto de tiempo | 7,24% @10 min → 26,05% @30 min → 32,30% @50 min; el corte a 40 min captura el 93,02% de los éxitos | §5.5 |
La fila que más debería importarte es la de builds: en media, casi cuatro de cada cinco intentos compilan y el diff apunta al sitio correcto en casi tres de cada cuatro. Y aun así, solo uno de cada tres checkers pasa la evaluación completa.
La pirámide del fallo: compila, el diff vale, y aun así suspende
La brecha entre el 73,65% de diffs válidos y el 32,30% de Pass@1 son 41,35 puntos. ¿Qué se queda en el camino? Todo lo que un build no mide: que el checker entienda el mecanismo del defecto y no un patrón superficial, que el proceso de trabajo sea sound, que los falsos positivos no exploten al escanear repos reales, y que el run termine de forma normal dentro del presupuesto.
El caso de GPT-5.6 con Hermes Agent lo resume: 100% de builds, 64% de diffs válidos, 23% de pases completos. Si tu criterio de éxito es “el agente produjo algo que compila y toca el fichero correcto”, estás midiendo el escalón más bajo de una pirámide cuyo último peldaño es el que tiene valor. El paper lo dice sin rodeos: “more than half of tasks remain unsuccessful even for the strongest configuration”.
El harness pesa hasta 14 puntos: no elijas modelo sin su entorno
Las medias por harness ya dan una diferencia de 10,81 puntos entre OpenCode (36,95%) y Hermes Agent (26,14%). Pero la media esconde lo interesante: la mejor combinación cambia según el modelo. Claude Opus 4.8 es primero con OpenCode; DeepSeek-V4-Pro lidera con Claude Code (38,33%, frente al 35,00% de Opus en ese harness); GPT-5.6 y GLM-5.2 rinden mejor con Claude Code. Y Kimi-K3 cae del 38,67% con OpenCode al 24,33% con Hermes Agent: 14,34 puntos de diferencia por cambiar de entorno con el mismo modelo.
Para quien contrata o monta stacks de agentes, la conclusión es incómoda y barata de aplicar: la unidad de evaluación es el par modelo-harness, no el modelo. El mismo desfase lo vimos en TasteBench con los evals de agentes: el entorno de ejecución no es un detalle de implementación, es parte del sistema bajo prueba. DeepSeek-V4-Pro, por cierto, es el modelo que más aparece en las tablas de resultados; tenemos análisis completo de la familia.
Hay un matiz de eficiencia con valor económico: Kimi-K3 es el que menos tool calls necesita en los tres harnesses. Con Claude Code usa 38,61 tool calls de media en runs exitosos frente a 62,50 de DeepSeek (−38,2%) con un Pass@1 casi idéntico (38,00 vs 38,33). A precio de API por llamada, esa diferencia no es ruido.
C/C++ es el sótano común, y es un tercio del dataset
Todos los modelos marcan su mínimo en C/C++, el estrato de CSA que concentra 159 de las 300 tareas. El mejor ahí es DeepSeek-V4-Pro con un 24,53%. Fuera de C/C++ los líderes se reparten: Opus 4.8 en Python (65,36%), DeepSeek en Go (53,33%), Qwen3.8-Max en Java (54,44%) y JavaScript (53,33%).
Que el estrato más grande sea el más difícil explica buena parte del agregado mediocre: el benchmark no es duro “de media”, es duro donde más tareas hay. Si tu interés es el análisis de código interpretado, los números de CodeQL son otra liga; si es C/C++, ningún modelo convence todavía.
Por qué fallan: se acaba el reloj y el plan no sobrevive al código
El análisis de 4.360 runs fallidos (§5.7) da una distribución que cualquier bucle largo de agente reconocerá: agotamiento de presupuesto (25,32%), proceso de síntesis deficiente (22,96%), modelado semántico insuficiente (21,15%) y exceso de falsos positivos (15,96%). El resto: detección o localización diferencial fallida (8,17%), sobreajuste al patch (3,56%), artefactos ausentes o inválidos (1,83%) y problemas de compilación o registro (1,05%).
El ejemplo del paper sobre la brecha plan-implementación es de lo más honesto que he leído en un benchmark este año: “a planned path-sensitive analysis becomes AST matching that omits locking and control-flow conditions”. El agente escribe un plan correcto y luego entrega una aproximación por patrones que se deja lo que hacía valioso el plan. Suena a code review de humana, con la diferencia de que ninguna persona lo firmó.
Sobre falsos positivos, el hallazgo incómodo es que nadie lo clava todo: “No evaluated configuration leads simultaneously in synthesis success, process and semantic quality, and observed diagnostic precision”. OpenCode gana en éxito pero arrastra un 6,63% de FP_pass frente al 1,97% de Claude Code; dentro de OpenCode, Opus 4.8 deja un 13,79% de FP con 174 alertas adjudicadas, mientras GPT-5.6 deja 0,00% con 7. Poca cosa, además, cambia si relajas el umbral de FP: la tasa de aceptación agregada sube solo 0,78 puntos entre el corte del 10% y el del 50% (§5.6).
Skills y presupuesto: lo que pesa en la ablation (con su caveat)
La ablation con DeepSeek-V4-Pro en OpenCode (§5.4) da la jerarquía de dependencias: 39,67% completo, 8,33% sin skill library, 13,33% sin feedback de ejecución y 0,33% en one-shot sin herramientas. La skill library pesa más que el feedback de ejecución en esta configuración, y el one-shot sin herramientas es casi cero: esta tarea es interactiva por diseño.
El propio paper advierte del límite: “Differences between historical and new run conditions prevent attributing the gaps solely to the ablated components”. Las condiciones de los runs históricos y los nuevos no son idénticas, así que los gaps no se pueden atribuir limpiamente a los componentes ablados. Cítalo con el caveat o no lo cites.
En la misma línea, la comparación con baseline (§5.3) en las 61 tareas del kernel de Linux, todo con DeepSeek-V4-Pro: el método skill-guiado de los autores alcanza un 80,3% de checkers válidos, KNighter (el sistema especializado previo) 67,2%, y el agente sin skills 29,5%. El dominio específico, empaquetado como skills, mueve la aguja más que el modelo. Conecta con lo que contamos de skills minadas de repositorios: el activo reutilizable puede no ser el agente, sino lo que sabes meterle en el contexto.
Y el reloj: con 10 minutos de presupuesto el Pass@1 agregado es 7,24%; con 30, 26,05%; con 50, 32,30%. El corte a 40 minutos captura el 93,02% de los éxitos de 50. Si encadenas agentes en flujos largos — el escenario del que hablamos en auto-mejora recursiva y agentes autónomos — el presupuesto de tiempo no es un detalle de infraestructura: es una variable de resultado.
Qué significa si usas coding agents
Primero: calibra expectativas por tipo de tarea. Cerrar un ticket acotado y construir una herramienta reutilizable con verificación adversarial son categorías distintas de trabajo. Los datos dicen que la segunda está en 32,30% de media y 45,33% en el mejor caso. No es “los agentes no saben programar”: es que esta tarea concreta exige plan que sobreviva a la implementación, semántica de vulnerabilidades y control de precisión a la vez.
Segundo: evalúa pares modelo-harness, no modelos. Con hasta 14 puntos de diferencia entre harnesses para el mismo modelo, cualquier decisión de stack basada solo en rankings de modelos está midiendo mal. Lo aplicable a tu contexto: replica tus tareas más frecuentes en dos harnesses y deja que los números decidan.
Tercero: el control de falsos positivos es un criterio de primera clase. Si usas agentes para escribir reglas de linter, queries de CodeQL o tests, añade a tu aceptación una medición de FP sobre código que no debería tocar. Ninguna configuración del benchmark lidera a la vez en éxito y en precisión; asumir que “detecta el bug” implica “no molesta” es exactamente el error que este benchmark pillica.
Cuarto: invierte en skills antes que en cambiar de modelo. La ablation y el baseline apuntan a lo mismo: la biblioteca de skills específicas del dominio es la palanca más gorda, con el caveat metodológico del paper como recordatorio de que la magnitud exacta está por confirmar.
Limitaciones: preprint, juez de la misma familia y un repo sin licencia blanket
Es un preprint v1 (06-oct-2026), sin revisión por pares. Todas las cifras son autoreportadas por los autores sobre APIs cerradas; son una foto, no una propiedad estable.
El juez comparte familia con un evaluado. Claude Opus 5 puntúa a Claude Opus 4.8 entre otros. La validación humana (κ=0,85 pooled) mitiga, pero el paper no discute el posible sesgo intrafamilia. Es observación propia, no declarada: el mismo patrón que señalamos en DecepEval, donde el juez compartía familia con tres evaluados.
La auditoría de contaminación tiene alcance limitado, y sus resultados juegan a favor del benchmark. Tras cruzar fechas de release con fechas de CVE, 3 de las 300 tareas son posteriores al release de Opus 4.8 y 1 al de GLM-5.2. Al sustituir identificadores, el recall exacto de CVEs cae del 10% al 1% (Opus) y del 8% al 1% (DeepSeek), pero el Pass@1 solo baja 2-3 puntos: reconocer el CVE de memoria aporta poco cuando lo que se evalúa es construir un checker. El paper matiza, con razón, que la publicación posterior por sí sola no certifica que una tarea sea inédita para el modelo.
El repo no es “open source” a secas. El paper es CC BY 4.0, pero el repositorio dice: “Third-party source and tools retain their own license files. This repository does not assign a new blanket license to all bundled third-party content.” Y es exigente: Linux x86-64, Docker, Python 3.10+, gh CLI y 100 GB de disco, con imagen congelada (LLVM/Clang 18.1.8, CodeQL 2.26.4). Replicable, sí; ligero, no.
Qué haría yo
- Separa “el agente cierra tareas” de “el agente construye herramientas” en tu planning. Para lo segundo, estos datos dan una tasa base: espera fallo en más de la mitad de los intentos incluso con la mejor configuración, y presupuesta revisión humana en el bucle.
- Mide el par modelo-harness en tus tareas antes de estandarizar un stack. Dos harnesses y tus cinco tareas más frecuentes dan más señal que cualquier leaderboard agregado.
- Convierte el control de FP en gate automático. Todo checker, regla de linter o test que genere un agente pasa por una pasada sobre código sano: si dispara, no entra. Es barato y es el criterio que separa las dos mitades de la tabla.
- Dedica el esfuerzo de optimización a las skills del dominio, no al siguiente modelo. La ablation (con su caveat) y el baseline del kernel sugieren que ahí está la palanca; una biblioteca de skills mantenida sigue pagando con el modelo de turnos.
- Si quieres replicar, reserva una tarde y un disco grande. El dataset está en Hugging Face, el repo trae scripts de descarga con SHA-256 por parte y la imagen de runtime está congelada. Con 100 GB libres y Docker, el coste de entrada es tiempo, no licencias.
Fuentes: abstract y paper (arXiv 2610.07557) · HTML v1 completo · repo oficial del benchmark (GitHub) · dataset en Hugging Face. Cifras verificadas contra el HTML v1 el 09-oct-2026.