¿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

Alternativas cuando falla una llamada a un modelo

Después de esta lección: Puedo mantener una función en marcha cuando falla una llamada a un modelo, eligiendo un respaldo para cada tipo de fallo.

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

Sigue funcionando cuando el modelo falla

Un respaldo es lo que hace una función cuando falla una llamada a un modelo, para que el usuario reciba algo. Importa porque las llamadas fallan de varias maneras, y una sola respuesta para todas es mala para la mayoría.

Un tiempo agotado merece un reintento. Un rechazo, no. Un presupuesto diario agotado pide una respuesta en caché o un mensaje honesto. Elige según el fallo.

Al final de esta lección

Nota

Puedo mantener una función en marcha cuando falla una llamada a un modelo, eligiendo un respaldo para cada tipo de fallo.

Palabras clave

PalabraQué significa
Respaldolo que haces en su lugar cuando falla una llamada
Reintentovolver a preguntar al mismo modelo, tras una espera
Segundo modelootro modelo al que se pregunta si falla el primero
Respuesta simpleun mensaje fijo y honesto, sin modelo
Degradardar una respuesta menor en lugar de ninguna
Tipo de falloel motivo por el que falló una llamada

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

Un respaldo es una cadena, en orden

Enumera las opciones de la menos costosa a la más degradada. Primero un reintento, tras una espera. Luego un segundo modelo. Luego una respuesta en caché, que puede ser vieja. Al final una respuesta simple: un mensaje fijo, verdadero, que dice al usuario qué hacer.

Cada paso cuesta tiempo y dinero. Una cadena que lo prueba todo en cada fallo duplica tu factura durante una caída.

Ejemplo resuelto: qué respaldo encaja

FalloPrimeroPor qué
Tiempo agotado, límite de ritmoReintentar una vezA menudo pasa solo
Error del servidorSegundo modeloEl primero está caído
Formato maloReintentar una vezUn segundo intento suele valer
RechazoRespuesta simpleVolver a preguntar no cambiará nada
Presupuesto agotadoRespuesta en cachéNo se permite ninguna llamada

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

Acota la cadena y dilo

Pon un límite a cada paso: un reintento, un segundo modelo. Espera entre intentos y cuenta la espera dentro del tiempo del usuario. Que un respaldo no oculte nunca un fallo. Registra qué paso respondió.

Una respuesta en caché puede estar desfasada, así que dilo si importa. Una respuesta simple nunca debe hacerse pasar por la del modelo.

Un error frecuente

Advertencia

Mucha gente cree que reintentar es siempre el respaldo más seguro. Pero reintentar un rechazo gasta dinero, y reintentar durante una caída añade carga. Reintenta solo los fallos que pueden pasar solos, y solo una vez.

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 la cadena de respaldos, parte 1

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' '' 'let now = 0; // milisegundos, en un reloj que movemos nosotros' 'const store = new Map([[\"horario\", \"Abrimos a las nueve y cerramos a las cinco de la tarde.\"]]);' 'const PLAIN = \"Lo siento, el asistente no puede responder ahora. Inténtalo más tarde.\";' '// Un fallo grabado sustituye a uno real. Nada aquí provoca un error de verdad.' 'function fail(kind) { throw new Error(kind); }' > fallback5.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 cadena de respaldos, parte 2

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function secondModel() {' '  const messages = [{ role: \"user\", content: \"Di el horario, de nueve a cinco, en una frase.\" }];' '  return (await ask(messages, \"Abrimos a las nueve y cerramos a las cinco de la tarde.\", 40)).text;' '}' >> fallback5.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 cadena de respaldos, parte 3

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function answer(question, second) {' '  const steps = [' '    [\"primer modelo\", function () { fail(\"rate_limit\"); }],' '    [\"reintento\", function () { now = now + 200; fail(\"rate_limit\"); }],' '    [\"segundo modelo\", second],' '    [\"caché\", function () { return store.has(question) ? store.get(question) : fail(\"miss\"); }],' '  ];' >> fallback5.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 cadena de respaldos, parte 4

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' '  for (const [name, run] of steps) {' '    try {' '      const text = await run();' '      console.log(question + \": respondió \" + name + \" a los \" + now + \" ms\");' '      return text;' '    } catch (error) {' '      console.log(question + \": \" + name + \" falló (\" + error.message + \")\");' '    }' '  }' '  console.log(question + \": respuesta simple\");' '  return PLAIN;' '}' >> fallback5.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 cadena de respaldos, parte 5

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  const down = function () { fail(\"server_error\"); };' '  await answer(\"horario\", secondModel);' '  await answer(\"horario\", down);' '  await answer(\"reembolso\", down);' '}' 'main();' >> fallback5.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 la cadena

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

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

Los fallos están grabados

Nada en este Run provoca un fallo real. Los rechazos y el error del servidor están escritos en el script como datos grabados, y el reloj es un número que mueve. Solo el segundo modelo es una llamada real.

Un sistema real recibe estos errores de una red real y espera de verdad entre intentos.

Una salida posible

LíneaQué muestra
horario: primer modelo falló (rate_limit)Un fallo grabado
horario: reintento falló (rate_limit)El reintento, tras 200 ms en nuestro reloj
horario: respondió segundo modelo a los 200 msLa única llamada real
horario: respondió caché a los 400 msEl segundo modelo está caído, así que responde la caché
reembolso: respuesta simpleNo había nada en caché, así que se usa el mensaje simple

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.