Anotar los riesgos para no olvidar ninguno
Un registro de riesgos es una tabla con lo que podría salir mal en una función. Anota lo probable que es y lo que harás al respecto.
Un equipo que solo habla de los riesgos olvida alguno. Un registro está escrito, así que puedes buscar huecos y poner primero lo peor.
Al final de esta lección
Nota
Puedo anotar los riesgos de una función de IA para que no quede nada fuera.
Palabras clave
| Palabra | Qué significa |
|---|---|
| Riesgo | algo que podría salir mal para una persona |
| Probabilidad | lo probable que es, de 1 a 3 |
| Impacto | lo grave que sería, de 1 a 3 |
| Medida | lo que haces para hacer más pequeño un riesgo |
| Área | una parte del recorrido de los datos, como el almacenamiento |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Cada riesgo tiene una puntuación y una medida
Da a cada riesgo una probabilidad y un impacto, cada uno de 1 a 3. La puntuación es el producto de los dos. Una puntuación de 2 o menos es baja, 3 o 4 es media, y 6 o 9 es alta.
Cada fila necesita también una medida. Un riesgo sin plan es solo una preocupación.
Ejemplo resuelto: probabilidad por impacto
| Riesgo | Probabilidad | Impacto | Puntuación | Nivel |
|---|---|---|---|---|
| El mensaje lleva un correo | 3 | 2 | 6 | Alto |
| El registro guarda mensajes enteros | 2 | 3 | 6 | Alto |
| La copia guarda datos borrados | 2 | 2 | 4 | Medio |
| El personal lee todos los chats | 1 | 3 | 3 | Medio |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Un registro puede tener huecos y filas malas
Una fila puede estar mal: una probabilidad de 5 o una medida vacía. Un registro también puede estar incompleto. Comprueba que cada área del recorrido de los datos tiene al menos una fila.
Las áreas típicas son recogida, envío, almacenamiento, acceso, borrado y entrenamiento. Un área sin fila es un hueco.
Un error frecuente
Advertencia
Mucha gente cree que la puntuación es una medición. Es un juicio escrito como número, y dos personas pueden discrepar. Úsala para ordenar la conversación y nunca para demostrar que una función es segura. Un registro corto puede ser solo uno incompleto.
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 comprobador del registro, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const required = [\"recogida\", \"envio\", \"almacenamiento\", \"acceso\", \"borrado\", \"entrenamiento\"];' 'const register = [' ' { risk: \"El mensaje lleva un correo\", area: \"envio\", l: 3, i: 2, fix: \"Ocultarlo antes\" },' ' { risk: \"El registro guarda mensajes enteros\", area: \"almacenamiento\", l: 2, i: 3, fix: \"Registrar solo la longitud\" },' ' { risk: \"La copia guarda datos borrados\", area: \"borrado\", l: 2, i: 2, fix: \"\" },' ' { risk: \"El personal lee todos los chats\", area: \"acceso\", l: 1, i: 3, fix: \"Limitar los lectores\" },' ' { risk: \"El proveedor guarda los mensajes\", area: \"recogida\", l: 0, i: 3, fix: \"Revisar el contrato\" },' '];' > register.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 comprobador del registro, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function level(s) { return s <= 2 ? \"bajo\" : s <= 4 ? \"medio\" : \"alto\"; }' 'function problems(r) {' ' const out = [];' ' if (r.l < 1 || r.l > 3) out.push(\"probabilidad fuera de rango\");' ' if (r.i < 1 || r.i > 3) out.push(\"impacto fuera de rango\");' ' if (r.fix.trim().length === 0) out.push(\"sin medida\");' ' return out;' '}' >> register.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 comprobador del registro, parte 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function covered(area) {' ' return register.some(function (r) { return r.area === area; });' '}' 'async function main() {' ' const ranked = register.slice().sort(function (a, b) { return b.l * b.i - a.l * a.i; });' ' ranked.forEach(function (r) {' ' const s = r.l * r.i;' ' console.log(s + \" \" + level(s) + \" | \" + r.risk + \" | \" + JSON.stringify(problems(r)));' ' });' ' console.log(\"áreas sin cubrir: \" + JSON.stringify(required.filter(function (a) { return covered(a) === false; })));' ' const q = \"Da una medida corta para este riesgo: una copia de seguridad guarda datos tras una petición de borrado.\";' ' const sample = \"Fija un plazo corto para las copias y di a la persona cuándo se limpian.\";' ' const reply = await ask([{ role: \"user\", content: q }], sample, 60);' ' console.log(\"el modelo dijo: \" + reply.text);' '}' 'main();' >> register.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 comprobador del registro
docker exec -w /home/node/project agent node register.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 |
|---|---|
| 6 alto | El mensaje lleva un correo | [] | El peor riesgo, sin ningún problema |
| 4 medio | La copia guarda datos borrados | ["sin medida"] | Una fila con una parte que falta |
| 0 bajo | El proveedor guarda los mensajes | ["probabilidad fuera de rango"] | Una fila con un número malo |
| áreas sin cubrir: ["entrenamiento"] | Un área sin fila |
| 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.