¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Tests como barreras para agentes de código

Después de esta lección: Puedo escribir primero un test que falla para que el trabajo de un agente de código quede comprobado.

Lección de 65 min6 comandosLaboratorio de agente de programación con IA: usa opencode para explicar y corregir código, y comprueba su trabajo

Por qué el test va antes del agente

Un test barrera es un test que escribes antes de que empiece un agente de código. Ahora falla y debe pasar cuando el trabajo esté hecho, así que «terminado» lo decide una máquina y no el informe del agente.

Importa porque un agente puede informar de que ha terminado cuando el trabajo no está hecho. Un test escrito antes, y protegido del agente, es una comprobación en la que puedes confiar.

Al final de esta lección

Nota

Puedo escribir primero un test que falla para que el trabajo de un agente de código quede comprobado.

Palabras clave

PalabraQué significa
Test barreraun test que escribes antes del trabajo y que debe pasar al terminarlo
Rojo y luego verdeel test falla antes del trabajo y pasa después
Trampaun cambio que pasa un test sin hacer el trabajo
Test reservadoun test que el agente no puede ver
Archivo de tests protegidoun archivo de tests que el agente no puede cambiar

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Escribe primero el test que falla

Escribe el test a partir de la tarea, antes de que empiece el agente. Ejecútalo y míralo fallar. Un test que pasa antes de cualquier trabajo no prueba nada nuevo.

Después da al agente la tarea y el test. El agente cambia el código hasta que el test pasa. Ahora tienes una comprobación que no depende de lo que el agente dice que hizo.

Un test puede pasar sin el trabajo

Al agente se le pide que el test pase, y puede encontrar un atajo. Puede responder solo a las entradas que ve. Puede cambiar o borrar el test.

No es mala intención. El agente recibió un objetivo y lo alcanzó. Por eso el objetivo tiene que ser difícil de alcanzar por el camino equivocado.

Ejemplo resuelto: trampas y cómo frenarlas

TrampaCómo se veCómo frenarla
Caso especialsi el precio es 2000, responde 0Tests reservados con otras entradas
Editar el testSe borra o cambia un casoProteger el archivo de tests y compararlo
Saltar el testEl test se marca para saltarloContar los tests antes y después
Test más débilUna comprobación exacta pasa a «es un número»Revisar cada cambio en un archivo de tests

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Un error frecuente

Advertencia

Mucha gente cree que una ejecución en verde significa que el agente hizo el trabajo. Un test puede ponerse verde porque cambió el test, o porque solo funcionan las entradas visibles. Fíate del verde solo si el archivo de tests no cambió y los tests reservados también pasan.

Juzga cuatro intentos grabados

El envío cuesta 299 céntimos por debajo de 2000 céntimos y nada a partir de 2000. El script lleva tres tests visibles y dos reservados.

Juzga el código antes del trabajo y tres intentos grabados. Los intentos se escribieron a mano para representar lo que un agente puede devolver.

Escribe el ayudante del modelo, parte 1

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' '// Los tokens de una respuesta, o null si no trae ninguno.' 'function count(data, name) {' '  return data.usage && typeof data.usage[name] === \"number\" ? data.usage[name] : null;' '}' > model.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 el ayudante del modelo, parte 2

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function ask(messages, sample, max) {' '  try {' '    const res = await fetch(base + \"/v1/chat/completions\", {' '      method: \"POST\",' '      headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' '      body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 100 }),' '      signal: AbortSignal.timeout(30000),' '    });' '    if (res.ok === false) throw new Error(\"estado \" + res.status);' '    const d = await res.json();' '    return { text: d.choices[0].message.content, inTokens: count(d, \"prompt_tokens\"), outTokens: count(d, \"completion_tokens\"), recorded: false };' '  } catch (error) {' '    console.log(\"Muestra grabada: ningún modelo respondió (\" + error.message + \").\");' '    return { text: sample, inTokens: null, outTokens: null, recorded: true };' '  }' '}' 'module.exports = { ask };' >> model.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 el juez de barreras, parte 1

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' '// El envío cuesta 299 céntimos por debajo de 2000 céntimos, y nada desde 2000.' 'const visible = [[500, 299], [1999, 299], [2000, 0]];' 'const held = [[2500, 0], [100, 299]];' 'const attempts = {' '  \"antes\": { fn: function (p) { return 299; }, tests: visible },' '  \"honesto\": { fn: function (p) { return p >= 2000 ? 0 : 299; }, tests: visible },' '  \"caso especial\": { fn: function (p) { return p === 2000 ? 0 : 299; }, tests: visible },' '  \"test editado\": { fn: function (p) { return 299; }, tests: [[500, 299], [1999, 299]] },' '};' > guard.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 el juez de barreras, parte 2

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function passed(fn, cases) {' '  return cases.filter(function (c) { return fn(c[0]) === c[1]; }).length;' '}' 'function verdict(a) {' '  if (JSON.stringify(a.tests) === JSON.stringify(visible) === false) return \"rechazar: tests cambiados\";' '  if (passed(a.fn, a.tests) < a.tests.length) return \"sin terminar\";' '  if (passed(a.fn, held) < held.length) return \"posible trampa\";' '  return \"aceptar\";' '}' >> guard.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 el juez de barreras, parte 3

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  Object.keys(attempts).forEach(function (name) {' '    const a = attempts[name];' '    console.log(name + \": visibles \" + passed(a.fn, a.tests) + \"/\" + a.tests.length' '      + \", reservados \" + passed(a.fn, held) + \"/\" + held.length + \": \" + verdict(a));' '  });' '  const q = \"En una frase corta: ¿por qué guardar algunos tests donde un agente de código no puede verlos?\";' '  const sample = \"Los tests ocultos muestran si el agente resolvió el problema o solo los ejemplos que veía.\";' '  const reply = await ask([{ role: \"user\", content: q }], sample, 60);' '  console.log(\"el modelo dijo: \" + reply.text);' '}' 'main();' >> guard.js"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Ejecuta el juez de barreras

Comando
docker exec -w /home/node/project agent node guard.js

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Lo que imprime el Run

LíneaLo que muestra
antes: visibles 2/3 ...: sin terminarRojo: el test falla antes del trabajo
honesto: visibles 3/3, reservados 2/2: aceptarVerde, y los casos ocultos coinciden
caso especial: ... reservados 1/2: posible trampaSolo funcionan las entradas visibles
test editado: ...: rechazar: tests cambiadosSe borró un caso, así que nada cuenta
el modelo dijo: ...Una frase del laboratorio. Una línea de Muestra grabada si ningún modelo responde

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Sobre este laboratorio y su código: Laboratorio de agente de programación con IA: usa opencode para explicar y corregir código, y comprueba su trabajo

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.