Un modelo de lenguaje puede rendir bien en un benchmark limpio y aun así tener problemas con los casos que de verdad importan en producción.

Los benchmarks y los conjuntos de datos curados son útiles al prototipar un sistema basado en modelos de lenguaje. Ayudan a los equipos a comparar modelos, probar un primer prompt y determinar si una idea es técnicamente plausible. Pero a medida que un sistema se acerca a producción, el problema de la evaluación cambia.

Las entradas reales suelen ser ambiguas. Las etiquetas pueden ser inconsistentes. Puede faltar contexto importante, o venir truncado. El conjunto de evaluación puede no reflejar la distribución de producción. Casos borde que rara vez aparecen en los benchmarks pueden transformarse en fuentes comunes de falla. E incluso cuando las métricas fuera de línea mejoran, esos resultados pueden no traducirse limpiamente en el comportamiento real.

El equipo de GitHub se topó con estos desafíos evaluando un sistema basado en modelos de lenguaje diseñado para reducir los falsos positivos del escaneo de secretos. Ese escaneo identifica credenciales, como tokens y llaves, que pueden haber sido subidas a un repositorio. Como algunas cadenas candidatas se parecen a un secreto sin ser realmente una credencial, los desarrolladores pueden perder tiempo investigando alertas que no requieren remediación.

Más que determinar si un modelo podía clasificar una cadena correctamente, la pregunta era si el sistema podía reducir el ruido de las alertas preservando suficiente exhaustividad para seguir siendo seguro en un flujo de trabajo de seguridad.

1. Partir por la decisión de producto, no por el modelo

Cuando un sistema con modelo de lenguaje no rinde como se espera, el primer instinto suele ser ajustar sus componentes técnicos: reescribir el prompt, agregar contexto, introducir otro paso de razonamiento, ajustar la tubería que lo rodea o cambiar de modelo. Antes de hacer cualquiera de esos cambios, hay que definir la decisión que la evaluación busca sustentar.

En el trabajo de escaneo de secretos, la pregunta fue: ¿puede el sistema reducir los falsos positivos preservando suficiente exhaustividad para ser seguro en un flujo de seguridad en producción?

En este caso, suprimir incorrectamente una credencial real es más grave que pedirle a un desarrollador que revise una alerta adicional. Por eso el equipo no trató la precisión y la exhaustividad como métricas intercambiables. El objetivo principal fue reducir falsos positivos y mejorar la precisión; la exhaustividad quedó como restricción de seguridad, y un experimento solo podía avanzar si su caída se mantenía dentro de un rango aceptable predefinido.

Los criterios de evaluación se ordenaron en tres niveles:

  • Resultado principal: el beneficio para el usuario que se buscaba mejorar, es decir la reducción de falsos positivos y la precisión
  • Restricción de seguridad: la exhaustividad, que impide que una mejora aparente introduzca un riesgo inaceptable
  • Salvaguardas operativas: latencia, costo, fiabilidad y compatibilidad con producción, que determinan si el resultado es viable de desplegar

Esta distinción evita tratar cada métrica como si valiera lo mismo. Un cambio que reduce falsos positivos pero baja bastante la exhaustividad no es automáticamente una mejora. Tampoco lo es uno que mejora la calidad y deja al sistema demasiado lento, caro o difícil de integrar.

ExperimentoPrecisiónExhaustividadLatenciaDecisión
Amejora grandecae bajo la salvaguardaaceptableno avanzar
Bmejora moderadadentro de la salvaguardaaceptableseguir probando

El experimento A puede parecer más fuerte si se mira la precisión de forma aislada. El B está más alineado con el objetivo de producto, porque mejora la experiencia del desarrollador sin violar la salvaguarda de exhaustividad.

2. Tratar la evaluación fuera de línea como una prueba de integración

Un sistema basado en modelos de lenguaje sigue cambiando después de su primera evaluación exitosa, así que evaluar no puede ser un ejercicio de una sola vez. Los equipos revisan prompts, adoptan modelos nuevos, cambian cómo se construyen las entradas y el contexto, y afinan la lógica de negocio alrededor. Cualquiera de esos cambios puede mejorar el sistema, introducir una regresión o desviar su comportamiento de forma inesperada.

Por eso GitHub trató la evaluación fuera de línea como una prueba de integración de extremo a extremo, y la volvió a correr cada vez que hubo un cambio significativo en el prompt, el modelo, la construcción de entradas o la lógica general. Para cada corrida se registró el prompt, el modelo, la versión del conjunto de datos y la configuración del sistema.

Eso permite responder preguntas como si el nuevo prompt mejoró la precisión sin reducir la exhaustividad, si la actualización de modelo ayudó en todo el conjunto de datos o solo en ciertas categorías, o si un cambio en el contexto arregló un patrón de error mientras introducía otro.

Cambiar una variable importante a la vez

La repetibilidad por sí sola no basta. Los experimentos también deben diseñarse para que la causa de un resultado quede clara. El equipo cambió una variable mayor a la vez y comparó cada corrida contra una línea base conocida: por ejemplo, evaluó una revisión del prompt por separado de una actualización de modelo antes de probar ambas juntas.

Esto importa porque incluso cambios pequeños en el prompt pueden desviar el comportamiento del modelo, mientras que una actualización de modelo puede afectar calidad, costo, latencia o consistencia del formato de salida. Si ambos cambian en el mismo experimento, no se sabe cuál causó la mejora o la regresión.

CorridaVersión de promptVersión de modeloPrecisiónExhaustividadLatenciaNotas
R-001v1Modelo A0,710,781,2 slínea base
R-002v2Modelo A0,750,771,2 ssolo cambio de prompt
R-003v1Modelo B0,740,801,0 ssolo cambio de modelo

Los valores de esa tabla son hipotéticos y se incluyen únicamente para ilustrar cómo se pueden registrar y comparar las corridas de evaluación.

GitHub también recomienda probar actualizaciones de modelo con regularidad. Cuando un sistema rinde mal, los desarrolladores suelen responder agregando más instrucciones al prompt, y a veces eso ayuda, pero no siempre: el prompt puede estar cargando una complejidad que en realidad viene del modelo. Un modelo más capaz puede rendir mejor con un prompt más simple que uno antiguo con ajuste extensivo, y los prompts simples son más fáciles de entender, probar y mantener.

3. Mantener la evaluación cerca de producción

Una evaluación fuera de línea solo sirve cuando se parece a la tarea que el sistema hará en producción. En un flujo de escaneo de secretos, el modelo rara vez evalúa un valor limpio y aislado: puede tener que juzgar un candidato junto a código circundante y otra información que es relevante, incompleta o potencialmente distractora.

La evaluación fuera de línea, entonces, necesitaba preservar las características importantes de la tarea real: el candidato evaluado, el contexto disponible para el modelo, la información de apoyo relevante, la forma en que las entradas se formatean y restringen, y la lógica del sistema alrededor del modelo.

Un ejemplo simplificado del propio artículo:

Código
example_token = "sample_value_for_documentation"
production_api_key = get_secret_from_environment()
candidate_value = "flagged_value"

Si el valor que el sistema debe evaluar es candidate_value, el modelo puede fijarse en example_token porque el nombre de esa variable parece más relevante para seguridad, y producir una explicación plausible sobre el valor equivocado. Este tipo de falla es fácil de perder cuando los ejemplos de evaluación contienen un único candidato obvio.

4. Las etiquetas de producción son señales, no verdad incuestionable

Los datos de producción pueden hacer más representativa una evaluación, pero sus etiquetas muchas veces capturan resultados de flujo de trabajo antes que verdad de terreno confiable. Una alerta de escaneo de secretos descartada o resuelta no necesariamente representa un falso positivo.

Un desarrollador podría resolver una alerta porque la credencial fue rotada, porque el riesgo se aceptó, porque había que despejar la alerta para desbloquear un flujo de trabajo, o porque la alerta estaba mal clasificada. Todos esos resultados se ven parecidos en los datos de producto y representan estados distintos.

Antes de usar etiquetas de producción, conviene preguntarse cómo se creó la etiqueta, si corresponde a la pregunta que la evaluación intenta responder, y si distintos resultados de flujo están quedando agrupados en la misma categoría. Para los subconjuntos importantes o ambiguos puede hacer falta una revisión manual.

5. Datos sintéticos y abiertos para cubrir los huecos

Los datos representativos de producción pueden ser limitados, sensibles o no estar disponibles al comienzo del desarrollo. Los ejemplos sintéticos, los benchmarks académicos y los conjuntos de datos abiertos ayudan a arrancar una evaluación y ampliar cobertura, pero deben complementar los datos parecidos a producción, no reemplazarlos.

Los ejemplos sintéticos sirven sobre todo para probar casos raros o difíciles de recolectar: entradas ambiguas, contexto faltante, formatos inusuales y patrones de falla subrepresentados. Una lista de cadenas de credenciales puede probar si un modelo reconoce formatos comunes, pero no alcanza para evaluar cómo razona sobre un candidato dentro de código real.

6. El análisis de errores muestra lo que el promedio esconde

Las métricas agregadas dicen si un sistema mejoró en general. El análisis de errores dice qué cambiar después. Un puntaje de precisión más alto no revela si los errores restantes vienen de entradas ambiguas, de un prompt mal planteado, de contexto faltante, de etiquetas ruidosas o de un conjunto de datos estrecho.

GitHub sostiene que estas prácticas aplican de forma amplia a sistemas con modelos de lenguaje en análisis de código, herramientas para desarrolladores, seguridad, análisis de datos y otros flujos de producción.