Tu propio benchmark de LLMs: por qué empezaría con programación competitiva
Cada nuevo modelo llega acompañado de una colección de números: razonamiento, matemáticas, código, multimodalidad, uso de herramientas, contextos largos y agentes.
El problema es que esos números responden, sobre todo, a las preguntas de quien diseñó el benchmark.
Si quieres decidir qué modelo funciona mejor para tus propios sistemas, puede ser más útil construir una capa de evaluación que puedas controlar, versionar y repetir.
La idea no es inventar un único “superbenchmark”. Es construir un benchmark harness: una infraestructura donde distintos conjuntos de tareas puedan ejecutarse bajo las mismas reglas, contra distintos modelos y con resultados auditables.
Y hay un primer dominio especialmente atractivo para empezar:
programación competitiva.
No porque represente toda la ingeniería de software, sino porque tiene tres propiedades excelentes para evaluar modelos: problemas claramente especificados, respuestas ejecutables y un juez objetivo.
El benchmark público no necesariamente mide lo que necesitas
Un leaderboard puede ser útil para descubrir tendencias, pero tiene limitaciones importantes.
La primera es la contaminación. Si un problema, su solución o una variante cercana apareció en datos de entrenamiento, una puntuación alta puede reflejar exposición previa además de capacidad de generalización.
La segunda es la calidad del propio benchmark. En julio de 2026, OpenAI publicó una auditoría de SWE-Bench Pro en la que su pipeline automático marcó el 27,4% de las tareas como problemáticas y una campaña humana identificó el 34,1%. Entre los fallos aparecieron tests demasiado estrictos, prompts incompletos, tests con poca cobertura y descripciones engañosas.
Eso importa porque un benchmark defectuoso puede medir la capacidad del modelo para adivinar las peculiaridades del test, no para resolver correctamente el problema.
La tercera limitación es más práctica: quizá el benchmark simplemente no representa tu carga de trabajo.
Un equipo que construye agentes de programación puede querer medir cosas diferentes a un laboratorio que evalúa razonamiento matemático. Puede importarle, por ejemplo:
- cuánto cuesta completar una tarea;
- cuántos intentos necesita el agente;
- si sabe reparar un programa después de un error;
- cuánto tiempo consume;
- si utiliza correctamente el shell;
- si introduce regresiones;
- o si una versión nueva del modelo empeora una tarea que antes resolvía.
Ahí empieza a tener sentido un sistema propio.
Benchmark #1: problemas de programación competitiva
La programación competitiva ofrece una unidad de evaluación muy limpia.
El modelo recibe un enunciado y debe producir un programa. Después, el sistema compila o ejecuta ese programa contra tests y obtiene uno de los resultados clásicos de los jueces online:
AC Accepted
WA Wrong Answer
TLE Time Limit Exceeded
MLE Memory Limit Exceeded
RE Runtime Error
CE Compilation Error
No necesitas preguntarle a otro LLM si “la solución parece buena”.
El código funciona o no funciona bajo un conjunto de tests determinado.
Un problema podría representarse así:
id: cp-000314
source: codeforces
source_id: 2045-C
published_at: 2026-08-17
difficulty: hard
topics:
- dynamic-programming
- strings
languages:
- python
- cpp
time_limit_ms: 2000
memory_limit_mb: 256
prompt: problem.md
tests: private
Después, el runner ejecuta una secuencia determinista:
modelo
↓
código generado
↓
compilación / ejecución
↓
tests privados
↓
AC / WA / TLE / MLE / RE / CE
Ese diseño es simple, pero produce una señal muy valiosa.
LiveCodeBench ya demostró por qué los problemas frescos importan
Esta idea tiene un precedente importante: LiveCodeBench.
El proyecto recopila continuamente problemas de concursos de LeetCode, AtCoder y Codeforces y conserva su fecha de publicación. Eso permite evaluar un modelo usando ventanas temporales concretas.
Si conoces aproximadamente el cutoff de entrenamiento de un modelo, puedes seleccionar únicamente problemas publicados después de esa fecha.
Conceptualmente:
training cutoff del modelo
│
▼
────────────┼──────────────────────── tiempo
│ problemas frescos
│ usados para evaluar
LiveCodeBench también muestra por qué no conviene reducir “programar” a una sola tarea. Además de generación de código, evalúa capacidades como self-repair, ejecución de código y predicción del output de tests.
La lección importante no es copiar LiveCodeBench exactamente.
Es adoptar su principio de freshness.
Tu benchmark podría mantener vistas como:
ALL
POST-CUTOFF
FRESH-365D
FRESH-90D
FRESH-30D
PRIVATE
Y entonces un resultado empieza a tener mucho más contexto:
Modelo X
Todos los problemas 81%
Post-cutoff 68%
Últimos 90 días 64%
Últimos 30 días 61%
Problemas privados 59%
Ese 61% o 59% puede ser más informativo que una puntuación brillante sobre un dataset que lleva años circulando por Internet.
El juez online debería ser una fuente, no tu infraestructura de evaluación
Hay una tentación evidente:
LLM
↓
submit a Codeforces
↓
esperar resultado
Pero depender del juez externo para cada evaluación introduce demasiadas variables:
- latencia;
- disponibilidad;
- cuentas y autenticación;
- límites de uso;
- cambios en la plataforma;
- dificultad para repetir exactamente una corrida;
- y condiciones de uso que pueden limitar la automatización o redistribución de contenido.
Por eso resulta más robusto separar dos funciones.
Los jueces online pueden ser fuente de problemas y referencia histórica. Tu plataforma debería intentar ejecutar la evaluación en un sandbox propio cuando las licencias, tests y términos de cada fuente lo permitan.
Online judges / tareas propias
↓
problem ingestion
↓
benchmark registry
↓
sandbox local
↓
evaluator determinista
La infraestructura queda bajo tu control.
Eso permite congelar una versión del benchmark y repetirla seis meses después sin que un servicio externo cambie debajo de tus pies.
No mezcles “modelo” y “agente” en el mismo ranking
Este punto es crítico.
Hay dos evaluaciones distintas que a menudo aparecen mezcladas.
Model-only
El modelo recibe el problema y produce una única respuesta.
problema → modelo → solución
Sin shell. Sin ejecutar tests. Sin navegar. Sin feedback.
Aquí intentas medir principalmente la capacidad del modelo.
Agent
El sistema puede escribir código, ejecutarlo, observar errores, modificarlo y volver a intentarlo.
problema
↓
agente escribe solución
↓
ejecuta tests
↓
observa error
↓
corrige
↓
vuelve a ejecutar
Aquí ya estás midiendo otra cosa:
modelo + harness + herramientas + estrategia de iteración.
Los dos rankings son interesantes, pero no significan lo mismo.
Un modelo que pierde en model-only podría convertirse en un agente superior si utiliza mejor el feedback, administra mejor el contexto o repara sus errores con mayor eficiencia.
pass@1 es sólo el comienzo
La métrica más intuitiva es pass@1: qué porcentaje de problemas se resuelve correctamente en el primer intento.
Pero un benchmark propio puede registrar bastante más.
| Métrica | Qué revela |
|---|---|
pass@1 | capacidad de resolver a la primera |
pass@3 | capacidad con varios intentos |
| compile rate | frecuencia con que genera código ejecutable |
| test pass ratio | porcentaje de tests superados |
| repair success | capacidad de corregirse tras feedback |
| attempts-to-AC | intentos necesarios para llegar a Accepted |
| latency | velocidad de respuesta |
| tokens | eficiencia de contexto y generación |
| cost | coste monetario por corrida |
| runtime | eficiencia del programa generado |
| memory | consumo de memoria de la solución |
Así, una comparación deja de ser:
Modelo A: 74
Modelo B: 71
Y se convierte en algo mucho más útil:
Modelo A Modelo B
pass@1 74% 71%
repair success 42% 68%
avg attempts 1.8 1.4
median latency 9.2s 15.7s
avg cost/problem $0.06 $0.03
Ahora ya puedes tomar una decisión de ingeniería.
El coste correcto puede ser “dólares por tarea resuelta”
Los proveedores suelen publicar precios por millón de tokens.
Para un sistema agéntico, esa unidad no siempre cuenta la historia completa.
Imagina dos modelos:
Modelo A
$0.03 por intento
40% de éxito
Modelo B
$0.07 por intento
85% de éxito
El modelo A parece más barato por llamada.
Pero el dato realmente importante podría ser:
coste por problema resuelto correctamente
Cuando incorporas retries, ejecuciones, herramientas y tiempo de cómputo, el ranking económico puede cambiar por completo.
Un benchmark propio te permite medir justamente esa unidad.
Benchmark #2: ingeniería de software real
La programación competitiva es un gran primer laboratorio, pero no representa mantener un repositorio real.
El segundo benchmark natural sería algo parecido a SWE-bench:
snapshot de repositorio
+
issue
+
tests secretos
↓
agente
↓
git diff
↓
tests
↓
PASS / FAIL
SWE-bench ejecuta repositorios en Docker y evalúa si el patch generado resuelve un issue real. Esa reproducibilidad es una idea que vale la pena conservar.
Pero la experiencia reciente de SWE-bench también deja otra lección: los tests y los prompts del benchmark necesitan su propia QA.
Un problema aparentemente válido puede estar mal especificado, exigir mediante tests algo que el enunciado nunca pidió o permitir shortcuts no deseados.
Por eso, para un benchmark privado, sería especialmente valioso escribir tareas nuevas deliberadamente para evaluación.
Eso reduce la contaminación y permite diseñar tests alrededor del comportamiento deseado, en lugar de reconstruir retrospectivamente la intención de un issue histórico.
OpenAI, en sus recomendaciones recientes sobre evaluaciones de terceros, también señala que los evaluadores deberían preferir tareas privadas o recién construidas cuando sea posible y tratar los problemas rotos como un riesgo estándar de validez.
Guarda el trace completo de cada corrida
Una puntuación sin contexto envejece mal.
Cada ejecución debería producir un artefacto reproducible con información como:
{
"benchmark": "competitive-programming",
"benchmark_version": "2026.09.1",
"problem": "cp-314",
"model": "provider/model-x",
"mode": "agent",
"temperature": 0,
"prompt_hash": "...",
"tokens_in": 1820,
"tokens_out": 2921,
"latency_ms": 12421,
"cost_usd": 0.031,
"attempts": 2,
"result": "AC",
"tests_passed": 47,
"tests_total": 47
}
En modo agente también conviene conservar el trace operacional:
qué vio
→ qué decidió
→ qué herramienta llamó
→ qué devolvió la herramienta
→ qué archivo modificó
→ qué test falló
→ cómo reaccionó
Eso transforma el benchmark en una herramienta de diagnóstico, no solamente en un leaderboard.
Si un modelo nuevo baja del 72% al 68%, puedes investigar por qué.
La arquitectura: construir un harness, no una colección de scripts
El sistema puede separarse en cinco piezas.
Benchmark Registry
│
▼
Benchmark Runner
│
├──────── Model adapters
│ ├ OpenAI
│ ├ Anthropic
│ ├ Google
│ └ modelos locales
│
▼
Sandbox / executor
│
▼
Evaluator
│
▼
Results DB + traces + dashboard
Cada benchmark define su contrato.
Cada proveedor implementa un adapter.
El runner se ocupa de ejecutar bajo reglas consistentes.
Y el evaluator decide qué significa éxito.
Eso permite imaginar una CLI sencilla:
llmbench run cp \
--model provider/model-x \
--suite fresh-30d
llmbench run swe \
--model provider/model-y \
--suite private-bugs-v1
llmbench compare \
provider/model-x \
provider/model-y
La parte valiosa no sería el comando.
Sería poder repetir exactamente la misma evaluación cuando aparezca un modelo nuevo.
Tu benchmark no tiene que ser universal
Ésta quizá sea la idea más importante.
Un benchmark propio no tiene que convencer a toda la industria.
Tiene que ayudarte a responder preguntas concretas:
- ¿qué modelo elijo para este agente?
- ¿la nueva versión realmente mejoró?
- ¿cuánto cuesta resolver una tarea real?
- ¿qué modelo repara mejor sus propios errores?
- ¿qué harness obtiene más valor del mismo modelo?
- ¿qué regresiones introdujo una actualización?
- ¿cuánto cae el rendimiento cuando usamos problemas posteriores al cutoff?
La programación competitiva es un excelente comienzo porque ofrece una señal objetiva y barata de automatizar.
Después puedes añadir debugging, ingeniería de repositorios, terminal, tool use, contextos largos, investigación web o incluso benchmarks privados derivados de tus propios flujos de trabajo.
El resultado final no sería simplemente otro leaderboard.
Sería algo más útil:
tu propio laboratorio para decidir cuándo un LLM realmente es mejor para el trabajo que quieres hacer.
Fuentes
- LiveCodeBench — sitio oficial
- LiveCodeBench — repositorio oficial
- SWE-bench — documentación oficial
- OpenAI: Separating signal from noise in coding evaluations, 8 de julio de 2026
- OpenAI: Why SWE-bench Verified no longer measures frontier coding capabilities, 23 de febrero de 2026
- OpenAI: A shared playbook for trustworthy third-party evaluations