Skip to main content

Bucle del agente

Cómo la CLI de Copilot procesa un mensaje de usuario de un extremo a otro: desde la solicitud hasta session.idle.

Architecture

Diagrama: diagrama de gráfico que muestra el proceso descrito.

El SDK es una capa de transporte: envía el mensaje al Copilot CLI a través de JSON-RPC y expone eventos de vuelta a la aplicación. La CLI es el orquestador que ejecuta el bucle de uso de herramientas por parte del agente, realizando una o varias llamadas a la API de LLM hasta que la tarea se completa.

Bucle de uso de herramientas

Cuando se llama a session.send({ prompt }), la CLI entra en un bucle:

Diagrama: Diagrama de flujo que muestra el proceso descrito.

El modelo ve el historial de conversaciones completo en cada llamada: aviso del sistema, mensaje de usuario y todas las llamadas y resultados de las herramientas anteriores.

Información clave: Cada iteración de este bucle es exactamente una llamada API de LLM, visible como un assistant.turn_start / assistant.turn_end par en el registro de eventos. No hay llamadas ocultas.

Turnos: lo que son

Un turno es una sola llamada API de LLM y sus consecuencias:

  1. La CLI envía el historial de conversaciones al LLM.
  2. El LLM responde (posiblemente con peticiones de herramientas)
  3. Si se solicitaron herramientas, la CLI las ejecuta.
  4. assistant.turn_end se emite

Un único mensaje de usuario suele dar lugar a varios turnos. Por ejemplo, una pregunta como "¿cómo funciona X en este código base?" puede producir:

TurnoQué hace el modelotoolRequests?
1Llama a grep y a glob para buscar en la base de código
✅ Sí
2Lee archivos específicos en función de los resultados de la búsqueda.
✅ Sí
3Lee más archivos para un contexto más profundo.
✅ Sí
4Genera la respuesta de texto final.
❌ No → finaliza el bucle

El modelo decide cada turno si desea solicitar más herramientas o generar una respuesta final. Cada llamada ve el contexto acumulado completo (todas las llamadas a herramientas y resultados anteriores), por lo que puede tomar una decisión informada sobre si tiene suficiente información.

Flujo de eventos para una interacción de varios turnos

Diagrama: Diagrama de flujo que muestra el proceso descrito.

¿Quién desencadena cada turno?

ActorResponsabilidad
La aplicaciónEnvía el mensaje inicial a través de session.send()
Copilot CLIEjecuta el bucle de uso de herramientas: ejecuta las herramientas y devuelve los resultados al LLM para el siguiente turno.
LLMDecide si solicitar herramientas (seguir en bucle) o generar una respuesta final (detenerse)
SDKDeja pasar los eventos; no controla el bucle

La CLI es puramente mecánica: "el modelo pide herramientas → ejecutar → volver a llamar al modelo". El modelo es quien decide cuándo detenerse.

session.idle frente a session.task_complete

Estas son dos señales de finalización diferentes con garantías muy diferentes:

session.idle

  • Siempre se emite cuando finaliza el bucle de uso de herramientas
  • Efímero: no se conserva en el disco, no se reproduce en el reanudación de la sesión
  • Significa: "el agente ha detenido el procesamiento y está listo para el siguiente mensaje"
  • Use esto como una señal fiable de "hecho"

El método del sendAndWait() SDK espera este evento:

// Blocks until session.idle fires
const response = await session.sendAndWait({ prompt: "Fix the bug" });

session.task_complete

  • Opcionalmente emitido: requiere que el modelo lo indique explícitamente.
  • Persistente: guardado en el registro de eventos de sesión en el disco
  • Significa: "el agente considera que se ha cumplido la tarea general"
  • Lleva un campo opcional summary
session.on("session.task_complete", (event) => {
    console.log("Task done:", event.data.summary);
});

Modo piloto automático: indicaciones de la CLI para task_complete

En modo de piloto automático (funcionamiento sin interfaz o autónomo), la CLI supervisa activamente si el modelo ha invocado task_complete. Si el bucle de uso de herramientas termina sin que eso ocurra, la CLI inyecta un mensaje de usuario sintético para orientar al modelo:

"Todavía no ha marcado la tarea como completada con la herramienta task_complete. Si estaba planeando, detenga la planeación y empiece a implementar. No ha terminado hasta que haya completado completamente la tarea".

Esto reinicia eficazmente el bucle tool-use: el modelo ve el nudge como un nuevo mensaje de usuario y continúa funcionando. La indicación también instruye al modelo para no llamar prematuramente a task_complete:

  • No lo llames si tienes preguntas abiertas, toma decisiones y sigue trabajando
  • No lo llame si se produce un error: intente resolverlo.
  • No lo invoques si quedan pasos pendientes: complétalos primero

Esto crea un mecanismo de finalización de dos niveles en Autopilot:

  1. El modelo llama a task_complete con un resumen → la CLI genera session.task_complete → listo
  2. El modelo se detiene sin invocarlo → la CLI lo reorienta → el modelo continúa o llama a task_complete

¿Por qué task_complete podría no aparecer?

En modo interactivo (chat normal), la CLI no solicita task_complete. El modelo puede omitirlo por completo. Motivos comunes:

  • Preguntas y respuestas conversacionales: El modelo responde a una pregunta y simplemente se detiene, no hay ninguna "tarea" discreta para completarse.
  • Discreción del modelo: el modelo genera una respuesta de texto final sin llamar a la señal de tarea completa.
  • Sesiones interrumpidas: la sesión finaliza antes de que el modelo alcance un punto de finalización.

La CLI emite session.idle independientemente, ya que es una señal mecánica (el bucle finalizó), no una semántica (el modelo cree que se ha hecho).

¿Cuál deberías usar?

Caso de usoSeñal
"Espere a que el agente finalice el procesamiento"
session.idle
"Saber cuándo se realiza una tarea de codificación"
session.task_complete (mejor esfuerzo)
"Tiempo de espera/control de errores"
session.idle

session.error ✅ |

Recuento de llamadas LLM

El número de pares del registro de eventos es igual al número total de assistant.turn_start / assistant.turn_end llamadas API de LLM realizadas. No hay llamadas ocultas para la planeación, evaluación o comprobación de finalización.

Para inspeccionar el recuento de turnos de una sesión:

# Count turns in a session's event log
grep -c "assistant.turn_start" ~/.copilot/session-state/<sessionId>/events.jsonl

Lectura adicional