迴圈概覽
每個代理程式工作階段都遵循相同的週期:- 接收提示。 Claude 接收您的提示,以及系統提示、工具定義和對話歷史記錄。SDK 會產生一個
SystemMessage,其子類型為"init",包含工作階段中繼資料。 - 評估並回應。 Claude 評估目前狀態並決定如何進行。它可能會以文字回應、要求一個或多個工具呼叫,或兩者都有。SDK 會產生一個或多個
AssistantMessage物件,每個內容區塊(例如文字區塊或工具呼叫要求)各一個。 - 執行工具。 SDK 執行每個要求的工具並收集結果。每組工具結果都會回饋給 Claude 以進行下一個決定。您可以使用 hooks 在工具執行前攔截、修改或阻止工具呼叫。
- 重複。 步驟 2 和 3 重複為一個週期。每個完整週期是一個回合。Claude 繼續呼叫工具並處理結果,直到它產生沒有工具呼叫的回應。
- 返回結果。 SDK 會產生最終的
AssistantMessage,包含文字回應(無工具呼叫),然後是ResultMessage,包含最終文字、代幣使用量、成本和工作階段 ID。
Glob 呼叫和結果回應。一個複雜的任務(「重構驗證模組並更新測試」)可以在許多回合中鏈接數十個工具呼叫,讀取檔案、編輯程式碼和執行測試,Claude 根據每個結果調整其方法。
回合和訊息
回合是迴圈內的一個往返:Claude 產生包含工具呼叫的輸出,SDK 執行這些工具,結果自動回饋給 Claude。這發生在不將控制權交回給您的程式碼的情況下。回合繼續進行,直到 Claude 產生沒有工具呼叫的輸出,此時迴圈結束並傳遞最終結果。 考慮提示「修復 auth.ts 中失敗的測試」的完整工作階段可能是什麼樣子。 首先,SDK 將您的提示發送給 Claude 並產生一個SystemMessage,包含工作階段中繼資料。然後迴圈開始:
- 回合 1: Claude 呼叫
Bash執行npm test。SDK 產生一個AssistantMessage,包含工具呼叫,執行命令,然後產生一個UserMessage,包含輸出(三個失敗)。 - 回合 2: Claude 在
auth.ts和auth.test.ts上呼叫Read。SDK 產生每個呼叫的AssistantMessage並返回檔案內容。 - 回合 3: Claude 呼叫
Edit修復auth.ts,然後呼叫Bash重新執行npm test。所有三個測試都通過。SDK 產生每個呼叫的AssistantMessage。 - 最終回合: Claude 產生一個純文字回應,沒有工具呼叫:「修復了驗證錯誤,所有三個測試現在都通過了。」SDK 產生最終的
AssistantMessage,包含此文字,然後是ResultMessage,包含相同的文字加上成本和使用量。
max_turns / maxTurns 限制迴圈,它只計算工具使用回合。例如,上面迴圈中的 max_turns=2 會在編輯步驟之前停止。您也可以使用 max_budget_usd / maxBudgetUsd 根據支出閾值限制回合。
沒有限制,迴圈會執行到 Claude 自己完成為止,這對於範圍明確的任務很好,但對於開放式提示(「改進此程式碼庫」)可能會執行很長時間。設定預算是生產代理程式的好預設值。請參閱下面的 回合和預算 以了解選項參考。
訊息類型
當迴圈執行時,SDK 會產生一串訊息。每個訊息都帶有一個類型,告訴您它來自迴圈的哪個階段。五個核心類型是:-
SystemMessage: 工作階段生命週期事件。subtype欄位區分它們:"init":執行的工作階段中繼資料。當SessionStart或Setuphook 在工作階段啟動期間執行時,其 hook 生命週期訊息 會在init訊息之前到達"compact_boundary":在 壓縮 後觸發"informational":來自迴圈的純文字狀態橫幅"worker_shutting_down":主機正在退出或遠端控制已斷開連線
"init"之外的每個子類型都是SDKMessage聯合 中的自己的類型,而不是SDKSystemMessage的子類型。 -
AssistantMessage: 在 Claude 回應的每個內容區塊後發出,包括最終純文字區塊。每個訊息都帶有單一內容區塊,例如文字或工具呼叫,來自一個回應的訊息共享一個訊息 ID。 -
UserMessage: 在每個工具執行後發出,包含發送回 Claude 的工具結果內容。也針對您在迴圈中期串流的任何使用者輸入發出。 -
StreamEvent: 僅在啟用部分訊息時發出。包含原始 API 串流事件(文字增量、工具輸入區塊)。請參閱 串流回應。 -
ResultMessage: 標記代理程式迴圈的結束。包含最終文字結果、代幣使用量、成本和工作階段 ID。檢查subtype欄位以確定任務是否成功或達到限制。少數尾隨系統事件(例如prompt_suggestion)可能在其後到達,因此請迭代串流至完成,而不是在結果時中斷。請參閱 處理結果。
處理訊息
您處理哪些訊息取決於您正在建立的內容:- 僅最終結果: 處理
ResultMessage以取得輸出、成本以及任務是否成功或達到限制。 - 進度更新: 處理
AssistantMessage以查看 Claude 在每個回合中做什麼,包括它呼叫了哪些工具。 - 即時串流: 啟用部分訊息(Python 中的
include_partial_messages、TypeScript 中的includePartialMessages)以實時取得StreamEvent訊息。請參閱 即時串流回應。
- Python: 使用從
claude_agent_sdk匯入的類別檢查訊息類型,使用isinstance()(例如,isinstance(message, ResultMessage))。 - TypeScript: 檢查
type字串欄位(例如,message.type === "result")。AssistantMessage和UserMessage將原始 API 訊息包裝在.message欄位中,因此內容區塊位於message.message.content,而不是message.content。
範例:檢查訊息類型並處理結果
範例:檢查訊息類型並處理結果
工具執行
工具讓您的代理程式能夠採取行動。沒有工具,Claude 只能以文字回應。有了工具,Claude 可以讀取檔案、執行命令、搜尋程式碼並與外部服務互動。內建工具
SDK 包含與 Claude Code 相同的工具:
在不提供任務追蹤工具的模型上,Claude Code 只在您選擇加入時才提供
TaskCreate 和 TaskUpdate。
除了內建工具,您還可以:
工具權限
Claude 根據任務決定呼叫哪些工具,但您控制這些呼叫是否允許執行。您可以自動批准特定工具、完全阻止其他工具,或要求對所有工具進行批准。三個選項一起工作以確定運行的內容:allowed_tools/allowedTools自動核准列出的工具。允許工具清單中包含["Read", "Glob", "Grep"]的唯讀 agent 會執行這些工具而不提示,但從網路路徑進行的讀取除外。未列出的工具仍然可用,對它們的呼叫若需要核准,會交由權限模式和canUseTool處理。disallowed_tools/disallowedTools阻止列出的工具,無論其他設定如何。請參閱 權限 以了解在工具執行前檢查規則的順序。permission_mode/permissionMode控制您想要多少人工監督。SDK 根據固定順序評估活動模式以及您的允許和拒絕規則,詳見權限如何被評估。請參閱權限模式以了解可用的模式。
"Bash(npm *)" 之類的規則來限定個別工具,以僅允許特定命令。請參閱 權限 以了解完整的規則語法。
當工具被拒絕時,Claude 會收到一條拒絕訊息作為工具結果,通常會嘗試不同的方法或報告它無法繼續。
平行工具執行
當 Claude 在單個回合中要求多個工具呼叫時,兩個 SDK 可以根據工具同時或順序執行它們。唯讀工具(如Read、Glob、Grep 和標記為唯讀的 MCP 工具)可以同時執行。修改狀態的工具(如 Edit、Write 和 Bash)順序執行以避免衝突。
自訂工具預設為順序執行。要為自訂工具啟用平行執行,請在其註釋中設定 readOnlyHint。TypeScript 和 Python SDK 都使用 MCP SDK 中的此欄位名稱。
控制迴圈如何執行
您可以限制迴圈執行的回合數、成本、Claude 推理的深度,以及工具是否需要在執行前獲得批准。所有這些都是ClaudeAgentOptions(Python)/ Options(TypeScript)上的欄位。
回合和預算
當達到任一限制時,SDK 會返回一個
ResultMessage,其中包含相應的錯誤子類型(error_max_turns 或 error_max_budget_usd)。請參閱 處理結果 以了解如何檢查這些子類型,以及 ClaudeAgentOptions / Options 以了解語法。
預算上限涵蓋 子代理程式:它們的支出計入總額。一旦支出達到上限,生成另一個子代理程式會失敗並顯示 Budget limit reached,Claude Code 會停止任何仍在執行的背景子代理程式。上限強制行為需要 Claude Code v2.1.217 或更新版本。
使用 串流輸入,當回合在最大回合限制時結束時,仍在佇列中的訊息會保持佇列狀態。Claude Code 不會將其新增到該回合的最後一次模型呼叫中。它為訊息開始新的回合,該回合的最大回合計數重新開始。預算總額會持續在訊息間累積,一旦支出達到 maxBudgetUsd,同一對話中的後續訊息會以 error_max_budget_usd 結果結束。/clear 會重新開始預算。
預算餘裕
Claude Code 會在模型回應送達後,將支出與max_budget_usd / maxBudgetUsd 上限進行比較,因為每個回應的成本來自 API 隨該回應傳回的 token 使用量。達到上限的那個回應仍會完成,並計入 total_cost_usd。因此,支出最多可能超過上限該單一回應的成本,再加上當下仍在執行的 subagent 在停止前的任何支出。設定上限時,請為此預留餘裕。
努力等級
effort 選項控制 Claude 應用多少推理。較低的努力等級每個回合使用更少的代幣並降低成本。並非所有模型都支援努力參數。請參閱 努力 以了解哪些模型支援它。
如果您不設定
effort,Claude Code 會自行解析努力等級,按照 調整努力等級 所述的順序。
effort 在每個回應內交換延遲和代幣成本以獲得推理深度。擴展思考 是一個單獨的功能,在輸出中產生 thinking 區塊,而 Python 或 TypeScript 上 ThinkingConfig 的 display 欄位控制您是否接收其文字。它們是獨立的:您可以設定 effort: "low" 並啟用擴展思考,或 effort: "max" 而不啟用它。query() 選項中設定 effort 以用於整個工作階段,或在 AgentDefinition 上使用 effort 欄位以每個子代理程式為基礎覆蓋工作階段等級。
權限模式
權限模式選項(Python 中的permission_mode、TypeScript 中的 permissionMode)控制代理程式是否在使用工具前要求批准:
對於互動式應用程式,使用
"default" 和工具批准回呼來顯示批准提示。對於開發機器上的自主代理程式,"acceptEdits" 自動批准檔案編輯和常見的檔案系統命令(mkdir、touch、mv、cp 等),同時仍然在允許規則後面限制其他 Bash 命令。為 CI、容器或其他隔離環境保留 "bypassPermissions"。請參閱 權限 以了解完整詳細資訊。
模型
設定model 選項以選擇哪個模型執行工作階段。如需更多資訊,請參閱 選擇模型。
上下文視窗
上下文視窗是工作階段期間可用於 Claude 的資訊總量。它不會在工作階段內的回合之間重置。所有內容都會累積:系統提示、工具定義、對話歷史記錄、工具輸入和工具輸出。在回合之間保持相同的內容(系統提示、工具定義、CLAUDE.md)會自動進行 提示快取,這會減少重複前綴的成本和延遲。如需了解自訂系統提示或append 文字如何影響跨工作階段的快取重複使用,請參閱 修改系統提示。
什麼消耗上下文
以下是每個元件如何影響 SDK 中上下文的方式:
大型工具輸出消耗大量上下文。讀取大檔案或執行具有詳細輸出的命令可以在單個回合中使用數千個代幣。上下文在回合中累積,因此具有許多工具呼叫的較長工作階段比短工作階段建立更多上下文。
自動壓縮
當上下文視窗接近其限制時,SDK 會自動壓縮對話:它總結較舊的歷史記錄以釋放空間,保持您最近的交換和關鍵決定完整。SDK 在串流中發出一個type: "system" 和 subtype: "compact_boundary" 的訊息(在 Python 中這是一個 SystemMessage;在 TypeScript 中它是一個單獨的 SDKCompactBoundaryMessage 類型)。
壓縮用摘要替換較舊的訊息,因此對話早期的特定指示可能不會被保留。持久規則應該在 CLAUDE.md 中(透過 settingSources 加載),而不是在初始提示中,因為 CLAUDE.md 內容在每個請求時重新注入。
您可以透過多種方式自訂壓縮行為:
- CLAUDE.md 中的摘要指示: 壓縮器像任何其他上下文一樣讀取您的 CLAUDE.md,因此您可以包含一個部分,告訴它在摘要時要保留什麼。壓縮器根據意圖匹配,因此部分標題是自由格式的。
PreCompacthook: 在壓縮發生前執行自訂邏輯,例如存檔完整成績單。hook 接收一個trigger欄位(manual或auto)。請參閱 hooks。- 手動壓縮: 將
/compact作為提示字串發送以按需觸發壓縮。以這種方式發送的命令是普通的 SDK 輸入。請參閱 按名稱分派命令。
範例:CLAUDE.md 中的摘要指示
範例:CLAUDE.md 中的摘要指示
將一個部分添加到您的專案的 CLAUDE.md,告訴壓縮器要保留什麼。標題名稱不是特殊的;使用任何清晰的標籤。
CLAUDE.md
保持上下文高效
長時間執行代理程式的幾個策略:- 為子任務使用 subagent。 每個 subagent 以全新的對話開始(沒有先前的訊息歷史記錄,儘管它確實載入自己的系統提示詞和專案級上下文,如 CLAUDE.md)。它看不到父級的回合,只有其最終回應會返回給父級。主 agent 的上下文只增加該摘要,而不是完整的子任務逐字稿。請參閱 subagent 繼承什麼 以了解詳細資訊。
- 選擇性地使用工具。 每個工具定義都佔用上下文空間。在
AgentDefinition上使用tools欄位將子代理程式限制在它們需要的最小集合。