迴圈概覽
每個代理程式工作階段都遵循相同的週期:- 接收提示。 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"是第一個訊息(工作階段中繼資料),"compact_boundary"在 壓縮 後觸發。在 TypeScript 中,壓縮邊界是其自己的SDKCompactBoundaryMessage類型,而不是SDKSystemMessage的子類型。AssistantMessage: 在每個 Claude 回應後發出,包括最終純文字回應。包含該回合的文字內容區塊和工具呼叫區塊。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 相同的工具:| 類別 | 工具 | 它們的作用 |
|---|---|---|
| 檔案操作 | Read、Edit、Write | 讀取、修改和建立檔案 |
| 搜尋 | Glob、Grep | 按模式查找檔案、使用正規表達式搜尋內容 |
| 執行 | Bash | 執行 shell 命令、指令碼、git 操作 |
| Web | WebSearch、WebFetch | 搜尋網路、擷取和解析頁面 |
| 探索 | ToolSearch | 動態查找和按需加載工具,而不是預先加載所有工具 |
| 協調 | Agent、Skill、AskUserQuestion、TaskCreate、TaskUpdate | 生成子代理程式、呼叫技能、詢問使用者、追蹤任務 |
工具權限
Claude 根據任務決定呼叫哪些工具,但您控制這些呼叫是否允許執行。您可以自動批准特定工具、完全阻止其他工具,或要求對所有工具進行批准。三個選項一起工作以確定運行的內容:allowed_tools/allowedTools自動批准列出的工具。具有["Read", "Glob", "Grep"]在其允許工具清單中的唯讀代理程式會執行這些工具而不提示。未列出的工具仍然可用,但需要權限。disallowed_tools/disallowedTools阻止列出的工具,無論其他設定如何。請參閱 權限 以了解在工具執行前檢查規則的順序。permission_mode/permissionMode控制對不受允許或拒絕規則涵蓋的工具會發生什麼。請參閱 權限模式 以了解可用的模式。
"Bash(npm *)" 之類的規則來限定個別工具,以僅允許特定命令。請參閱 權限 以了解完整的規則語法。
當工具被拒絕時,Claude 會收到一條拒絕訊息作為工具結果,通常會嘗試不同的方法或報告它無法繼續。
平行工具執行
當 Claude 在單個回合中要求多個工具呼叫時,兩個 SDK 可以根據工具同時或順序執行它們。唯讀工具(如Read、Glob、Grep 和標記為唯讀的 MCP 工具)可以同時執行。修改狀態的工具(如 Edit、Write 和 Bash)順序執行以避免衝突。
自訂工具預設為順序執行。要為自訂工具啟用平行執行,請在其註釋中設定 readOnlyHint。TypeScript 和 Python SDK 都使用 MCP SDK 中的此欄位名稱。
控制迴圈如何執行
您可以限制迴圈執行的回合數、成本、Claude 推理的深度,以及工具是否需要在執行前獲得批准。所有這些都是ClaudeAgentOptions(Python)/ Options(TypeScript)上的欄位。
回合和預算
| 選項 | 它控制什麼 | 預設值 |
|---|---|---|
最大回合(max_turns / maxTurns) | 最大工具使用往返次數 | 無限制 |
最大預算(max_budget_usd / maxBudgetUsd) | 停止前的最大成本 | 無限制 |
ResultMessage,其中包含相應的錯誤子類型(error_max_turns 或 error_max_budget_usd)。請參閱 處理結果 以了解如何檢查這些子類型,以及 ClaudeAgentOptions / Options 以了解語法。
努力等級
effort 選項控制 Claude 應用多少推理。較低的努力等級每個回合使用更少的代幣並降低成本。並非所有模型都支援努力參數。請參閱 努力 以了解哪些模型支援它。
| 等級 | 行為 | 適合 |
|---|---|---|
"low" | 最少推理、快速回應 | 檔案查找、列出目錄 |
"medium" | 平衡推理 | 常規編輯、標準任務 |
"high" | 徹底分析 | 重構、除錯 |
"xhigh" | 擴展推理深度 | 編碼和代理任務;建議在 Opus 4.7 上使用 |
"max" | 最大推理深度 | 需要深入分析的多步驟問題 |
effort,Python SDK 會保留參數未設定,並遵循模型的預設行為。TypeScript SDK 預設為 "high"。
effort 在每個回應內交換延遲和代幣成本以獲得推理深度。擴展思考 是一個單獨的功能,在輸出中產生可見的思考鏈區塊。它們是獨立的:您可以設定 effort: "low" 並啟用擴展思考,或 effort: "max" 而不啟用它。query() 選項中設定 effort 以用於整個工作階段,或在 AgentDefinition 上使用 effort 欄位以每個子代理程式為基礎覆蓋工作階段等級。
權限模式
權限模式選項(Python 中的permission_mode、TypeScript 中的 permissionMode)控制代理程式是否在使用工具前要求批准:
| 模式 | 行為 |
|---|---|
"default" | 不受允許規則涵蓋的工具會觸發您的批准回呼;沒有回呼意味著拒絕 |
"acceptEdits" | 自動批准檔案編輯和常見的檔案系統命令(mkdir、touch、mv、cp 等);其他 Bash 命令遵循預設規則 |
"plan" | 唯讀工具執行;Claude 探索並產生計畫而不編輯您的原始檔案 |
"dontAsk" | 永不提示。由 權限規則 預先批准的工具執行,其他所有工具都被拒絕 |
"auto"(僅 TypeScript) | 使用模型分類器批准或拒絕每個工具呼叫。請參閱 自動模式 以了解可用性和行為 |
"bypassPermissions" | 執行所有允許的工具而不詢問。在 Unix 上以 root 身份執行時無法使用。僅在隔離環境中使用,其中代理程式的操作無法影響您關心的系統 |
"default" 和工具批准回呼來顯示批准提示。對於開發機器上的自主代理程式,"acceptEdits" 自動批准檔案編輯和常見的檔案系統命令(mkdir、touch、mv、cp 等),同時仍然在允許規則後面限制其他 Bash 命令。為 CI、容器或其他隔離環境保留 "bypassPermissions"。請參閱 權限 以了解完整詳細資訊。
模型
如果您不設定model,SDK 會使用 Claude Code 的預設值,這取決於您的驗證方法和訂閱。明確設定它(例如,model="claude-sonnet-4-6")以固定特定模型或使用較小的模型以獲得更快、更便宜的代理程式。請參閱 模型 以了解可用的 ID。
上下文視窗
上下文視窗是工作階段期間可用於 Claude 的資訊總量。它不會在工作階段內的回合之間重置。所有內容都會累積:系統提示、工具定義、對話歷史記錄、工具輸入和工具輸出。在回合之間保持相同的內容(系統提示、工具定義、CLAUDE.md)會自動進行 提示快取,這會減少重複前綴的成本和延遲。什麼消耗上下文
以下是每個元件如何影響 SDK 中上下文的方式:| 來源 | 何時加載 | 影響 |
|---|---|---|
| 系統提示 | 每個請求 | 小的固定成本,始終存在 |
| CLAUDE.md 檔案 | 工作階段開始,透過 settingSources | 每個請求中的完整內容(但提示快取,因此只有第一個請求支付完整成本) |
| 工具定義 | 每個請求;MCP 架構預設延遲 | 內建工具架構在每個請求時加載。工具搜尋 預設延遲 MCP 工具架構,在 Vertex AI 或非第一方 ANTHROPIC_BASE_URL 上回退到預先加載。請參閱 配置工具搜尋 以了解完整矩陣 |
| 對話歷史記錄 | 在回合中累積 | 隨著每個回合增長:提示、回應、工具輸入、工具輸出 |
| 技能描述 | 工作階段開始,透過設定來源 | 簡短摘要;完整內容僅在呼叫時加載 |
自動壓縮
當上下文視窗接近其限制時,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 輸入,而不是僅限 CLI 的快捷方式。請參閱 SDK 中的命令。
範例:CLAUDE.md 中的摘要指示
範例:CLAUDE.md 中的摘要指示
將一個部分添加到您的專案的 CLAUDE.md,告訴壓縮器要保留什麼。標題名稱不是特殊的;使用任何清晰的標籤。
CLAUDE.md
保持上下文高效
長時間執行代理程式的幾個策略:- 為子任務使用子代理程式。 每個子代理程式以新鮮的對話開始(沒有先前的訊息歷史記錄,儘管它確實加載自己的系統提示和專案級上下文,如 CLAUDE.md)。它看不到父級的回合,只有其最終回應作為工具結果返回給父級。主代理程式的上下文增長該摘要,而不是完整的子任務成績單。請參閱 子代理程式繼承什麼 以了解詳細資訊。
- 選擇性地使用工具。 每個工具定義都佔用上下文空間。在
AgentDefinition上使用tools欄位將子代理程式限制在它們需要的最小集合。 - 監視 MCP 伺服器成本。 MCP 工具搜尋 預設延遲 MCP 工具架構,並按需加載它們。當工具搜尋關閉、在 Vertex AI 上或在非第一方
ANTHROPIC_BASE_URL後面時,每個 MCP 伺服器將其所有工具架構添加到每個請求,因此具有許多工具的幾個伺服器可以在代理程式執行任何工作之前消耗大量上下文。 - 為常規任務使用較低的努力。 為僅需要讀取檔案或列出目錄的代理程式設定 努力 為
"low"。這會減少代幣使用量和成本。
工作階段和連續性
與 SDK 的每次互動都會建立或繼續一個工作階段。從ResultMessage.session_id(在兩個 SDK 中都可用)捕獲工作階段 ID 以稍後恢復。TypeScript SDK 也將其公開為初始化 SystemMessage 上的直接欄位;在 Python 中,它嵌套在 SystemMessage.data 中。
當您恢復時,先前回合的完整上下文會被恢復:讀取的檔案、執行的分析和採取的操作。您也可以分叉一個工作階段以分支到不同的方法,而不修改原始工作階段。
請參閱 工作階段管理 以了解恢復、繼續和分叉模式的完整指南。
在 Python 中,
ClaudeSDKClient 在多個呼叫中自動處理工作階段 ID。請參閱 Python SDK 參考 以了解詳細資訊。處理結果
當迴圈結束時,ResultMessage 告訴您發生了什麼並給您輸出。subtype 欄位(在兩個 SDK 中都可用)是檢查終止狀態的主要方式。
| 結果子類型 | 發生了什麼 | result 欄位可用? |
|---|---|---|
success | Claude 正常完成了任務 | 是 |
error_max_turns | 在完成前達到 maxTurns 限制 | 否 |
error_max_budget_usd | 在完成前達到 maxBudgetUsd 限制 | 否 |
error_during_execution | 錯誤中斷了迴圈(例如,API 失敗或取消的請求) | 否 |
error_max_structured_output_retries | 結構化輸出驗證在配置的重試限制後失敗 | 否 |
result 欄位(最終文字輸出)僅在 success 變體上存在,因此在讀取它之前始終檢查子類型。所有結果子類型都帶有 total_cost_usd、usage、num_turns 和 session_id,因此您可以追蹤成本並在錯誤後恢復。在 Python 中,total_cost_usd 和 usage 被類型化為可選的,在某些錯誤路徑上可能是 None,因此在格式化它們之前進行保護。請參閱 追蹤成本和使用量 以了解有關解釋 usage 欄位的詳細資訊。
結果還包括一個 stop_reason 欄位(TypeScript 中的 string | null、Python 中的 str | None),指示模型為什麼在最後一個回合停止生成。常見值是 end_turn(模型正常完成)、max_tokens(達到輸出代幣限制)和 refusal(模型拒絕了請求)。在錯誤結果子類型上,stop_reason 帶有迴圈結束前最後一個助手回應的值。要檢測拒絕,請檢查 stop_reason === "refusal"(TypeScript)或 stop_reason == "refusal"(Python)。請參閱 SDKResultMessage(TypeScript)或 ResultMessage(Python)以了解完整類型。
Hooks
Hooks 是在迴圈中的特定點觸發的回呼:在工具執行前、執行後、代理程式完成時等。一些常用的 hooks 是:| Hook | 何時觸發 | 常見用途 |
|---|---|---|
PreToolUse | 在工具執行前 | 驗證輸入、阻止危險命令 |
PostToolUse | 在工具返回後 | 審計輸出、觸發副作用 |
UserPromptSubmit | 當提示被發送時 | 將額外上下文注入提示 |
Stop | 當代理程式完成時 | 驗證結果、保存工作階段狀態 |
SubagentStart / SubagentStop | 當子代理程式生成或完成時 | 追蹤和聚合平行任務結果 |
PreCompact | 在上下文壓縮前 | 在摘要前存檔完整成績單 |
PreToolUse hook 會阻止它執行,Claude 會收到拒絕訊息。
兩個 SDK 都支援上述所有事件。TypeScript SDK 包含 Python 尚不支援的額外事件。請參閱 使用 hooks 控制執行 以了解完整的事件清單、每個 SDK 的可用性和完整的回呼 API。
將其全部整合在一起
此範例將本頁的關鍵概念組合成一個修復失敗測試的單個代理程式。它使用允許的工具(自動批准,以便代理程式自主執行)、專案設定和回合和推理努力的安全限制來配置代理程式。當迴圈執行時,它捕獲工作階段 ID 以進行潛在恢復、處理最終結果並列印總成本。後續步驟
現在您了解了迴圈,以下是根據您正在建立的內容去往何處:- 還沒有執行代理程式? 從 快速入門 開始,以安裝 SDK 並查看完整範例端到端執行。
- 準備好連接到您的專案? 加載 CLAUDE.md、技能和檔案系統 hooks,以便代理程式自動遵循您的專案約定。
- 建立互動式 UI? 啟用 串流 以在迴圈執行時顯示即時文字和工具呼叫。
- 需要對代理程式可以做什麼進行更嚴格的控制? 使用 權限 鎖定工具存取,並使用 hooks 在工具執行前審計、阻止或轉換工具呼叫。
- 執行長期或昂貴的任務? 將隔離的工作卸載到 子代理程式 以保持主上下文精簡。