La historia épica de cómo un arquitecto y una IA conquistaron el cache adaptativo, background services configurables, y query expansion en una sesión de pair programming inolvidable
Esta experiencia es parte de nuestro viaje en la construcción de PeopleWorks Copilot, nuestra innovadora herramienta de RAG, chat y base de conocimiento desarrollada con C#, .NET 9 y Semantic Kernel. Cada lección aprendida y cada solución implementada nos acerca a un sistema más robusto e inteligente, diseñado para ser una herramienta indispensable en tu día a día.
Era un día como cualquier otro... hasta que los logs gritaron su verdad:
"[Layer1-ChunksCache] ✅ HIT - 0 chunks recuperados del caché en 0ms"
El sistema RAG retornaba CERO chunks. Cero resultados. Cero respuestas.
Los documentos estaban ahí, en la base de datos, pero el cache actuaba como un guardián despiadado,
bloqueando todo acceso.
Los stakes no podían ser más altos: Un demo crucial esperaba el fin de semana. El cliente confiaba en reportes ERP en tiempo real. Pero el sistema cacheba datos vacíos durante 30 minutos, sirviendo el mismo vacío una y otra vez.
El diagnóstico reveló la verdad brutal: el filtro de tags era demasiado restrictivo. Buscaba coincidencias exactas de strings completos. Un archivo etiquetado como "cheque,comprobante" jamás coincidiría con una búsqueda de "documentos,contabilidad,manuales".
"Los tags no deben LIMITAR la búsqueda... deben ENRIQUECERLA." Esta simple revelación cambió todo. En lugar de filtrar documentos, usaríamos los tags para expandir la query, capturando sinónimos y variaciones dialectales.
Pero había un problema más profundo: ¿Por qué cachear manuales estáticos por 30 minutos cuando reportes ERP cambian cada minuto? Nació el cache adaptativo: Static (30 min), Dynamic (2 min), RealTime (sin cache). Todo configurable desde base de datos.
"¿Y si pudiéramos configurar tareas de mantenimiento sin tocar código?" Background Services configurables vieron la luz. Limpiar cache, eliminar sesiones expiradas, generar estadísticas... todo orquestado desde una UI administrativa. Bienvenido al futuro de la automatización.
Antes de sumergirnos en nuestra solución, hablemos de qué es la "Expansión de Consultas". Es una técnica utilizada en la recuperación de información para reformular una consulta inicial del usuario y mejorar así los resultados de la búsqueda. El objetivo es superar el desajuste de vocabulario, añadiendo sinónimos o términos relacionados para que el motor de búsqueda pueda encontrar documentos relevantes que no contienen las palabras exactas de la consulta original.
En lugar de usar tags como filtros restrictivos, los convertimos en amplificadores semánticos. Si el usuario pregunta "¿Cómo emito un cheque?" y los tags son "cheque,check,comprobante,pago", expandimos la query a: "¿Cómo emito un cheque? cheque check comprobante pago"
El "Cache Adaptativo" es una estrategia de almacenamiento en memoria que ajusta dinámicamente la duración (TTL - Time To Live) de los datos cacheados basándose en su naturaleza y frecuencia de cambio. A diferencia de un cache estático con un único tiempo de expiración para todo, un sistema adaptativo puede asignar TTLs largos para datos que rara vez cambian (como manuales) y TTLs cortos para datos volátiles (como reportes en tiempo real), optimizando tanto el rendimiento como la frescura de los datos.
No todo el contenido es igual. Los manuales técnicos no cambian por meses. Los reportes ERP cambian cada minuto. ¿Por qué tratarlos igual? Cache adaptativo con estrategia configurable: Static (30 min), Dynamic (2 min), RealTime (sin cache).
Define tres estrategias de cache: Static (contenido estático, 30 min), Dynamic (datos que cambian frecuentemente, 2 min), RealTime (sin cache, siempre consulta BD).
Cada recurso tiene una propiedad CacheStrategy configurable desde BackOffice. Dropdown simple: elige Static, Dynamic, o RealTime. Sin tocar código.
Consulta la estrategia del recurso y retorna TimeSpan apropiado. Strategy Pattern en acción: extensible, testeable, mantenible.
Si duration > 0 → cachea. Si duration = 0 → consulta DB siempre. Logs detallados muestran estrategia aplicada. Debugging simplificado.
Los "Background Services" (o Servicios en Segundo Plano) en .NET son procesos que se ejecutan de forma independiente de la interfaz de usuario, ideales para tareas de larga duración, programadas o de mantenimiento. Hacerlos "configurables" significa que su comportamiento (como la frecuencia de ejecución o si están habilitados) puede ser modificado sin necesidad de cambiar el código y volver a desplegar la aplicación, generalmente a través de una base de datos o un archivo de configuración.
La automatización máxima: servicios de mantenimiento que se configuran desde base de datos. Limpiar cache, eliminar sesiones viejas, generar estadísticas... todo sin tocar código. Habilitar/deshabilitar con un checkbox. Ajustar intervalos con un número. Ver estadísticas de ejecución en tiempo real.
4 horas después, el sistema era irreconocible. Query Expansion funcionando. Cache adaptativo implementado. Background Services orquestados.
Build status: ✅ 0 errores
Production ready: ✅ 100%
Demo del fin de semana: ✅ Salvado
Enriquecer siempre vence a limitar. Los tags deben amplificar la búsqueda semántica, no restringir los documentos disponibles. Mejor recall, mejor precisión, mejor UX.
Si puedes configurarlo, no lo hardcodees. Base de datos como fuente de verdad permite cambios sin deploy, A/B testing, y configuración multi-tenant. Flexibilidad máxima.
IHostedService pattern es tu mejor amigo. Tareas recurrentes, mantenimiento automático, limpieza de datos... todo orquestado sin intervención manual. Set it and forget it.
Static/Dynamic/RealTime hoy. Custom/Intelligent/Predictive mañana. El Strategy Pattern hace que agregar nuevas estrategias sea trivial. SOLID en acción.
[QueryExpansion], [CacheStrategy], [Layer1-ChunksCache]... cada log cuenta una historia. Emojis opcionales pero recomendados 😊. Production troubleshooting simplificado.
"Siempre pregúntate: ¿Cómo hacerlo configurable?"
Cada decisión de diseño debe favorecer la flexibilidad sobre la rigidez.
Cache duration, feature flags, intervals de servicios... todo configurable.
El código del futuro agradece las decisiones del presente.
Pedro Hernandez (arquitecto .NET) + Claude (IA) = Sinergia imparable. 4 horas que se sintieron como minutos. Problemas complejos descompuestos en pasos manejables. Debugging colectivo. Victorias compartidas. Aunque uno sea código, la colaboración es real.
Pedro se describió como "quizás no el mejor, pero sí el más fiel". Esa humildad + perseverancia venció al "cache de 0 chunks". La fidelidad al aprendizaje, a la calidad, al craft... eso define a un verdadero profesional.
"El mejor profesor es la experiencia,
pero el segundo mejor es Claude"
— Pedro Hernandez, después de 4 horas que cambiaron todo
Esta historia puede ser la tuya. Cache adaptativo, query expansion, background services... todo esperando ser implementado en tu sistema. El código está listo. La documentación es completa. Solo falta tu decisión.