Ordenar el buzón de ayuda
Clasificar textos con un modelo es pedirle que elija una etiqueta de una lista fija para cada mensaje. Importa porque un programa sabe encaminar una etiqueta, pero no una frase libre.
La aplicación de la cafetería de un campus quiere enviar cada mensaje a facturación, al equipo de la aplicación o a una ventanilla general. Un modelo puede leer el mensaje y nombrar el servicio. La duda es cuántas veces acierta.
Al final de esta lección
Nota
Puedo etiquetar textos con una lista fija y medir cuántas etiquetas son correctas.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Etiqueta | una palabra que nombra la clase de un texto | facturacion |
| Etiquetas permitidas | la lista fija de la que sale la etiqueta | |
| Desconocido | la etiqueta de un texto que no encaja en ninguna | |
| Respuesta conocida | la etiqueta que una persona eligió de antemano | |
| Exactitud | la parte de etiquetas iguales a la respuesta conocida | |
| Casos de prueba | textos con respuesta conocida, para medir |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Da una lista fija y una etiqueta desconocido
Pon las etiquetas permitidas en la instrucción y di: responde solo con la palabra. Añade una salida. Si ninguna etiqueta encaja, el modelo debe decir desconocido, para que no se vea obligado a elegir una equivocada.
Luego limpia lo que vuelve. Una respuesta puede traer una mayúscula, un punto o palabras de más. Conviértela en una etiqueta permitida, o en desconocido.
Ejemplo resuelto: limpiar cinco respuestas
| Respuesta | Etiqueta limpia | Por qué |
|---|---|---|
| facturacion | facturacion | Ya es una etiqueta permitida |
| Fallo. | fallo | Se quitan la mayúscula y el punto |
| "otro" | otro | Se quitan las comillas |
| Es un fallo | desconocido | Varias palabras, no una etiqueta |
| reembolso | desconocido | No está en la lista permitida |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Mide con respuestas conocidas
Para saber si un etiquetador es bueno, pruébalo. Escribe antes unos casos de prueba: textos con una respuesta conocida que una persona eligió. Pasa el modelo por cada uno, limpia la etiqueta y compara.
La exactitud es el número de etiquetas correctas dividido por el total, como porcentaje entero. Luego lee las erróneas: te muestran qué corregir en la instrucción.
Escribir la ayuda 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\";' '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 la ayuda del modelo, parte 2
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 etiquetador, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' '' 'const allowed = [\"facturacion\", \"fallo\", \"otro\"];' '// Casos con respuesta conocida, escritos por una persona antes de preguntar al modelo.' 'const cases = [' ' { text: \"Me cobraron dos veces el menú.\", expected: \"facturacion\" },' ' { text: \"La aplicación se cierra al pulsar Pagar.\", expected: \"fallo\" },' ' { text: \"¿A qué hora abre la cafetería los sábados?\", expected: \"otro\" },' ' { text: \"Mi reembolso todavía no ha llegado.\", expected: \"facturacion\" },' '];' > label5.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 etiquetador, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' '// Muestras grabadas, usadas solo si ningún modelo responde. Dos son desordenadas a propósito.' 'const samples = [\"facturacion\", \"Fallo.\", \"otro\", \"reembolso\"];' 'const PROMPT = \"Pon a este mensaje de ayuda exactamente una palabra de esta lista: facturacion, fallo, otro. Si ninguna encaja, responde desconocido. Responde solo con la palabra.\n\nMensaje: \";' '' '// Convertir cualquier respuesta en una etiqueta permitida, o en desconocido.' 'function cleanLabel(reply) {' ' let text = reply.trim().toLowerCase();' ' while (text.length > 0 && (text.endsWith(\".\") || text.endsWith(\" \"))) text = text.slice(0, -1);' ' return allowed.includes(text) ? text : \"desconocido\";' '}' >> label5.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 etiquetador, parte 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' let right = 0;' ' let unknown = 0;' ' for (let at = 0; at < cases.length; at = at + 1) {' ' const reply = await ask([{ role: \"user\", content: PROMPT + cases[at].text }], samples[at], 10);' ' const label = cleanLabel(reply);' ' if (label === cases[at].expected) right = right + 1;' ' if (label === \"desconocido\") unknown = unknown + 1;' ' console.log((at + 1) + \" \" + label + \" (esperada \" + cases[at].expected + \") \" + (label === cases[at].expected ? \"bien\" : \"mal\"));' ' }' ' console.log(\"Exactitud: \" + right + \" de \" + cases.length + \" (\" + Math.floor(right * 100 / cases.length) + \" por ciento)\");' ' console.log(\"Etiquetas desconocidas: \" + unknown);' '}' 'main();' >> label5.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Ejecutarlo con cuatro mensajes
docker exec -w /home/node/project agent node label5.jsSe 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ínea | Lo que puede mostrar |
|---|---|
| 1 a 4 | Una etiqueta, la etiqueta esperada, y bien o mal |
| Exactitud | Por ejemplo 3 de 4 (75 por ciento), o 4 de 4 |
| Etiquetas desconocidas | Cuántas respuestas no pudieron convertirse en una etiqueta permitida |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Un error frecuente
Advertencia
Mucha gente cree que un 100 por ciento en pocos casos demuestra que el etiquetador es bueno. Un puñado de casos demuestra poco. Usa muchos casos, incluye casos difíciles y lee las respuestas erróneas.