← Todo el material
Curso Avanzado 23 de agosto de 2026

Evals — Módulo 8: cuándo un número es señal y cuándo es ruido

Octavo módulo del Curso de Evals: el módulo que casi nadie escribe y que evita meses persiguiendo fantasmas. Las tres fuentes de varianza, el error estándar de una proporción con la fórmula a mano, intervalos de confianza, por qué las comparaciones pareadas son mucho más potentes que comparar dos promedios, el test de McNemar, la corrección por comparaciones múltiples y cuántas veces repetir cada caso.

☰ Índice del contenido

En el módulo 7 cerramos el catálogo de cosas que se pueden medir: trayectorias, tool use, conversaciones completas. Ya tienes números. Y con los números llega la pregunta que decide si todo ese trabajo sirvió de algo o si acabas de construir una máquina de generar decisiones al azar con apariencia de rigor: cambiaste el prompt, la métrica subió de 0.82 a 0.86 en cincuenta casos, ¿mejoraste? La respuesta honesta —y la vamos a demostrar con aritmética en este módulo— es que no tienes idea. Y actuar como si la tuvieras es lo que hace que equipos enteros pasen meses persiguiendo fantasmas.

La tesis del módulo

La mayoría de las “mejoras” que celebran los equipos de IA no son mejoras: son la misma varianza medida dos veces. Sin un mínimo de estadística, un programa de evals no reduce la incertidumbre — la disfraza de tres decimales.

Las tres fuentes de varianza

Antes de las fórmulas hay que saber de dónde sale el ruido, porque cada fuente se ataca distinto.

        DE DÓNDE SALE EL RUIDO DE TU MÉTRICA

  ┌───────────────────────────────────────────────┐
  │ 1. EL MODELO                                  │
  │    temperatura > 0, y también a temp 0:       │
  │    batching, kernels no deterministas,        │
  │    el proveedor actualiza sin avisar          │
  │    se ataca con: repeticiones, temp 0         │
  ├───────────────────────────────────────────────┤
  │ 2. EL JUEZ                                    │
  │    el mismo par (caso, respuesta) puntuado    │
  │    distinto en dos corridas                   │
  │    se ataca con: rúbrica, temp 0, promedio    │
  ├───────────────────────────────────────────────┤
  │ 3. LA MUESTRA                                 │
  │    tus 50 casos son UNA muestra del universo  │
  │    de casos posibles; otra muestra da otro    │
  │    número aunque el sistema sea idéntico      │
  │    se ataca con: n mayor, casos pareados      │
  └───────────────────────────────────────────────┘

  Las tres se suman. La tercera es casi siempre
  la más grande, y es la que nadie mide.

1. El modelo. Con temperatura mayor que cero es obvio. Lo que sorprende es que a temperatura 0 tampoco es determinista: la suma en punto flotante no es asociativa, el orden de las operaciones cambia según cómo el servidor agrupe las peticiones (batching), y basta un empate mínimo entre dos tokens para que la trayectoria completa diverja. Súmale que el proveedor actualiza pesos e infraestructura sin avisarte. Temperatura 0 reduce mucho esta fuente; no la elimina.

2. El juez. El módulo 4 ya lo cubrió: el mismo par (caso, respuesta) puede recibir 4 hoy y 3 mañana. Con métricas binarias y una rúbrica bien anclada esta fuente es pequeña; con escalas de 1 a 10 y criterios vagos, puede ser la dominante.

3. La muestra. Esta es la grande y la que nadie mide. Tus cincuenta casos son una muestra del universo de peticiones posibles. Si hubieras elegido otros cincuenta igual de válidos, el número sería distinto. Cuánto distinto es exactamente lo que la estadística sabe calcular, y es mucho más de lo que la gente intuye.

Ojo: las tres fuentes se suman, y las dos primeras se atacan con repeticiones mientras la tercera solo se ataca con más casos o con un mejor diseño experimental. Repetir cien veces los mismos cinco casos no arregla nada: sigues midiendo cinco casos, ahora con más confianza en un número que no representa a tus usuarios.

La pregunta del módulo, con números

Tomemos el caso concreto. Tu métrica es una proporción: la fracción de casos que pasaron. Prompt A da 0.82 sobre 50 casos. Cambias algo, corres de nuevo, sale 0.85. ¿Mejoraste?

Antes de cualquier fórmula, un detalle que ya dice mucho: con 50 casos, 0.85 ni siquiera es un resultado posible. Cada caso vale 1/50 = 0.02, así que los valores alcanzables cerca de ahí son 0.82 (41 casos), 0.84 (42) y 0.86 (43). La granularidad de tu métrica es 2 puntos porcentuales. Si alguien te reporta 0.847 sobre 50 casos, o promedió varias corridas sin decirlo o el número está inventado.

Trabajemos entonces con lo posible: 41/50 = 0.82 contra 43/50 = 0.86. Dos casos más de cincuenta.

Error estándar de una proporción

La herramienta base. Si p es la proporción observada y n el número de casos:

EE = √( p × (1 − p) / n )

El error estándar (EE, o standard error) es cuánto se movería tu proporción si repitieras el experimento muchas veces con muestras distintas del mismo tamaño. Es la desviación típica de tu estimación, no de tus datos.

Para p = 0.82 y n = 50:

EE = √(0.82 × 0.18 / 50) = √(0.1476 / 50) = √0.002952 = 0.0543

Es decir, 5,4 puntos porcentuales. Tu “0.82” es en realidad “0.82 más/menos 5,4 puntos de fluctuación típica”. Y la diferencia que estás celebrando son 4 puntos: menos que el ruido de una sola de las dos mediciones.

Intervalo de confianza

El intervalo de confianza al 95% (IC 95%) es el rango donde caería tu métrica el 95% de las veces si repitieras el muestreo. Para una proporción, la versión simple (llamada Wald) es:

IC 95% = p ± 1,96 × EE

Con nuestros números: 0.82 ± 1,96 × 0.0543 = 0.82 ± 0.106 → [0.714 , 0.926].

Léelo despacio, porque es el momento incómodo del módulo: tu sistema, medido con 50 casos, tiene una tasa de éxito real que podría estar en cualquier punto entre 71% y 93%. Con eso pretendías detectar una mejora de 4 puntos.

El IC de la variante B (0.86) es [0.764 , 0.956]. Los dos intervalos se solapan casi por completo.

Cuidado: la fórmula de Wald se rompe cuando p se acerca a 0 o a 1. Con 49/50 = 0.98 da [0.941 , 1.019], y una proporción mayor que 1 es un absurdo. En esa zona —donde viven las métricas de seguridad, que quieres cerca de 1— hay que usar el intervalo de Wilson, que para el mismo 49/50 da [0.895 , 0.996]: asimétrico y acotado, como corresponde. El código de más abajo trae los dos.

La tabla que hay que tener pegada al monitor

Margen de error (la mitad del ancho del IC 95%) según el número de casos, para el peor caso p = 0.5 y para una métrica alta típica p = 0.85:

n (casos)Margen si p = 0.5Margen si p = 0.85
20± 21,9 pts± 15,6 pts
30± 17,9 pts± 12,8 pts
50± 13,9 pts± 9,9 pts
100± 9,8 pts± 7,0 pts
200± 6,9 pts± 4,9 pts
500± 4,4 pts± 3,1 pts
1000± 3,1 pts± 2,2 pts

Tres lecturas que cambian cómo trabajas:

  1. Con 50 casos no puedes detectar diferencias menores a ~10 puntos. Todo lo que celebres por debajo de eso es ruido. La regla rápida de la investigación de evaluación de agentes —“con 50 casos, ±10 puntos”— sale exactamente de aquí.
  2. La precisión mejora con √n, no con n. Para reducir el margen a la mitad necesitas cuatro veces más casos. Pasar de 50 a 100 casos apenas te lleva de ±13,9 a ±9,8. Es la razón por la que “agrega más casos” deja de ser una estrategia viable rápido.
  3. Cuando la métrica es alta, el margen es más chico. Detectar la diferencia entre 0.95 y 0.98 necesita menos casos que entre 0.50 y 0.53. Es una de las pocas buenas noticias del módulo.

Comparaciones pareadas: el truco que lo cambia todo

Aquí está la técnica más valiosa del módulo, y la buena noticia después de tanta mala.

Todo lo anterior asumía que estás comparando dos muestras independientes. Pero cuando comparas dos variantes de tu sistema, no tienes por qué hacerlo así: puedes correr los mismos casos por ambas. Y eso cambia el problema por completo.

La intuición: casi toda la varianza viene de que unos casos son fáciles y otros difíciles. Si corres los mismos casos por A y por B, esa dificultad se cancela — es la misma para las dos. Lo único que queda son los casos donde A y B discrepan, y esos son los que llevan toda la información.

     COMPARACIÓN PAREADA: TABLA DE 2x2

                        VARIANTE B
                    bien        mal
                 ┌──────────┬──────────┐
        bien     │    a     │    b     │
  VAR A          │   164    │    0     │
                 ├──────────┼──────────┤
        mal      │    c     │    d     │
                 │     6    │    30    │
                 └──────────┴──────────┘

   a, d = coinciden ── NO aportan información
   b    = A acertó y B falló  (B empeoró)
   c    = A falló y B acertó  (B mejoró)

   Solo b y c deciden. Aquí: b=0, c=6.
   Seis casos que B arregló y ninguno que rompió.

Las celdas a y d son los casos donde ambas variantes hicieron lo mismo: no distinguen nada y se descartan. Los discordantes b y c son toda la evidencia. Si el cambio no hiciera nada, b y c deberían salir parecidos por azar; si c es sistemáticamente mayor que b, hay señal.

El test de McNemar

El test de McNemar formaliza exactamente eso: bajo la hipótesis de que no hay diferencia, cada caso discordante tiene 50% de probabilidad de caer en b y 50% en c. Es literalmente lanzar b + c monedas y ver si el resultado es raro. La versión exacta usa la distribución binomial:

p = P(obtener un desbalance al menos tan extremo como el observado en b+c lanzamientos de moneda justa)

Un valor p es la probabilidad de ver una diferencia como la tuya (o mayor) si en realidad no hubiera ninguna diferencia. Chico = raro por azar = probablemente hay algo. El umbral convencional es 0.05.

Veamos el poder de la técnica con un ejemplo verificable. Comparamos dos variantes sobre 200 casos: A acierta 164 (0.82) y B acierta 170 (0.85). Tres puntos de diferencia.

AnálisisDatosResultado¿Declaras mejora?
Independiente (dos promedios)164/200 vs 170/200p = 0.419No
Pareado McNemar, b=10 c=1626 discordantesp = 0.327No
Pareado McNemar, b=4 c=1014 discordantesp = 0.180No
Pareado McNemar, b=0 c=66 discordantesp = 0.031Sí

Los cuatro análisis miran la misma diferencia de 3 puntos. El independiente da p = 0.419, un resultado completamente indistinguible del azar. El pareado con b=0 y c=6 da p = 0.031: significativo. La diferencia entre “no concluyo nada” y “declaro mejora” no está en el tamaño de la diferencia, sino en cuántos casos rompió el cambio mientras arreglaba otros.

Eso es exactamente lo que quieres saber y lo que un promedio jamás te va a decir: un cambio que arregla 16 casos y rompe 10 es sospechoso aunque el neto sea positivo (probablemente moviste el sistema al azar); un cambio que arregla 6 y no rompe ninguno es una mejora real aunque el neto sea más chico.

Ojo: la lista de casos que el cambio rompió (la celda b) vale más que el valor p. Léela siempre a mano. Un cambio que sube el promedio rompiendo tres casos que antes funcionaban puede ser inaceptable si esos tres son los casos importantes, y ningún test estadístico sabe eso por ti.

Por eso las comparaciones pareadas son la forma por defecto de comparar variantes en evals. Necesitas guardar el resultado por caso, no solo el promedio: es un archivo con caso_id, resultado por corrida, y es la diferencia entre poder hacer estadística seria y no poder.

Cuántas veces repetir cada caso

Las repeticiones atacan las fuentes 1 y 2 (modelo y juez), no la 3. Como el error estándar cae con √k, las tres primeras repeticiones se llevan casi todo el beneficio:

Repeticiones (k)Reducción del EE por casoCosto
1—× 1
3× 0,58 (−42%)× 3
5× 0,45 (−55%)× 5
10× 0,32 (−68%)× 10

La regla práctica: k = 3 en las decisiones que importan, k = 1 en el gate de CI. Y una consideración de presupuesto que decide sola: con presupuesto fijo, 150 casos × 1 repetición le gana casi siempre a 50 casos × 3 repeticiones, porque la varianza de muestreo (fuente 3) suele dominar. Las repeticiones son para cuando ya tienes casos suficientes y sospechas del modelo o del juez.

Un uso mejor de las repeticiones que promediarlas: reportar la tasa de consistencia, la fracción de casos donde las k corridas dieron el mismo resultado. Un sistema con 0.85 de éxito y 0.98 de consistencia es confiable; el mismo 0.85 con 0.70 de consistencia es un sistema que alterna aciertos y desastres, y ese diagnóstico no aparece en el promedio.

Veinte variantes y el problema de las comparaciones múltiples

El último error, el más sutil y el más caro. Probaste veinte variantes del prompt, la número 14 salió mejor con p = 0.04, la declaras ganadora, la despliegas y en producción no pasa nada.

La razón es aritmética. Un umbral de p < 0.05 significa que aceptas un 5% de probabilidad de falsa alarma por comparación. Si haces veinte comparaciones independientes sin cambios reales:

P(al menos un falso positivo) = 1 − (1 − 0.05)²⁰ = 1 − 0.95²⁰ = 0.642

Comparaciones (m)P(al menos un falso positivo)Umbral corregido (Bonferroni)
15%0.05
522,6%0.010
1040,1%0.005
2064,2%0.0025

Con veinte variantes, es más probable que improbable que al menos una “gane” sin ser mejor. Y la que gana es, por construcción, la que tuvo más suerte.

La corrección de Bonferroni es la defensa más simple: divide el umbral por el número de comparaciones. Con veinte variantes, exige p < 0.0025 en vez de p < 0.05. Es conservadora —te va a hacer perder mejoras reales— pero es una línea, y una línea conservadora es infinitamente mejor que ninguna.

Dos prácticas que rinden más que la corrección:

Un conjunto held-out. Iteras y eliges sobre el set de desarrollo tanto como quieras, sin corregir nada. Cuando tienes tu ganadora, la validas una sola vez contra un conjunto de casos que nunca miraste. Una comparación, sin corrección necesaria, y una respuesta honesta. Es la misma idea del conjunto de test en Machine Learning, y por la misma razón: si eliges mirando el examen, tu nota no mide lo que crees.

Declarar la hipótesis antes de correr. “Espero que agregar el ejemplo few-shot suba la tasa de tool use correcto” es una hipótesis con una comparación. “Corramos veinte variantes a ver cuál sale mejor” es pesca, y la pesca necesita corrección.

Código: decidir si la diferencia es significativa

"""Estadística mínima para decidir si una diferencia entre dos
variantes es señal o ruido.

    pip install scipy

Todo lo que hace scipy aquí se puede hacer a mano; las fórmulas
están en los docstrings para que el número no sea magia.
"""
from __future__ import annotations

import math
from dataclasses import dataclass
from statistics import NormalDist

from scipy.stats import binomtest

Z95 = 1.959963985  # cuantil normal para 95% bilateral


# --- 1. Una sola proporción: error estándar e intervalo ------------------

def error_estandar(k: int, n: int) -> float:
    """EE = sqrt( p(1-p) / n ). Cuánto se movería p con otra muestra."""
    p = k / n
    return math.sqrt(p * (1 - p) / n)


def ic_wald(k: int, n: int, z: float = Z95) -> tuple[float, float]:
    """IC 95% = p ± z·EE. Simple pero se rompe cerca de 0 y de 1
    (puede devolver límites fuera de [0,1])."""
    p = k / n
    h = z * error_estandar(k, n)
    return p - h, p + h


def ic_wilson(k: int, n: int, z: float = Z95) -> tuple[float, float]:
    """Intervalo de Wilson: asimétrico y siempre dentro de [0,1].

    centro = (p + z²/2n) / (1 + z²/n)
    medio  = z·sqrt( p(1-p)/n + z²/4n² ) / (1 + z²/n)

    Úsalo SIEMPRE que la proporción esté sobre 0.9 o bajo 0.1,
    que es justo donde viven las métricas de seguridad.
    """
    p = k / n
    den = 1 + z * z / n
    centro = (p + z * z / (2 * n)) / den
    medio = z * math.sqrt(p * (1 - p) / n + z * z / (4 * n * n)) / den
    return centro - medio, centro + medio


# --- 2. Comparación PAREADA: la que debes usar ---------------------------

@dataclass
class ResultadoPareado:
    n: int
    a_ok_b_ok: int       # celda a: coinciden bien
    b_solo_a: int        # celda b: A acertó, B falló  (B ROMPIÓ)
    c_solo_b: int        # celda c: A falló, B acertó  (B ARREGLÓ)
    a_mal_b_mal: int     # celda d: coinciden mal
    delta: float
    p_valor: float
    ic_delta: tuple[float, float]
    casos_rotos: list[str]

    @property
    def significativo(self) -> bool:
        return self.p_valor < 0.05


def comparar_pareado(res_a: dict[str, bool],
                     res_b: dict[str, bool]) -> ResultadoPareado:
    """McNemar exacto sobre los MISMOS casos corridos por dos variantes.

    `res_a` y `res_b` son {caso_id: paso_o_no}. Los casos donde ambas
    coinciden no aportan información: toda la evidencia está en los
    discordantes, y el test es preguntarse si b+c monedas justas darían
    un desbalance así de extremo.
    """
    ids = sorted(set(res_a) & set(res_b))
    n = len(ids)
    if n == 0:
        raise ValueError("No hay casos en común: la comparación no es pareada")

    a = b = c = d = 0
    rotos = []
    for i in ids:
        if res_a[i] and res_b[i]:
            a += 1
        elif res_a[i] and not res_b[i]:
            b += 1
            rotos.append(i)          # lo más importante de todo el output
        elif not res_a[i] and res_b[i]:
            c += 1
        else:
            d += 1

    delta = (c - b) / n              # cambio neto en la proporción
    discordantes = b + c

    if discordantes == 0:
        # Idénticas caso por caso: no hay nada que testear
        return ResultadoPareado(n, a, b, c, d, 0.0, 1.0, (0.0, 0.0), [])

    # Test binomial exacto: preferible a la aproximación chi-cuadrado,
    # que es mala cuando hay pocos discordantes (que es lo normal en evals).
    p_valor = binomtest(min(b, c), discordantes, 0.5,
                        alternative="two-sided").pvalue

    # IC de la diferencia pareada:
    #   EE_delta = sqrt( (b+c) - (c-b)²/n ) / n
    ee = math.sqrt(discordantes - (c - b) ** 2 / n) / n
    ic = (delta - Z95 * ee, delta + Z95 * ee)

    return ResultadoPareado(n, a, b, c, d, delta, p_valor, ic, rotos)


# --- 3. Comparación independiente (cuando no hay más remedio) ------------

def comparar_independiente(k_a: int, n_a: int,
                           k_b: int, n_b: int) -> dict:
    """Test z de dos proporciones con muestras distintas.

    p_pool = (k_a + k_b) / (n_a + n_b)
    EE     = sqrt( p_pool(1-p_pool) (1/n_a + 1/n_b) )
    z      = (p_b - p_a) / EE

    Mucho menos potente que el pareado: úsalo solo si de verdad no
    puedes correr los mismos casos por ambas variantes.
    """
    p_a, p_b = k_a / n_a, k_b / n_b
    p_pool = (k_a + k_b) / (n_a + n_b)
    ee = math.sqrt(p_pool * (1 - p_pool) * (1 / n_a + 1 / n_b))
    if ee == 0:
        return {"delta": 0.0, "z": 0.0, "p_valor": 1.0}
    z = (p_b - p_a) / ee
    p_valor = 2 * (1 - NormalDist().cdf(abs(z)))
    return {"delta": p_b - p_a, "z": z, "p_valor": p_valor}


# --- 4. Comparaciones múltiples -----------------------------------------

def bonferroni(alfa: float, m: int) -> float:
    """Umbral corregido para m comparaciones.

    P(al menos un falso positivo) = 1 - (1-alfa)^m
    Con alfa=0.05 y m=20 eso es 0.642: es MÁS PROBABLE QUE NO que
    alguna variante 'gane' por puro azar.
    """
    return alfa / m

Y el runner que responde la pregunta del módulo:

if __name__ == "__main__":
    # Escenario: 200 casos corridos por A y por B.
    # A acierta 164 (0.82). B acierta 170 (0.85). Tres puntos.
    # Los casos 0..163 los aciertan ambas; los 164..169 solo B;
    # los 170..199 fallan ambas.
    res_a, res_b = {}, {}
    for i in range(200):
        cid = f"caso_{i:03d}"
        if i < 164:
            res_a[cid], res_b[cid] = True, True      # celda a
        elif i < 170:
            res_a[cid], res_b[cid] = False, True     # celda c: B arregló
        else:
            res_a[cid], res_b[cid] = False, False    # celda d

    r = comparar_pareado(res_a, res_b)
    print(f"n={r.n}  a={r.a_ok_b_ok} b={r.b_solo_a} "
          f"c={r.c_solo_b} d={r.a_mal_b_mal}")
    print(f"delta = {r.delta:+.3f}   p = {r.p_valor:.4f}")
    print(f"IC 95% del delta = [{r.ic_delta[0]:+.4f}, {r.ic_delta[1]:+.4f}]")
    print(f"casos que B rompió: {r.casos_rotos or 'ninguno'}")
    print(f"¿significativo? {r.significativo}")

    ind = comparar_independiente(164, 200, 170, 200)
    print(f"\nmismo delta, análisis independiente: p = {ind['p_valor']:.4f}")

    print(f"\nIC de A solo:  {tuple(round(x, 3) for x in ic_wald(164, 200))}")
    print(f"IC seguridad Wald  (49/50): "
          f"{tuple(round(x, 3) for x in ic_wald(49, 50))}")
    print(f"IC seguridad Wilson(49/50): "
          f"{tuple(round(x, 3) for x in ic_wilson(49, 50))}")

# n=200  a=164 b=0 c=6 d=30
# delta = +0.030   p = 0.0312
# IC 95% del delta = [+0.0064, +0.0536]
# casos que B rompió: ninguno
# ¿significativo? True
#
# mismo delta, análisis independiente: p = 0.4190
#
# IC de A solo:  (0.767, 0.873)
# IC seguridad Wald  (49/50): (0.941, 1.019)
# IC seguridad Wilson(49/50): (0.895, 0.996)

Los tres resultados a subrayar. Primero: la misma diferencia de 3 puntos da p = 0.031 pareada y p = 0.419 independiente — un factor de más de 13 en el valor p, solo por haber corrido los mismos casos. Segundo: el IC del delta pareado es [+0.6 , +5.4] puntos, que no incluye el cero, y eso es la definición operativa de “hay señal”. Tercero: el Wald de 49/50 devuelve 1.019, una probabilidad mayor que uno, mientras Wilson devuelve un intervalo sensato; en las métricas de seguridad esa diferencia importa.

La tabla de decisión: ¿puedo declarar mejora?

El cierre del bloque. Recórrela de arriba abajo y detente en la primera fila que aplique.

Situación¿Declaras mejora?Qué hacer
n < 30 casosNoNo hay poder estadístico para nada. Consigue más casos
Diferencia menor que la granularidad (1/n)NoEl número que reportas es imposible; revisa cómo se calculó
Corridas independientes, distintos casosNoVuelve a correr los mismos casos por ambas variantes
Pareado, p ≥ 0.05NoSin evidencia. Ni la descartes: quizá falte n
Pareado, p < 0.05, pero b > 0 en casos críticosNoRompió algo importante. Lee la celda b antes que el promedio
Probaste m variantes y no corregisteNoAplica Bonferroni o valida la ganadora en el held-out
Elegiste la ganadora mirando el mismo set en el que iterasteNoOverfitting al examen. Valida una vez contra held-out
Pareado, p < 0.05, b = 0 o solo casos menores, held-out confirmaSíRegistra el delta con su IC, no solo el promedio

Y la regla que resume el módulo entero: reporta siempre el intervalo, nunca el punto. “Subimos de 0.82 a 0.85” es una afirmación sin información. “Subimos 3 puntos, IC 95% [+0.6, +5.4], p = 0.031, sin casos rotos, confirmado en held-out” es una decisión defendible.

Errores comunes

  • Celebrar diferencias más chicas que el margen de error. Con 50 casos el margen es ±10 puntos; cualquier mejora de 2 o 3 puntos ahí es ruido. Es el error más frecuente de la industria y el que más semanas quema.
  • Comparar dos promedios de corridas independientes. Descarta gratis casi todo el poder estadístico. Corre los mismos casos por ambas variantes y usa McNemar: la misma diferencia puede pasar de p = 0.42 a p = 0.03.
  • Guardar solo el promedio de cada corrida. Sin el resultado por caso no puedes hacer análisis pareado, no puedes leer qué se rompió y no puedes recalcular nada. Guarda siempre caso_id, resultado por corrida.
  • Usar Wald cerca de 0 o de 1. Devuelve intervalos que salen de [0,1] y engaña justo en el rango donde viven las métricas de seguridad. Wilson en esa zona, siempre.
  • Probar veinte variantes sin corregir. Con m = 20 y α = 0.05, la probabilidad de que alguna gane por azar es 64%. O corriges el umbral o validas la ganadora contra un held-out que no miraste.
  • Repetir mucho unos pocos casos. Las repeticiones atacan la varianza del modelo y del juez, no la de la muestra. Con presupuesto fijo, 150 casos × 1 casi siempre supera a 50 casos × 3.
  • Reportar tres decimales sobre 50 casos. Un “0.847” cuando la granularidad es 0.02 es precisión falsa. Reporta la cantidad de decimales que el tamaño de muestra sostiene, y el intervalo al lado.
  • Confundir “no significativo” con “no hay diferencia”. Son cosas distintas: significa que tu experimento no tuvo poder para detectarla. La conclusión correcta es “no sé”, y la acción es más casos o un experimento mejor diseñado.

La frase para llevarse

“Un número sin intervalo de confianza no es una medición: es una opinión con decimales.”

Qué viene

Módulo 9: red teaming y seguridad. Cambiamos de eje por completo. Hasta aquí todo el curso midió si el agente hace bien lo que le pides; ahora vamos a medir si hace mal lo que un atacante le pide. Prompt injection directa e indirecta, jailbreaks, extracción del prompt del sistema, exfiltración de datos a través de las tools que le conectaste, y la métrica que casi todas las suites de seguridad olvidan: la tasa de falsos positivos sobre casos benignos, porque un agente que bloquea todo tiene 100% de resistencia y 0% de utilidad. Y con la estadística de este módulo en la mano, vas a poder decir por fin cuántos ataques necesitas en tu suite para que “resistió el 97%” signifique algo.

Material relacionado

EvalsEstadísticaSignificanciaMcNemarMétricas

Preguntas sobre este curso

Regístrate gratis para hacer preguntas y guardar tu progreso.

✉ Entérate de lo nuevo

Recibe un aviso cuando publique nuevos cursos, workshops o investigaciones. Sin spam.