Agent-Loop
Hier wird beschrieben, wie die Copilot CLI eine Benutzernachricht Ende-zu-Ende verarbeitet (vom Senden des Prompts bissession.idle).
Architektur
Das SDK ist die Transportschicht. Es sendet Prompts per JSON-RPC an die Copilot CLI und leitet Ereignisse an die Anwendung weiter. Die agentische Tool-Nutzungsschleife und die Orchestrierung eines oder mehrerer LLM-API-Aufrufe bis zum Abschluss der Aufgabe werden auf Seiten der CLI ausgeführt.Tool-Nutzungsschleife
Wenn Siesession.send({ prompt }) aufrufen, tritt die CLI in die folgende Schleife ein.
Das Modell berücksichtigt bei jedem Aufruf den gesamten Konversationsverlauf (System-Prompt / User-Message / alle bisherigen Tool-Aufrufe und Ergebnisse).
Wichtig: Eine Iteration dieser Schleife entspricht exakt einem LLM-API-Aufruf und ist im Ereignis-Log als ein Paar assistant.turn_start / assistant.turn_end sichtbar. Es gibt keine versteckten Aufrufe.
Was ist ein Turn?
Ein Turn ist ein einzelner LLM-API-Aufruf und dessen Ergebnis.- Die CLI sendet den Konversationsverlauf an das LLM
- Das LLM antwortet (ggf. mit Tool-Anfragen)
- Falls Tool-Anfragen vorliegen, führt die CLI sie aus
assistant.turn_endwird ausgelöst
| Turn | Verhalten des Modells | toolRequests? |
|---|---|---|
| 1 | Codebase mit grep und glob durchsuchen | ✅ Yes |
| 2 | Auf Basis der Suchergebnisse bestimmte Dateien lesen | ✅ Yes |
| 3 | Für tieferen Kontext weitere Dateien lesen | ✅ Yes |
| 4 | Endgültige Textantwort erzeugen | ❌ No → loop ends |
Ereignisfluss bei mehreren Turns
Wer startet welchen Turn
| Actor | Responsibility |
|---|---|
| Your app | Sendet den initialen Prompt via session.send() |
| Copilot CLI | Führt die Tool-Nutzungsschleife aus und gibt Tool-Ergebnisse als Eingabe des nächsten Turns an das LLM zurück |
| LLM | Entscheidet, ob es mit Tool-Anfragen fortfährt oder mit einer endgültigen Antwort abschließt |
| SDK | Leitet nur Ereignisse weiter. Es steuert die Schleife nicht |
Unterschied zwischen session.idle und session.task_complete
Beide sind Abschlusssignale, ihre Garantien unterscheiden sich jedoch deutlich.
session.idle
- Wird beim Beenden der Tool-Nutzungsschleife immer ausgelöst
- Flüchtig (ephemeral). Wird nicht auf die Festplatte persistiert und beim Fortsetzen der Session nicht wiedergegeben
- Bedeutung: „Der Agent hat die Verarbeitung angehalten und kann die nächste Nachricht entgegennehmen”
- Verwenden Sie dieses Signal als zuverlässiges „Fertig”-Signal
sendAndWait() des SDK wartet auf dieses Ereignis.
session.task_complete
- Optional (wird nur ausgelöst, wenn das Modell dies explizit signalisiert)
- Persistiert (wird im Session-Event-Log gespeichert)
- Bedeutung: „Der Agent selbst hat die Gesamtaufgabe als erledigt bewertet”
- Kann eine optionale
summaryenthalten
Autopilot-Modus: Die CLI drängt zu task_complete
Im Autopilot-Modus (headless / autonom) verfolgt die CLI, ob das Modell task_complete aufgerufen hat. Endet die Tool-Nutzungsschleife ohne task_complete, fügt die CLI die folgende synthetische Benutzernachricht ein, um das Modell dazu zu bewegen.
“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.”Dadurch wird die Tool-Nutzungsschleife praktisch wieder aufgenommen. Das Modell empfängt diese Aufforderung als neue Benutzernachricht und setzt die Arbeit fort. Die Aufforderung enthält auch den Hinweis, „
task_complete nicht zu früh aufzurufen”.
- Rufen Sie es nicht auf, wenn offene Fragen bestehen. Entscheiden Sie und setzen Sie die Arbeit fort
- Rufen Sie es nicht auf, wenn Sie lediglich auf einen Fehler gestoßen sind. Versuchen Sie, ihn zu lösen
- Rufen Sie es nicht auf, wenn noch Aufgaben ausstehen. Erledigen Sie diese zuerst
- Das Modell ruft
task_completemit Summary auf → Die CLI löstsession.task_completeaus → Abschluss - Das Modell stoppt ohne Aufruf → Die CLI drängt → Das Modell setzt fort oder ruft
task_completeauf
Warum task_complete ausbleibt
Im Interactive-Modus (normaler Chat) drängt die CLI nicht zu task_complete. Das Modell kann es weglassen. Die Hauptgründe sind:
- Konversationelle Q&A: Frage beantworten und beenden, ohne diskrete „erledigte Aufgabe”
- Modellentscheidung: Endgültigen Text zurückgeben, ohne
task_completeaufzurufen - Unterbrochene Sessions: Die Session endet, bevor das Modell einen Abschlusspunkt erreicht
session.idle aus. Dies ist kein semantisches Signal (Modell bewertet als abgeschlossen), sondern ein mechanisches Signal (Schleife beendet).
Welches sollten Sie verwenden?
| Use case | Signal |
|---|---|
| „Auf das Ende der Agent-Verarbeitung warten” | session.idle ✅ |
| „Wissen, dass eine Coding-Aufgabe abgeschlossen ist” | session.task_complete (best-effort) |
| „Timeout-/Fehlerbehandlung” | session.idle + session.error ✅ |
Anzahl der LLM-Aufrufe zählen
Die Anzahl der Paareassistant.turn_start / assistant.turn_end im Event-Log stimmt mit der Gesamtzahl der LLM-API-Aufrufe überein. Es gibt keine versteckten Aufrufe für Planung, Bewertung oder Abschlussprüfung.
Beispiel zum Prüfen der Anzahl der Turns in einer Session:
Verwandte Dokumentation
- Streaming-Ereignisse — Feldreferenz für jeden Event-Typ
- Session fortsetzen — Speichern und Fortsetzen von Sessions
- Session-Hooks — Abfangen von Ereignissen innerhalb der Schleife (Berechtigungen, Tools)