Bucle del Agente (OpenClaw)

Un bucle agentico es la ejecución completa y “real” de un agente: recepción → ensamblaje de contexto → inferencia del modelo → ejecución de herramientas → streaming de respuestas → persistencia. Es la ruta autoritativa que convierte un mensaje en acciones y una respuesta final, manteniendo consistente el estado de la sesión.

En OpenClaw, un bucle es una ejecución única y serializada por sesión que emite eventos de ciclo de vida y de stream mientras el modelo piensa, llama herramientas y transmite la salida. Este documento explica cómo se conecta ese bucle de principio a fin.

Puntos de entrada

  • RPC del Gateway: agent y agent.wait.
  • CLI: comando agent.

Cómo funciona (visión general)

  1. El RPC agent valida parámetros, resuelve la sesión (sessionKey/sessionId), persiste los metadatos de sesión y devuelve { runId, acceptedAt } de inmediato.
  2. agentCommand ejecuta el agente:
    • resuelve el modelo + valores por defecto de thinking/verbose
    • carga el snapshot de skills
    • llama a runEmbeddedPiAgent (runtime pi-agent-core)
    • emite lifecycle end/error si el bucle embebido no lo hace
  3. runEmbeddedPiAgent:
    • serializa ejecuciones mediante colas por sesión + globales
    • resuelve el modelo + perfil de autenticación y construye la sesión pi
    • se suscribe a eventos pi y transmite deltas de asistente/herramienta
    • aplica timeout -> aborta la ejecución si se excede
    • devuelve payloads + metadatos de uso
  4. subscribeEmbeddedPiSession conecta los eventos de pi-agent-core al stream agent de OpenClaw:
    • eventos de herramienta => stream: "tool"
    • deltas del asistente => stream: "assistant"
    • eventos de ciclo de vida => stream: "lifecycle" (phase: "start" | "end" | "error")
  5. agent.wait usa waitForAgentJob:
    • espera por lifecycle end/error para el runId
    • devuelve { status: ok|error|timeout, startedAt, endedAt, error? }

Encolamiento + concurrencia

  • Las ejecuciones se serializan por clave de sesión (carril de sesión) y opcionalmente a través de un carril global.
  • Esto previene condiciones de carrera en herramientas/sesiones y mantiene consistente el historial de sesión.
  • Los canales de mensajería pueden elegir modos de cola (collect/steer/followup) que alimentan este sistema de carriles. Consulta Cola de comandos.

Preparación de sesión + workspace

  • El workspace se resuelve y crea; las ejecuciones en sandbox pueden redirigir a una raíz de workspace sandbox.
  • Los skills se cargan (o se reutilizan de un snapshot) y se inyectan en el entorno y el prompt.
  • Los archivos de bootstrap/contexto se resuelven e inyectan en el reporte del system prompt.
  • Se adquiere un bloqueo de escritura de sesión; SessionManager se abre y prepara antes del streaming.

Ensamblaje del prompt + system prompt

  • El system prompt se construye a partir del prompt base de OpenClaw, el prompt de skills, el contexto de bootstrap y las configuraciones por ejecución.
  • Se aplican los límites específicos del modelo y los tokens reservados para compactación.
  • Consulta System prompt para ver qué recibe el modelo.

Puntos de enganche (dónde puedes interceptar)

OpenClaw tiene dos sistemas de hooks:

  • Hooks internos (hooks del Gateway): scripts dirigidos por eventos para comandos y eventos del ciclo de vida.
  • Hooks de plugins: puntos de extensión dentro del ciclo de vida del agente/herramienta y el pipeline del gateway.

Hooks internos (hooks del Gateway)

  • agent:bootstrap: se ejecuta mientras se construyen los archivos de bootstrap antes de finalizar el system prompt. Úsalo para agregar/eliminar archivos de contexto de bootstrap.
  • Hooks de comandos: /new, /reset, /stop y otros eventos de comando (consulta la documentación de Hooks).

Consulta Hooks para configuración y ejemplos.

Hooks de plugins (ciclo de vida del agente + gateway)

Se ejecutan dentro del bucle del agente o del pipeline del gateway:

  • before_model_resolve: se ejecuta antes de la sesión (sin messages) para sobrescribir determinísticamente provider/modelo antes de la resolución del modelo.
  • before_prompt_build: se ejecuta después de cargar la sesión (con messages) para inyectar prependContext, systemPrompt, prependSystemContext o appendSystemContext antes de enviar el prompt. Usa prependContext para texto dinámico por turno y los campos de system-context para directrices estables que deben ir en el espacio del system prompt.
  • before_agent_start: hook de compatibilidad heredado que puede ejecutarse en cualquiera de las fases; prefiere los hooks explícitos anteriores.
  • agent_end: inspecciona la lista final de mensajes y los metadatos de ejecución al completar.
  • before_compaction / after_compaction: observa o anota ciclos de compactación.
  • before_tool_call / after_tool_call: intercepta parámetros/resultados de herramientas.
  • tool_result_persist: transforma sincrónicamente los resultados de herramientas antes de escribirlos en la transcripción de la sesión.
  • message_received / message_sending / message_sent: hooks de mensajes entrantes + salientes.
  • session_start / session_end: límites del ciclo de vida de la sesión.
  • gateway_start / gateway_stop: eventos del ciclo de vida del gateway.

Consulta Plugins para la API de hooks y detalles de registro.

Streaming + respuestas parciales

  • Los deltas del asistente se transmiten desde pi-agent-core y se emiten como eventos assistant.
  • El streaming por bloques puede emitir respuestas parciales en text_end o message_end.
  • El streaming de razonamiento puede emitirse como un stream separado o como respuestas por bloques.
  • Consulta Streaming para el comportamiento de chunking y respuestas por bloques.

Ejecución de herramientas + herramientas de mensajería

  • Los eventos de inicio/actualización/fin de herramienta se emiten en el stream tool.
  • Los resultados de herramientas se sanitizan por tamaño y payloads de imagen antes de registrar/emitir.
  • Los envíos de herramientas de mensajería se rastrean para suprimir confirmaciones duplicadas del asistente.

Moldeado + supresión de respuestas

  • Los payloads finales se ensamblan a partir de:
    • texto del asistente (y razonamiento opcional)
    • resúmenes inline de herramientas (cuando verbose + permitido)
    • texto de error del asistente cuando el modelo falla
  • NO_REPLY se trata como un token silencioso y se filtra de los payloads salientes.
  • Los duplicados de herramientas de mensajería se eliminan de la lista final de payloads.
  • Si no quedan payloads renderizables y una herramienta tuvo error, se emite una respuesta de error de herramienta de respaldo (a menos que una herramienta de mensajería ya haya enviado una respuesta visible al usuario).

Compactación + reintentos

  • La auto-compactación emite eventos de stream compaction y puede activar un reintento.
  • En un reintento, los buffers en memoria y los resúmenes de herramientas se resetean para evitar salida duplicada.
  • Consulta Compactación para el pipeline de compactación.

Streams de eventos (actual)

  • lifecycle: emitido por subscribeEmbeddedPiSession (y como respaldo por agentCommand)
  • assistant: deltas transmitidos desde pi-agent-core
  • tool: eventos de herramientas transmitidos desde pi-agent-core

Manejo del canal de chat

  • Los deltas del asistente se almacenan en buffer como mensajes delta de chat.
  • Un final de chat se emite en lifecycle end/error.

Timeouts

  • Valor por defecto de agent.wait: 30s (solo la espera). El parámetro timeoutMs lo sobrescribe.
  • Runtime del agente: agents.defaults.timeoutSeconds por defecto 600s; se aplica en el temporizador de abort de runEmbeddedPiAgent.

Dónde puede terminar antes

  • Timeout del agente (abort)
  • AbortSignal (cancelación)
  • Desconexión del Gateway o timeout del RPC
  • Timeout de agent.wait (solo espera, no detiene al agente)