¿Empeoró el nuevo prompt la función?
Una ejecución de regresión compara dos versiones de una función sobre los mismos casos y dice qué empeoró. Importa porque un ajuste que arregla un mensaje suele romper otro, y nadie lo ve.
La tienda tiene una versión nueva de su clasificador. La tasa de aciertos parece la de antes. Eso no significa que nada haya cambiado.
Al final de esta lección
Nota
Puedo comparar dos versiones sobre los mismos casos y decidir si una es peor.
Palabras clave
| Palabra | Qué significa |
|---|---|
| Regresión | un caso que aprobaba antes y ahora falla |
| Tasa de aciertos | la parte de casos que aprueban |
| Versión base | la versión con la que se compara |
| Ruido | la variación entre ejecuciones de una versión sin cambios |
| Caso inestable | un caso que aprueba en unas ejecuciones y falla en otras |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Compara los mismos casos, versión a versión
Ejecuta las dos versiones sobre el mismo conjunto de referencia y guarda el resultado de cada caso. La tasa de aciertos da un solo número. La lista de casos que cambiaron da la razón.
Una regresión es un caso que aprobaba en la versión base y ahora falla. Lee esa lista antes que la tasa.
Ejemplo resuelto: la misma tasa, otros casos
| Versión | Casos aprobados de 12 | Tasa de aciertos | Casos que fallan |
|---|---|---|---|
| Antigua, ejecución 1 | 10 | 83 por ciento | 8, 12 |
| Antigua, ejecución 2 | 9 | 75 por ciento | 5, 11, 12 |
| Nueva | 9 | 75 por ciento | 4, 10, 12 |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Una ejecución prueba poco, porque las respuestas varían
Un modelo puede responder distinto cada vez al mismo mensaje. Así que ejecuta la versión antigua dos veces. La diferencia entre esas dos tasas es el ruido.
Un caso inestable aprueba en una ejecución y falla en la siguiente. No culpes de él a la versión nueva.
Decide con la tasa, luego con los casos
Si la tasa nueva es más baja que la antigua en más que el ruido, di que es peor. Si queda dentro del ruido, la tasa no dice nada.
Mira entonces los casos. Un caso que aprobó en todas las ejecuciones antiguas y falla en la nueva es una regresión firme, y es la que hay que arreglar.
Escribe las tres ejecuciones grabadas, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const want = [\"facturación\", \"envío\", \"otro\", \"facturación\", \"envío\", \"otro\", \"facturación\", \"envío\", \"desconocido\", \"desconocido\", \"facturación\", \"otro\"];' '// Ejecuciones grabadas: una etiqueta y una urgencia por caso, y un texto donde importa.' 'const runA1 = [[\"facturación\", 2], [\"envío\", 2], [\"otro\", 1], [\"facturación\", 2], [\"envío\", 3], [\"otro\", 1], [\"facturación\", 2], [\"facturación\", 2], [\"desconocido\", 1], [\"desconocido\", 1], [\"facturación\", 3], [\"envío\", 2]];' > runs.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe las tres ejecuciones grabadas, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const runA2 = [[\"facturación\", 2], [\"envío\", 2], [\"otro\", 1], [\"facturación\", 2], [\"otro\", 1], [\"otro\", 1], [\"facturación\", 2], [\"envío\", 2], [\"desconocido\", 1], [\"desconocido\", 1], [\"otro\", 2], [\"envío\", 2]];' >> runs.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe las tres ejecuciones grabadas, parte 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const runB = [[\"facturación\", 2], [\"envío\", 2], [\"otro\", 1], [\"otro\", 2], [\"envío\", 3], [\"otro\", 1], [\"facturación\", 2], [\"envío\", 2], [\"desconocido\", 1], [\"desconocido\", 1, \"Tu reembolso ha sido aprobado.\"], [\"facturación\", 3], [\"envío\", 2]];' 'module.exports = { want, runA1, runA2, runB };' >> runs.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe la comparación, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { want, runA1, runA2, runB } = require(\"./runs\");' '// Las reglas de la lección 2, abreviadas: etiqueta correcta, urgencia de 1 a 3, ninguna frase prohibida.' 'function passes(entry, expected) {' ' const said = (entry[2] || \"\").toLowerCase();' ' return entry[0] === expected && entry[1] >= 1 && entry[1] <= 3 && said.includes(\"reembolso ha sido\") === false;' '}' 'function results(run) {' ' return run.map(function (entry, at) { return passes(entry, want[at]); });' '}' > compare3.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe la comparación, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function rate(list) {' ' return Math.floor(list.filter(Boolean).length * 100 / list.length);' '}' 'const a1 = results(runA1);' 'const a2 = results(runA2);' 'const b = results(runB);' 'console.log(\"Tasa de aciertos A1: \" + rate(a1) + \" por ciento\");' 'console.log(\"Tasa de aciertos A2: \" + rate(a2) + \" por ciento\");' 'console.log(\"Tasa de aciertos B: \" + rate(b) + \" por ciento\");' 'const noise = Math.abs(rate(a1) - rate(a2));' 'console.log(\"Ruido entre A1 y A2: \" + noise + \" puntos\");' >> compare3.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe la comparación, parte 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const low = Math.min(rate(a1), rate(a2));' 'const high = Math.max(rate(a1), rate(a2));' 'let verdict = \"sin cambio claro\";' 'if (rate(b) < low - noise) verdict = \"peor\";' 'if (rate(b) > high + noise) verdict = \"mejor\";' 'console.log(\"Veredicto solo con las tasas: \" + verdict);' 'const worse = [];' 'const unstable = [];' 'const always = [];' 'for (let at = 0; at < want.length; at = at + 1) {' ' const same = a1[at] === a2[at];' ' if (same === false) unstable.push(at + 1);' ' else if (a1[at] && b[at] === false) worse.push(at + 1);' ' else if (a1[at] === false && b[at] === false) always.push(at + 1);' '}' 'console.log(\"Regresiones (aciertan en A1 y A2, fallan en B): \" + worse.join(\", \"));' 'console.log(\"Inestables (difieren entre A1 y A2): \" + unstable.join(\", \"));' 'console.log(\"Fallan en todas las ejecuciones: \" + always.join(\", \"));' >> compare3.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Compara las versiones
docker exec -w /home/node/project agent node compare3.jsSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Lo que muestra la comparación
| Línea | Qué muestra |
|---|---|
| Tasas de aciertos | A1 83, A2 75, B 75 por ciento |
| Ruido | 8 puntos |
| Veredicto con las tasas | sin cambio claro |
| Regresiones | los casos 4 y 10 |
| Inestables | los casos 5, 8 y 11 |
| Fallan en todas | el caso 12 |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Pruébalo
Consejo
En runs.js cambia la urgencia del caso 1 de runB de 2 a 9 y compara otra vez. El caso 1 debe unirse a las regresiones.
Un error frecuente
Advertencia
Mucha gente compara una ejecución de cada versión y se fía de la diferencia. Cuando las respuestas varían, una sola ejecución puede engañar en los dos sentidos. Ejecuta la base al menos dos veces, mide el ruido y juzga un cambio solo frente a él.