# Plan de mejora continua del Buscador Multisearch Cómo hacer que el aplicativo aprenda de su uso y vaya afinándose solo, sin necesidad de re-programarlo cada vez que falla. Tercera entrega del proyecto, después de `mejoras_buscador_multisearch.md` y `diccionario_maestro_oposiciones.md`. --- ## 1. La idea en una frase El Buscador 1 ya tiene un activo que el Buscador 2 no tiene: los botones **"Coincidencia correcta"** y **"Falso positivo"** debajo de cada hit. Cada clic es una etiqueta supervisada gratis. Si el sistema guarda esos clics y los procesa con cabeza, se va afinando solo. No hace falta IA sofisticada para v1 — basta con estadística bien hecha. A esto se le añaden señales más débiles (qué hits abre el usuario, qué patrones se ignoran semana tras semana) y un análisis del propio corpus (qué patrones generan ruido). Con eso se montan cuatro bucles de mejora de distinto plazo. --- ## 2. Las tres fuentes de información ### 2.1 Feedback explícito del usuario (alta calidad) Los dos botones del email son oro. Cada vez que se pulsa "Correcta" o "Falso positivo", guardar: - `id_hit`: identificador único del registro. - `usuario_id`: quién lo marcó. - `categoria`: deporte, informática, hacienda, etc. - `patron_disparado`: qué patrón del diccionario causó la coincidencia. - `boletin` y `pagina_boletin`. - `fragmento_texto`: ±300 caracteres alrededor del patrón. - `nivel_confianza_asignado`: ALTA / MEDIA / BAJA. - `reglas_exclusion_aplicadas`: cuáles disparon (vacío si ninguna). - `palabras_ancla_detectadas`: cuáles de convocatoria/plantilla aparecieron. - `etiqueta_usuario`: "correcta" o "falso_positivo". - `timestamp`. Si varios usuarios reciben el mismo hit (porque están suscritos a la misma categoría), se acumulan votos y se calcula consenso. Tres marcas "Falso positivo" sobre el mismo registro = ya no se vuelve a enviar a nadie aunque vuelva a disparar. ### 2.2 Señales implícitas (baja calidad pero muchísimas) Se pueden registrar sin pedirle nada al usuario, simplemente instrumentando el email y el "Descargar PDF": - **Clic en "Descargar PDF"**: implica interés. Si una oferta es vista como ALTA pero nadie nunca descarga el PDF, algo va mal — o el resumen miente o esa categoría no se está leyendo. - **Apertura del email**: pixel tracker estándar. Si un usuario lleva 2 semanas sin abrir, replantear su suscripción. - **Tiempo entre envío y clic**: las ofertas reales se miran en horas. - **Reenvíos** (si el email tiene "Forward to a friend"): señal fuerte. Estas señales solas no se usan para decisiones automáticas. Se cruzan con las explícitas para confirmar patrones. ### 2.3 Análisis estadístico del propio corpus (no requiere usuarios) Cosas que el sistema puede medir sin que nadie haga nada: - **Frecuencia de cada patrón**: ¿cuántas veces dispara `socorrista` por semana?, ¿en qué boletines? - **Concentración por boletín**: si el 60 % de los hits de un patrón caen en un solo boletín, es sospechoso (ese boletín probablemente tiene una palabra recurrente que no es convocatoria — caso DOE Extremadura con `informáticos` en protocolos de transporte). - **Solapamiento entre patrones**: si dos patrones casi siempre disparan juntos (porque las ofertas reales usan ambos términos), uno puede ser redundante. Si nunca se solapan, ambos son necesarios. - **Tasa de duplicación intra-boletín**: si un patrón siempre tiene 8–10 duplicados por boletín, su deduplicación es vital. --- ## 3. Los cuatro bucles de mejora ### 3.1 Bucle diario — Umbrales y deduplicación Lo que el sistema puede recalcular cada noche sin riesgo: - **Umbral de similaridad para deduplicación**. Empezar en 0.85. Si el histórico muestra que con 0.80 se eliminan duplicados reales sin perder ofertas distintas, bajarlo. Si con 0.85 quedan duplicados, subir precisión a 0.88. Ajuste pequeño, comparable al backtest del día. - **Lista negra del día**. Registros marcados "Falso positivo" por ≥ 3 usuarios distintos del mismo perfil = no reenviar a nadie más en las siguientes 24 h (por si el boletín se vuelve a procesar o aparece en un boletín hermano). - **Suspensión temporal de patrones**. Si un patrón saca > 50 hits en un solo día y > 80 % se marcan FP en las primeras 4 h, **degradarlo automáticamente a BAJA** durante 24 h y alertar al equipo. Esto frena cascadas de ruido como las del Buscador 2 en DOE Extremadura. Nada de esto modifica el diccionario en sí — son ajustes operativos del día. ### 3.2 Bucle semanal — Reglas de exclusión y palabras-ancla Cada lunes, procesar el histórico de la semana anterior: - **Detección de contextos recurrentes en FP**. Para cada categoría, agrupar los fragmentos marcados como FP y buscar n-gramas (3–5 palabras) que aparezcan en ≥ 30 % de los FP pero en < 10 % de los TP. Esos n-gramas son candidatos a nueva regla de exclusión. Ejemplos realistas: - "comisión de valoración compuesta por" → propuesta R-nueva-1. - "consejería de educación cultura y deportes" sin convocatoria → confirma R3-deporte. - "protocolo técnico para definición tecnológica" → propuesta R-nueva-2 (caso DOE Extremadura). El sistema **propone**, no aplica. Genera un informe semanal con candidatos ordenados por impacto estimado ("aplicar esta regla habría evitado 47 FP la semana pasada sin tocar ningún TP"). Un revisor humano (puedes ser tú o el equipo) aprueba o rechaza. - **Refuerzo de palabras-ancla**. Mismo procedimiento al revés: n-gramas que aparecen en TP pero raramente en FP son buenos candidatos a palabras-ancla nuevas. Ejemplo plausible: "fase de oposición" no estaba en la lista inicial pero aparece en muchos TP. - **Ratio precisión por patrón**. Calcular para cada patrón TP / (TP + FP) sobre todo el histórico. Patrones con ratio < 50 % se marcan para revisión manual: o se acotan con palabra-ancla obligatoria, o se eliminan. ### 3.3 Bucle mensual — Patrones del diccionario Cada primer día de mes, revisar: - **Patrones zombi**: los que llevan 30 días sin disparar ni una vez. No se eliminan (pueden ser estacionales: `socorrista` raramente dispara fuera de mayo-septiembre). Pero se listan en un informe "patrones inactivos" por si son señal de algo (cambio de nomenclatura, error ortográfico que ya nadie usa). - **Patrones inflacionados**: los que disparan > 100 hits/mes con ratio TP < 60 %. Son candidatos a acotar (añadirles `requiere_ancla:`) o partirlos en variantes más específicas. - **Candidatos a patrones nuevos**. Para cada categoría, mirar las ofertas reales (TP) del mes y extraer los **bigramas y trigramas específicos del dominio** que aparecen con frecuencia. Cruzar con el diccionario actual. Si un trigrama frecuente en TP no está cubierto por ningún patrón, proponerlo como patrón nuevo. Esto es lo más parecido a "el sistema aprende vocabulario por su cuenta". Ejemplo aplicable a Informática: si el mes pasado hubo 6 ofertas de "técnico/a de administración electrónica" que se captaron gracias a otros patrones laterales pero no por un patrón directo, el sistema lo propone como patrón candidato. - **Detección de ofertas perdidas (false negatives)**. Esto es lo más difícil pero lo más valioso. Maneras de aproximarlo: - Si un usuario marca un hit como "Correcta" pero el patrón que lo disparó es ambiguo (ej. dispara `auxiliar` y casualmente la oferta es de auxiliar administrativo de hacienda), revisar si hubiera debido coincidir con un patrón más específico. - Cruzar el listado de convocatorias con bases de datos públicas (BDNS, oposicionesgob.es) si están disponibles: ofertas que están en esas BBDD pero el sistema no envió son FN candidatos. - Encuesta puntual a usuarios: "esta semana, ¿has encontrado alguna oferta interesante que no te llegó por aquí?" — 2 minutos al mes aporta señales que de otro modo no tendrías. ### 3.4 Bucle trimestral — Cobertura y categorías Cada 3 meses, decisiones grandes: - **Ampliación de boletines cubiertos**. Mirar qué ofertas se han perdido por estar en boletines no cubiertos. Si hay > 20 ofertas por trimestre en un boletín no cubierto, priorizar su integración. - **Apertura de nuevas categorías**. Si > N usuarios piden una categoría no contemplada (ej. "policía local", "bomberos"), prepararla a partir del diccionario maestro y abrirla. - **Revisión global de los umbrales de confianza** ALTA / MEDIA / BAJA. Con el histórico trimestral, ¿se podrían ajustar las fronteras para reducir el número de falsos positivos sin perder ofertas reales? - **Re-evaluación del propio sistema de feedback**. ¿La gente pulsa los botones? Si la tasa de clics está por debajo del 5 % de hits enviados, la fuente de aprendizaje se seca. Considerar gamificación, recordatorios o ajustes en la interfaz. --- ## 4. Qué automatizar y qué dejar en humano | Acción | Automático | Humano | Por qué | |---|---|---|---| | Deduplicación por CVE | ✅ | | Determinista, riesgo cero | | Suspender patrón con > 80 % FP en 4 h | ✅ | | Para frenar cascadas | | Lista negra de hits con ≥ 3 votos FP | ✅ | | Consenso suficiente | | Bajar de ALTA a MEDIA por contexto | ✅ | | Reglas explícitas conocidas | | Recalibrar umbral de similaridad | ✅ | | Pequeño, reversible | | Añadir nueva regla de exclusión | | ✅ | Riesgo de bloquear TP reales | | Añadir nueva palabra-ancla | | ✅ | Riesgo de inflar ALTA en falso | | Añadir nuevo patrón al diccionario | | ✅ | Decisión de cobertura | | Eliminar patrón del diccionario | | ✅ | Difícil deshacer si afecta TP raros | | Modificar categorías o boletines | | ✅ | Decisión de producto | Regla general: el sistema **propone** cambios al diccionario y a las reglas con su estimación de impacto. El humano **aprueba o rechaza** en un solo clic. Eso baja el coste de mantenimiento del diccionario sin ceder el control. --- ## 5. El dashboard mínimo Un panel sencillo con: - **Métricas globales por día/semana/mes**, por categoría: - Hits enviados. - Hits marcados "Correcta" / "Falso positivo" / sin marcar. - Ratio precisión = TP / (TP + FP) entre los marcados. - Hits clicados ("Descargar PDF"). - Hits únicos vs duplicados detectados. - **Top patrones del mes** ordenados por volumen y por ratio TP/FP. - **Top reglas de exclusión** por número de hits que están bloqueando. - **Boletines más ruidosos** (mayor ratio FP). - **Cola de propuestas pendientes** (nuevas reglas, nuevos patrones, patrones a acotar) — el corazón del bucle semanal y mensual. - **Usuarios inactivos** (sin abrir email en 30 días) — para limpieza. No hace falta nada visual sofisticado. Una página HTML con tablas y un par de gráficos basta. Esto se construye una vez y dura años. --- ## 6. Cuándo (y cómo) meter IA / LLM A medio plazo, cuando ya haya 6+ meses de datos etiquetados, se puede introducir un modelo de clasificación de fragmentos. **No antes**, por tres motivos: 1. **Sin datos etiquetados, el modelo es un oráculo opaco**. Con datos etiquetados, es un clasificador supervisado normal y se puede evaluar. 2. **El sistema de patrones + reglas + scoring ya cubre el 90 % de los casos**. Lo que queda son casos límite donde el contexto importa más que la palabra exacta. Un modelo pequeño (incluso un embedding + regresión logística) puede decidir esos casos. 3. **Riesgo de regresión**. Hasta que el clasificador iguale o supere al sistema de reglas en producción, se mantiene en "shadow mode": registra qué decidiría sin afectar al usuario, se compara con el sistema actual, se promociona solo cuando demuestre que mejora. Tres aplicaciones realistas de LLM **después** de tener histórico: - **Resumen del fragmento** en lugar del trozo OCR pelado. "Convocatoria de 2 plazas de socorrista en Santiago-Pontones, concurso de méritos, presentación de solicitudes hasta el 15 de junio." Mucho más legible que el corte de OCR actual. - **Extracción estructurada**: número de plazas, fecha límite, organismo convocante, grupo, sistema selectivo. Útil para alertas filtradas. - **Clasificación contextual de casos límite**: "este fragmento, ¿es una oferta de empleo, una subvención, una composición de tribunal o una mención administrativa?". Es justo lo que las reglas de exclusión hacen aproximadamente — un modelo pequeño lo haría mejor en los bordes. Coste y latencia: con un modelo local (Llama 3.1 8B, Mistral 7B o similar) corriendo en una GPU modesta, procesar un fragmento de 300 caracteres son ~150 ms. Para 200 hits diarios, son 30 segundos de cómputo total. Asumible cuando llegue el momento. --- ## 7. Riesgos a vigilar - **Sesgo de confirmación**. El sistema aprende lo que los usuarios marcan. Si todos los usuarios actuales son del mismo perfil (ej. equipo de formación de oposiciones), el sistema se especializará en lo que ellos buscan y perderá relevancia para perfiles distintos. Mitigación: no aplicar reglas aprendidas globalmente si la muestra es pequeña. - **Drift estacional**. `socorrista` pico en mayo-septiembre; profesores en marzo-julio. Si el bucle mensual desactiva un patrón por inactividad en febrero, está cometiendo un error. Mitigación: el bucle mensual nunca elimina patrones, solo los lista; revisión humana mira si la inactividad es estructural o estacional. - **Cambios de nomenclatura en boletines**. Un BOP puede cambiar la forma en la que presenta las convocatorias. Si las reglas de exclusión son demasiado estrictas, podrían empezar a tirar TP. Mitigación: el ratio precisión por categoría se vigila semanalmente; si baja > 10 % respecto a la línea base, alerta automática. - **Acumulación de "ya no enviar"**. La lista negra de hits crece. A los 2 años puede tener miles de entradas. Mitigación: caducar entradas a los 6 meses (los registros antiguos no se republicarán; si lo hacen, se vuelve a evaluar). - **Privacidad y RGPD**. Guardar quién marca qué = dato personal. Si los usuarios son empleados de la empresa, basta con la base contractual. Si son externos, política de privacidad explícita. Los fragmentos de boletín no son personales (son publicaciones oficiales). --- ## 8. Roadmap sugerido **Mes 1 (con la v1 del buscador ya en marcha):** - Asegurar que cada clic en los botones se persiste con todos los campos de 2.1. - Empezar a guardar señales implícitas (apertura email, clic en "Descargar PDF"). - Construir el dashboard mínimo (sección 5). **Mes 2-3:** - Activar bucle diario (suspensión de patrones, lista negra del día). - Activar bucle semanal en modo informe (propone, no aplica). - Primer humano-en-el-bucle: revisar las propuestas semanales y aprobar/rechazar. **Mes 4-6:** - Activar bucle mensual (patrones zombi, inflacionados, candidatos a nuevos). - Empezar a medir convergencia: ¿está bajando la tasa de FP semana a semana? **Mes 7-12:** - Bucle trimestral en marcha. - Si hay datos suficientes (~5.000-10.000 hits etiquetados por categoría activa), evaluar viabilidad de un clasificador en shadow mode. **Año 2:** - Si el clasificador en shadow funciona bien, promocionarlo a producción como capa adicional de scoring. - Empezar a explorar LLM para resumen y extracción estructurada. --- ## 9. Lo mínimo que ya estás haciendo bien Mientras se monta todo esto, hay tres cosas del diseño actual que **ya son auto-mejora gratis** y no debes perder: 1. **Los dos botones del email**. Sin ellos no hay supervisión. Que sigan ahí siempre, en todas las categorías. 2. **El campo `patron_disparado` visible en cada hit**. Permite al humano y al sistema saber por qué se ha enviado cada cosa. Sin ese dato no se aprende nada. 3. **El nivel de confianza explícito (ALTA/MEDIA/BAJA)**. Convertir el email en algo binario "te lo mando o no te lo mando" pierde la información de matiz que alimenta el aprendizaje. Con esas tres piezas + el dashboard + el bucle semanal en modo informe, el sistema empieza a mejorar solo en 4-6 semanas. Lo demás (clasificador, LLM, embeddings) se construye encima cuando haya datos para ello. --- ## 10. Resumen ejecutivo en cinco líneas - El sistema **ya** tiene la fuente de datos para mejorar solo: los dos botones del email. - Hace falta **guardar** ese feedback estructurado y montar un **dashboard** que lo procese. - Cuatro bucles encadenados (diario, semanal, mensual, trimestral) van ajustando umbrales, exclusiones, patrones y cobertura sin re-programar. - El sistema **propone** cambios; el humano **aprueba** con un clic. No se ceden las llaves al algoritmo. - IA/LLM es **opcional y tardío**: solo cuando haya 6+ meses de datos etiquetados, y en shadow mode antes de promocionar.