Skip to main content
Agent SDK 讓您可以在自己的應用程式中嵌入 Claude Code 的自主代理程式迴圈。SDK 是一個獨立套件,可讓您以程式設計方式控制工具、權限、成本限制和輸出。 TypeScript 和 Python SDK 都包含原生 Claude Code 二進位檔,因此大多數安裝不需要單獨安裝 Claude Code。請參閱快速入門的安裝說明以了解需要單獨安裝的情況。 當您啟動代理程式時,SDK 會執行與 Claude Code 相同的執行迴圈:Claude 評估您的提示、呼叫工具採取行動、接收結果,並重複直到任務完成。本頁說明該迴圈內發生的情況,以便您可以有效地建立、除錯和最佳化代理程式。

迴圈概覽

每個代理程式工作階段都遵循相同的週期: 代理程式迴圈的圖表:您的提示進入代理程式迴圈,Claude 評估並要求工具呼叫(其結果回饋到另一個評估中),或返回最終答案 代理程式迴圈的圖表:您的提示進入代理程式迴圈,Claude 評估並要求工具呼叫(其結果回饋到另一個評估中),或返回最終答案
  1. 接收提示。 Claude 接收您的提示,以及系統提示、工具定義和對話歷史記錄。SDK 會產生一個 SystemMessage,其子類型為 "init",包含工作階段中繼資料。
  2. 評估並回應。 Claude 評估目前狀態並決定如何進行。它可能會以文字回應、要求一個或多個工具呼叫,或兩者都有。SDK 會產生一個或多個 AssistantMessage 物件,每個內容區塊(例如文字區塊或工具呼叫要求)各一個。
  3. 執行工具。 SDK 執行每個要求的工具並收集結果。每組工具結果都會回饋給 Claude 以進行下一個決定。您可以使用 hooks 在工具執行前攔截、修改或阻止工具呼叫。
  4. 重複。 步驟 2 和 3 重複為一個週期。每個完整週期是一個回合。Claude 繼續呼叫工具並處理結果,直到它產生沒有工具呼叫的回應。
  5. 返回結果。 SDK 會產生最終的 AssistantMessage,包含文字回應(無工具呼叫),然後是 ResultMessage,包含最終文字、代幣使用量、成本和工作階段 ID。
一個快速問題(「這裡有什麼檔案?」)可能需要一到兩個回合的 Glob 呼叫和結果回應。一個複雜的任務(「重構驗證模組並更新測試」)可以在許多回合中鏈接數十個工具呼叫,讀取檔案、編輯程式碼和執行測試,Claude 根據每個結果調整其方法。

回合和訊息

回合是迴圈內的一個往返:Claude 產生包含工具呼叫的輸出,SDK 執行這些工具,結果自動回饋給 Claude。這發生在不將控制權交回給您的程式碼的情況下。回合繼續進行,直到 Claude 產生沒有工具呼叫的輸出,此時迴圈結束並傳遞最終結果。 考慮提示「修復 auth.ts 中失敗的測試」的完整工作階段可能是什麼樣子。 首先,SDK 將您的提示發送給 Claude 並產生一個 SystemMessage,包含工作階段中繼資料。然後迴圈開始:
  1. 回合 1: Claude 呼叫 Bash 執行 npm test。SDK 產生一個 AssistantMessage,包含工具呼叫,執行命令,然後產生一個 UserMessage,包含輸出(三個失敗)。
  2. 回合 2: Claude 在 auth.tsauth.test.ts 上呼叫 Read。SDK 產生每個呼叫的 AssistantMessage 並返回檔案內容。
  3. 回合 3: Claude 呼叫 Edit 修復 auth.ts,然後呼叫 Bash 重新執行 npm test。所有三個測試都通過。SDK 產生每個呼叫的 AssistantMessage
  4. 最終回合: Claude 產生一個純文字回應,沒有工具呼叫:「修復了驗證錯誤,所有三個測試現在都通過了。」SDK 產生最終的 AssistantMessage,包含此文字,然後是 ResultMessage,包含相同的文字加上成本和使用量。
那是四個回合:三個有工具呼叫,一個最終純文字回應。 您可以使用 max_turns / maxTurns 限制迴圈,它只計算工具使用回合。例如,上面迴圈中的 max_turns=2 會在編輯步驟之前停止。您也可以使用 max_budget_usd / maxBudgetUsd 根據支出閾值限制回合。 沒有限制,迴圈會執行到 Claude 自己完成為止,這對於範圍明確的任務很好,但對於開放式提示(「改進此程式碼庫」)可能會執行很長時間。設定預算是生產代理程式的好預設值。請參閱下面的 回合和預算 以了解選項參考。

訊息類型

當迴圈執行時,SDK 會產生一串訊息。每個訊息都帶有一個類型,告訴您它來自迴圈的哪個階段。五個核心類型是:
  • SystemMessage 工作階段生命週期事件。subtype 欄位區分它們:
    • "init":執行的工作階段中繼資料。當 SessionStartSetup hook 在工作階段啟動期間執行時,其 hook 生命週期訊息 會在 init 訊息之前到達
    • "compact_boundary":在 壓縮 後觸發
    • "informational":來自迴圈的純文字狀態橫幅
    • "worker_shutting_down":主機正在退出或遠端控制已斷開連線
    在 TypeScript 中,除了 "init" 之外的每個子類型都是 SDKMessage 聯合 中的自己的類型,而不是 SDKSystemMessage 的子類型。
  • AssistantMessage 在 Claude 回應的每個內容區塊後發出,包括最終純文字區塊。每個訊息都帶有單一內容區塊,例如文字或工具呼叫,來自一個回應的訊息共享一個訊息 ID。
  • UserMessage 在每個工具執行後發出,包含發送回 Claude 的工具結果內容。也針對您在迴圈中期串流的任何使用者輸入發出。
  • StreamEvent 僅在啟用部分訊息時發出。包含原始 API 串流事件(文字增量、工具輸入區塊)。請參閱 串流回應
  • ResultMessage 標記代理程式迴圈的結束。包含最終文字結果、代幣使用量、成本和工作階段 ID。檢查 subtype 欄位以確定任務是否成功或達到限制。少數尾隨系統事件(例如 prompt_suggestion)可能在其後到達,因此請迭代串流至完成,而不是在結果時中斷。請參閱 處理結果
這五種類型涵蓋了完整的代理程式迴圈生命週期。兩個 SDK 也會產生可觀測性事件,例如速率限制狀態和任務通知,這些事件不需要驅動迴圈。請參閱 Python 訊息類型參考TypeScript 訊息類型參考 以了解完整清單。

處理訊息

您處理哪些訊息取決於您正在建立的內容:
  • 僅最終結果: 處理 ResultMessage 以取得輸出、成本以及任務是否成功或達到限制。
  • 進度更新: 處理 AssistantMessage 以查看 Claude 在每個回合中做什麼,包括它呼叫了哪些工具。
  • 即時串流: 啟用部分訊息(Python 中的 include_partial_messages、TypeScript 中的 includePartialMessages)以實時取得 StreamEvent 訊息。請參閱 即時串流回應
您檢查訊息類型的方式取決於 SDK:
  • Python: 使用從 claude_agent_sdk 匯入的類別檢查訊息類型,使用 isinstance()(例如,isinstance(message, ResultMessage))。
  • TypeScript: 檢查 type 字串欄位(例如,message.type === "result")。AssistantMessageUserMessage 將原始 API 訊息包裝在 .message 欄位中,因此內容區塊位於 message.message.content,而不是 message.content

工具執行

工具讓您的代理程式能夠採取行動。沒有工具,Claude 只能以文字回應。有了工具,Claude 可以讀取檔案、執行命令、搜尋程式碼並與外部服務互動。

內建工具

SDK 包含與 Claude Code 相同的工具: 不提供任務追蹤工具的模型上,Claude Code 只在您選擇加入時才提供 TaskCreateTaskUpdate 除了內建工具,您還可以:

工具權限

Claude 根據任務決定呼叫哪些工具,但您控制這些呼叫是否允許執行。您可以自動批准特定工具、完全阻止其他工具,或要求對所有工具進行批准。三個選項一起工作以確定運行的內容:
  • allowed_tools / allowedTools 自動批准列出的工具。具有 ["Read", "Glob", "Grep"] 在其允許工具清單中的唯讀代理程式會執行這些工具而不提示。未列出的工具仍然可用,對它們的呼叫需要批准會根據權限模式和 canUseTool 進行處理。
  • disallowed_tools / disallowedTools 阻止列出的工具,無論其他設定如何。請參閱 權限 以了解在工具執行前檢查規則的順序。
  • permission_mode / permissionMode 控制您想要多少人工監督。SDK 根據固定順序評估活動模式以及您的允許和拒絕規則,詳見權限如何被評估。請參閱權限模式以了解可用的模式。
您也可以使用 "Bash(npm *)" 之類的規則來限定個別工具,以僅允許特定命令。請參閱 權限 以了解完整的規則語法。 當工具被拒絕時,Claude 會收到一條拒絕訊息作為工具結果,通常會嘗試不同的方法或報告它無法繼續。

平行工具執行

當 Claude 在單個回合中要求多個工具呼叫時,兩個 SDK 可以根據工具同時或順序執行它們。唯讀工具(如 ReadGlobGrep 和標記為唯讀的 MCP 工具)可以同時執行。修改狀態的工具(如 EditWriteBash)順序執行以避免衝突。 自訂工具預設為順序執行。要為自訂工具啟用平行執行,請在其註釋中設定 readOnlyHintTypeScriptPython SDK 都使用 MCP SDK 中的此欄位名稱。

控制迴圈如何執行

您可以限制迴圈執行的回合數、成本、Claude 推理的深度,以及工具是否需要在執行前獲得批准。所有這些都是 ClaudeAgentOptions(Python)/ Options(TypeScript)上的欄位。

回合和預算

當達到任一限制時,SDK 會返回一個 ResultMessage,其中包含相應的錯誤子類型(error_max_turnserror_max_budget_usd)。請參閱 處理結果 以了解如何檢查這些子類型,以及 ClaudeAgentOptions / Options 以了解語法。 預算上限涵蓋 子代理程式:它們的支出計入總額。一旦支出達到上限,生成另一個子代理程式會失敗並顯示 Budget limit reached,Claude Code 會停止任何仍在執行的背景子代理程式。上限強制行為需要 Claude Code v2.1.217 或更新版本。 使用 串流輸入,當回合在最大回合限制時結束時,仍在佇列中的訊息會保持佇列狀態。Claude Code 不會將其新增到該回合的最後一次模型呼叫中。它為訊息開始新的回合,該回合的最大回合計數重新開始。

努力等級

effort 選項控制 Claude 應用多少推理。較低的努力等級每個回合使用更少的代幣並降低成本。並非所有模型都支援努力參數。請參閱 努力 以了解哪些模型支援它。 如果您不設定 effort,Claude Code 會自行解析努力等級,按照 調整努力等級 所述的順序。
effort 在每個回應內交換延遲和代幣成本以獲得推理深度。擴展思考 是一個單獨的功能,在輸出中產生 thinking 區塊,而 PythonTypeScriptThinkingConfigdisplay 欄位控制您是否接收其文字。它們是獨立的:您可以設定 effort: "low" 並啟用擴展思考,或 effort: "max" 而不啟用它。
對於執行簡單、範圍明確的任務(如列出檔案或執行單個 grep)的代理程式,使用較低的努力來降低成本和延遲。在頂級 query() 選項中設定 effort 以用於整個工作階段,或在 AgentDefinition 上使用 effort 欄位以每個子代理程式為基礎覆蓋工作階段等級。

權限模式

權限模式選項(Python 中的 permission_mode、TypeScript 中的 permissionMode)控制代理程式是否在使用工具前要求批准: 對於互動式應用程式,使用 "default" 和工具批准回呼來顯示批准提示。對於開發機器上的自主代理程式,"acceptEdits" 自動批准檔案編輯和常見的檔案系統命令(mkdirtouchmvcp 等),同時仍然在允許規則後面限制其他 Bash 命令。為 CI、容器或其他隔離環境保留 "bypassPermissions"。請參閱 權限 以了解完整詳細資訊。

模型

如果您不設定 model,SDK 會使用 Claude Code 的預設值,這取決於您的驗證方法和訂閱。明確設定它(例如,model="claude-sonnet-5")以固定特定模型或使用較小的模型以獲得更快、更便宜的代理程式。請參閱 模型 以了解可用的 ID。

上下文視窗

上下文視窗是工作階段期間可用於 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,因此您可以包含一個部分,告訴它在摘要時要保留什麼。壓縮器根據意圖匹配,因此部分標題是自由格式的。
  • PreCompact hook: 在壓縮發生前執行自訂邏輯,例如存檔完整成績單。hook 接收一個 trigger 欄位(manualauto)。請參閱 hooks
  • 手動壓縮:/compact 作為提示字串發送以按需觸發壓縮。以這種方式發送的命令是普通的 SDK 輸入。請參閱 按名稱分派命令
將一個部分添加到您的專案的 CLAUDE.md,告訴壓縮器要保留什麼。標題名稱不是特殊的;使用任何清晰的標籤。
CLAUDE.md

保持上下文高效

長時間執行代理程式的幾個策略:
  • 為子任務使用子代理程式。 每個子代理程式以新鮮的對話開始(沒有先前的訊息歷史記錄,儘管它確實加載自己的系統提示和專案級上下文,如 CLAUDE.md)。它看不到父級的回合,只有其最終回應作為工具結果返回給父級。主代理程式的上下文增長該摘要,而不是完整的子任務成績單。請參閱 子代理程式繼承什麼 以了解詳細資訊。
  • 選擇性地使用工具。 每個工具定義都佔用上下文空間。在 AgentDefinition 上使用 tools 欄位將子代理程式限制在它們需要的最小集合。
  • 監視 MCP 伺服器成本。 MCP 工具搜尋 預設延遲 MCP 工具架構,並按需加載它們。當工具搜尋關閉或已回退到預先加載時,每個 MCP 伺服器將其所有工具架構添加到每個請求,因此具有許多工具的幾個伺服器可以在代理程式執行任何工作之前消耗大量上下文。請參閱 配置工具搜尋 以了解回退適用的配置。
  • 為常規任務使用較低的努力。 為僅需要讀取檔案或列出目錄的代理程式設定 努力"low"。這會減少代幣使用量和成本。
有關每個功能上下文成本的詳細分解,請參閱 了解上下文成本

工作階段和連續性

與 SDK 的每次互動都會建立或繼續一個工作階段。從 ResultMessage.session_id(在兩個 SDK 中都可用)捕獲工作階段 ID 以稍後恢復。TypeScript SDK 也將其公開為初始化 SystemMessage 上的直接欄位;在 Python 中,它嵌套在 SystemMessage.data 中。 當您恢復時,先前回合的完整上下文會被恢復:讀取的檔案、執行的分析和採取的操作。您也可以分叉一個工作階段以分支到不同的方法,而不修改原始工作階段。 請參閱 工作階段管理 以了解恢復、繼續和分叉模式的完整指南。若要在無狀態容器或無伺服器主機之間恢復工作階段,請傳遞 session_store / sessionStore 配接器,以便 SDK 將文字記錄鏡像到您自己的後端,另一個主機可以恢復它們。Claude Code 子程序仍然首先寫入本機磁碟。請參閱 雙寫入架構 以了解哪個副本在新工作階段與從存放區恢復的執行中存活,以及如何保持本機副本為暫時性。
在 Python 中,ClaudeSDKClient 在多個呼叫中自動處理工作階段 ID。請參閱 Python SDK 參考 以了解詳細資訊。

處理結果

當迴圈結束時,ResultMessage 告訴您發生了什麼並給您輸出。subtype 欄位(在兩個 SDK 中都可用)是檢查終止狀態的主要方式。 result 欄位保存最終文字輸出,僅在 success 變體上存在,因此在讀取它之前始終檢查子類型。 所有結果子類型都帶有 total_cost_usdusagenum_turnssession_id,因此您可以追蹤成本並在錯誤後恢復。有兩件事需要防範:
  • 在工作階段當機後,最終結果是 error_during_execution,其成本欄位可能被清零,其 stop_reasonnull,程序在發出它後退出。請參閱 在工作階段當機後復原總計
  • 在 Python 中,total_cost_usdusagemodel_usage 被類型化為可選的,因此在讀取它們之前檢查它們不是 None
usage 欄位僅涵蓋主要代理迴圈。使用 modelUsage 或 Python 中的 model_usage 進行整個樹的代幣和成本計算。請參閱 追蹤成本和使用量 以了解有關解釋 usage 欄位的詳細資訊。
當查詢以錯誤結果結束時:
  • 單次 query() 呼叫會產生最終結果訊息,然後引發包含失敗文字的錯誤,例如 Reached maximum number of turns。引發是有意的。如果您的程式碼需要在其後繼續,請將迴圈包裝在 try 區塊中。底層 Claude Code 程序也會以非零代碼退出。
  • 串流輸入工作階段保持活躍,您可以繼續傳送訊息,除了在工作階段當機後,它會發出最終 error_during_execution 結果並退出程序。
結果還包括一個 stop_reason 欄位(TypeScript 中的 string | null、Python 中的 str | None),指示模型為什麼在最後一個回合停止生成。常見值是 end_turn(模型正常完成)、max_tokens(達到輸出代幣限制)和 refusal(模型拒絕了請求)。在迴圈產生的錯誤結果上,stop_reason 帶有迴圈結束前最後一個助手回應的值;工作階段當機後 Claude Code 合成的結果帶有 null 要檢測拒絕,請檢查 stop_reason === "refusal"(TypeScript)或 stop_reason == "refusal"(Python)。請參閱 SDKResultMessage(TypeScript)或 ResultMessage(Python)以了解完整類型。

Hooks

Hooks 是在迴圈中的特定點觸發的回呼:在工具執行前、執行後、代理程式完成時等。一些常用的 hooks 是: Hooks 在您的應用程式進程中執行,而不是在代理程式的上下文視窗內,因此它們不消耗上下文。Hooks 也可以短路迴圈:拒絕工具呼叫的 PreToolUse hook 會阻止它執行,Claude 會收到拒絕訊息。 兩個 SDK 都支援上述所有事件。TypeScript SDK 包含 Python 尚不支援的額外事件。請參閱 使用 hooks 控制執行 以了解完整的事件清單、每個 SDK 的可用性和完整的回呼 API。

將其全部整合在一起

此範例將本頁的關鍵概念組合成一個修復失敗測試的單個代理程式。它使用允許的工具(自動批准,以便代理程式自主執行)、專案設定和回合和推理努力的安全限制來配置代理程式。當迴圈執行時,它捕獲工作階段 ID 以進行潛在恢復、處理最終結果並列印總成本。 因為單一的 query() 呼叫在產生錯誤結果後會引發異常,迴圈被包裝在 try 區塊中,以便在達到限制時指令碼能夠乾淨地退出。
當代理程式成功完成時,此範例會列印一行 Done: 及代理程式對修復的摘要,然後列印一行類似 Cost: $0.0312 的內容。

後續步驟

現在您了解了迴圈,以下是根據您正在建立的內容去往何處:
  • 還沒有執行代理程式?快速入門 開始,以安裝 SDK 並查看完整範例端到端執行。
  • 準備好連接到您的專案? 加載 CLAUDE.md、技能和檔案系統 hooks,以便代理程式自動遵循您的專案約定。
  • 建立互動式 UI? 啟用 串流 以在迴圈執行時顯示即時文字和工具呼叫。
  • 需要對代理程式可以做什麼進行更嚴格的控制? 使用 權限 鎖定工具存取,並使用 hooks 在工具執行前審計、阻止或轉換工具呼叫。
  • 執行長期或昂貴的任務? 將隔離的工作卸載到 子代理程式 以保持主上下文精簡。
  • 部署為服務? 請參閱 託管 Agent SDK 以取得容器和無伺服器指導,以及 工作階段儲存 以將工作階段保存到您自己的後端。
有關代理程式迴圈的更廣泛概念圖片(不是 SDK 特定的),請參閱 Claude Code 如何運作。如需在 Claude Code 中設計迴圈的實用指南,從輪流制到目標導向和主動迴圈,請參閱部落格上的 Loop engineering: getting started with loops