wandres.dev
AGENTS Y WORKFLOWS · IA con estado

Qué es un agente: el modelo que decide los pasos

Un programa clásico decide qué hacer y usa el modelo como una función cara; un agente invierte ese reparto de poder. Le das un objetivo, un puñado de capacidades y un presupuesto, y es el modelo quien elige qué invocar, en qué orden y cuándo parar. Ese giro convierte una llamada única en un bucle de observar, decidir y actuar que se extiende en el tiempo, y ahí nace el problema que define el nivel entero: un bucle que dura necesita recordar. Vemos la frontera entre inferencia y agencia, las piezas que componen un agente y por qué sin estado persistente no hay agente sino una sucesión de amnesias.

⏱ 18 min

Todo lo que has construido hasta aquí obedece a un plan que escribiste tú. Tu código decide qué se ejecuta, en qué orden y cuándo termina; incluso cuando llamas a un modelo, el modelo es un subordinado al que consultas en un punto fijo del programa. Un agente rompe ese contrato. Le entregas un objetivo en lenguaje natural, un conjunto de capacidades y un límite, y a partir de ahí es él quien traza el plan: mira lo que sabe, elige una acción, observa el resultado y vuelve a decidir, tantas veces como haga falta. Lo que antes era una línea recta se convierte en un bucle, y un bucle que puede durar minutos, horas o días necesita algo que ninguna función sin estado sabe dar: una memoria que sobreviva a la petición que lo arrancó.

🎯 Al terminar esta lección sabrás
  • Distinguir una llamada única al modelo de un bucle agéntico que decide sus propios pasos.
  • Identificar las piezas que convierten un modelo en un agente: herramientas, memoria, bucle e identidad.
  • Entender por qué un agente sin estado persistente pierde la continuidad entre turnos.
  • Reconocer el ciclo observar, decidir y actuar como la unidad de diseño de todo el nivel.

De la inferencia a la agencia

La inferencia que ya conoces es una función: le pasas un texto, devuelve otro texto. Cara, no determinista en el contenido, pero función al fin y al cabo. Tú decides cuántas veces la llamas, con qué contexto, y qué haces con lo que devuelve. El plan vive entero en tu código, y el modelo es una herramienta dentro de ese plan.

La agencia empieza cuando das la vuelta a esa relación. Le describes al modelo un catálogo de funciones que puede pedir —consultar un pedido, buscar en el índice vectorial, emitir un reembolso— y su respuesta deja de ser necesariamente texto: puede ser la intención de invocar una de ellas con unos argumentos concretos. Tu programa ejecuta lo que ha pedido, le devuelve el resultado como un mensaje más de la conversación y vuelve a preguntarle. El modelo mira el nuevo estado y decide otra vez. El ciclo se repite hasta que responde con texto final o hasta que un límite lo detiene.

import { generateText, stepCountIs } from "ai";

const resultado = await generateText({
  model,
  system: "Eres un asistente de soporte. Usa las herramientas antes de afirmar nada.",
  messages: historial,
  tools: herramientas,
  stopWhen: stepCountIs(8),
});

Ese stopWhen es la primera pista de que estás en otro régimen: en una llamada normal no hace falta declarar cuándo parar, porque solo hay un paso. Aquí el número de pasos no lo sabes de antemano —lo descubre el modelo mientras razona—, así que hay que acotarlo desde fuera. Lo que ha cambiado no es la potencia del modelo, es quién lleva el control del flujo.

Para desmitificar del todo el asunto conviene mirar qué es un bucle agéntico por dentro. No hay ningún proceso pensando entre llamada y llamada: hay una lista de mensajes que crece, y en cada vuelta se le vuelve a enviar entera al modelo. Así se ve el historial justo antes de la tercera inferencia.

const historial = [
  { role: "user", content: "Que ha pasado con mi pedido A-1001" },
  {
    role: "assistant",
    content: [{ type: "tool-call", toolName: "buscarPedido", input: { codigo: "A-1001" } }],
  },
  {
    role: "tool",
    content: [{ type: "tool-result", toolName: "buscarPedido", output: { estado: "en reparto" } }],
  },
];

La intención del modelo y el resultado de tu función son, literalmente, dos mensajes más de la conversación. De esa observación tan modesta se derivan casi todas las consecuencias prácticas del nivel: que el contexto crece en cada paso y por tanto el coste por vuelta también, que el modelo no recuerda nada que no esté en esa lista, y que si la lista se pierde entre dos turnos el agente vuelve a nacer sin saber nada de lo anterior.

En una cadena fija En un agente
El orden lo fijas tú al escribir el código El orden se decide en tiempo de ejecución
El número de llamadas se conoce de antemano El número de pasos es una variable a acotar
El fallo es una excepción a propagar El fallo es una observación más que el modelo interpreta
El coste es predecible por petición El coste hay que gobernarlo con un presupuesto

Esa última fila resume el cambio económico y merece un momento. En una cadena fija sabes, antes de desplegar, cuántas llamadas hace cada petición y cuánto cuesta la más cara. En un agente no lo sabes: dos usuarios con la misma pregunta pueden consumir tres pasos y treinta. El coste deja de ser una constante del sistema y pasa a ser una distribución, con su media, su cola larga y sus casos patológicos. Todo lo que veremos en la última lección de este nivel nace de aceptar esa frase y actuar en consecuencia.

Las cuatro piezas de un agente

Un agente no es un modelo más listo: es un modelo dentro de una arquitectura. Quítale cualquiera de estas cuatro piezas y lo que queda es un chat con buena prosa.

🔧

Herramientas

Funciones tuyas descritas al modelo con nombre, propósito y esquema de argumentos. Son su única vía para tocar el mundo: sin ellas solo puede hablar de actuar.

🧠

Memoria

El historial del turno actual, que es su contexto de trabajo, y lo que debe sobrevivir a la conversación: preferencias, hechos aprendidos, tareas a medias.

🔁

Bucle

El motor que ejecuta lo que el modelo pide, le devuelve el resultado y vuelve a invocarlo. Con su condición de parada, su presupuesto y su gestión de errores.

🪪

Identidad

Un agente es siempre el agente de alguien o de algo. Esa identidad decide qué memoria carga, qué permisos tiene y a qué instancia hay que dirigirse.

Ninguna de las cuatro la aporta el proveedor del modelo. El modelo es un servicio remoto sin memoria, sin manos y sin nombre; herramientas, memoria, bucle e identidad son código que escribes tú y que vive en tu infraestructura. Por eso el trabajo del ingeniero en un sistema agéntico no consiste en elegir bien el modelo, sino en construir bien las cuatro piezas que lo rodean, y por eso cambiar de proveedor —algo que suena a decisión enorme— suele tocar una línea de configuración, mientras que cambiar la granularidad de la memoria toca el sistema entero.

De las cuatro, la identidad es la que más se olvida y la que más determina la arquitectura. Un asistente de soporte no es un servicio anónimo al que llegan peticiones sueltas: es una entidad por conversación, con su historial, su presupuesto y sus permisos. Cuando el cliente vuelve mañana, tiene que caer en el mismo agente y no en uno recién nacido con el mismo nombre.

Los grados de agencia

Conviene desactivar de entrada la lectura binaria del término. Agente no es un interruptor que se enciende: es un dial con al menos cuatro posiciones, y cada una traslada al modelo una porción distinta del control.

En el primer escalón está la cadena fija. Tú escribes el grafo entero y el modelo solo transforma texto dentro de cada nodo: resume, extrae, clasifica. Es el diseño más aburrido y, muy a menudo, el correcto. En el segundo aparece el enrutamiento: el modelo elige una rama entre varias que escribiste tú. Lo que delegas ahí es una decisión concreta, no el plan; el grafo sigue siendo tuyo y sigue siendo auditable de un vistazo.

El tercer escalón es el agente acotado, y es donde vive prácticamente todo lo que llega a producción: el modelo compone con libertad sobre un catálogo cerrado de herramientas, pero con un tope de pasos, un presupuesto y una lista de acciones que exigen confirmación humana. El cuarto es el agente abierto, el que crea subtareas, genera código y arranca a otros agentes. Máxima capacidad y máxima varianza; también la depuración más difícil que existe hoy en el oficio.

Escalón Qué delegas Cuándo es la elección correcta
Cadena fija Nada del plan Los pasos son siempre los mismos
Enrutamiento Una decisión entre ramas tuyas Hay varios caminos conocidos
Agente acotado La composición sobre un catálogo cerrado El plan depende de lo que se vaya descubriendo
Agente abierto La creación de tareas nuevas Rara vez, y nunca sin envolvente

La disciplina consiste en elegir siempre el escalón más bajo que resuelve el problema. Cada peldaño que subes te cobra en cuatro monedas a la vez. Coste, porque multiplicas las inferencias. Latencia, porque cada vuelta del bucle es una llamada completa al modelo y todas se suman en serie, de modo que un agente de cuatro pasos tarda cuatro veces lo que tardaría una respuesta directa. Superficie de fallo, porque crece el conjunto de acciones componibles. Y dificultad de diagnóstico, porque el rastro que hay que leer cuando algo sale mal deja de ser una línea y pasa a ser un árbol. Subir un escalón por costumbre, o porque suena mejor al contarlo en una reunión, es la forma más rápida de convertir un problema resuelto en uno abierto.

Por qué el bucle necesita recordar

flowchart LR
OBJ[objetivo del usuario] --> M[el modelo decide]
M -->|texto final| FIN[respuesta al usuario]
M -->|llamada a herramienta| T[ejecutar la herramienta]
T --> R[resultado como mensaje nuevo]
R --> MEM[memoria del agente]
MEM --> M
style M fill:#89b4fa,color:#11111b
style MEM fill:#f9e2af,color:#11111b
style FIN fill:#a6e3a1,color:#11111b

Míralo con atención: cada vuelta del bucle lee la memoria y escribe en ella. El modelo es una función sin estado —siempre lo ha sido—, así que la única continuidad posible es la que le entregas en el contexto. La memoria no es un adorno del agente: es literalmente lo que le da existencia a lo largo del tiempo.

Y ahí choca con el runtime que llevas todo el track usando. Un Worker nace y muere con la petición. Si el agente vive en un Worker sin estado, cada turno arranca de cero y hay que rehidratar el historial desde algún almacén, mutarlo y volver a escribirlo. Ese patrón de leer, modificar y escribir, ejecutado desde isolates distintos, tiene todos los problemas que ya conoces: dos pestañas del mismo usuario pisándose el historial, un turno que se solapa con otro, una herramienta que se ejecuta dos veces porque el reintento no supo que la primera había pasado.

Conviene además separar dos memorias que se confunden todo el tiempo. Una es la memoria de trabajo: el historial del turno en curso, lo que de verdad viaja en el contexto de cada inferencia. Es cara —se paga en tokens en cada vuelta—, es finita y hay que podarla o resumirla cuando crece. La otra es la memoria persistente: lo que el agente debe seguir sabiendo dentro de un mes, y que casi nunca es la transcripción literal sino su destilado —quién es este cliente, qué se le prometió, qué quedó pendiente—. Confundirlas produce los dos fallos clásicos y opuestos: agentes que reenvían al modelo media enciclopedia en cada paso y agentes que saludan como si nunca hubieran hablado contigo.

A todo esto se suma la forma de la interacción. Un turno agéntico no es una respuesta: es un proceso que emite tokens, anuncia que va a llamar a una herramienta, informa del resultado y sigue pensando. Ese goteo pide un canal abierto en los dos sentidos, no un ciclo de pedir y responder. Y si el bucle tarda dos minutos, o si se queda esperando a que alguien apruebe una acción delicada, el usuario debe poder cerrar la pestaña, volver más tarde y encontrarse el proceso justo donde lo dejó.

Lo que un agente necesita, entonces, es un lugar con nombre estable, con un solo hilo que serialice los turnos, con almacenamiento pegado al cómputo y capaz de sostener conexiones vivas. Esa lista no es una casualidad ni un deseo: es, punto por punto, la definición de un Durable Object. Por eso el Agents SDK no inventa un runtime nuevo, sino que se apoya en el que ya tenías.

Merece la pena subrayar lo poco romántico del diagnóstico. Nada de lo que hemos enumerado tiene que ver con la calidad del modelo, con el tamaño de su ventana de contexto ni con su capacidad de razonar. Son requisitos de sistemas distribuidos clásicos —identidad, exclusión mutua, durabilidad, empuje desde el servidor— que aparecen en cuanto un proceso deja de caber en una petición. La parte de IA de un sistema agéntico es, casi siempre, la más sencilla de construir y la que menos código ocupa; la parte difícil es la de siempre.

Con eso queda dibujado el mapa del nivel. La lección siguiente pone el agente en su sitio, sobre los Durable Objects. La tercera abre la puerta al mundo con las herramientas. La cuarta saca el trabajo pesado del bucle y lo lleva a procesos durables. Y la quinta se ocupa de lo único que separa un experimento vistoso de un sistema en producción: los límites.

La agencia no es inteligencia: es la cesión del control de flujo a un componente no determinista

Conviene decirlo sin romanticismo, porque la palabra agente arrastra una mitología que estorba al ingeniero. Lo que separa a un agente de una llamada a un modelo no es que piense mejor, ni que sea más consciente, ni que tenga voluntad: es una decisión puramente arquitectónica que tú tomas al escribir el sistema. Estás moviendo la responsabilidad del control de flujo desde tu código —determinista, revisable, testeable— hacia un componente estadístico cuya salida no puedes predecir. Durante setenta años la disciplina entera del software se construyó sobre la premisa contraria: el programador fija el grafo de ejecución y la máquina lo recorre. Un agente conserva la máquina pero externaliza el grafo, y lo reconstruye en cada ejecución a partir del lenguaje. De ese único cambio se derivan, como teoremas, todas las dificultades del nivel. El coste deja de ser una constante por petición y pasa a ser una variable aleatoria, así que necesita presupuesto. La terminación deja de estar garantizada por la estructura del código, así que necesita un límite de pasos. La corrección deja de poder demostrarse leyendo el programa, así que necesita observabilidad de las trazas. Y el conjunto de efectos posibles deja de ser el que escribiste y pasa a ser el que se puede componer con las herramientas que expusiste, así que el diseño del catálogo de herramientas es una decisión de seguridad, no de ergonomía. El ingeniero que interioriza esto deja de preguntarse cómo hacer al agente más listo y empieza a preguntarse lo único que importa: qué puede hacer este agente en el peor caso, cuánto puede gastar antes de que yo me entere, y cómo sabré después qué hizo exactamente. Un agente bien construido no es el que acierta más, es el que falla dentro de límites que tú elegiste.

⚔️ Encuentra el bucle en un problema tuyo
  1. Elige una tarea real de tu dominio que hoy resuelvas con una cadena fija de llamadas. Escribe el grafo de pasos tal como está en tu código hoy.
  2. Reescribe el mismo problema como objetivo más catálogo de capacidades. Enumera las herramientas mínimas que el modelo necesitaría y el esquema de argumentos de cada una.
  3. Estima el peor caso: cuántos pasos podría dar el bucle y cuánto costaría esa ejecución. Decide un valor concreto para stopWhen y justifícalo.
  4. Señala qué información debe sobrevivir entre turnos y cuál puede reconstruirse. Explica qué se rompe exactamente si esa memoria se pierde a mitad.
  5. Argumenta, con un caso concreto, la frase: la agencia es la cesión del control de flujo a un componente no determinista. Indica qué garantía pierdes y con qué mecanismo la repones.