La arquitectura de bucle de agentes

@djfarrelly
INGLÉShace 4 semanas · 18 jun 2026
559K
800
104
22
3.1K

TL;DR

Este artículo explora la arquitectura de tres capas de los sistemas de agentes (bucles, habilidades y orquestación), enfatizando la necesidad de una ejecución duradera para prevenir fallas y permitir una IA que evolucione por sí misma.

Todo el mundo pregunta "WTF es un loop?" Aquí está la pregunta que nadie se hace: ¿qué ejecuta el loop?

El discurso sobre IA ha convergido en los loops como un primitivo central de los sistemas de agentes. Matt Van Horn (@mvanhorn) trazó el linaje de los agent loops desde ReAct hasta el uso de herramientas, pasando por loops de orquestación hasta loops supervisando loops. Addy Osmani (@addyosmani) desglosó los bloques de construcción dentro de los loops: automatizaciones, árboles de trabajo, skills, conectores, sub-agentes. Van Horn se enfocó en la durabilidad, argumentando que los loops que no pueden sobrevivir a un reinicio no son loops. El hilo clave de Osmani fue la orquestación: diseñar el sistema que le da instrucciones al agente en lugar de que lo hagas tú.

Quiero llevar sus puntos más allá. La durabilidad no es solo una propiedad del loop. Es toda la capa de ejecución que está debajo. El hecho importante es que la orquestación durable es fundamental para construir la arquitectura de tu agent loop. Analicemos esa arquitectura.

Donde los loops se rompen

Los patrones /loop y /goal manejan bien el trabajo de un solo agente en una sola sesión. Un agente itera hasta que una tarea está completa. Eso cubre mucho terreno. Pero la siguiente etapa (Etapa 5 en el marco de Van Horn) es donde todo se desmorona:

  • Loops supervisando otros loops
  • Loops que se ejecutan en horarios, no solo activados por un humano
  • Loops que sobreviven a reinicios de procesos, despliegues y caídas
  • Loops que generan sub-agentes y esperan resultados (a veces horas después)
  • Loops que necesitan ser observables después del hecho

Eso no es un problema de prompting. Es un problema de infraestructura.

Van Horn cita a @runes_leo: "Lo más costoso en la programación con IA ya no es escribir código, es gestionar el agent loop." Un while True en una terminal no te da nada de esto. Tampoco lo hace un proceso de larga duración en una VM o sandbox.

Piensa en lo que sucede cuando ejecutas un agent loop en un servidor. El proceso morirá o se reiniciará. Un despliegue, un OOM, una reclamación de instancia spot. El loop se reinicia. Pero, ¿qué estaba haciendo? ¿En qué paso estaba? ¿Ya envió ese mensaje de Slack? ¿Ya invocó al sub-agente?

No lo sabes. Empieza de nuevo. Vuelve a obtener datos que ya tenía. Vuelve a llamar al LLM para decisiones que ya tomó. Envía una notificación duplicada. Genera un sub-agente duplicado. Te despiertas con tres mensajes idénticos de Slack y un equipo confundido.

La solución no es un "mejor manejo de errores" — es un modelo de ejecución donde cada paso tiene un punto de control, cada decisión se persiste, y la recuperación significa reanudar desde el último paso exitoso.

La arquitectura del agent loop en tres capas

Tres capas. Cada una se asigna a un primitivo concreto.

Capa 1: El Loop

Un loop es un cron más un tomador de decisiones. Se ejecuta en un horario (o un disparador), evalúa el estado y decide qué hacer a continuación.

Esta es la definición de Van Horn hecha concreta: lo que cron nunca tuvo es la decisión en el medio. El agente decide, no tú. El cron es el latido. El LLM es el tomador de decisiones. Los steps son la ejecución durable que guarda el progreso.

typescript
1export const infraHealthCheck = inngest.createFunction(
2 { id: "infra-health-check" },
3 { cron: "*/30 * * * *" }, // Cada 30 minutos
4 async ({ step }) => {
5 const metrics = await step.run("fetch-service-metrics", async () => {
6 return await fetchServiceMetrics(); // tasas de error, latencia, memoria, CPU
7 });
8
9 const assessment = await step.run("assess-health", async () => {
10 return await callLLM({
11 prompt: `Dadas estas métricas de servicio, clasifica la salud general del sistema
12 como "normal", "degradada" o "crítica". Explica tu razonamiento.
13 Métricas: ${JSON.stringify(metrics)}`,
14 });
15 });
16
17 if (assessment.status === "degraded" || assessment.status === "critical") {
18 await step.invoke("triage-incident", {
19 function: incidentTriage,
20 data: { metrics, assessment, services: assessment.affectedServices },
21 });
22 }
23 }
24);

Todos los lunes a las 9am, el loop se activa. Obtiene datos, le pregunta al LLM si vale la pena generar un informe, e invoca un skill si es así. Si el proceso se reinicia entre pasos, los pasos ya completados no se re-ejecutan. Ese es el loop. No el LLM, el loop alrededor del LLM.

Capa 2: El Skill

En este contexto, un skill no es un prompt. Es un flujo de trabajo durable. Multietapa, reintentable, componible, desplegable de forma independiente.

Van Horn: "El loop es la tubería. El activo es el skill al que llama." Esta es la parte que se acumula. Cada nuevo skill que el sistema aprende hace que cada loop sea más capaz.

typescript
1export const incidentTriage = inngest.createFunction(
2 { id: "incident-triage", retries: 3 },
3 { event: "infra.incident.triage" },
4 async ({ event, step }) => {
5 const details = await step.run("fetch-detailed-metrics", async () => {
6 return await fetchDetailedMetrics({ services: event.data.services });
7 });
8
9 const deploys = await step.run("fetch-deploy-history", async () => {
10 return await fetchRecentDeploys({ since: hoursAgo(2) });
11 });
12
13 const analysis = await step.run("correlate-incident", async () => {
14 return await callLLM({
15 prompt: `Correlaciona estas métricas de servicio con los despliegues recientes.
16 Identifica la causa raíz probable y la severidad.
17 Métricas: ${JSON.stringify(details)}
18 Despliegues recientes: ${JSON.stringify(deploys)}`,
19 });
20 });
21
22 await step.run("post-triage-summary", async () => {
23 await slack.postMessage({
24 channel: "#incidents",
25 text: formatTriageSummary({
26 analysis,
27 affectedServices: event.data.services,
28 recommendedActions: analysis.recommendations,
29 }),
30 });
31 });
32
33 return analysis;
34 }
35);

Este skill obtiene, clasifica y enruta. Es una unidad de trabajo con tolerancia a fallos incorporada. El skill puede ser un flujo de trabajo de IA con un LLM en el medio o código determinista.

Capa 3: El Orquestador

El orquestador es el motor que lo ejecuta todo: programa crons, ejecuta pasos, gestiona reintentos, aplica límites de concurrencia, almacena el historial de ejecuciones y despliega en caliente nuevas funciones/flujos de trabajo sin interrumpir las que están en ejecución.

Esta es la capa de la que nadie habla porque se supone que debe ser invisible. Pero es fundamental.

La mayoría de la gente piensa en los agentes como "LLM + herramientas." La arquitectura del agent loop replantea esto como: los agentes son "loops + skills + orquestación." El LLM + herramientas están dentro de los loops. Los LLM y las herramientas se pueden intercambiar o ajustar mientras la arquitectura permanece. La orquestación hace posible la arquitectura.

Qué sucede cuando las cosas se rompen

El camino feliz es fácil. Pero esto es software ejecutándose en producción, ¿acaso las cosas siempre salen según lo planeado?

Tu skill de triaje de incidentes se activa y la API de métricas se cae por tiempo de espera. La lectura tuvo que ir a disco y la caché en memoria no tenía los datos. El paso que llama a esta API ahora reintenta y vuelve a golpear la API. Los datos ahora están parcialmente en caché y la API se completa. El skill continúa con el siguiente paso como si nada hubiera pasado.

A veces, no es tan simple. ¿Qué pasa si una clave de API caduca, o tu proveedor de hosting está caído durante 30 minutos? Todos tus reintentos se agotan. ¿Y ahora qué? También tienes que manejar los fallos.

typescript
1export const incidentTriage = inngest.createFunction(
2 {
3 id: "incident-triage",
4 retries: 3,
5 onFailure: async ({ error, event, step }) => {
6 // La función falló después de agotar los reintentos.
7 // Todavía tenemos los datos del evento original. Nada se pierde.
8 await step.run("notify-failure", async () => {
9 await slack.postMessage({
10 channel: "#agent-ops",
11 text: `⚠️ El triaje de incidentes falló: ${error.message}. ` +
12 `Se reintentará en el próximo ciclo de verificación de salud. ` +
13 `Servicios afectados: ${event.data.services.join(", ")}`,
14 });
15 });
16 },
17 },
18 { event: "infra.incident.triage" },
19 async ({ event, step }) => {
20 /* la misma lógica que el skill de arriba */
21 }
22);

El manejador \onFailure\ se activa después de que se agotan todos los reintentos. Publica en un canal de operaciones para que alguien lo sepa. El evento se conserva, nada se pierde. La próxima ejecución programada retoma donde la fallida no pudo.

La orquestación durable debe darte reintentos a nivel de paso para errores transitorios y ganchos de manejo de fallos para errores no recuperables. Sin esto, las cosas se rompen (como sucede), y te enteras horas o días después.

Los errores transitorios también son costosos. Si tu skill o agente reintenta desde el principio, estás llamando a los LLM múltiples veces y quemando tokens innecesariamente. La llamada al LLM puede tener un punto de control. Ahora multiplica esto por 10, o 30, agentes en todo tu sistema. Eso es costoso.

El checkpointing a nivel de paso no es solo una característica de corrección. Es un ahorrador de dinero.

El agente que construye sus propios skills

Aquí es donde se pone más interesante. El sistema no es estático, está diseñado para evolucionar y extenderse a sí mismo.

El agente no solo se ejecuta dentro de loops — sino que crea nuevos loops y los registra en el motor de orquestación. Cada función desplegada es un skill durable que se ejecuta de forma independiente, se puede activar desde un loop o agente, o ejecutarse en un horario, con su propia lógica de reintento. Los skills se acumulan.

Es un agente consciente de la orquestación.

Así es como funciona. Un agente de IA tiene acceso al SDK de orquestación como una herramienta. Puede escribir nuevas funciones, registrarlas en el motor, y comienzan a ejecutarse inmediatamente. El proceso del agente recarga en caliente las nuevas funciones sin reiniciar ni interrumpir las ejecuciones en curso.

Veamos un ejemplo concreto:

1. Un humano expresa una necesidad. El ingeniero dice: "Nuestros servicios siguen teniendo picos de latencia durante la noche y nadie se da cuenta hasta la mañana." Este es el disparador. El agente no necesita inferir un patrón vago a partir de datos ambientales. Tiene instrucciones claras.

2. El agente escribe un skill. Dos funciones multietapa: un loop de verificación de salud que se ejecuta cada 30 minutos, obteniendo tasas de error, latencia y uso de recursos, con el LLM clasificando la salud del sistema como normal, degradada o crítica. Y un skill de triaje de incidentes que obtiene métricas detalladas y el historial de despliegues recientes, correlaciona las causas raíz con un LLM, y publica un resumen del triaje en Slack con acciones recomendadas. Manejo de errores: si la API de métricas está caída, espera y reintenta. Si el LLM falla, recurre a una clasificación de severidad basada en reglas.

3. El agente despliega el skill. El agente escribe el código de la función que es recogido por un proceso sidecar. Las nuevas funciones se registran automáticamente. Están activas de inmediato, sin canal de despliegue, sin PR.

4. El skill se ejecuta autónomamente. Cada 30 minutos, el motor activa la verificación de salud. Si algo está mal, invoca el skill de triaje. Sin humanos en el loop. Completamente durable.

5. El agente itera sobre la señal. Esta es la parte que la gente pasa por alto, así que déjame ser específico sobre lo que significa "iterar". El agente no nota patrones mágicamente. Tiene un loop de revisión separado: una función activada por cron que se ejecuta semanalmente, lee el historial de ejecuciones del orquestador y evalúa el rendimiento:

typescript
1export const reviewSkillPerformance = inngest.createFunction(
2 { id: "review-skill-performance" },
3 { cron: "0 10 * * 5" }, // Cada viernes a las 10am
4 async ({ step }) => {
5 const runs = await step.run("fetch-run-history", async () => {
6 return await getInngestRuns({
7 functionId: "incident-triage",
8 since: daysAgo(7),
9 });
10 });
11
12 const analysis = await step.run("analyze-performance", async () => {
13 const successRate = runs.filter(r => r.status === "completed").length / runs.length;
14 const avgDuration = average(runs.map(r => r.duration));
15 const incidents = await fetchIncidentOutcomes(); // ¿Se correlacionaron los incidentes con caídas reales?
16
17 return await callLLM({
18 prompt: `Revisa el rendimiento de este skill durante la última semana.
19 Tasa de éxito: ${successRate}
20 Duración promedio: ${avgDuration}ms
21 Incidentes correlacionados con caídas reales: ${incidents.confirmed}/${incidents.total}
22 Falsos positivos: ${incidents.falsePositives}
23 El equipo actuó sobre las alertas: ${incidents.actedOn}/${incidents.total}
24
25 ¿Deberíamos ajustar los umbrales o la clasificación? ¿Qué cambios específicos?`,
26 });
27 });
28
29 if (analysis.shouldModify) {
30 await step.invoke("update-skill", {
31 function: coreAgent,
32 data: { prompt: `Actualiza los skills de incident-triage basándote en los siguientes cambios propuestos: ${analysis.proposedChanges}` },
33 });
34 }
35 }
36);

La "revisión" es una función. Lee el historial de ejecuciones, verifica si los incidentes se correlacionaron con caídas reales, y alimenta esa señal al LLM. Si la verificación de salud sigue marcando un servicio como degradado pero el equipo lo ignora porque los umbrales son demasiado sensibles, el loop de revisión lo detecta y el skill se actualiza para ajustar la clasificación. No es magia. Es un cron job con un LLM en el asiento de la decisión.

¿Qué pasa con la validación? El agente que escribe código es tan bueno como las barreras de seguridad a su alrededor. El código se puede verificar con tipos. El agente puede invocar la función misma para probarla, ya que puede interactuar con el motor de orquestación. Si bien no es infalible, le estás dando al agente central la capacidad de depurar los skills que escribe de forma nativa dentro del sistema en el que opera. El loop de revisión detecta problemas que no se detectan en la depuración inicial.

Llevando esto un paso más allá, el agente puede usar los hooks onFailure para activarse a sí mismo y evaluar un fallo dado. Es un bucle de retroalimentación que sigue mejorando.

¿Qué pasa con los conflictos? Los controles de flujo, específicamente, los controles de concurrencia o los singletons manejan el caso simple (concurrency: { limit: 1, key: "[event.data.service" }]) lo que significa que solo un triaje de incidentes se ejecuta a la vez por servicio. Pero la pregunta más profunda es: ¿qué pasa si dos verificaciones de salud detectan problemas en el mismo servicio simultáneamente? El orquestador los pone en cola. El segundo triaje espera hasta que el primero se complete. Sin alertas duplicadas, sin condiciones de carrera. Esto no es teórico. Es el mismo primitivo de concurrencia que usarías en cualquier cola de trabajos.

El agente no solo está ejecutando tareas. Está construyendo infraestructura para sí mismo. Cada skill durable persiste más allá de la conversación que lo creó. Mata el proceso del agente y reinícialo. Los skills siguen ejecutándose. Cambia el modelo subyacente. Los skills siguen ejecutándose. El agente es efímero — su producción es duradera.

Dan Farrelly | Inngest.com - inline image

Descripción general del sistema de arquitectura del agent loop

La vista del desarrollador

Esto importa porque si el desarrollador no puede ver lo que el agente desplegó, depurar lo que se rompió y auditar lo que se ejecutó a las 3am, toda la arquitectura es un gran riesgo.

El motor de orquestación almacena cada ejecución, cada paso, cada entrada, cada salida, cada reintento. ¿Un skill que el agente desplegó el martes pasado y falló a las 4am? Puedes ver exactamente qué paso falló, cuál fue la entrada, qué error lanzó y cuántas veces reintentó antes de rendirse. Trazas completas hasta el nivel de paso son la salida del propio motor de orquestación.

Esto no es un panel de control añadido después del hecho. Es inherente a la ejecución durable. Cada step.run() es un punto de control. Cada punto de control es observable. Cuando lo que escribió el código no es un humano, la observabilidad no es algo agradable de tener — es la capa de confianza.

En el día a día, el flujo de trabajo del desarrollador se ve así: revisa el panel de ejecuciones por la mañana. Ve qué skills se ejecutaron durante la noche, cuáles tuvieron éxito, cuáles fallaron. Si un skill que escribió el agente se está comportando mal, puedes leer el código directamente, editarlo, eliminarlo o decirle al agente que lo arregle. El agente lo creó, pero tú lo posees. El agente y sus skills siguen siendo un jardín del que debes cuidar.

Por qué la durabilidad es fundamental

Van Horn: "Estas cosas tienen que sobrevivir a un reinicio."

Esto es lo que significa la durabilidad en la práctica:

Requisito

Qué significa

Por qué el simple bucle while falla

Reintento independiente de pasos

Si el paso 3 de 5 falla, reintenta el paso 3, no los pasos 1 y 2

Un reinicio del loop vuelve a ejecutar todo desde cero

Ciclo de vida de sub-agentes

Generar una tarea hija, esperarla (quizás horas), cancelarla si el padre se cancela

No hay gestión incorporada del ciclo de vida padre-hijo

Entrega garantizada de eventos

Si un evento se dispara mientras el agente está caído, aún debe procesarse

Los eventos se pierden si el proceso no está en ejecución

Observabilidad posterior

Ver qué sucedió después del hecho: cada paso, cada decisión, cada reintento

Los logs son tu única opción, y son efímeros

Despliegue en caliente sin tiempo de inactividad

Desplegar una nueva versión de función sin matar las ejecuciones en curso

El reinicio del proceso lo mata todo

Control de concurrencia

Ejecutar solo N instancias de un skill a la vez

No hay primitivos de concurrencia incorporados

"Simplemente ejecútalo en un contenedor" te da tiempo de actividad. No te da corrección. Un contenedor que se reinicia después de una caída trae el proceso de vuelta, pero cada loop en curso comienza de nuevo. Cada paso se re-ejecuta. Cada llamada al LLM se re-hace. El loop parece estar ejecutándose, pero está ejecutándose a ciegas.

Cómo se compara esto con las herramientas existentes

Algunas herramientas pueden ofrecerte una solución "bonita" y llave en mano para este tipo de sistema, o puedes elegir juntar algunas herramientas de nivel inferior y crear tu propio sistema. Ninguna elección es incorrecta, pero la capa de arquitectura adecuada debería permitirte a ti, y a tu agente, evolucionar con el tiempo. Flexible, dinámica, durable.

Primitivos de ejecución durable que encajan bien para un agente, que un agente puede escribir fácilmente, y la observabilidad y APIs para observar y permitir que el propio agente sea consciente de la orquestación.

Un ejemplo funcional

Estamos probando estos patrones internamente en Inngest y puedes ver un concepto de esto en el repositorio del proyecto "utah" aquí: https://github.com/inngest/utah: Es un arnés de agente construido sobre la orquestación durable de Inngest que también es consciente de la orquestación.

El sistema tiene un proceso sidecar que permite al agente principal escribir y editar funciones de Inngest en su propio espacio de trabajo, extendiéndose a sí mismo con "skills" (en el contexto de este artículo). Pronto, planeamos proporcionar un sistema completo con loops de inicio como ejemplos, pero las ideas allí pueden demostrar las ideas de este artículo un poco más claramente.

El loop que se acumula

La publicación reciente de Satya Nadella nombró algo que la industria ha estado sintiendo: el foso no es el modelo — es el loop.

Su planteamiento: hay dos tipos de capital. Capital humano, el conocimiento y juicio que tu equipo ha construido durante años. Y lo que él llama capital de tokens, los flujos de trabajo de IA, patrones de decisión y skills aprendidos que una empresa construye sobre los modelos base.

La tesis: estos se acumulan juntos. Cada flujo de trabajo mejorado genera una mejor señal. Una mejor señal produce un comportamiento de IA más preciso. Un comportamiento más preciso libera la atención humana para trabajo de mayor juicio. Una máquina de escalada de colinas.

Esto es lo que la arquitectura del agent loop permite de forma concreta:

  • Cada skill durable que el agente despliega es conocimiento institucional codificado como infraestructura ejecutable. Persiste. Se ejecuta ya sea que un humano esté mirando o no.
  • Un loop de revisión activado por cron que evalúa el rendimiento del skill e itera. Esa es la máquina de escalada de colinas hecha realidad. No un diagrama de volante en una presentación. Una función con un disparador cron.
  • Si tus skills mueren al reiniciar el proceso, la acumulación se reinicia a cero. La durabilidad es lo que hace que la inversión persista.

El punto clave de Nadella: "Una empresa debería poder cambiar un modelo 'generalista' sin perder la experiencia de 'veterano de la empresa' incorporada en su sistema de aprendizaje." Ese es el patrón de la biblioteca de skills. Las funciones durables no les importa qué LLM las llama.

Construye en consecuencia

La conversación ha sido sobre lo que hacen los agentes: loops, herramientas, razonamiento, ingeniería de contexto. La siguiente conversación es sobre qué ejecuta los agentes.

Tres capas: loop, skill, orquestador. El loop es la unidad de trabajo. El skill es el activo. El motor de orquestación es lo que hace que ambos sean durables. El patrón sidecar es el modelo: un agente escribe sus propios skills durables, los despliega, revisa cómo se desempeñan e itera. No es un experimento mental. Es un modelo funcional.

Construimos Inngest para ser el motor de orquestación para esto: step.run(), step.invoke(), disparadores cron, control de flujo basado en eventos, controles de concurrencia y observabilidad completa a nivel de paso. Pero el patrón de arquitectura es más grande que cualquier herramienta individual. Si estás construyendo agent loops en producción, define las tres capas.

Los primitivos existen hoy. Construye en consecuencia.

Guardar con un clic

Lee artículos virales en profundidad con IA en YouMind

Guarda la fuente, haz preguntas concretas, resume el argumento y convierte un artículo viral en notas reutilizables en un único espacio de trabajo con IA.

Explora YouMind
Para creadores

Convierte tu Markdown en un artículo de 𝕏 impecable

Cuando publicas tus propios textos largos, dar formato en 𝕏 a imágenes, tablas y bloques de código es un fastidio. YouMind convierte un borrador completo en Markdown en un artículo de 𝕏 impecable y listo para publicar.

Prueba Markdown a 𝕏

Más patrones por descifrar

Artículos virales recientes

Explorar más artículos virales