ADR-003 — Patrón extractor: LLM + regex fallback
Estado: Aceptado
Fecha: 2026-04-09
Rama: feature/rag-studio
Contexto
El extractor_node usa un LLM pequeño (llama3.1:8b vía Ollama) con with_structured_output para extraer guest_name, guests_count, check_in y check_out de los mensajes del huésped.
Se detectó que llama3.1:8b falla silenciosamente en la extracción de nombres: devuelve null para guest_name incluso cuando el usuario dice explícitamente "Me llamo Ernesto Rodríguez", sin lanzar excepción. Esto causaba un bucle donde el bot pedía el nombre repetidamente al usuario aunque ya lo hubiese dado.
Decisión
Implementar extracción en dos capas en cascada:
-
Capa primaria — LLM structured output: intento principal. Cubre fechas en lenguaje natural, cantidades implícitas ("somos tres") y nombres en cualquier posición del mensaje.
-
Capa secundaria — Regex fallback: se activa cuando la capa primaria devuelve
nullparaguest_name(no solo en excepción). Patrón específico para frases de presentación: -
Preservación de estado: si ambas capas fallan pero el estado ya tiene un
guest_nameválido de turnos anteriores, se preserva. Evita que el bot "olvide" el nombre entre turnos.
Consecuencias
Positivas: - Elimina el bucle de nombre repetido, el error de UX más frecuente en las evals. - El regex es determinista y rápido (sin latencia de LLM). - La lógica de preservación evita regresiones cuando el extractor fluctúa.
Negativas: - El regex solo cubre frases explícitas de presentación. Nombres dados de forma implícita ("para Juan García") no se capturan por esta capa. - Dos rutas de código que mantener.
Alternativas descartadas
- Solo regex: demasiado frágil para fechas en lenguaje natural ("el próximo viernes").
- Modelo más grande:
llama3.1:70bresolvería el problema pero no está disponible en Ollama local con el hardware actual. - Groq para extracción: añade latencia de red y coste; el modelo local es suficiente con el fallback.