Saltar al contenido principal

Bucle del agente

Explica cómo Copilot CLI procesa un mensaje del usuario de extremo a extremo (desde el envío del prompt hasta session.idle).

Arquitectura

El SDK es la capa de transporte. Envía los prompts al Copilot CLI mediante JSON-RPC y retransmite los eventos a tu aplicación. El CLI es quien ejecuta el bucle de uso de herramientas al estilo agente, orquestando una o más llamadas a la API del LLM hasta completar la tarea.

Bucle de uso de herramientas

Cuando llamas a session.send({ prompt }), el CLI entra en el siguiente bucle: En cada llamada, el modelo consulta todo el historial de la conversación (system prompt, mensaje del usuario y todas las llamadas a herramientas y sus resultados hasta ese momento). Importante: una iteración de este bucle equivale exactamente a una llamada a la API del LLM y aparece en el log de eventos como un par assistant.turn_start / assistant.turn_end. No hay llamadas ocultas.

Qué es un turn

Un turn es una llamada a la API del LLM y su resultado.
  1. El CLI envía el historial de la conversación al LLM
  2. El LLM responde (posiblemente incluyendo solicitudes de herramientas)
  3. Si hay solicitudes de herramientas, el CLI las ejecuta
  4. Se emite assistant.turn_end
En un solo mensaje del usuario suelen producirse varios turns. Por ejemplo, ante una pregunta como «¿cómo funciona X en esta base de código?» pasa esto:
TurnComportamiento del modelo¿toolRequests?
1Busca en la base de código con grep y glob✅ Sí
2Lee ficheros concretos según los resultados de la búsqueda✅ Sí
3Lee más para obtener contexto adicional✅ Sí
4Genera la respuesta final en texto❌ No → termina el bucle
En cada turn, el modelo decide si «usar más herramientas» o «pasar a la respuesta final». Como cada llamada ve todo el contexto acumulado (incluyendo las llamadas a herramientas y resultados anteriores), puede evaluar si tiene información suficiente.

Flujo de eventos con varios turns

Quién inicia cada turn

ActorResponsabilidad
Tu appEnvía el prompt inicial con session.send()
Copilot CLIEjecuta el bucle de uso de herramientas y devuelve los resultados de la ejecución al LLM como entrada del siguiente turn
LLMDecide si continuar solicitando herramientas o devolver la respuesta final y terminar
SDKSolo retransmite eventos. No controla el bucle
El comportamiento del CLI es mecánico («el modelo pide una herramienta → se ejecuta → se vuelve a llamar al modelo»). Quien toma la decisión de parar es el modelo.

Diferencias entre session.idle y session.task_complete

Ambas son señales de finalización, pero garantizan cosas muy distintas.

session.idle

  • Se emite siempre al terminar el bucle de uso de herramientas
  • Es efímera: no se persiste en disco ni se reproduce al reanudar la sesión
  • Significado: «el agente ha dejado de procesar y puede aceptar el siguiente mensaje»
  • Úsala como señal fiable de «terminado»
En el SDK, sendAndWait() espera este evento.
// Espera hasta que se emita session.idle
const response = await session.sendAndWait({ prompt: "Fix the bug" });

session.task_complete

  • Se emite opcionalmente (solo cuando el modelo lo señala explícitamente)
  • Es persistente (se guarda en el log de eventos de la sesión)
  • Significado: «el propio agente considera que la tarea global se ha cumplido»
  • Puede incluir un summary opcional
session.on("session.task_complete", (event) => {
    console.log("Task done:", event.data.summary);
});

Modo autopilot: el CLI empuja al modelo a llamar a task_complete

En el modo autopilot (headless / autónomo), el CLI hace un seguimiento de si el modelo ha llamado a task_complete. Si el bucle de uso de herramientas termina sin task_complete, el CLI inyecta el siguiente mensaje sintético de usuario para instar al modelo:
“You have not yet marked the task as complete using the task_complete tool. If you were planning, stop planning and start implementing. You aren’t done until you have fully completed the task.”
Con esto, el bucle de uso de herramientas se reanuda de hecho. El modelo recibe ese aviso como un nuevo mensaje de usuario y continúa el trabajo. El aviso incluye también «no llames a task_complete demasiado pronto»:
  • No lo llames si quedan dudas sin resolver. Decide y sigue trabajando.
  • No lo llames solo por haber encontrado un error. Intenta resolverlo.
  • No lo llames si quedan tareas pendientes. Termínalas primero.
En autopilot hay entonces un mecanismo de finalización en dos fases:
  1. El modelo llama a task_complete con un summary → el CLI emite session.task_complete → terminado
  2. El modelo se detiene sin llamarlo → el CLI le insiste → el modelo continúa o llama a task_complete

Por qué puede no aparecer task_complete

En el modo interactive (chat convencional), el CLI no empuja hacia task_complete. El modelo puede omitirlo. Principales razones:
  • Q&A conversacional: responde a la pregunta y termina, sin una «tarea» discreta que completar
  • Decisión del modelo: devuelve el texto final sin llamar a task_complete
  • Sesión interrumpida: la sesión termina antes de que el modelo llegue a un punto de finalización
En cambio, el CLI siempre emite session.idle porque no es una señal semántica (el modelo lo considera completo) sino mecánica (el bucle terminó).

¿Cuál deberías usar?

Caso de usoSeñal
«Esperar a que el agente termine de procesar»session.idle
«Saber que una tarea de programación ha terminado»session.task_complete (best-effort)
«Gestionar timeouts / errores»session.idle + session.error

Contar el número de llamadas al LLM

El número de pares assistant.turn_start / assistant.turn_end del log de eventos coincide con el total de llamadas a la API del LLM. No hay llamadas ocultas de planificación, evaluación o verificación de finalización. Ejemplo para comprobar el número de turns de una sesión:
# Cuenta los turns en el log de eventos de la sesión
grep -c "assistant.turn_start" ~/.copilot/session-state/<sessionId>/events.jsonl

Documentación relacionada

Última modificación el 13 de julio de 2026