Qué hacer cuando falla una función de IA
Un incidente es un momento en que una función perjudica a los usuarios o al negocio, como reembolsos erróneos o una dirección filtrada. Gestionar un incidente es hallarlo, limitarlo, arreglarlo y aprender de él.
Importa porque una respuesta tranquila y ordenada limita el daño. Después, una buena revisión evita que el mismo fallo se repita.
Al final de esta lección
Nota
Puedo gestionar un incidente de IA y aprender de él.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Incidente | un momento en que una función perjudica a los usuarios | |
| Cronología | los sucesos en orden, con sus horas | |
| Gravedad | lo serio que es, de 1 a 3 | 2 |
| Mitigar | limitar el daño antes de arreglar la causa | |
| Revisión | una reunión para aprender qué dejó pasar el fallo |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Empieza con una cronología hecha con los registros
Pon cada suceso en orden de hora, aunque los registros lleguen en otro orden. Cada línea dice cuándo, quién y qué.
Después calcula dos números. El tiempo hasta detectar es lo que pasa desde el inicio hasta la primera señal. El tiempo hasta recuperar es lo que pasa desde el inicio hasta el arreglo.
Ejemplo resuelto: un texto de reembolsos erróneo
| Minuto | Quién | Suceso | Qué da |
|---|---|---|---|
| 0 | lanzamiento | El texto nuevo sale a producción | El inicio |
| 25 | soporte | Primer aviso de un cliente | Tiempo hasta detectar: 25 |
| 31 | guardia | Se declara el incidente | Empieza el trabajo |
| 40 | guardia | Se restaura el texto antiguo | El daño se detiene |
| 52 | monitor | Los reembolsos vuelven a cero | Tiempo hasta recuperar: 52 |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
La gravedad decide quién hace qué
Escribe la regla de gravedad antes de un incidente. Gravedad 1 es datos privados a la vista, o la mitad de los usuarios o más. Gravedad 2 es el diez por ciento o más. Lo que sea menos es 3.
Cada gravedad tiene una lista corta de acciones, y cada acción tiene un rol: líder, técnico o comunicación. Los roles evitan que todos hagan lo mismo.
Ejemplo resuelto: gravedad y acciones
| Gravedad | Cuándo | Acciones |
|---|---|---|
| 1 | Datos privados, o 50 por ciento o más | Avisar al responsable, revertir, avisar a los usuarios, hacer una revisión |
| 2 | De 10 a 49 por ciento | Revertir, avisar al equipo, hacer una revisión |
| 3 | Menos del 10 por ciento | Anotarlo en el registro |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Un error frecuente
Advertencia
Mucha gente cree que una revisión debe hallar quién cometió el error. Así la gente oculta cosas la próxima vez. Pregunta qué dejó pasar el sistema: ningún canario, ninguna alerta, una regla que nadie comprobó. Escribe roles en la revisión y nunca culpes a una persona.
Escribe el ayudante del modelo, parte 1
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
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 script del incidente, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const events = [' ' { at: 31, who: \"guardia\", kind: \"declared\", what: \"se declara el incidente\" },' ' { at: 0, who: \"lanzamiento\", kind: \"start\", what: \"el texto nuevo sale a producción\" },' ' { at: 52, who: \"monitor\", kind: \"resolved\", what: \"los reembolsos erróneos vuelven a cero\" },' ' { at: 25, who: \"soporte\", kind: \"detected\", what: \"primer aviso de un cliente\" },' ' { at: 40, who: \"guardia\", kind: \"mitigated\", what: \"se restaura el texto antiguo\" },' '];' > incident.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 script del incidente, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function first(kind) { return events.filter(function (e) { return e.kind === kind; })[0].at; }' 'function severity(percent, privateData) {' ' if (privateData || percent >= 50) return 1;' ' return percent >= 10 ? 2 : 3;' '}' 'const sorted = events.slice().sort(function (a, b) { return a.at - b.at; });' >> incident.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 script del incidente, parte 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' sorted.forEach(function (e) { console.log(\"minuto \" + e.at + \" \" + e.who + \": \" + e.what); });' ' console.log(\"tiempo hasta detectar: \" + (first(\"detected\") - first(\"start\")) + \" minutos\");' ' console.log(\"tiempo hasta recuperar: \" + (first(\"resolved\") - first(\"start\")) + \" minutos\");' ' console.log(\"gravedad: \" + severity(18, false));' ' const q = \"En una frase corta, ¿por qué una revisión debe nombrar roles y no personas?\";' ' const sample = \"Si se culpa a alguien, la gente oculta sus errores, y la revisión debe hallar lo que el sistema dejó pasar.\";' ' const reply = await ask([{ role: \"user\", content: q }], sample, 60);' ' console.log(\"el modelo dijo: \" + reply.text);' '}' 'main();' >> incident.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 informe del incidente
docker exec -w /home/node/project agent node incident.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 imprime el Run
| Línea | Qué muestra |
|---|---|
| minuto 0 lanzamiento: el texto nuevo sale a producción | Cinco sucesos, ordenados por minuto |
| tiempo hasta detectar: 25 minutos | El primer aviso menos el inicio |
| tiempo hasta recuperar: 52 minutos | Resuelto menos el inicio |
| gravedad: 2 | Con el 18 por ciento afectado y sin datos privados |
| el modelo dijo: ... | Una frase del laboratorio. Una muestra grabada si ningún modelo responde |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.