Seguir los datos por una función
Una revisión del flujo de datos sigue los datos personales desde que entran hasta que terminan. Pregunta adónde van, quién los ve, cuánto tiempo se quedan y para qué.
Una revisión detecta problemas sobre el papel, antes de que una función salga. Es una forma de pensar, y no un certificado de que algo cumple la ley.
Al final de esta lección
Nota
Puedo revisar el flujo de datos de una función con una lista de comprobación.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Flujo de datos | el camino que siguen los datos personales por una función | |
| Lista de comprobación | una lista de preguntas que cada paso debe responder | |
| Lugar aprobado | un sitio al que has decidido que pueden ir los datos | nuestra base de datos |
| Lector | una persona o grupo que puede ver los datos | |
| Finalidad | el motivo por el que un paso usa los datos |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Un flujo es una lista de pasos
Escribe cada paso del recorrido como una fila. Un paso tiene un nombre, los datos que usa, el lugar al que van y quién puede leerlos allí.
Tiene también los días que se guardan, si se ocultaron antes y el motivo de uso. Cinco preguntas convierten esas filas en una revisión.
Las cinco comprobaciones
| Comprobación | Falla cuando | Ejemplo del Run |
|---|---|---|
| Enviado sin ocultar | Los datos van a un lugar no aprobado, sin ocultar | App al modelo |
| Demasiados lectores | Entre los lectores están todos | Escritura del registro |
| Sin límite | No se fija ningún número de días | Escritura del registro |
| Conservado demasiado | Los días superan tu límite | Exportación semanal, 400 días |
| Sin finalidad | No se anota ningún motivo | Exportación semanal |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
La revisión informa de cada fallo
Comprueba cada paso en orden y anota todos los fallos que tenga. Un paso puede fallar varias comprobaciones. Un paso que no falla ninguna no añade nada a la lista.
Cuenta los fallos por comprobación. Así ves, por ejemplo, cuántos pasos no tienen límite, y puedes arreglarlos juntos.
Un error frecuente
Advertencia
Mucha gente cree que un flujo que pasa la lista cumple la ley. No es así. Solo muestra que cinco preguntas tienen respuesta. Las normas, como el RGPD, cambian según el lugar y el uso, así que decide una persona con la formación adecuada. Esta lección no es asesoramiento legal.
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 revisor de flujos, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const approved = [\"nuestra app\", \"nuestra base de datos\"];' 'const limit = 90;' 'const flow = [' ' { step: \"Formulario a la app\", data: [\"correo\", \"mensaje\"], to: \"nuestra app\", who: [\"soporte\"], keep: 30, redacted: false, why: \"Atender al cliente\" },' ' { step: \"App al modelo\", data: [\"mensaje\"], to: \"proveedor del modelo\", who: [\"proveedor del modelo\"], keep: 0, redacted: false, why: \"Redactar una respuesta\" },' ' { step: \"Escritura del registro\", data: [\"correo\"], to: \"nuestra base de datos\", who: [\"todos\"], keep: null, redacted: false, why: \"Depurar\" },' '];' > review.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 revisor de flujos, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'flow.push({ step: \"Exportación semanal\", data: [\"correo\"], to: \"proveedor de analítica\", who: [\"analista\"], keep: 400, redacted: true, why: \"\" });' 'flow.push({ step: \"Caché\", data: [], to: \"nuestra app\", who: [\"soporte\"], keep: 1, redacted: false, why: \"Rapidez\" });' 'function check(s) {' ' const out = [];' ' if (s.data.length > 0 && approved.indexOf(s.to) < 0 && s.redacted === false) out.push(\"enviado sin ocultar\");' ' if (s.who.indexOf(\"todos\") >= 0) out.push(\"demasiados lectores\");' ' if (s.keep === null) out.push(\"sin límite\");' ' else if (s.keep > limit) out.push(\"conservado demasiado\");' ' if (s.why.trim().length === 0) out.push(\"sin finalidad\");' ' return out;' '}' >> review.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 revisor de flujos, parte 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' let failing = 0;' ' flow.forEach(function (s) {' ' const f = check(s);' ' if (f.length > 0) failing = failing + 1;' ' console.log(s.step + \" -> \" + (f.length === 0 ? \"pasa\" : f.join(\", \")));' ' });' ' console.log(\"pasos que fallan: \" + failing + \" de \" + flow.length);' ' const q = \"En una frase corta, ¿por qué anotar la finalidad de cada paso que usa datos personales?\";' ' const sample = \"Una finalidad escrita muestra para qué se usan los datos, y un paso sin motivo destaca.\";' ' const reply = await ask([{ role: \"user\", content: q }], sample, 60);' ' console.log(\"el modelo dijo: \" + reply.text);' '}' 'main();' >> review.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 revisor de flujos
docker exec -w /home/node/project agent node review.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 |
|---|---|
| Formulario a la app -> pasa | Lugar aprobado, un motivo y un límite |
| App al modelo -> enviado sin ocultar | Un mensaje salió sin ocultar |
| Escritura del registro -> demasiados lectores, sin límite | Dos fallos en un paso |
| Exportación semanal -> conservado demasiado, sin finalidad | Dos fallos más |
| pasos que fallan: 3 de 5 | El resumen |
| el modelo dijo: ... | Una frase. Las palabras cambian en cada ejecución |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.