Agent Loop
說明 Copilot CLI 如何端對端處理使用者訊息(從送出 prompt 到session.idle)。
架構
SDK 是傳輸層。透過 JSON-RPC 將 prompt 送至 Copilot CLI,並將事件轉遞給應用程式。實際執行代理式工具使用迴圈、直到任務完成前協調一次以上 LLM API 呼叫的是 CLI 端。工具使用迴圈
呼叫session.send({ prompt }) 後,CLI 進入下列迴圈。
模型會於每次呼叫時參考 整段對話歷史(system prompt / user message / 目前為止的所有工具呼叫與結果)。
重點: 此迴圈的每次迭代與 1 次 LLM API 呼叫完全對應,事件日誌上會呈現為 1 組 assistant.turn_start / assistant.turn_end。並無隱藏的呼叫。
何謂 Turn(回合)
Turn 指的是 1 次 LLM API 呼叫及其結果。- CLI 將對話歷史送至 LLM
- LLM 回應(可能包含 tool 請求)
- 若有 tool 請求則由 CLI 執行
- 觸發
assistant.turn_end
模型會在每個 turn 判斷「還要使用更多工具嗎」或「進入最終回覆」。由於每次呼叫都能看到 累積的完整脈絡(含過去的 tool 呼叫與結果),因此能判斷資訊是否足夠。
多 turn 時的事件流
各 turn 由誰啟動
CLI 的動作是機械式的(「模型請求 tool → 執行 → 再次呼叫模型」)。決定何時停止的是 模型。
session.idle 與 session.task_complete 的差異
雖然兩者皆為完成訊號,但保證內容差異很大。
session.idle
- 於工具使用迴圈結束時 必定發出
- 短暫性(ephemeral)。不會持久化至磁碟,session 重啟時不會重播
- 意義:「代理停止處理,可接受下一則訊息」
- 作為可信賴的「完成」訊號應使用此事件
sendAndWait() 會等待此事件。
session.task_complete
- 選擇性發出(僅在模型明確發出訊號時)
- 持久化(會儲存於 session 事件日誌)
- 意義:「代理自行判斷整體任務已達成」
- 可包含任意
summary
Autopilot 模式:CLI 促使 task_complete
在 autopilot mode(headless / autonomous)中,CLI 會追蹤模型是否呼叫了 task_complete。若工具使用迴圈結束時仍未呼叫 task_complete,CLI 會插入下述合成使用者訊息以促使模型回應。
“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.”這實質上會使工具使用迴圈重啟。模型會將此提示視為新的使用者訊息並繼續作業。提示中也包含「不要過早呼叫
task_complete」的注意事項。
- 若尚有未解決的疑問則不要呼叫。做出判斷並繼續作業
- 若僅是遇到錯誤則不要呼叫。嘗試解決
- 若還有殘留任務則不要呼叫。先完成它們
- 模型附上 summary 呼叫
task_complete→ CLI 發出session.task_complete→ 完成 - 模型未呼叫就停止 → CLI 促使 → 模型繼續或呼叫
task_complete
task_complete 未出現的原因
在 interactive mode(一般對話)中,CLI 不會促使 task_complete,模型有時會省略。主要原因如下。
- 對話式 Q&A:只是回答問題後結束,並沒有明確的「已完成任務」
- 模型判斷:不呼叫
task_complete而直接回傳最終文字 - 中斷的 session:模型還沒抵達完成點時 session 就已結束
session.idle,因為它並非語義訊號(模型判斷完成),而是機械訊號(迴圈結束)。
該使用哪一個?
計算 LLM 呼叫次數
事件日誌中的assistant.turn_start / assistant.turn_end 配對數與 LLM API 呼叫總數一致。並無用於規劃、評估、確認完成的隱藏呼叫。
Session 內 turn 數的確認範例:
相關文件
- 串流事件 — 各事件類型的欄位層級參考
- Session 恢復 — session 儲存與恢復
- Session Hook — 攔截迴圈內事件(權限、工具)