Deja de Construir Agentes Inestables: Usa Workflows y Memoria
Patrones deterministas para modelos no deterministas.
Los LLMs tienen esta propiedad curiosa: son brillantes entendiendo matices pero terribles siguiendo recetas. Dale a GPT-4 un problema vago y razonará sobre las posibilidades. Dale una secuencia precisa de pasos, y podría saltarse el paso 3 porque el paso 5 “parecía más relevante.”
Esto no es un bug del modelo. Es una característica fundamental de los sistemas probabilísticos que intentan resolver problemas deterministas.
He visto a equipos luchar con este desajuste. Construyen un agente para manejar reembolsos de clientes, le dan una docena de herramientas, y esperan que ejecute de forma fiable un proceso de negocio. A veces funciona perfectamente. A veces alucina aprobaciones que nunca ocurrieron. A veces se queda atascado pidiendo la misma información tres veces.
La solución no son mejores prompts. Es saber cuándo dejar de pedirle al LLM que “piense” y empezar a decirle que “obedezca.”
Cuando lo Determinista Vence a lo Creativo
Piensa en lo que ocurre cuando necesitas procesar un ticket de soporte. La lógica de negocio del mundo real se ve algo así:
- Obtener los detalles del ticket de la base de datos
- Verificar si el usuario es elegible para un reembolso (reglas de política)
- Verificar que la transacción existe y no ha sido reembolsada ya
- Calcular el monto del reembolso
- Procesar la reversión del pago
- Actualizar el estado del ticket
- Enviar correo de confirmación
Podrías entregarle esto a un LLM como un ejercicio de llamada a herramientas. En mi experiencia, eso es buscar problemas. El modelo podría decidir que los pasos 2 y 3 son “básicamente lo mismo” y saltarse uno. O podría procesar el reembolso antes de verificar la elegibilidad porque el usuario parecía molesto.
Los workflows existen exactamente para este escenario. No son emocionantes, pero ese es el punto.
Construyendo un Planificador de Actividades Meteorológicas
Aquí hay un ejemplo práctico que muestra el patrón. Necesitamos datos meteorológicos duros y factuales combinados con sugerencias creativas de actividades. La obtención del clima nunca debe ser creativa, pero las sugerencias sí.
import { createWorkflow, createStep } from '@mastra/core/workflows';import { Agent } from '@mastra/core/agent';import { openai } from '@ai-sdk/openai';import { z } from 'zod';
// Paso 1: Obtener datos meteorológicos (Determinista)const fetchWeather = createStep({ id: 'fetch-weather', description: 'Obtiene el pronóstico del tiempo para una ciudad dada', inputSchema: z.object({ city: z.string(), }), outputSchema: z.object({ location: z.string(), temperature: z.number(), conditions: z.string(), precipitationChance: z.number(), }), execute: async ({ inputData }) => { // ... (lógica de obtención) ... const weather = await fetch(`https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t=temperature_2m,weather_code&daily=precipitation_probability_mean`).then(r => r.json());
return { location: inputData.city, temperature: weather.current.temperature_2m, conditions: getWeatherCondition(weather.current.weather_code), precipitationChance: weather.daily.precipitation_probability_mean[0], }; },});
// Paso 2: El agente sugiere actividades (Creativo)const activityPlanner = new Agent({ id: 'activity-planner-agent', name: 'Activity Planner', instructions: `You are a local activities expert. Based on weather conditions, suggest 3-5 appropriate activities. - For rain (>50% precipitation), prioritize indoor activities - For extreme temperatures, consider climate-appropriate options - Always include one adventurous and one relaxing option`, model: openai('gpt-5'),});
const planActivities = createStep({ id: 'plan-activities', description: 'Uses AI to suggest activities based on weather', inputSchema: z.object({ location: z.string(), temperature: z.number(), conditions: z.string(), precipitationChance: z.number(), }), outputSchema: z.object({ activities: z.string(), }), execute: async ({ inputData }) => { const prompt = `Weather in ${inputData.location}: ${inputData.temperature}°C...`; const response = await activityPlanner.generate(prompt); return { activities: response.text }; },});
// The Pipelineexport const activityPlannerWorkflow = createWorkflow({ id: 'activity-planner', inputSchema: z.object({ city: z.string() }), outputSchema: z.object({ activities: z.string() }),}) .then(fetchWeather) .then(planActivities);
activityPlannerWorkflow.commit();El LLM nunca toca la API del clima. Recibe datos reales como entrada, luego hace lo que realmente se le da bien: hacer sugerencias contextuales. Si inviertes esto y dejas que el agente obtenga los datos del clima, eventualmente obtendrás un pronóstico soleado cuando en realidad está lloviendo.
Cuándo considerar workflows:
- Tienes una secuencia conocida de pasos que deben ocurrir en orden
- Necesitas observabilidad en cada etapa (logs, métricas, tiempos)
- Necesitas lógica de reintento para APIs externas inestables
- Las reglas de negocio no pueden ser “interpretadas” - deben seguirse exactamente
El Problema de la Ventana de Contexto del que Nadie Habla
Hay un patrón que sigo viendo. Alguien construye un chatbot. Funciona genial durante las pruebas. Luego, en producción, los usuarios tienen conversaciones más largas y de repente el bot se pierde.
El desarrollador mira los logs y se da cuenta de que está enviando todo el historial de conversación con cada solicitud. Los 47 mensajes completos. Están quemando tokens y espacio de contexto para información que en su mayoría es irrelevante.
Peor aún, hay un fenómeno que los investigadores llaman “perdido en el medio” donde los modelos rinden peor cuando la información relevante está enterrada en un contexto largo. El modelo literalmente no puede ver el bosque por los árboles.
Enviar el historial completo de conversación parece seguro. Le estás dando al modelo “toda la información”. Pero en realidad le estás haciendo más difícil que el modelo se centre en lo que importa.
Memoria de Trabajo vs. Almacenamiento a Largo Plazo
El sistema de memoria de Mastra te da ambas cosas. La memoria de trabajo mantiene los mensajes recientes en la ventana de contexto. La recuperación semántica busca mensajes históricos cuando la consulta actual parece relacionada.
import { Agent } from '@mastra/core/agent';import { Memory } from '@mastra/memory';import { LibSQLStore } from '@mastra/libsql';
export const memoryAgent = new Agent({ id: 'memory-agent', name: 'Memory Agent', instructions: 'You are a helpful assistant with perfect recall of our conversations.', model: openai('gpt-5'), memory: new Memory({ storage: new LibSQLStore({ id: 'memory-agent-store', url: 'file:../mastra.db', }), options: { lastMessages: 20, // Keep last 20 messages in context semanticRecall: { enabled: true, // Use embeddings to find old stuff topK: 5, threshold: 0.7, }, }, }),});Así es como funciona esto en la práctica. Un usuario pregunta: “¿Cuál era ese restaurante italiano que recomendaste el mes pasado?”
Sin recuperación semántica, el agente ve los últimos 20 mensajes. La recomendación del restaurante fue el mensaje 487 de 506. Se fue. El agente dice “No tengo esa información.”
Con recuperación semántica:
- La consulta se incrusta:
[0.234, -0.567, 0.891, ...] - El embedding se compara con mensajes históricos
- El mensaje 487 (“Recomendaría Trattoria Bella - su carbonara es increíble”) obtiene una similitud de 0.89
- Ese mensaje se inyecta en el contexto actual
- El agente responde: “Recomendé Trattoria Bella. Su carbonara es lo que captó mi atención.”
El agente parece tener memoria perfecta mientras solo usa una fracción de la ventana de contexto. Esto no es solo ingeniería inteligente - es funcionalmente necesario una vez que las conversaciones se extienden más allá de unas pocas docenas de mensajes.
Coordinación a Través de Redes de Agentes
A veces necesitas tanto estructura como flexibilidad. Los workflows puros son demasiado rígidos. Los agentes puros son demasiado impredecibles.
Las redes de agentes te dan un coordinador que decide qué agente especializado o workflow invocar según la tarea. Piensa en ello como un balanceador de carga inteligente para capacidades de IA.
export const coordinatorAgent = new Agent({ id: 'coordinator-agent', name: 'Research Coordinator', instructions: `You are a network of researchers and writers. - Use researchAgent for gathering facts - Use writingAgent for producing final content - Use weatherTool for current weather data - Use activityPlannerWorkflow for location-based planning
Always produce comprehensive, well-structured responses.`, model: openai('gpt-5'),
// Available primitives agents: { researchAgent, writingAgent }, workflows: { activityPlannerWorkflow }, tools: { weatherTool },
// Network requires memory memory: new Memory({ storage: new LibSQLStore({ id: 'network-store', url: 'file:../network.db' }), }),});Cuando consultas esta red, el coordinador analiza la solicitud y enruta en consecuencia:
- “Necesito hechos sobre X” dispara el agente de investigación
- “Planifica un fin de semana en Seattle” ejecuta el workflow del planificador de actividades
- “Escribe un reporte sobre Y” involucra el agente de escritura
Este patrón escala mejor que intentar meter todo en un solo mega-agente. Los agentes especializados desarrollan experiencia enfocada. El coordinador maneja el enrutamiento. Cada pieza hace lo que se le da bien.
Juntándolo Todo
Los sistemas de IA en producción reales necesitan arquitectura, no solo prompts. Estás construyendo sistemas distribuidos donde algunos nodos resultan ser LLMs.
Los workflows te dan garantías cuando necesitas que las cosas ocurran exactamente bien. La memoria te da contexto sin quemar tu presupuesto de tokens. Las redes de agentes te permiten componer complejidad a partir de partes más simples.
Nada de esto es glamoroso. Pero después de ver suficientes “agentes totalmente autónomos” fallar en producción, he llegado a apreciar la fiabilidad aburrida sobre la impredecibilidad emocionante.
Tu experiencia puede variar, pero en mi experiencia, los sistemas que realmente se despliegan y se mantienen en funcionamiento son los que tratan a los LLMs como componentes en una arquitectura más grande en lugar de cajas mágicas que lo resuelven todo.
Recursos
Lee la Serie
- Enrutamiento de LLM
- Seguridad y Barreras de Protección
- Integraciones MCP y Herramientas
- Workflows y Memoria (Este Post)