La mayoría de los fallos de agentes en producción no son realmente «fallos del modelo». Son fallos de estado.
El agente olvidó al usuario. Dos workers no coincidían en lo que había ocurrido en el último paso. Una herramienta se reintentó después de una caída y duplicó un efecto secundario. Un producto de chat daba la impresión de no tener memoria porque el framework era stateless por defecto y nadie agregó persistencia. O sucedió lo contrario: un equipo construyó una capa de orquestación muy stateful para un caso de uso que solo necesitaba un ciclo stateless sencillo de solicitud y respuesta.
Por eso, «agentes stateful vs stateless» no es un debate académico. Es una decisión de arquitectura con consecuencias directas para el costo, la latencia, la confiabilidad, la facilidad de depuración y la complejidad para el equipo.
Para este artículo revisé la documentación oficial y los registros de cambios de Vercel AI SDK, LangChain/LangGraph, Agno y AgentOS el March 24, 2026. El objetivo no es coronar a un framework, sino ayudar a ingenieros, arquitectos y PMs a decidir dónde debe vivir el estado en un sistema real.
TL;DR
- AI SDK es el que más prioriza un enfoque stateless de los tres. Ofrece un excelente ciclo de herramientas, pero tú te encargas de la persistencia a menos que agregues explícitamente proveedores de memoria, herramientas de memoria o un almacén de chats o mensajes.
- LangChain/LangGraph es el que más prioriza la orquestación stateful. Los threads, checkpoints, stores, interrupciones y la ejecución duradera son conceptos de primera clase.
- Agno v2 + AgentOS adopta una postura híbrida: los agentes, equipos y workflows son objetos de runtime stateless, pero las sesiones, los resúmenes, la memoria y las trazas viven en tu base de datos y se exponen mediante un runtime de producción.
- En la práctica, el patrón más sólido para producción suele ser: workers stateless, estado persistido.
- Si tu aplicación es principalmente un producto web con chat en streaming, empieza con AI SDK. Si necesitas threads reanudables y ejecución duradera, considera seriamente LangChain/LangGraph. Si quieres un runtime de agentes centrado en Python y autoalojado, con sesiones y APIs integradas, Agno/AgentOS es una opción atractiva.
Qué aprenderás aquí
- Qué significan realmente «stateful» y «stateless» en los sistemas de agentes.
- Por qué el mismo producto puede ser stateful para el usuario y seguir siendo stateless en la capa de runtime.
- Cómo modelan el estado de forma diferente AI SDK, LangChain y Agno/AgentOS.
- Qué implican estas diferencias para los reintentos, la capacidad de reanudar, el escalado horizontal y la observabilidad.
- Patrones de implementación concretos con ejemplos de código y diagramas ASCII.
- Un marco práctico de decisión para ingenieros y PMs que planifican sistemas de producción.
Revisión de fuentes: lo que la documentación respalda claramente
Esta es la interpretación más clara de la documentación oficial.
1. AI SDK no presupone memoria persistente por defecto
La documentación de AI SDK es explícita: sin memoria, cada conversación comienza desde cero. El framework ofrece un ToolLoopAgent reutilizable, llamadas a herramientas, control del ciclo, streaming, utilidades de prueba e integración con la UI, pero la memoria de larga duración es algo que debes agregar deliberadamente.
La documentación muestra tres enfoques explícitos para la memoria:
- herramientas definidas por el proveedor
- proveedores de memoria externos
- herramientas de memoria personalizadas
La documentación de la UI también presenta la persistencia de mensajes como una responsabilidad de la aplicación: almacenar UIMessage[], volver a cargarlos, validarlos y guardarlos en onFinish.
Mi conclusión: es mejor entender AI SDK como un conjunto de herramientas para ciclos de agentes stateless, con patrones de persistencia opcionales, no como un runtime duradero integrado.
2. LangChain/LangGraph trata el estado del thread como una primitiva de primera clase
La documentación actual de LangChain indica que la memoria a corto plazo forma parte del estado del agente y se persiste mediante un checkpointer. Un thread ID identifica la conversación y el runtime vuelve a cargar ese estado en invocaciones posteriores. La documentación también es muy explícita sobre la ejecución duradera, la capacidad de reanudar y la necesidad de encapsular cuidadosamente los efectos secundarios para que la reproducción sea segura.
Mi conclusión: LangChain/LangGraph es la opción más adecuada cuando el estado es central para el producto, no solo un detalle de implementación.
3. Agno v2 hizo que el runtime fuera stateless, mientras mantiene las sesiones y la memoria persistentes
El registro de cambios de Agno v2 es especialmente claro en este punto: los agentes, equipos y workflows ahora son completamente stateless. Al mismo tiempo, la documentación indica que, una vez configurada una base de datos, Agno almacena automáticamente el historial de conversaciones, el estado de la sesión y los metadatos de ejecución, además de las llamadas a herramientas y los archivos multimedia de forma opcional. Los resúmenes de sesión, la gestión del historial y los IDs de sesión son conceptos integrados.
AgentOS expone esos agentes y workflows como una API de producción con sesiones, memoria, conocimiento, trazas, RBAC y hooks en segundo plano.
Mi conclusión: la arquitectura de Agno/AgentOS se basa en objetos de runtime stateless respaldados por infraestructura de sesiones persistentes. Es una separación muy adecuada para producción.
Primero, aclaremos el vocabulario
Los equipos suelen confundir tres significados diferentes de «estado».
1. Estado de la llamada al modelo
Toda llamada a un LLM se basa fundamentalmente en una solicitud. El modelo solo conoce lo que está dentro del prompt actual, las herramientas y las funciones de contexto del proveedor.
2. Estado de la conversación
Es la memoria acumulada de un thread:
- mensajes anteriores
- resultados de herramientas
- resúmenes
- preferencias del usuario
- variables del workflow
3. Estado del runtime
Es lo que permite que un sistema sobreviva a las condiciones reales de producción:
- reintentos
- caídas
- reinicios
- pausas para aprobación humana
- ejecución con múltiples workers
Esta distinción importa porque un sistema puede ser:
- stateless en la capa de runtime
- stateful en la capa de conversación
- y aun así ofrecer al usuario una experiencia completamente continua
De hecho, esa es la configuración de producción en la que más confío.
El patrón de arquitectura en el que más confío
User / API Client
|
v
+-------------------------+
| Stateless worker |
| API route / pod / task |
+-----------+-------------+
|
| load thread/session/workflow state
v
+-------------------------+
| Shared state layer |
| Postgres / Redis / DB |
| checkpoints / sessions |
+-----------+-------------+
|
| run model + tools
v
+-------------------------+
| Save updated state |
| messages / summary / |
| checkpoints / metrics |
+-------------------------+
Esto te da:
- escalado horizontal sin sesiones adherentes
- persistencia fácil de depurar
- mejor recuperación ante fallos
- una separación más clara entre la orquestación y la infraestructura
Los frameworks de este artículo se diferencian principalmente en cuánto de esa arquitectura ofrecen de forma predeterminada.
Los tres frameworks en una tabla
| Framework | Enfoque predeterminado | Dónde suele vivir el estado | Caso más adecuado |
|---|---|---|---|
| AI SDK | Prioriza stateless | La base de datos de tu aplicación, un almacén de mensajes o una herramienta o proveedor de memoria externo | Aplicaciones web y productos de chat que ya tienen una capa de aplicación en TypeScript |
| LangChain / LangGraph | Orquestación stateful de threads y workflows | Checkpointer + store + thread ID | Agentes de larga duración, reanudables y de múltiples pasos con ejecución duradera |
| Agno / AgentOS | Runtime stateless, sesiones stateful | Sesiones y memorias de Agno respaldadas por una base de datos + APIs del runtime de AgentOS | Equipos de Python que crean APIs y workflows de agentes autoalojados |
Vercel AI SDK: stateless primero, el estado es tu responsabilidad
AI SDK ofrece una abstracción muy clara para el ciclo de un agente. Ese es su superpoder.
Defines un ToolLoopAgent una vez, conectas las herramientas, configuras stopWhen y lo usas en cualquier parte de tu aplicación. Pero eso no significa automáticamente que el agente recuerde algo entre solicitudes.
Stateless por defecto
Esta es la configuración más sencilla:
import { ToolLoopAgent, stepCountIs, tool } from "ai";
import { z } from "zod";
const lookupOrder = tool({
description: "Look up an order by ID",
inputSchema: z.object({
orderId: z.string(),
}),
execute: async ({ orderId }) => {
return { orderId, status: "shipped" };
},
});
const supportAgent = new ToolLoopAgent({
model: "openai/gpt-5",
instructions: "You are a support triage agent.",
tools: { lookupOrder },
stopWhen: stepCountIs(8),
});
export async function POST(req: Request) {
const { prompt } = await req.json();
const result = await supportAgent.generate({ prompt });
return Response.json({
text: result.text,
steps: result.steps,
});
}
Es clara y perfectamente útil. También es stateless entre solicitudes. Si el mismo usuario regresa más tarde, este agente no sabe nada a menos que tú mismo recuperes el contexto.
Convertir AI SDK en un producto stateful
El patrón oficial de persistencia consiste en almacenar y volver a cargar los mensajes del chat explícitamente:
import { openai } from "@ai-sdk/openai";
import {
convertToModelMessages,
streamText,
type UIMessage,
} from "ai";
import { loadChat, saveChat } from "./chat-store";
export async function POST(req: Request) {
const { message, id }: { message: UIMessage; id: string } = await req.json();
const previousMessages = await loadChat(id);
const messages = [...previousMessages, message];
const result = streamText({
model: openai("gpt-5-mini"),
messages: await convertToModelMessages(messages),
});
return result.toUIMessageStreamResponse({
originalMessages: messages,
onFinish: ({ messages }) => {
saveChat({ chatId: id, messages });
},
});
}
Ahora el producto se comporta como stateful porque el chat tiene continuidad, pero el runtime todavía puede ser stateless porque cualquier worker puede cargar el UIMessage[] anterior desde el almacenamiento.
AI SDK en producción
Browser / app
|
v
API route
|
+--> load messages from DB
+--> run ToolLoopAgent / streamText
+--> save updated messages
|
v
stream response
Dónde destaca AI SDK
- Ya tienes una aplicación en Next.js o TypeScript y quieres integrar el ciclo del agente en tu arquitectura existente.
- Quieres control total sobre qué se persiste y cuándo.
- Quieres un framework que se mantenga cerca de los patrones de las aplicaciones web en lugar de imponer un modelo de runtime extenso.
Dónde AI SDK puede ser riesgoso
- Los equipos a veces suponen que «agente» implica «memoria». En AI SDK, no es así.
- Si agregas memoria demasiado tarde, terminas con mucho código de persistencia específico de la aplicación, disperso entre rutas y componentes.
- Si necesitas flujos reanudables de aprobación humana, efectos secundarios preparados para la reproducción o recuperación a nivel de workflow, probablemente tendrás que construir bastante por tu cuenta o combinar AI SDK con otra capa de workflow.
LangChain / LangGraph: threads stateful y ejecución duradera
La arquitectura actual de LangChain tiene un enfoque diferente. La abstracción clave no es solo «un ciclo de herramientas». Es el estado de un grafo a lo largo del tiempo.
La documentación describe la memoria a corto plazo como parte del estado del agente, persistida con un checkpointer. Un thread se convierte en la identidad duradera de la conversación. Esta es una postura sobre el estado mucho más definida que la de AI SDK.
Memoria stateful a corto plazo con un thread
import { createAgent } from "langchain";
import { MemorySaver } from "@langchain/langgraph";
const checkpointer = new MemorySaver();
const agent = createAgent({
model: "openai:gpt-5",
tools: [],
checkpointer,
});
await agent.invoke(
{
messages: [{ role: "user", content: "Hi, I am Bob." }],
},
{
configurable: { thread_id: "support-thread-1" },
}
);
await agent.invoke(
{
messages: [{ role: "user", content: "What's my name?" }],
},
{
configurable: { thread_id: "support-thread-1" },
}
);
Reutilizar el mismo thread_id no es una simple comodidad. Es el mecanismo central del estado.
Checkpointer de producción
import { createAgent } from "langchain";
import { PostgresSaver } from "@langchain/langgraph-checkpoint-postgres";
const DB_URI =
"postgresql://postgres:postgres@localhost:5442/postgres?sslmode=disable";
const checkpointer = PostgresSaver.fromConnString(DB_URI);
const agent = createAgent({
model: "openai:gpt-5",
tools: [],
checkpointer,
});
La documentación también separa el estado del thread a corto plazo de la memoria a largo plazo mediante un store. Esto importa porque «el mismo thread» y «el mismo usuario en distintos threads» no son el mismo problema.
La ejecución duradera es el verdadero diferenciador en producción
Aquí es donde LangGraph va más allá de la memoria de chat.
La documentación de ejecución duradera indica explícitamente que:
- los checkpoints permiten reanudar
- los workflows deben ser deterministas e idempotentes
- los efectos secundarios deben encapsularse cuidadosamente
- los workflows reanudados se reproducen desde un punto de inicio seguro, no desde una línea exacta de código
Es exactamente el tipo de detalle que los arquitectos deben tener en cuenta.
LangChain en producción
Client
|
v
LangChain agent
|
+--> load thread state via checkpointer
+--> run model step
+--> run tool step(s)
+--> checkpoint after step(s)
|
v
resume later with same thread_id
Cuándo LangChain es la opción adecuada
- Necesitas pausar y reanudar, interrupciones o revisión humana durante el proceso.
- Te importan la ejecución duradera y una semántica de reproducción explícita.
- El thread de conversación es en sí mismo una primitiva del producto, no solo una comodidad de la UI.
- Quieres que la memoria, el estado y el control del workflow formen parte del framework en lugar de ser código personalizado de la aplicación.
Dónde los equipos encuentran problemas
- El poder de LangChain puede tentar a los equipos a orquestar en exceso casos de uso sencillos.
- Una vez que adoptas el estado de los threads y la semántica de reproducción, también asumes la necesidad de razonar cuidadosamente sobre la idempotencia y los efectos secundarios.
- Es fácil confundir «podemos persistir todo» con «debemos persistir todo». Los threads largos siguen necesitando estrategias de recorte, resumen o eliminación.
Agno + AgentOS: runtime stateless, sesiones stateful
La arquitectura reciente de Agno es una de las más interesantes del ecosistema actual porque es muy explícita sobre la separación entre un runtime stateless y un estado de sesión persistente.
El registro de cambios de v2 indica que los agentes, equipos y workflows ahora son completamente stateless. Al mismo tiempo, la documentación de sesiones indica que, una vez que proporcionas una base de datos, Agno almacena automáticamente:
- historial de conversaciones
- estado de la sesión
- metadatos de ejecución
- llamadas a herramientas opcionales
- archivos multimedia opcionales
Es un patrón sólido para producción.
Un producto stateful con un objeto de agente stateless
from agno.agent import Agent
from agno.db.postgres import PostgresDb
from agno.models.openai import OpenAIResponses
db = PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai")
support_agent = Agent(
name="support-agent",
model=OpenAIResponses(id="gpt-5.2"),
db=db,
add_history_to_context=True,
num_history_runs=3,
enable_session_summaries=True,
)
support_agent.run(
"My name is Alice and I need help with order ORD-9001",
session_id="ticket_9001",
user_id="alice@example.com",
)
support_agent.run(
"What order am I asking about?",
session_id="ticket_9001",
user_id="alice@example.com",
)
Para el usuario se siente stateful porque el mismo session_id recupera la conversación. Pero el objeto de runtime en sí no es el sistema de registro.
Exponerlo como una API de producción con AgentOS
from agno.os import AgentOS
agent_os = AgentOS(
agents=[support_agent],
run_hooks_in_background=True,
)
app = agent_os.get_app()
Ahora tienes una interfaz de runtime autoalojada para agentes, sesiones, trazas y funciones operativas.
Agno en producción
Client / product
|
v
AgentOS API
|
+--> load session from DB
+--> run stateless agent/workflow
+--> persist messages, state, metrics, summary
|
v
response + operational trace
El matiz importante
La documentación de caché de sesiones de Agno indica explícitamente que la caché en memoria es para desarrollo y pruebas y no se recomienda para uso en producción.
Es una buena señal. Refuerza la arquitectura prevista:
- Persistencia respaldada por una base de datos como fuente de verdad
- Runtime stateless para escalar
- Funciones de sesión para la continuidad
AgentOS agrega estructura operativa
AgentOS no es solo un wrapper. La documentación lo presenta como el runtime de producción y el plano de control para sistemas multiagente, con:
- endpoints de API
- streaming compatible con SSE
- sesiones, memoria, conocimiento y trazas en tu base de datos
- JWT/RBAC
- hooks en segundo plano
Un detalle sutil pero importante para producción: los hooks en segundo plano son útiles para logging, analítica, notificaciones y procesamiento no crítico, pero la documentación indica explícitamente que no son adecuados para guardrails porque se ejecutan después de enviar la respuesta.
Ese es el tipo de honestidad operativa que me gusta ver en la documentación de un framework.
Cuándo Agno/AgentOS es la opción adecuada
- Quieres una plataforma de agentes centrada en Python, con sesiones y APIs de runtime listas para usar.
- Quieres un framework que adopte objetos de runtime stateless y al mismo tiempo te ofrezca continuidad estructurada de las conversaciones.
- Estás construyendo equipos, workflows o servicios internos de agentes autoalojados.
Dónde los equipos encuentran problemas
- Si tu caso de uso es en realidad solo una ruta de chat sencilla dentro de una aplicación web, AgentOS puede ofrecer más runtime del que necesitas.
- Si dependes de la caché de sesiones en lugar de almacenamiento duradero, estás trabajando en contra del modelo de producción previsto por el framework.
- Sigues necesitando un buen diseño de IDs de sesión, límites entre tenants y una estrategia de compactación del estado.
La verdadera comparación: ¿dónde vive el estado?
Esta es la pregunta que haría en cada revisión de arquitectura.
AI SDK
El estado vive principalmente en:
- el transporte de chat de tu frontend
- tu ruta de API
- tu base de datos
- herramientas o proveedores de memoria opcionales
El framework no intenta ser tu runtime duradero.
LangChain / LangGraph
El estado vive principalmente en:
- checkpoints de threads
- estado del grafo
- stores a largo plazo
- ejecución de workflows reproducible
El framework asume que el estado es central.
Agno / AgentOS
El estado vive principalmente en:
- sesiones respaldadas por una base de datos
- historial y resúmenes de sesión
- memoria y conocimiento opcionales
- APIs del runtime de AgentOS
La capa de runtime permanece stateless; la continuidad vive en la capa de sesiones.
Mi marco práctico de decisión
Si hoy estuviera asesorando a un equipo, usaría estas reglas.
Elige un diseño que priorice stateless cuando:
- cada solicitud pueda responderse a partir de la entrada actual más una pequeña cantidad de contexto recuperado
- los reintentos no necesiten semántica de reanudación
- tu producto sea principalmente una aplicación web, no un motor de workflows
- quieras el enfoque más sencillo para el escalado horizontal
Elige un diseño con threads stateful cuando:
- la misma conversación deba evolucionar a lo largo de muchos turnos
- los resultados de las herramientas afecten decisiones posteriores
- las aprobaciones humanas pausen y reanuden la misma tarea
- necesites poder auditar lo que el agente sabía en cada paso
Elige durabilidad de workflows cuando:
- las tareas puedan ejecutarse durante minutos u horas
- los fallos y reinicios sean normales
- los efectos secundarios de las herramientas tengan consecuencias importantes
- necesites una orquestación segura ante la reproducción, no solo historial de chat
El mejor patrón para producción suele ser híbrido
Esta es la conclusión central.
Una arquitectura madura para producción normalmente no consiste en:
- «todo stateless»
y normalmente tampoco consiste en:
- «mantener todo el estado dentro de un worker adherente de larga duración»
Consiste en esto:
Stateless compute
+
Durable shared state
+
Clear replay rules
+
Explicit session/thread IDs
Por eso los tres frameworks pueden funcionar en sistemas serios, aunque partan de supuestos diferentes.
Qué recomendaría según el caso de uso
1. Copiloto de atención al cliente dentro de una aplicación web
Empieza con AI SDK si tu equipo ya trabaja principalmente con TypeScript y React. Mantén el runtime stateless, persiste tú mismo los mensajes del chat y agrega memoria más allá del thread solo si el producto realmente la necesita.
2. Agente de investigación u operaciones que pausa, reanuda y llama a muchas herramientas
Elige LangChain/LangGraph si los checkpoints, la reproducción y la semántica de los threads son parte del workflow principal.
3. Plataforma interna para múltiples APIs y workflows de agentes
Usa Agno + AgentOS si quieres un runtime nativo de Python con gestión de sesiones integrada y aspectos del servicio en producción ya modelados.
Reflexión final
La pregunta más útil no es «¿Mi agente debería ser stateful o stateless?».
La mejor pregunta es:
¿Qué partes del sistema necesitan memoria y cuáles deberían seguir siendo desechables?
Eso conduce a mejores decisiones de arquitectura.
AI SDK dice: mantén el ciclo sencillo y deja que la aplicación se encargue de la persistencia.
LangChain dice: modela explícitamente los threads, checkpoints y la ejecución duradera.
Agno/AgentOS dice: mantén los objetos de runtime stateless, pero persiste las sesiones y expónlas mediante una API de producción.
Todas son opciones defendibles. La correcta depende de si tu problema principal es:
- la integración con una aplicación web
- la durabilidad de los workflows
- o las operaciones del runtime de agentes
Si respondes bien esa pregunta, el modelo de estado suele surgir por sí solo.
Fuentes
- Vercel AI SDK, creación de agentes
- Vercel AI SDK, memoria
- Vercel AI SDK, persistencia de mensajes de chatbot
- Base de conocimiento de Vercel, cómo crear agentes de IA con Vercel y AI SDK
- Documentación de LangChain JS, agentes
- Documentación de LangChain JS, memoria a corto plazo
- Documentación de LangGraph JS, memoria
- Documentación de LangGraph JS, persistencia
- Documentación de LangGraph Python, ejecución duradera
- Registro de cambios de Agno v2.0
- Agno, persistencia de sesiones
- Agno, gestión de sesiones
- Agno, gestión del historial
- Agno, resúmenes de sesión
- AgentOS, ¿qué es AgentOS?
- AgentOS, hooks en segundo plano