¿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

Datos personales fuera de los prompts

Después de esta lección: Puedo cambiar los datos personales por marcadores antes de llamar a un modelo y restituirlos después.

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

El mensaje con un teléfono dentro

Mantener los datos personales fuera de los prompts significa que el modelo solo ve lo que necesita para la tarea. Importa porque un prompt se envía a otro servicio y a menudo acaba en un registro.

Una herramienta de soporte envía cada mensaje a un modelo para redactar una respuesta. El mensaje lleva un nombre, un correo y un teléfono. La respuesta no necesita ninguno. La herramienta puede cambiarlos por marcadores y devolverlos después.

Al final de esta lección

Nota

Puedo cambiar los datos personales por marcadores antes de llamar a un modelo y restituirlos después.

Palabras clave

PalabraQué significaEjemplo
Dato personalcualquier detalle que identifica a una persona viva
Minimización de datosenviar solo lo que necesita la tarea
Ocultarcambiar un valor por un sustituto
Marcadoruna etiqueta que representa un valor retirado[CORREO_1]
Tabla de correspondenciala tabla que une cada marcador con su valor

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

Envía solo lo que necesita la tarea

Pregunta primero si el modelo necesita el valor. Responder a una queja necesita la queja, no el teléfono. Quita lo que no haga falta.

Si la respuesta debe mencionar a una persona, usa un marcador. El modelo escribe «Estimada [NOMBRE_1]» y tu propio código pone después el nombre real.

Ejemplo: antes y después

ValorEnviado al modeloGuardado en la tabla
Lucía[NOMBRE_1][NOMBRE_1] es Lucía
[email protected][CORREO_1][CORREO_1] es [email protected]
600123456[TELEFONO_1][TELEFONO_1] es 600123456
Lucía (otra vez)[NOMBRE_1]El mismo valor conserva el mismo marcador

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

Ocultar tiene límites

Una regla encuentra las formas que escribiste: una palabra con arroba, una larga tira de dígitos, un nombre de una lista. No ve el nombre de una calle, un apodo o un número escrito con espacios.

Por eso ocultar reduce el riesgo y nunca lo elimina. Pruébalo con ejemplos desordenados y conserva una comprobación que busque lo que quede.

Escribir 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\";' '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 || 200 }),' '      signal: AbortSignal.timeout(30000),' '    });' '    if (res.ok === false) throw new Error(\"estado \" + res.status);' '    return (await res.json()).choices[0].message.content;' > 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.

Escribir el ayudante del modelo, parte 2

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' '  } catch (error) {' '    console.log(\"Muestra grabada: ningún modelo respondió (\" + error.message + \").\");' '    const list = [].concat(sample);' '    const turn = messages.filter(function (m) { return m.role === \"assistant\"; }).length;' '    return list[Math.min(turn, list.length - 1)];' '  }' '}' '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.

Escribir el script de ocultación, parte 1

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' '' 'const names = [\"Lucía\", \"Mateo\"];' 'const ticket = \"Hola, soy Lucía. Escribe a [email protected] o llama al 600123456. Mateo me ayudó ayer.\";' 'function allDigits(text) {' '  return text.length >= 8 && text.split(\"\").every(function (c) { return c >= \"0\" && c <= \"9\"; });' '}' > redact.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 ocultación, parte 2

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function redact(text, names) {' '  const map = {};' '  const seen = {};' '  const words = text.split(\" \");' '  for (let i = 0; i < words.length; i++) {' '    let bare = words[i];' '    while (bare.endsWith(\".\") || bare.endsWith(\",\")) bare = bare.slice(0, -1);' '    const tail = words[i].slice(bare.length);' '    let kind = \"\";' '    if (bare.includes(\"@\")) kind = \"CORREO\";' '    if (allDigits(bare)) kind = \"TELEFONO\";' '    if (names.includes(bare)) kind = \"NOMBRE\";' >> redact.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 ocultación, parte 3

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' '    if (kind === \"\") continue;' '    if (seen[bare] === undefined) {' '      const n = Object.keys(map).filter(function (k) { return k.startsWith(\"[\" + kind); }).length + 1;' '      seen[bare] = \"[\" + kind + \"_\" + n + \"]\";' '      map[seen[bare]] = bare;' '    }' '    words[i] = seen[bare] + tail;' '  }' '  return { text: words.join(\" \"), map: map };' '}' >> redact.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 ocultación, parte 4

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function restore(text, map) {' '  let out = text;' '  for (const key of Object.keys(map)) out = out.split(key).join(map[key]);' '  return out;' '}' 'async function main() {' '  const safe = redact(ticket, names);' '  console.log(\"Enviado al modelo: \" + safe.text);' '  console.log(\"Queda una @: \" + safe.text.includes(\"@\"));' '  const rule = \"Escribe una respuesta de dos frases para la clienta. Conserva cada marcador entre corchetes exactamente como está escrito.\";' '  const messages = [{ role: \"system\", content: rule }, { role: \"user\", content: safe.text }];' '  const sample = \"Estimada [NOMBRE_1], gracias por tu mensaje. Escribiremos hoy a [CORREO_1].\";' >> redact.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 ocultación, parte 5

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' '  const reply = await ask(messages, sample, 100);' '  console.log(\"Respuesta con marcadores: \" + reply);' '  console.log(\"Restituida para la clienta: \" + restore(reply, safe.map));' '  console.log(\"Línea de registro: \" + Object.keys(safe.map).length + \" elementos ocultos, respuesta de \" + reply.length + \" caracteres\");' '}' 'main();' >> redact.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 ocultación

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

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

Una salida posible

LíneaQué muestra
Enviado al modeloEl mensaje con [NOMBRE_1], [CORREO_1], [TELEFONO_1] y [NOMBRE_2] en lugar de los valores
Queda una @false
Respuesta con marcadoresDos frases que conservan los marcadores. Las palabras cambian en cada ejecución
Restituida para la clientaLa respuesta con los valores reales devueltos
Línea de registroCuentas y una longitud, sin texto personal

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

Qué puede contener un registro

Un registro lo lee más gente que la aplicación, y dura más. Registra lo que necesites para encontrar un fallo: un identificador de petición, un identificador de usuario, una cuenta, una hora, una decisión.

No registres el prompt ni la respuesta enteros. Si debes guardar uno para depurar, guarda la copia oculta, poco tiempo y con acceso controlado.

Un error frecuente

Advertencia

Mucha gente cree que, una vez ocultado el prompt, los registros son seguros. La respuesta, los mensajes de error y la petición original aún pueden contener los valores reales. Revisa cada lugar por el que pasa el texto: el prompt, la respuesta, los registros y cualquier caché.

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.