Vai al contenuto principale

Loop dell’agente

Descrive come la Copilot CLI elabora end-to-end i messaggi dell’utente (dall’invio del prompt fino a session.idle).

Architettura

L’SDK è il livello di trasporto. Invia i prompt alla Copilot CLI tramite JSON-RPC e inoltra gli eventi all’applicazione. È la CLI a eseguire il loop di utilizzo degli strumenti in modo agentico, orchestrando una o più chiamate API all’LLM fino al completamento del task.

Loop di utilizzo degli strumenti

Quando chiami session.send({ prompt }), la CLI entra nel seguente loop. A ogni chiamata il modello fa riferimento all’intera cronologia della conversazione (system prompt / user message / tutte le chiamate a strumenti e i relativi risultati fino a quel momento). Importante: una iterazione di questo loop corrisponde esattamente a una chiamata API all’LLM e, nel log degli eventi, appare come una coppia assistant.turn_start / assistant.turn_end. Non ci sono chiamate nascoste.

Cos’è un turn

Un turn è una singola chiamata API all’LLM e il suo risultato.
  1. La CLI invia la cronologia della conversazione all’LLM
  2. L’LLM risponde (eventualmente includendo richieste di strumenti)
  3. Se ci sono richieste di strumenti, la CLI le esegue
  4. Viene emesso assistant.turn_end
Un singolo messaggio dell’utente genera solitamente più turn. Ad esempio, per una domanda come “Come funziona X in questa codebase?” si ha qualcosa di simile.
TurnComportamento del modellotoolRequests?
1Cerca nella codebase con grep e glob✅ Sì
2Legge file specifici in base ai risultati della ricerca✅ Sì
3Legge ulteriori file per un contesto più approfondito✅ Sì
4Genera la risposta testuale finale❌ No → loop ends
A ogni turn il modello decide se “continuare a usare strumenti” o “passare alla risposta finale”. Poiché ogni chiamata può vedere tutto il contesto accumulato (incluse le chiamate a strumenti passate e i loro risultati), può giudicare se le informazioni sono sufficienti.

Flusso di eventi in caso di più turn

Chi avvia ciascun turn

AttoreResponsabilità
La tua appInvia il primo prompt con session.send()
Copilot CLIEsegue il loop di utilizzo degli strumenti e restituisce all’LLM i risultati come input del turn successivo
LLMDecide se richiedere altri strumenti e proseguire, oppure restituire la risposta finale e terminare
SDKSi limita a inoltrare gli eventi. Non controlla il loop
Il comportamento della CLI è meccanico (“il modello richiede uno strumento → esegue → richiama il modello”). Chi decide la condizione di arresto è il modello.

Differenza tra session.idle e session.task_complete

Entrambi sono segnali di completamento, ma offrono garanzie molto diverse.

session.idle

  • Sempre emesso al termine del loop di utilizzo degli strumenti
  • Effimero (ephemeral). Non viene persistito su disco e non viene riprodotto alla ripresa della sessione
  • Significato: “l’agente ha smesso di elaborare ed è pronto ad accettare il prossimo messaggio”
  • Da usare come segnale affidabile di “completato”
Il metodo sendAndWait() dell’SDK attende questo evento.
// Attende finché non viene emesso session.idle
const response = await session.sendAndWait({ prompt: "Fix the bug" });

session.task_complete

  • Emissione facoltativa (solo se il modello lo segnala esplicitamente)
  • Persistito (salvato nel log degli eventi della sessione)
  • Significato: “l’agente stesso ha giudicato completato l’intero task”
  • Può includere un summary opzionale
session.on("session.task_complete", (event) => {
    console.log("Task done:", event.data.summary);
});

Modalità autopilot: la CLI sollecita task_complete

In modalità autopilot (headless / autonoma), la CLI tiene traccia di se il modello ha chiamato task_complete. Se il loop di utilizzo degli strumenti termina senza task_complete, la CLI inserisce il seguente messaggio utente sintetico per sollecitare il modello.
“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.”
Questo di fatto riavvia il loop di utilizzo degli strumenti. Il modello riceve la sollecitazione come nuovo messaggio dell’utente e prosegue il lavoro. La sollecitazione include anche l’indicazione di “non chiamare task_complete troppo presto”.
  • Non chiamarlo se restano domande aperte. Decidi e continua a lavorare
  • Non chiamarlo se hai appena incontrato un errore. Prova a risolverlo
  • Non chiamarlo se ci sono task residui. Completali prima
In autopilot si ottiene quindi il seguente meccanismo di completamento in due fasi.
  1. Il modello chiama task_complete con un summary → la CLI emette session.task_complete → completato
  2. Il modello si ferma senza chiamarlo → la CLI sollecita → il modello prosegue oppure chiama task_complete

Perché task_complete potrebbe non essere emesso

In modalità interattiva (chat normale), la CLI non sollecita task_complete. Il modello può ometterlo. I motivi principali sono i seguenti.
  • Q&A conversazionale: risponde alla domanda e termina, senza un “task completato” discreto
  • Decisione del modello: restituisce il testo finale senza chiamare task_complete
  • Sessione interrotta: la sessione termina prima che il modello raggiunga un punto di completamento
La CLI emette invece sempre session.idle. Questo perché non è un segnale semantico (il modello ha giudicato completato) ma un segnale meccanico (il loop è terminato).

Quale usare

Caso d’usoSegnale
”Attendere la fine dell’elaborazione dell’agente”session.idle
“Sapere che il task di coding è stato completato”session.task_complete (best-effort)
“Gestione di timeout/errori”session.idle + session.error

Contare il numero di chiamate all’LLM

Il numero di coppie assistant.turn_start / assistant.turn_end nel log degli eventi coincide con il numero totale di chiamate API all’LLM. Non ci sono chiamate nascoste per pianificazione, valutazione o conferma del completamento. Esempio di verifica del numero di turn di una sessione:
# Conta i turn nel log eventi della sessione
grep -c "assistant.turn_start" ~/.copilot/session-state/<sessionId>/events.jsonl

Documenti correlati

Ultima modifica il 13 luglio 2026