Diego RomeroIngeniero y peregrino

Los datos privados de una empresa podrían hacer mucho más útiles a los modelos pequeños

Los datos privados de una empresa podrían hacer mucho más útiles a los modelos pequeños

Dos rondas de un experimento de clasificación de correos, una auditoría que tumbó la primera y muchas formas de enseñar una decisión de negocio a un modelo, medidas sobre el mismo test.

Una empresa puede tener años de correos y de tickets de soporte que muestran cómo decide su gente. Quién recibe una petición. Qué incidencia necesita atención inmediata. Cuándo se espera una respuesta y cuándo el trabajo puede seguir sin ella.

Buena parte de ese conocimiento es difícil de recoger en una instrucción general como «clasifica este correo». Depende de las responsabilidades de la empresa, de sus costumbres de trabajo y de sus excepciones. Un correo que a alguien de fuera le parece rutinario puede necesitar atención hoy por un compromiso que solo esa empresa conoce.

Por eso quiero probar modelos pequeños con datos privados de empresa. Si esas decisiones pueden convertirse en ejemplos de entrenamiento fiables, ¿podría un modelo pequeño y rápido aprender lo suficiente de un flujo de trabajo concreto como para ser útil?

Todavía no lo he probado con datos reales de una empresa. Lo que sí he hecho son dos rondas del mismo experimento con datos sintéticos, con tres familias de modelos y todas las formas razonables de enseñarles la decisión. La versión corta:

  • Los ejemplos son lo que enseña la decisión a un modelo pequeño. Cuatro modelos de 0,3 a 2,2 mil millones de parámetros pasaron del 8–57% al 90–93% tras un fine-tuning con 1.985 correos etiquetados, y responden en centésimas de segundo.
  • Un modelo preentrenado para decidir no necesita ejemplos. El mayor modelo de Decision 3.0, de 26 mil millones de parámetros, sacó un 98,5% tal como viene. Un modelo generalista de 9 mil millones llegó como mucho al 61% con una política escrita.
  • Con suficientes ejemplos, un modelo mayor llega más lejos. Los modelos de 8 a 9 mil millones de parámetros con fine-tuning rondaron el 99% (Decision 3.0 flash, 99,2%; Qwen3.5-9B, 99,0%), frente al 90–95% de los más pequeños, a varias veces su coste por correo.
  • Escribir un prompt mejor ayuda un poco; meter ejemplos en el prompt, no. Se cumplió en todas las familias.

Los datos son sintéticos y las etiquetas siguen una política que se aplica sin excepciones, así que nada de esto demuestra cómo funcionaría un modelo dentro de una empresa. Sí muestra qué palancas mueven a un modelo en una decisión como esta y cuánto cuesta cada una.

No lo hice solo. Dos agentes de programación, Codex y Claude Code, me ayudaron a escribir los scripts de generación del dataset, de entrenamiento y de evaluación, a analizar los resultados y a gestionar los entornos de Colab y de la DGX Spark. Yo diseñé los experimentos y revisé las cifras que aparecen aquí. El código, los datasets y todas las mediciones están publicados en el repositorio teaching-one-decision de GitHub.

Los datos útiles explican una decisión

Cada correo necesita tres respuestas: qué equipo se encarga, qué urgencia tiene y si quien escribe espera una respuesta por escrito.

Parecen campos sencillos hasta que alguien tiene que etiquetarlos de forma coherente. Un mensaje sobre un producto técnico puede corresponder a ventas. Una incidencia resuelta puede seguir llevando un asunto urgente. Una petición para actualizar un documento puede requerir una acción sin requerir una respuesta por correo.

Los registros de una empresa podrían ayudar a explicar esas diferencias. Los ejemplos que merece la pena buscar conectan el mensaje, el contexto disponible en ese momento, la decisión y cualquier corrección posterior. Un ticket que se pasa a otro equipo puede revelar un error de asignación. Una corrección humana puede mostrar dónde una regla necesita una excepción.

El ejemplo de entrenamiento tiene que contener información suficiente para justificar su etiqueta. Si la urgencia depende de un plazo interno, el modelo necesita ese plazo en su entrada. Si la etiqueta depende de información que el modelo no ve, el modelo solo puede adivinar.

Una regla de decisión estable también es distinta de un dato que cambia. El entrenamiento puede enseñar al modelo cómo tratar un plazo incumplido. El plazo vigente debe venir del sistema de la empresa en el momento de decidir. Ningún checkpoint se mantendrá al día de cada contrato o cada cambio de plantilla.

Arquitectura empresarial propuesta: casos históricos revisados entrenan un checkpoint; los correos nuevos y el contexto actual del negocio alimentan ese modelo, que devuelve decisiones tipadas para revisión humana.

Arquitectura propuesta. El histórico revisado da forma al checkpoint fuera de línea; los datos actuales del negocio llegan con cada correo nuevo. Nada de este diagrama se desplegó en los experimentos.

Primera ronda: un resultado que no se sostuvo

El primer test usó 3.200 correos sintéticos de 80 familias temáticas. Laya multilingual, un modelo de 322 millones de parámetros que puntúa decisiones tipadas en lugar de generar texto, pasó del 16,75% al 88,25% tras el fine-tuning, por delante de Qwen3.5-9B, con un 80,00%.

Luego lo auditó. Un clasificador de recuento de palabras entrenado con los mismos correos, sin GPU, sacó un 84%. Todos los correos de prioridad alta decían «en N minutos» o mencionaban el servicio en producción, así que una sola expresión regular los encontraba todos. Los distractores, un hilo citado con «URGENTE» y una instrucción inyectada, eran idénticos en entrenamiento y en test, y la mayor parte de la ventaja de Laya venía de esos correos. Además, Qwen se había ejecutado sin sus kernels optimizados.

Todas las cifras cuadraban con las predicciones en bruto. Sencillamente, el test era demasiado fácil para mostrar qué había aprendido el modelo.

Segunda ronda: un test hecho para resistir atajos

Rehíce el dataset para que los patrones superficiales no bastaran para resolverlo.

La prioridad depende del contexto, no de las palabras. Cada entrada empieza con una cabecera del sistema de clasificación: cuándo llegó el correo, el nivel de servicio del cliente (Premium o Standard) y las incidencias abiertas. Un correo es de prioridad alta solo si trata de una incidencia marcada con «customer impact: yes», fija un plazo que vence el mismo día en que se recibió o viene de una cuenta Premium cuyo trabajo está bloqueado.

El mismo texto puede llevar etiquetas distintas. 620 correos son gemelos contrafactuales: el mismo texto con otra cabecera. «El jueves a las 15:00» es urgente si el correo llega el jueves por la mañana y rutinario si llega el lunes. Un modelo que solo lee las palabras puede acertar, como mucho, la mitad de cada par.

La categoría sigue a la petición, no al tema. Cada cliente escribe a los cinco equipos, y la mitad de los correos mencionan de pasada el tema de otro equipo.

Sin plantillas. Escribí a mano 80 cuentas de cliente, 150 tipos de petición y 60 tipos de aviso. Las cuentas y los tipos de petición del test nunca aparecen en entrenamiento. gpt-6.1-sol redactó cada correo a partir de un guion estructurado, una segunda comprobación confirmó que el texto se ajustaba al guion, y las etiquetas salieron siempre del guion, nunca de un modelo.

El resultado tiene 3.176 correos: 1.985 de entrenamiento, 395 de validación, 398 de calibración y 398 de test. Antes de ejecutar ningún modelo comprobé que no se podía atajar:

Comprobación sobre el test Primera ronda Segunda ronda
Clasificador de recuento de palabras entrenado con todo el train 84,0% 52,0%
El mismo clasificador, solo prioridad 93,5% 62,1%
Reglas de palabras clave, o reglas que leen la cabecera y cruzan fechas 35,3% 27–28%
Frases del test que aparecen literalmente en entrenamiento 48% 8%
gpt-6.1-sol con solo la política escrita — 99,5%

La última fila importa tanto como las demás. Un test difícil no sirve si sus etiquetas son ambiguas; cuando un modelo potente que solo tiene la política escrita recupera el 99,5% de ellas, es que se deducen de la entrada. Pasar esa comprobación por todos los correos también destapó errores míos: 11 temas de aviso ambiguos y 140 peticiones que no tienen sentido «sin respuesta», como «explicadme por qué…». Los corregí y los regeneré antes de nada.

Tres familias, cinco formas de enseñar

Comparé tres familias de modelos:

  • Laya multilingual, 322 millones de parámetros, un modelo de decisión que puntúa opciones de respuesta.
  • Qwen3.5-9B, un modelo generalista que genera texto, ejecutado en 4 bits y con su salida JSON restringida al esquema.
  • Decision 3.0, seis modelos de decisión de 0,59 a 26 mil millones de parámetros, creados por el equipo de vLLM Semantic Router sobre Qwen 3.5 y 3.8 y publicados el 10 de octubre de 2026. Como Laya, puntúan las opciones de respuesta en una sola pasada y usan el mismo formato de preguntas.

Y cinco formas de enseñarles la decisión, aplicadas a cada familia donde tienen sentido:

  1. La política escrita, tal cual. La definición de cada campo como instrucción. Es zero-shot: sin ejemplos.
  2. Prompt v2. La misma política reescrita como un procedimiento explícito, por ejemplo «calcula la fecha del plazo y compárala con la fecha de Received». No añade información.
  3. Prompt v2 con ocho ejemplos. Los mismos ocho correos de entrenamiento para todos los modelos, que cubren todos los equipos y prioridades y dos pares de gemelos.
  4. Razonamiento (thinking). Solo Qwen: hasta 1.024 tokens de razonamiento antes de responder. Los modelos de decisión no generan texto.
  5. Fine-tuning con los 1.985 correos de entrenamiento. Fine-tuning completo para los modelos de decisión pequeños y adaptadores QLoRA o LoRA para los mayores. Los detalles están en el apéndice.

Laya y Qwen se ejecutaron en una NVIDIA T4 de Google Colab. Decision 3.0, en una NVIDIA DGX Spark (GB10). La precisión es comparable entre todos; la velocidad, solo dentro del mismo hardware.

Sin ejemplos: lo que el modelo ya sabe

Modelo Tamaño Política escrita Prompt v2 Prompt v2 + 8 ejemplos
Laya 0,32B 8,5% — —
d3-edge 0,59B 17,3% 14,3% 11,6%
d3-lite 0,85B 32,7% 31,4% 28,1%
d3-nano 2,2B 56,5% 57,3% 53,8%
d3-mini 4,5B 72,6% 74,9% 64,6%
d3-flash 8,4B 79,4% 84,2% 77,1%
Qwen3.5-9B 9B 53,3% 61,3% 59,3%
d3 26B 98,5% 98,0% 98,7%

Los tres campos correctos, en los 398 correos de test. Qwen con razonamiento llegó al 75,0% en una muestra de 44 correos (59,1% con el prompt v2 solo, en los mismos correos), a 94 segundos por correo.

Destacan tres cosas.

El preentrenamiento para decidir pesa más que el tamaño. d3-flash y Qwen tienen un tamaño parecido, y d3-flash sacó entre un 79 y un 84% frente al 53–61% de Qwen. También usó la cabecera: en los 74 pares de gemelos acertó la prioridad de los dos correos en el 80–82% de los pares; Qwen, en el 19–35%.

El mayor modelo de decisión ya está en el techo. d3, con 26 mil millones de parámetros, sacó un 98,5% (intervalo del 95%: 97,5–99,5%) sin ejemplos. Detectó los 122 correos urgentes sin ninguna falsa alarma y acertó los dos correos de cada par de gemelos. Sus seis errores fueron todos avisos dudosos, como un cambio de cortafuegos que un lector archivaría en técnico y otro en información. Se publicó un día antes de que generara el dataset, así que no puede haber visto estos correos.

El prompt es una palanca pequeña. Reescribir la política como un procedimiento ayudó a los modelos medianos y grandes entre dos y ocho puntos, y no ayudó a los pequeños. Ocho ejemplos en el prompt empeoraron a casi todos los modelos, a veces en diez puntos. Los modelos pequeños, sobre todo, se pierden con instrucciones largas.

Con ejemplos: lo que aporta el fine-tuning

Modelo Tamaño Antes Tras el fine-tuning Intervalo del 95% Prioridad Tiempo de entrenamiento Hardware
Laya 0,32B 8,5% 92,5% 89,2–95,5% 97,7% 44 min T4
d3-edge 0,59B 17,3% 92,7% 90,0–95,5% 99,2% 40 min GB10
d3-lite 0,85B 32,7% 90,5% 87,9–93,0% 97,7% 81 min GB10
d3-nano 2,2B 56,5% 92,5% 89,2–95,2% 98,0% 137 min GB10
d3-mini, LoRA 4,5B 72,6% 94,5% 92,0–96,5% 100,0% 76 min GB10
d3-flash, LoRA 8,4B 79,4% 99,2% 98,5–100% 99,5% 109 min GB10
Qwen3.5-9B, QLoRA, 448 correos 9B 53,3% 93,2% 90,5–95,7% 94,2% 61 min T4
Qwen3.5-9B, QLoRA, todo el train 9B 53,3% 99,0% 98,0–100% 99,8% 262 min T4
d3 (sin fine-tuning, ver abajo) 26B 98,5% — — — — GB10

En los modelos de decisión, los tiempos de entrenamiento incluyen la validación tras cada época.

Todos los modelos pequeños aprendieron la decisión. Laya y los tres modelos de decisión más pequeños empezaron entre el 8 y el 57% y terminaron entre el 90 y el 93%. Aprendieron a usar la cabecera, no solo las palabras: d3-edge detectó los 122 correos urgentes sin falsas alarmas y acertó la prioridad de los dos correos en todos los pares de gemelos. Entre estos modelos pequeños, el tamaño apenas importó una vez que tuvieron los ejemplos: d3-nano, casi cuatro veces mayor que d3-edge, acabó al mismo nivel.

Un modelo mayor entrenado con los mismos datos llegó más lejos. Con QLoRA sobre todo el conjunto de entrenamiento, Qwen alcanzó el 99,0%, claramente por encima de los modelos pequeños; los intervalos no se solapan. Una primera ejecución de QLoRA que, por un fallo de planificación, solo vio 448 correos ya llegó al 93,2%: un modelo preentrenado mayor necesita menos ejemplos para igualar a uno pequeño.

No hice fine-tuning del modelo de decisión de 26B. Ya sacaba un 98,5% sin ejemplos, en el techo de consistencia de las etiquetas. En un test de 398 correos, un fine-tuning podría sumar como mucho 1,5 puntos, dentro del intervalo, así que no se podría demostrar ninguna mejora, y habría costado unas cinco horas de GPU. Fue una decisión deliberada, no una ejecución fallida.

Los modelos medianos llegaron arriba con una sola pasada de LoRA. d3-flash, con 8,4 mil millones de parámetros, alcanzó el 99,2% (98,5–100%), al nivel de Qwen con fine-tuning y de tamaño parecido. d3-mini, con 4,5 mil millones, llegó al 94,5% y acertó todas las decisiones de prioridad y de respuesta; todos sus errores restantes fueron de equipo. El patrón entre familias es claro: en torno al 90–95% tras el fine-tuning para modelos de hasta 4,5 mil millones de parámetros, y en torno al 99% para los de 8 a 9 mil millones, tanto si empezaron como modelos de decisión como si eran generalistas. De dónde partían importó sin ejemplos; con ellos, mucho menos.

Lo que cuesta usar cada opción

En precisión, los mejores están cerca. En coste de uso, no.

Opción Los tres campos Por correo Memoria de GPU Hardware
d3-edge, con fine-tuning 92,7% 0,04 s 1,3 GiB GB10
Laya, con fine-tuning 92,5% 0,05 s 1,5 GiB T4
d3-lite, con fine-tuning 90,5% 0,09 s 1,8 GiB GB10
d3-nano, con fine-tuning 92,5% 0,13 s 4,3 GiB GB10
d3-mini, con fine-tuning 94,5% 0,32 s 8,8 GiB GB10
d3-flash, con fine-tuning 99,2% 0,52 s 16 GiB GB10
d3, tal cual 98,5% 1,7 s 49 GiB GB10
Qwen3.5-9B, QLoRA, todo el train 99,0% 5,0 s 8,2 GiB T4
Qwen3.5-9B, prompt v2 61,3% 4,1 s 8,0 GiB T4
Qwen3.5-9B, con razonamiento 75,0% (44 correos) 94 s — T4

Los tiempos son medianas por correo después de cargar el modelo, de uno en uno y sin procesamiento por lotes. Los lotes ayudarían a todas las opciones, y los modelos generativos suelen ganar más con ellos, así que estas diferencias son un máximo para esta configuración. La carga también cambia: menos de 12 segundos para los modelos pequeños, unos 100 segundos para Qwen y unos 320 segundos para el modelo de decisión de 26B.

En una sola T4, los modelos pequeños con fine-tuning procesarían 1.000 correos en un minuto, más o menos. Qwen con fine-tuning tardaría unos 80 minutos. El modelo de decisión de 26B necesita unos 50 GB de memoria, lo que descarta las GPU pequeñas, aunque no necesita ningún dato de entrenamiento.

Cómo elegiría

  • Sin ejemplos etiquetados: un modelo preentrenado para decidir, tan grande como permita el hardware. En este test, el modelo de Decision 3.0 de 26B llegó al techo solo con la política escrita, y el de 8,4B alcanzó el 79–84% donde un modelo generalista del mismo tamaño se quedó en el 61%.
  • Con ejemplos etiquetados y mucho volumen: fine-tuning de un modelo de decisión pequeño. Aquí rondó el 92%, responde en centésimas de segundo y funciona en un hardware que una empresa puede tener en casa.
  • Con ejemplos etiquetados y la máxima precisión: fine-tuning de un modelo de 8 a 9 mil millones de parámetros, a ser posible uno hecho para decidir. d3-flash con LoRA llegó aquí al 99,2% a medio segundo por correo en la GB10; Qwen con fine-tuning, al 99,0% a cinco segundos en la T4. El modelo de decisión de 26B llegó al 98,5% sin entrenamiento, con unos 50 GB de memoria.
  • Elijas lo que elijas: construye un test que un clasificador de recuento de palabras no pueda superar y comprueba que sus etiquetas se deducen de la entrada antes de fiarte de ninguna cifra.

Lo que una empresa tendría que aportar

Un piloto real empieza con una sola decisión bien acotada y con las personas que ya la toman. Tienen que ponerse de acuerdo sobre las etiquetas antes de que nadie extraiga un dataset grande.

A partir de ahí, el piloto necesita:

  • Una muestra revisada. Cada caso lleva la entrada disponible en el momento de decidir, una decisión objetivo revisada y una nota de por qué los casos ambiguos recibieron su etiqueta. Incluye decisiones corregidas, casos raros y ejemplos cerca de las fronteras entre categorías. Los mensajes rutinarios mantienen su proporción real.
  • Una mirada crítica al histórico. Un resultado histórico es un punto de partida para revisar, no la verdad. Puede recoger un error, una política obsoleta o un apaño temporal, y entrenar con él sin cambios reproduciría esas decisiones. Si los revisores no se ponen de acuerdo, hay que aclarar la política antes de entrenar más el modelo.
  • El contexto que necesita la decisión, en la entrada. El segundo test funcionó porque la cabecera llevaba los datos de los que depende la prioridad. En una empresa, eso significa que el compromiso de servicio, el responsable actual o el estado de una incidencia viajan con el mensaje.
  • Activos controlados. El dataset y el checkpoint resultante son activos internos y necesitan los mismos controles que los datos de origen. Un modelo pequeño no hace privado un sistema por sí solo, y estas ejecuciones no probaron un despliegue privado en una empresa.
  • Un test honesto. Reserva un periodo posterior de casos reales, mantén juntos los hilos completos y comprueba si coincidir en cliente o en proyecto hace el test demasiado fácil. Ejecuta un baseline de recuento de palabras antes que cualquier modelo y comprueba que las etiquetas son coherentes con la política escrita.

En un primer piloto, las decisiones seguirían bajo revisión humana y se registraría cada corrección. Así se miden los errores que importan y, a la vez, se generan ejemplos nuevos.

Flujo operativo propuesto: inferencia programada, validación del esquema, liberación de recursos y revisión humana; las correcciones revisadas alimentan una actualización del modelo que se evalúa por separado.

Flujo de piloto propuesto. Las predicciones se guardan y cualquier GPU temporal se libera antes de la revisión. Al principio se revisan todos los casos. Las correcciones entran en un dataset revisado; nunca actualizan automáticamente el modelo en producción.

Lo que esto no demuestra

Los datos son sintéticos. La política es explícita y se aplica sin excepciones, y las decisiones reales tienen más ruido: dos personas con experiencia a veces discrepan sobre el mismo correo. Las bandejas de entrada reales tienen además hilos largos con muchos participantes, contexto que falta y políticas que cambian. Los correos los escribió un modelo de lenguaje a partir de guiones, así que comparten su estilo. Cada configuración se ejecutó una vez, con una semilla. La ejecución con razonamiento cubrió 44 correos. Laya y Qwen se ejecutaron en una GPU distinta de la de Decision 3.0, así que sus velocidades no son directamente comparables.

Así que la pregunta sigue abierta: ¿pueden las decisiones revisadas de una empresa enseñar su flujo de trabajo a un modelo pequeño y rápido? Estos experimentos dicen que el método funciona cuando los ejemplos llevan el contexto adecuado, que los modelos hechos para decidir parten mucho más cerca de la respuesta y que un test hay que comprobarlo a fondo antes de creérselo. La siguiente prueba útil tiene que venir de datos reales y revisados de una empresa.


Apéndice: cómo se configuró cada modelo

Común a todos. Los mismos 398 correos de test, la misma cabecera y texto, la misma política escrita. La precisión completa significa acertar los tres campos. Intervalos: bootstrap al 95% sobre las diez cuentas de test (5.000 remuestreos). Ningún correo de test se usó para entrenar, seleccionar modelos ni calibrar.

Laya, fine-tuning completo (T4). convaiinnovations/laya-multilingual en la revisión 1720e3e, con el propio entrenador de Laya y el encoder desbloqueado. AdamW con weight decay de 0,01, tasas de aprendizaje de 2,5e-5 (encoder) y 1e-4 (cabeza), coseno hasta 1e-6, 32 decisiones por actualización, precisión mixta FP16, gradient checkpointing, cuatro épocas y se conserva la mejor época de validación (la cuarta); las temperaturas de probabilidad se ajustaron con el conjunto de calibración.

Qwen3.5-9B (T4). Revisión c202236, pesos NF4 de 4 bits, cálculo en FP16, atención SDPA, kernels flash-linear-attention y causal-conv1d confirmados, decodificación greedy, JSON restringido con LM Format Enforcer, de un correo en un correo. Todas las respuestas fueron JSON válido. QLoRA: rango 16, alfa 32, dropout de 0,05 en todas las capas lineales del modelo de lenguaje (unos 43 millones de parámetros entrenables), pérdida solo sobre los tokens de la respuesta, AdamW paginado de 8 bits a 2e-4 con 10 actualizaciones de calentamiento y caída coseno hasta el 10%, ocho correos por actualización y el prompt v2 como prompt de sistema. La ejecución completa entrenó con 1.984 de los 1.985 correos (el tamaño de lote redondea hacia abajo) en 4 horas y 22 minutos.

Decision 3.0 (GB10). Revisiones fijadas para los seis modelos. Evaluados con su propio runtime (trust_remote_code, revisado antes de usarlo): preguntas de texto, una pasada por pregunta y probabilidades de respuesta desde una capa de lectura sobre códigos de respuesta. Los modelos no incluyen código de entrenamiento, así que escribí un entrenador que reutiliza su constructor de prompts y reproduce su camino de puntuación con gradientes; una autocomprobación confirmó que coincidía con las probabilidades de su runtime (diferencia máxima inferior a 10⁻⁷ en los cinco modelos) antes de entrenar. Modelos pequeños (edge, lite, nano): fine-tuning completo, AdamW con tasas máximas de 1e-5 (backbone) y 5e-5 (capa de lectura), calentamiento lineal del 5% y luego caída coseno, 32 elementos por actualización, cuatro épocas y la mejor época de validación. Las tasas más altas de Laya sin calentamiento hicieron colapsar a d3-edge en un primer intento, con normas de gradiente de hasta unos 960, así que las bajé. Modelos mayores (mini, flash): LoRA con la misma configuración que el QLoRA de Qwen, pero sobre pesos BF16 porque había memoria de sobra, con la capa de lectura congelada y una época. El modelo de 26B no se entrenó, por el motivo explicado arriba.

Software. Colab: PyTorch 2.11 (CUDA 13.0), Transformers 5.19, PEFT 0.21.0, bitsandbytes 0.50.2. DGX Spark: PyTorch 2.11 (CUDA 13.0), Transformers 5.17 (lo exige Decision 3.0), flash-linear-attention 0.5.2, Triton 3.6, PEFT 0.21.0.


Nota del experimento: dos datasets sintéticos. El segundo tiene 3.176 correos separados por cuenta de cliente, con etiquetas derivadas de forma determinista de escenarios escritos a mano y texto redactado por gpt-6.1-sol. No se usaron datos privados de ninguna empresa. Codex y Claude Code ayudaron con la generación del dataset, los scripts de entrenamiento y evaluación, el análisis de resultados y la gestión de los entornos (Colab mediante colab-cli y una DGX Spark a través de la sesión SSH del operador); el autor diseñó los experimentos y revisó las cifras. Las revisiones de los modelos estaban fijadas. Las predicciones por correo, los informes de entrenamiento, los tiempos, los hashes y los scripts de auditoría están en el repositorio público.