Quién pidió eso al asistente
Un registro de auditoría dice quién hizo qué y cuándo, sin guardar el texto privado. Importa porque, cuando algo falla, hay que reconstruir lo ocurrido sin haber copiado los mensajes de todos.
El martes una herramienta rechaza una petición rara. El viernes alguien pregunta por qué. Un registro con un identificador, el nombre de la herramienta, un resultado y una hora lo responde. Una copia del chat también, y sería un riesgo.
Al final de esta lección
Nota
Puedo escribir registros de auditoría sin contenido privado y borrarlos cuando acaba su tiempo de retención.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Registro de auditoría | una nota de quién hizo qué, cuándo y con qué resultado | |
| Retención | cuánto tiempo se guarda un registro | |
| Purga | borrar los registros que han pasado su tiempo | |
| Reloj simulado | una hora que fija tu código, para que una prueba controle el tiempo | |
| Identificador | un código que representa a una persona sin nombrarla | u-17 |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Anota quién, qué y cuándo
Escribe un registro pequeño por cada cosa que hizo la función. Limítate a una lista fija de campos. Todo lo demás, como un prompt o una respuesta, se descarta antes de guardar.
Usa un identificador para la persona, no un nombre. Añade registros y no los edites nunca, para que el registro siga siendo fiable.
Ejemplo: un registro de auditoría
| Campo | Ejemplo | Por qué está |
|---|---|---|
| at | una hora | Cuándo ocurrió |
| id | 1 | Un número para cada registro, que pone el script |
| user | u-17 | Quién pidió, sin nombre |
| action | read_note | Qué hizo la función |
| outcome | permitida | Qué decidieron las comprobaciones |
| tokens | 120 | Lo que costó, en una cuenta |
| (no se guarda) | el texto del prompt | Puede contener datos personales |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Guarda los registros mientras sirvan
Cada registro tiene una razón, y esa razón termina. Elige un tiempo de retención por tipo: corto para el texto del chat, más largo para los registros de auditoría. Luego borra lo más antiguo.
Las obligaciones legales varían según el país y el sector: comprueba las que te afecten antes de elegir un número.
Escribir el script de auditoría, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const DAY = 24 * 60 * 60 * 1000;' 'let now = Date.UTC(2026, 0, 1);' 'const allowed = [\"user\", \"action\", \"outcome\", \"tokens\"];' 'const log = [];' '' '// Un registro de auditoría guarda quién, qué y cuándo. Nunca el texto.' 'function record(fields) {' ' const clean = { at: now, id: log.length + 1 };' ' for (const key of allowed) {' ' if (key in fields) clean[key] = fields[key];' ' }' ' log.push(clean);' ' return clean;' '}' > audit.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribir el script de auditoría, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'record({ user: \"u-17\", action: \"read_note\", outcome: \"permitida\", tokens: 120, prompt: \"Hola, soy Lucía\" });' 'now = now + 20 * DAY;' 'record({ user: \"u-18\", action: \"run_shell\", outcome: \"rechazada\", tokens: 0 });' 'now = now + 20 * DAY;' 'record({ user: \"u-17\", action: \"add_numbers\", outcome: \"permitida\", tokens: 60 });' 'console.log(\"Campos guardados: \" + Object.keys(log[0]).join(\", \"));' 'console.log(\"Prompt guardado: \" + (\"prompt\" in log[0]));' >> audit.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribir el script de auditoría, parte 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' '// Retención: guardar un registro 30 días y luego borrarlo.' 'const KEEP = 30 * DAY;' 'function purge(list, at) {' ' return list.filter(function (item) { return at - item.at <= KEEP; });' '}' 'const left = purge(log, now);' 'console.log(\"Antes: \" + log.length + \", después: \" + left.length);' 'console.log(\"Identificadores que quedan: \" + left.map(function (item) { return item.id; }).join(\", \"));' >> audit.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Ejecutar el script de auditoría
docker exec -w /home/node/project agent node audit.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 el script
| Línea | Qué indica |
|---|---|
| Campos guardados: at, id, user, action, outcome, tokens | El campo prompt se descartó |
| Prompt guardado: false | Nada privado llegó al registro |
| Antes: 3, después: 2 | El primer registro tiene 40 días y el límite es 30 |
| Identificadores que quedan: 2, 3 | Los dos registros recientes sobreviven |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Una lista hace de almacén real
El script guarda su registro en un array y mueve a mano un reloj simulado. Un sistema real usa una base de datos, con copias de seguridad y control de acceso, y una tarea programada que purga.
Las copias de seguridad también cuentan. Un registro borrado de la base sigue en la copia del mes pasado, salvo que la copia caduque también.
Un error frecuente
Advertencia
Mucha gente cree que registrar más siempre es más seguro. Un registro que guarda cada prompt es en sí un almacén de datos personales, y hay que protegerlo y borrarlo como tal. Registra los campos que necesitarás para responder a una pregunta, y no más.