Agent loop
Hier leggen we uit hoe de Copilot CLI een gebruikersbericht end-to-end verwerkt (van het versturen van de prompt totsession.idle).
Architectuur
De SDK is de transportlaag. Deze stuurt prompts via JSON-RPC naar de Copilot CLI en geeft events door aan je app. Het is de CLI die de agent-achtige tool-gebruiksloop uitvoert en één of meer LLM-API-aanroepen orkestreert totdat de taak is voltooid.De tool-gebruiksloop
Wanneer jesession.send({ prompt }) aanroept, gaat de CLI de volgende loop in.
Het model kijkt bij elke aanroep naar de volledige gespreksgeschiedenis (system prompt / user message / alle eerdere tool-aanroepen en resultaten).
Belangrijk: één iteratie van deze loop komt exact overeen met één LLM-API-aanroep en is in de eventlog zichtbaar als één paar assistant.turn_start / assistant.turn_end. Er zijn geen verborgen aanroepen.
Wat is een turn?
Een turn is één LLM-API-aanroep en het resultaat daarvan.- De CLI stuurt de gespreksgeschiedenis naar het LLM
- Het LLM antwoordt (eventueel met tool-verzoeken)
- Als er tool-verzoeken zijn, voert de CLI ze uit
assistant.turn_endwordt uitgestuurd
Het model beslist per turn of het “nog meer tools gebruikt” of “doorgaat naar het definitieve antwoord”. Elke aanroep ziet de volledige opgebouwde context (inclusief eerdere tool-aanroepen en resultaten) en kan dus beoordelen of er genoeg informatie is.
Eventflow bij meerdere turns
Wie start elke turn?
Het gedrag van de CLI is mechanisch (“model vraagt tools aan → uitvoeren → model opnieuw aanroepen”). De beslisser over wanneer te stoppen is het model.
Het verschil tussen session.idle en session.task_complete
Beide zijn voltooiingssignalen, maar de garanties verschillen sterk.
session.idle
- Wordt altijd uitgestuurd aan het einde van de tool-gebruiksloop
- Vluchtig (ephemeral). Wordt niet naar disk gepersisteerd en niet opnieuw afgespeeld bij het hervatten van een sessie
- Betekenis: “De agent is gestopt met verwerken en kan het volgende bericht ontvangen”
- Gebruik dit signaal als betrouwbaar “klaar”-signaal
sendAndWait() van de SDK wacht op dit event.
session.task_complete
- Optioneel (alleen wanneer het model dit expliciet signaleert)
- Wordt gepersisteerd (opgeslagen in de sessie-eventlog)
- Betekenis: “De agent heeft zelf geoordeeld dat de hele taak is volbracht”
- Kan een optionele
summarybevatten
Autopilot-modus: de CLI dringt aan op task_complete
In de autopilot mode (headless / autonomous) houdt de CLI bij of het model task_complete heeft aangeroepen. Eindigt de tool-gebruiksloop zonder task_complete, dan voegt de CLI het volgende synthetische gebruikersbericht in om het model aan te sporen.
“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.”Hierdoor wordt de tool-gebruiksloop feitelijk hervat. Het model ontvangt deze aansporing als een nieuw gebruikersbericht en gaat door met werken. De aansporing bevat ook de instructie om
task_complete niet te vroeg aan te roepen.
- Zijn er onopgeloste vragen, roep het dan niet aan. Neem een beslissing en werk door
- Ben je alleen op een fout gestuit, roep het dan niet aan. Probeer de fout op te lossen
- Zijn er nog resterende taken, roep het dan niet aan. Rond die eerst af
- Het model roept
task_completeaan met een summary → de CLI stuurtsession.task_completeuit → klaar - Het model stopt zonder aanroep → de CLI spoort aan → het model gaat door of roept
task_completeaan
Waarom task_complete soms uitblijft
In de interactive mode (gewone chat) spoort de CLI niet aan tot task_complete. Het model kan het weglaten. De belangrijkste redenen zijn:
- Conversationele Q&A: het beantwoordt een vraag en stopt; er is geen discrete “voltooide taak”
- Modelbeslissing: het geeft de definitieve tekst terug zonder
task_completeaan te roepen - Onderbroken sessie: de sessie eindigt voordat het model het voltooiingspunt bereikt
session.idle uit. Dat is namelijk geen semantisch signaal (het model vindt het klaar), maar een mechanisch signaal (de loop is geëindigd).
Welke moet je gebruiken?
Het aantal LLM-aanroepen tellen
Het aantalassistant.turn_start/assistant.turn_end-paren in de eventlog komt overeen met het totale aantal LLM-API-aanroepen. Er zijn geen verborgen aanroepen voor plannen, evalueren of voltooiingscontrole.
Voorbeeld om het aantal turns van een sessie te controleren:
Gerelateerde documentatie
- Streaming-events — Referentie op veldniveau voor elk eventtype
- Sessies hervatten — Sessies opslaan en hervatten
- Sessiehooks — Events binnen de loop onderscheppen (permissies en tools)