agent-sdk/agent-loop.md +395 −0 created
1> ## Documentation Index
2> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
3> Use this file to discover all available pages before exploring further.
4
5# Cara kerja agent loop
6
7> Pahami lifecycle pesan, eksekusi tool, context window, dan arsitektur yang menggerakkan agent SDK Anda.
8
9Agent SDK memungkinkan Anda untuk menyematkan autonomous agent loop Claude Code dalam aplikasi Anda sendiri. SDK adalah paket standalone yang memberikan Anda kontrol programatik atas tools, permissions, cost limits, dan output. Anda tidak perlu menginstal Claude Code CLI untuk menggunakannya.
10
11Ketika Anda memulai agent, SDK menjalankan [execution loop yang sama yang menggerakkan Claude Code](/id/how-claude-code-works#the-agentic-loop): Claude mengevaluasi prompt Anda, memanggil tools untuk mengambil tindakan, menerima hasilnya, dan mengulangi sampai tugas selesai. Halaman ini menjelaskan apa yang terjadi di dalam loop tersebut sehingga Anda dapat membangun, debug, dan mengoptimalkan agent Anda secara efektif.
12
13## Loop sekilas
14
15Setiap sesi agent mengikuti siklus yang sama:
16
17<img src="https://mintcdn.com/claude-code/gvy2DIUELtNA8qD3/images/agent-loop-diagram.svg?fit=max&auto=format&n=gvy2DIUELtNA8qD3&q=85&s=192e1bd6c8a2950a16e5ee0b94e27e26" alt="Agent loop: prompt masuk, Claude mengevaluasi, cabang ke tool calls atau final answer" width="680" height="150" data-path="images/agent-loop-diagram.svg" />
18
191. **Terima prompt.** Claude menerima prompt Anda, bersama dengan system prompt, tool definitions, dan conversation history. SDK menghasilkan [`SystemMessage`](#message-types) dengan subtype `"init"` yang berisi session metadata.
202. **Evaluasi dan respons.** Claude mengevaluasi state saat ini dan menentukan cara melanjutkan. Ini dapat merespons dengan teks, meminta satu atau lebih tool calls, atau keduanya. SDK menghasilkan [`AssistantMessage`](#message-types) yang berisi teks dan permintaan tool call apa pun.
213. **Eksekusi tools.** SDK menjalankan setiap tool yang diminta dan mengumpulkan hasilnya. Setiap set hasil tool umpan balik ke Claude untuk keputusan berikutnya. Anda dapat menggunakan [hooks](/id/agent-sdk/hooks) untuk mengintersepsi, memodifikasi, atau memblokir tool calls sebelum dijalankan.
224. **Ulangi.** Langkah 2 dan 3 berulang sebagai siklus. Setiap siklus penuh adalah satu turn. Claude terus memanggil tools dan memproses hasil sampai menghasilkan respons tanpa tool calls.
235. **Kembalikan hasil.** SDK menghasilkan [`AssistantMessage`](#message-types) final dengan respons teks (tanpa tool calls), diikuti oleh [`ResultMessage`](#message-types) dengan teks final, token usage, cost, dan session ID.
24
25Pertanyaan cepat ("file apa yang ada di sini?") mungkin membutuhkan satu atau dua turn memanggil `Glob` dan merespons dengan hasilnya. Tugas kompleks ("refactor modul auth dan perbarui tests") dapat merantai puluhan tool calls di banyak turn, membaca file, mengedit kode, dan menjalankan tests, dengan Claude menyesuaikan pendekatannya berdasarkan setiap hasil.
26
27## Turns dan messages
28
29Turn adalah satu round trip di dalam loop: Claude menghasilkan output yang mencakup tool calls, SDK menjalankan tools tersebut, dan hasilnya umpan balik ke Claude secara otomatis. Ini terjadi tanpa menghasilkan kontrol kembali ke kode Anda. Turns berlanjut sampai Claude menghasilkan output tanpa tool calls, di mana titik loop berakhir dan hasil final dikirimkan.
30
31Pertimbangkan seperti apa sesi penuh untuk prompt "Fix the failing tests in auth.ts".
32
33Pertama, SDK mengirim prompt Anda ke Claude dan menghasilkan [`SystemMessage`](#message-types) dengan session metadata. Kemudian loop dimulai:
34
351. **Turn 1:** Claude memanggil `Bash` untuk menjalankan `npm test`. SDK menghasilkan [`AssistantMessage`](#message-types) dengan tool call, menjalankan perintah, kemudian menghasilkan [`UserMessage`](#message-types) dengan output (tiga kegagalan).
362. **Turn 2:** Claude memanggil `Read` pada `auth.ts` dan `auth.test.ts`. SDK mengembalikan konten file dan menghasilkan `AssistantMessage`.
373. **Turn 3:** Claude memanggil `Edit` untuk memperbaiki `auth.ts`, kemudian memanggil `Bash` untuk menjalankan kembali `npm test`. Ketiga tests lulus. SDK menghasilkan `AssistantMessage`.
384. **Turn final:** Claude menghasilkan respons hanya teks tanpa tool calls: "Fixed the auth bug, all three tests pass now." SDK menghasilkan `AssistantMessage` final dengan teks ini, kemudian [`ResultMessage`](#message-types) dengan teks yang sama ditambah cost dan usage.
39
40Itu adalah empat turns: tiga dengan tool calls, satu respons hanya teks final.
41
42Anda dapat membatasi loop dengan `max_turns` / `maxTurns`, yang menghitung tool-use turns saja. Misalnya, `max_turns=2` dalam loop di atas akan berhenti sebelum langkah edit. Anda juga dapat menggunakan `max_budget_usd` / `maxBudgetUsd` untuk membatasi turns berdasarkan threshold pengeluaran.
43
44Tanpa batas, loop berjalan sampai Claude selesai sendiri, yang baik untuk tugas yang well-scoped tetapi dapat berjalan lama pada prompts open-ended ("improve this codebase"). Menetapkan budget adalah default yang baik untuk production agents. Lihat [Turns dan budget](#turns-dan-budget) di bawah untuk referensi opsi.
45
46## Message types
47
48Saat loop berjalan, SDK menghasilkan aliran messages. Setiap message membawa tipe yang memberi tahu Anda tahap loop mana yang berasal darinya. Lima tipe inti adalah:
49
50* **`SystemMessage`:** session lifecycle events. Field `subtype` membedakannya: `"init"` adalah message pertama (session metadata), dan `"compact_boundary"` menyala setelah [compaction](#automatic-compaction). Di TypeScript, compact boundary adalah tipe [`SDKCompactBoundaryMessage`](/id/agent-sdk/typescript#sdkcompactboundarymessage) tersendiri daripada subtype dari `SDKSystemMessage`.
51* **`AssistantMessage`:** dipancarkan setelah setiap respons Claude, termasuk yang hanya teks final. Berisi text content blocks dan tool call blocks dari turn itu.
52* **`UserMessage`:** dipancarkan setelah setiap eksekusi tool dengan tool result content yang dikirim kembali ke Claude. Juga dipancarkan untuk input pengguna apa pun yang Anda stream mid-loop.
53* **`StreamEvent`:** hanya dipancarkan ketika partial messages diaktifkan. Berisi raw API streaming events (text deltas, tool input chunks). Lihat [Stream responses](/id/agent-sdk/streaming-output).
54* **`ResultMessage`:** menandai akhir dari agent loop. Berisi hasil teks final, token usage, cost, dan session ID. Periksa field `subtype` untuk menentukan apakah tugas berhasil atau mencapai batas. Sejumlah kecil trailing system events, seperti `prompt_suggestion`, dapat tiba setelahnya, jadi iterasi stream hingga selesai daripada break pada hasil. Lihat [Handle the result](#handle-the-result).
55
56Lima tipe ini mencakup lifecycle agent loop penuh di kedua SDK. TypeScript SDK juga menghasilkan additional observability events (hook events, tool progress, rate limits, task notifications) yang memberikan detail ekstra tetapi tidak diperlukan untuk menjalankan loop. Lihat [Python message types reference](/id/agent-sdk/python#message-types) dan [TypeScript message types reference](/id/agent-sdk/typescript#message-types) untuk daftar lengkap.
57
58### Handle messages
59
60Messages mana yang Anda handle tergantung pada apa yang Anda bangun:
61
62* **Final results only:** handle `ResultMessage` untuk mendapatkan output, cost, dan apakah tugas berhasil atau mencapai batas.
63* **Progress updates:** handle `AssistantMessage` untuk melihat apa yang dilakukan Claude setiap turn, termasuk tools mana yang dipanggilnya.
64* **Live streaming:** aktifkan partial messages (`include_partial_messages` di Python, `includePartialMessages` di TypeScript) untuk mendapatkan `StreamEvent` messages secara real time. Lihat [Stream responses in real-time](/id/agent-sdk/streaming-output).
65
66Cara Anda memeriksa message types tergantung pada SDK:
67
68* **Python:** periksa message types dengan `isinstance()` terhadap classes yang diimpor dari `claude_agent_sdk` (misalnya, `isinstance(message, ResultMessage)`).
69* **TypeScript:** periksa field string `type` (misalnya, `message.type === "result"`). `AssistantMessage` dan `UserMessage` membungkus raw API message dalam field `.message`, jadi content blocks berada di `message.message.content`, bukan `message.content`.
70
71<Accordion title="Contoh: Periksa message types dan handle results">
72 <CodeGroup>
73 ```python Python theme={null}
74 from claude_agent_sdk import query, AssistantMessage, ResultMessage
75
76 async for message in query(prompt="Summarize this project"):
77 if isinstance(message, AssistantMessage):
78 print(f"Turn completed: {len(message.content)} content blocks")
79 if isinstance(message, ResultMessage):
80 if message.subtype == "success":
81 print(message.result)
82 else:
83 print(f"Stopped: {message.subtype}")
84 ```
85
86 ```typescript TypeScript theme={null}
87 import { query } from "@anthropic-ai/claude-agent-sdk";
88
89 for await (const message of query({ prompt: "Summarize this project" })) {
90 if (message.type === "assistant") {
91 console.log(`Turn completed: ${message.message.content.length} content blocks`);
92 }
93 if (message.type === "result") {
94 if (message.subtype === "success") {
95 console.log(message.result);
96 } else {
97 console.log(`Stopped: ${message.subtype}`);
98 }
99 }
100 }
101 ```
102 </CodeGroup>
103</Accordion>
104
105## Tool execution
106
107Tools memberikan agent Anda kemampuan untuk mengambil tindakan. Tanpa tools, Claude hanya dapat merespons dengan teks. Dengan tools, Claude dapat membaca file, menjalankan perintah, mencari kode, dan berinteraksi dengan layanan eksternal.
108
109### Built-in tools
110
111SDK mencakup tools yang sama yang menggerakkan Claude Code:
112
113| Kategori | Tools | Apa yang mereka lakukan |
114| :------------------ | :----------------------------------------------- | :--------------------------------------------------------------------------- |
115| **File operations** | `Read`, `Edit`, `Write` | Baca, modifikasi, dan buat file |
116| **Search** | `Glob`, `Grep` | Temukan file berdasarkan pola, cari konten dengan regex |
117| **Execution** | `Bash` | Jalankan shell commands, scripts, git operations |
118| **Web** | `WebSearch`, `WebFetch` | Cari web, ambil dan parse halaman |
119| **Discovery** | `ToolSearch` | Temukan dan muat tools secara dinamis on-demand daripada preloading semuanya |
120| **Orchestration** | `Agent`, `Skill`, `AskUserQuestion`, `TodoWrite` | Spawn subagents, invoke skills, tanya pengguna, track tasks |
121
122Melampaui built-in tools, Anda dapat:
123
124* **Hubungkan layanan eksternal** dengan [MCP servers](/id/agent-sdk/mcp) (databases, browsers, APIs)
125* **Tentukan custom tools** dengan [custom tool handlers](/id/agent-sdk/custom-tools)
126* **Muat project skills** melalui [setting sources](/id/agent-sdk/claude-code-features) untuk reusable workflows
127
128### Tool permissions
129
130Claude menentukan tools mana yang akan dipanggil berdasarkan tugas, tetapi Anda mengontrol apakah panggilan tersebut diizinkan untuk dieksekusi. Anda dapat auto-approve tools spesifik, memblokir yang lain sepenuhnya, atau memerlukan approval untuk semuanya. Tiga opsi bekerja bersama untuk menentukan apa yang berjalan:
131
132* **`allowed_tools` / `allowedTools`** auto-approves tools yang terdaftar. Agent read-only dengan `["Read", "Glob", "Grep"]` dalam daftar allowed tools-nya menjalankan tools tersebut tanpa prompting. Tools yang tidak terdaftar masih tersedia tetapi memerlukan permission.
133* **`disallowed_tools` / `disallowedTools`** memblokir tools yang terdaftar, terlepas dari pengaturan lainnya. Lihat [Permissions](/id/agent-sdk/permissions) untuk urutan aturan yang diperiksa sebelum tool berjalan.
134* **`permission_mode` / `permissionMode`** mengontrol apa yang terjadi pada tools yang tidak tercakup oleh allow atau deny rules. Lihat [Permission mode](#permission-mode) untuk mode yang tersedia.
135
136Anda juga dapat scope individual tools dengan rules seperti `"Bash(npm *)"` untuk mengizinkan hanya perintah spesifik. Lihat [Permissions](/id/agent-sdk/permissions) untuk full rule syntax.
137
138Ketika tool ditolak, Claude menerima rejection message sebagai tool result dan biasanya mencoba pendekatan berbeda atau melaporkan bahwa tidak dapat melanjutkan.
139
140### Parallel tool execution
141
142Ketika Claude meminta multiple tool calls dalam satu turn, kedua SDK dapat menjalankannya secara concurrent atau sequential tergantung pada tool. Read-only tools (seperti `Read`, `Glob`, `Grep`, dan MCP tools yang ditandai sebagai read-only) dapat berjalan secara concurrent. Tools yang memodifikasi state (seperti `Edit`, `Write`, dan `Bash`) berjalan secara sequential untuk menghindari conflicts.
143
144Custom tools default ke sequential execution. Untuk mengaktifkan parallel execution untuk custom tool, set `readOnlyHint` dalam annotationsnya. Kedua [TypeScript](/id/agent-sdk/typescript#tool) dan [Python](/id/agent-sdk/python#tool) SDKs menggunakan field name ini dari MCP SDK.
145
146## Control how the loop runs
147
148Anda dapat membatasi berapa banyak turns yang diambil loop, berapa banyak biayanya, seberapa dalam Claude bernalar, dan apakah tools memerlukan approval sebelum berjalan. Semua ini adalah fields pada [`ClaudeAgentOptions`](/id/agent-sdk/python#claudeagentoptions) (Python) / [`Options`](/id/agent-sdk/typescript#options) (TypeScript).
149
150### Turns dan budget
151
152| Opsi | Apa yang dikontrolnya | Default |
153| :--------------------------------------------- | :---------------------------- | :-------------- |
154| Max turns (`max_turns` / `maxTurns`) | Maximum tool-use round trips | Tidak ada batas |
155| Max budget (`max_budget_usd` / `maxBudgetUsd`) | Maximum cost sebelum berhenti | Tidak ada batas |
156
157Ketika salah satu batas tercapai, SDK mengembalikan `ResultMessage` dengan error subtype yang sesuai (`error_max_turns` atau `error_max_budget_usd`). Lihat [Handle the result](#handle-the-result) untuk cara memeriksa subtypes ini dan [`ClaudeAgentOptions`](/id/agent-sdk/python#claudeagentoptions) / [`Options`](/id/agent-sdk/typescript#options) untuk syntax.
158
159### Effort level
160
161Opsi `effort` mengontrol berapa banyak reasoning yang diterapkan Claude. Lower effort levels menggunakan fewer tokens per turn dan mengurangi cost. Tidak semua models mendukung effort parameter. Lihat [Effort](https://platform.claude.com/docs/en/build-with-claude/effort) untuk models mana yang mendukungnya.
162
163| Level | Behavior | Baik untuk |
164| :--------- | :-------------------------------- | :-------------------------------------------------- |
165| `"low"` | Minimal reasoning, fast responses | File lookups, listing directories |
166| `"medium"` | Balanced reasoning | Routine edits, standard tasks |
167| `"high"` | Thorough analysis | Refactors, debugging |
168| `"xhigh"` | Extended reasoning depth | Coding dan agentic tasks; recommended pada Opus 4.7 |
169| `"max"` | Maximum reasoning depth | Multi-step problems memerlukan deep analysis |
170
171Jika Anda tidak set `effort`, Python SDK membiarkan parameter unset dan menunda ke model's default behavior. TypeScript SDK defaults ke `"high"`.
172
173<Note>
174 `effort` trades latency dan token cost untuk reasoning depth dalam setiap respons. [Extended thinking](https://platform.claude.com/docs/en/build-with-claude/extended-thinking) adalah fitur terpisah yang menghasilkan visible chain-of-thought blocks dalam output. Mereka independen: Anda dapat set `effort: "low"` dengan extended thinking diaktifkan, atau `effort: "max"` tanpanya.
175</Note>
176
177Gunakan lower effort untuk agents yang melakukan simple, well-scoped tasks (seperti listing files atau menjalankan single grep) untuk mengurangi cost dan latency. Set `effort` dalam top-level `query()` options untuk seluruh sesi, atau per subagent dengan field `effort` pada [`AgentDefinition`](/id/agent-sdk/subagents#agentdefinition-configuration) untuk override session level.
178
179### Permission mode
180
181Opsi permission mode (`permission_mode` di Python, `permissionMode` di TypeScript) mengontrol apakah agent meminta approval sebelum menggunakan tools:
182
183| Mode | Behavior |
184| :------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
185| `"default"` | Tools yang tidak tercakup oleh allow rules memicu approval callback Anda; tidak ada callback berarti deny |
186| `"acceptEdits"` | Auto-approves file edits dan common filesystem commands (`mkdir`, `touch`, `mv`, `cp`, dll.); Bash commands lainnya mengikuti default rules |
187| `"plan"` | Read-only tools berjalan; Claude mengeksplorasi dan menghasilkan plan tanpa mengedit source files Anda |
188| `"dontAsk"` | Tidak pernah prompt. Tools pre-approved oleh [permission rules](/id/settings#permission-settings) berjalan, semuanya lainnya ditolak |
189| `"auto"` (TypeScript only) | Menggunakan model classifier untuk approve atau deny setiap tool call. Lihat [Auto mode](/id/permission-modes#eliminate-prompts-with-auto-mode) untuk availability dan behavior |
190| `"bypassPermissions"` | Menjalankan semua allowed tools tanpa bertanya. Tidak dapat digunakan saat berjalan sebagai root pada Unix. Gunakan hanya dalam isolated environments di mana tindakan agent tidak dapat mempengaruhi systems yang Anda pedulikan |
191
192Untuk interactive applications, gunakan `"default"` dengan tool approval callback untuk surface approval prompts. Untuk autonomous agents pada dev machine, `"acceptEdits"` auto-approves file edits dan common filesystem commands (`mkdir`, `touch`, `mv`, `cp`, dll.) sambil masih gating Bash commands lainnya di belakang allow rules. Reserve `"bypassPermissions"` untuk CI, containers, atau isolated environments lainnya. Lihat [Permissions](/id/agent-sdk/permissions) untuk full details.
193
194### Model
195
196Jika Anda tidak set `model`, SDK menggunakan Claude Code's default, yang tergantung pada authentication method dan subscription Anda. Set secara eksplisit (misalnya, `model="claude-sonnet-4-6"`) untuk pin model spesifik atau untuk menggunakan smaller model untuk faster, cheaper agents. Lihat [models](https://platform.claude.com/docs/en/about-claude/models) untuk available IDs.
197
198## The context window
199
200Context window adalah total jumlah informasi yang tersedia untuk Claude selama sesi. Ini tidak reset antara turns dalam sesi. Semuanya terakumulasi: system prompt, tool definitions, conversation history, tool inputs, dan tool outputs. Content yang tetap sama di seluruh turns (system prompt, tool definitions, CLAUDE.md) secara otomatis [prompt cached](https://platform.claude.com/docs/en/build-with-claude/prompt-caching), yang mengurangi cost dan latency untuk repeated prefixes.
201
202### What consumes context
203
204Berikut adalah cara setiap komponen mempengaruhi context dalam SDK:
205
206| Sumber | Ketika dimuat | Dampak |
207| :----------------------- | :---------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- |
208| **System prompt** | Setiap request | Small fixed cost, selalu present |
209| **CLAUDE.md files** | Session start, melalui [`settingSources`](/id/agent-sdk/claude-code-features) | Full content dalam setiap request (tetapi prompt-cached, jadi hanya request pertama yang membayar full cost) |
210| **Tool definitions** | Setiap request | Setiap tool menambahkan schemanya; gunakan [MCP tool search](/id/agent-sdk/mcp#mcp-tool-search) untuk load tools on-demand daripada semuanya sekaligus |
211| **Conversation history** | Terakumulasi di seluruh turns | Tumbuh dengan setiap turn: prompts, responses, tool inputs, tool outputs |
212| **Skill descriptions** | Session start, melalui setting sources | Short summaries; full content dimuat hanya ketika invoked |
213
214Large tool outputs mengkonsumsi significant context. Membaca file besar atau menjalankan command dengan verbose output dapat menggunakan ribuan tokens dalam satu turn. Context terakumulasi di seluruh turns, jadi longer sessions dengan banyak tool calls membangun significantly lebih banyak context daripada short ones.
215
216### Automatic compaction
217
218Ketika context window mendekati limitnya, SDK secara otomatis compacts conversation: ini merangkum older history untuk membebaskan space, menjaga most recent exchanges dan key decisions Anda tetap intact. SDK memancarkan message dengan `type: "system"` dan `subtype: "compact_boundary"` dalam stream ketika ini terjadi (di Python ini adalah `SystemMessage`; di TypeScript ini adalah tipe [`SDKCompactBoundaryMessage`](/id/agent-sdk/typescript#sdkcompactboundarymessage) terpisah).
219
220Compaction menggantikan older messages dengan summary, jadi specific instructions dari early dalam conversation mungkin tidak dipertahankan. Persistent rules milik CLAUDE.md (dimuat melalui [`settingSources`](/id/agent-sdk/claude-code-features)) daripada dalam initial prompt, karena CLAUDE.md content di-re-inject pada setiap request.
221
222Anda dapat customize compaction behavior dalam beberapa cara:
223
224* **Summarization instructions dalam CLAUDE.md:** Compactor membaca CLAUDE.md Anda seperti context lainnya, jadi Anda dapat menyertakan section yang memberi tahu apa yang dipertahankan saat merangkum. Section header adalah free-form (bukan magic string); compactor matches pada intent.
225* **`PreCompact` hook:** Jalankan custom logic sebelum compaction terjadi, misalnya untuk archive full transcript. Hook menerima field `trigger` (`manual` atau `auto`). Lihat [hooks](/id/agent-sdk/hooks).
226* **Manual compaction:** Kirim `/compact` sebagai prompt string untuk trigger compaction on demand. (Slash commands yang dikirim dengan cara ini adalah SDK inputs, bukan CLI-only shortcuts. Lihat [slash commands dalam SDK](/id/agent-sdk/slash-commands).)
227
228<Accordion title="Contoh: Summarization instructions dalam CLAUDE.md">
229 Tambahkan section ke CLAUDE.md proyek Anda yang memberi tahu compactor apa yang dipertahankan. Nama header tidak special; gunakan label yang jelas apa pun.
230
231 ```markdown CLAUDE.md theme={null}
232 # Summary instructions
233
234 When summarizing this conversation, always preserve:
235 - The current task objective and acceptance criteria
236 - File paths that have been read or modified
237 - Test results and error messages
238 - Decisions made and the reasoning behind them
239 ```
240</Accordion>
241
242### Keep context efficient
243
244Beberapa strategi untuk long-running agents:
245
246* **Gunakan subagents untuk subtasks.** Setiap subagent dimulai dengan fresh conversation (tidak ada prior message history, meskipun dimuat system prompt dan project-level context seperti CLAUDE.md sendiri). Ini tidak melihat parent's turns, dan hanya final responsenya kembali ke parent sebagai tool result. Main agent's context tumbuh oleh summary itu, bukan oleh full subtask transcript. Lihat [What subagents inherit](/id/agent-sdk/subagents#what-subagents-inherit) untuk details.
247* **Jadilah selective dengan tools.** Setiap tool definition mengambil context space. Gunakan field `tools` pada [`AgentDefinition`](/id/agent-sdk/subagents#agentdefinition-configuration) untuk scope subagents ke minimum set yang mereka butuhkan, dan gunakan [MCP tool search](/id/agent-sdk/mcp#mcp-tool-search) untuk load tools on demand daripada preloading semuanya.
248* **Perhatikan MCP server costs.** Setiap MCP server menambahkan semua tool schemas-nya ke setiap request. Beberapa servers dengan banyak tools dapat mengkonsumsi significant context sebelum agent melakukan pekerjaan apa pun. Tool `ToolSearch` dapat membantu dengan loading tools on-demand daripada preloading semuanya. Lihat [MCP tool search](/id/agent-sdk/mcp#mcp-tool-search) untuk configuration.
249* **Gunakan lower effort untuk routine tasks.** Set [effort](#effort-level) ke `"low"` untuk agents yang hanya perlu membaca files atau list directories. Ini mengurangi token usage dan cost.
250
251Untuk detailed breakdown dari per-feature context costs, lihat [Understand context costs](/id/features-overview#understand-context-costs).
252
253## Sessions dan continuity
254
255Setiap interaksi dengan SDK membuat atau melanjutkan sesi. Capture session ID dari `ResultMessage.session_id` (tersedia di kedua SDKs) untuk resume nanti. TypeScript SDK juga mengeksposnya sebagai direct field pada init `SystemMessage`; di Python ini nested dalam `SystemMessage.data`.
256
257Ketika Anda resume, full context dari previous turns dipulihkan: files yang dibaca, analysis yang dilakukan, dan actions yang diambil. Anda juga dapat fork sesi untuk branch ke pendekatan berbeda tanpa memodifikasi original.
258
259Lihat [Session management](/id/agent-sdk/sessions) untuk full guide pada resume, continue, dan fork patterns.
260
261<Note>
262 Di Python, `ClaudeSDKClient` menangani session IDs secara otomatis di seluruh multiple calls. Lihat [Python SDK reference](/id/agent-sdk/python#choosing-between-query-and-claudesdkclient) untuk details.
263</Note>
264
265## Handle the result
266
267Ketika loop berakhir, `ResultMessage` memberi tahu Anda apa yang terjadi dan memberikan output. Field `subtype` (tersedia di kedua SDKs) adalah cara utama untuk memeriksa termination state.
268
269| Result subtype | Apa yang terjadi | Field `result` tersedia? |
270| :------------------------------------ | :------------------------------------------------------------------- | :----------------------: |
271| `success` | Claude menyelesaikan tugas secara normal | Ya |
272| `error_max_turns` | Mencapai batas `maxTurns` sebelum selesai | Tidak |
273| `error_max_budget_usd` | Mencapai batas `maxBudgetUsd` sebelum selesai | Tidak |
274| `error_during_execution` | Error mengganggu loop (misalnya, API failure atau cancelled request) | Tidak |
275| `error_max_structured_output_retries` | Structured output validation gagal setelah configured retry limit | Tidak |
276
277Field `result` (final text output) hanya present pada variant `success`, jadi selalu periksa subtype sebelum membacanya. Semua result subtypes membawa `total_cost_usd`, `usage`, `num_turns`, dan `session_id` sehingga Anda dapat track cost dan resume bahkan setelah errors. Di Python, `total_cost_usd` dan `usage` diketik sebagai optional dan mungkin `None` pada beberapa error paths, jadi guard sebelum formatting mereka. Lihat [Tracking costs dan usage](/id/agent-sdk/cost-tracking) untuk details tentang interpreting `usage` fields.
278
279Hasil juga mencakup field `stop_reason` (`string | null` di TypeScript, `str | None` di Python) yang menunjukkan mengapa model berhenti generating pada final turn-nya. Common values adalah `end_turn` (model selesai secara normal), `max_tokens` (mencapai output token limit), dan `refusal` (model menolak request). Pada error result subtypes, `stop_reason` membawa value dari last assistant response sebelum loop berakhir. Untuk mendeteksi refusals, periksa `stop_reason === "refusal"` (TypeScript) atau `stop_reason == "refusal"` (Python). Lihat [`SDKResultMessage`](/id/agent-sdk/typescript#sdkresultmessage) (TypeScript) atau [`ResultMessage`](/id/agent-sdk/python#resultmessage) (Python) untuk full type.
280
281## Hooks
282
283[Hooks](/id/agent-sdk/hooks) adalah callbacks yang menyala pada points spesifik dalam loop: sebelum tool berjalan, setelah dikembalikan, ketika agent selesai, dan sebagainya. Beberapa commonly used hooks adalah:
284
285| Hook | Ketika menyala | Common uses |
286| :------------------------------- | :------------------------------------- | :---------------------------------------- |
287| `PreToolUse` | Sebelum tool dieksekusi | Validate inputs, block dangerous commands |
288| `PostToolUse` | Setelah tool dikembalikan | Audit outputs, trigger side effects |
289| `UserPromptSubmit` | Ketika prompt dikirim | Inject additional context ke prompts |
290| `Stop` | Ketika agent selesai | Validate hasil, save session state |
291| `SubagentStart` / `SubagentStop` | Ketika subagent spawned atau completed | Track dan aggregate parallel task results |
292| `PreCompact` | Sebelum context compaction | Archive full transcript sebelum merangkum |
293
294Hooks berjalan dalam application process Anda, bukan di dalam agent's context window, jadi mereka tidak mengkonsumsi context. Hooks juga dapat short-circuit loop: `PreToolUse` hook yang menolak tool call mencegahnya dari executing, dan Claude menerima rejection message sebagai gantinya.
295
296Kedua SDKs mendukung semua events di atas. TypeScript SDK mencakup additional events yang Python belum dukung. Lihat [Control execution dengan hooks](/id/agent-sdk/hooks) untuk complete event list, per-SDK availability, dan full callback API.
297
298## Put it all together
299
300Contoh ini menggabungkan key concepts dari halaman ini ke dalam single agent yang memperbaiki failing tests. Ini mengkonfigurasi agent dengan allowed tools (auto-approved sehingga agent berjalan secara autonomous), project settings, dan safety limits pada turns dan reasoning effort. Saat loop berjalan, ini menangkap session ID untuk potential resumption, handles final result, dan prints total cost.
301
302<CodeGroup>
303 ```python Python theme={null}
304 import asyncio
305 from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
306
307
308 async def run_agent():
309 session_id = None
310
311 async for message in query(
312 prompt="Find and fix the bug causing test failures in the auth module",
313 options=ClaudeAgentOptions(
314 allowed_tools=[
315 "Read",
316 "Edit",
317 "Bash",
318 "Glob",
319 "Grep",
320 ], # Listing tools here auto-approves them (no prompting)
321 setting_sources=[
322 "project"
323 ], # Load CLAUDE.md, skills, hooks from current directory
324 max_turns=30, # Prevent runaway sessions
325 effort="high", # Thorough reasoning for complex debugging
326 ),
327 ):
328 # Handle the final result
329 if isinstance(message, ResultMessage):
330 session_id = message.session_id # Save for potential resumption
331
332 if message.subtype == "success":
333 print(f"Done: {message.result}")
334 elif message.subtype == "error_max_turns":
335 # Agent ran out of turns. Resume with a higher limit.
336 print(f"Hit turn limit. Resume session {session_id} to continue.")
337 elif message.subtype == "error_max_budget_usd":
338 print("Hit budget limit.")
339 else:
340 print(f"Stopped: {message.subtype}")
341 if message.total_cost_usd is not None:
342 print(f"Cost: ${message.total_cost_usd:.4f}")
343
344
345 asyncio.run(run_agent())
346 ```
347
348 ```typescript TypeScript theme={null}
349 import { query } from "@anthropic-ai/claude-agent-sdk";
350
351 let sessionId: string | undefined;
352
353 for await (const message of query({
354 prompt: "Find and fix the bug causing test failures in the auth module",
355 options: {
356 allowedTools: ["Read", "Edit", "Bash", "Glob", "Grep"], // Listing tools here auto-approves them (no prompting)
357 settingSources: ["project"], // Load CLAUDE.md, skills, hooks from current directory
358 maxTurns: 30, // Prevent runaway sessions
359 effort: "high" // Thorough reasoning for complex debugging
360 }
361 })) {
362 // Save the session ID to resume later if needed
363 if (message.type === "system" && message.subtype === "init") {
364 sessionId = message.session_id;
365 }
366
367 // Handle the final result
368 if (message.type === "result") {
369 if (message.subtype === "success") {
370 console.log(`Done: ${message.result}`);
371 } else if (message.subtype === "error_max_turns") {
372 // Agent ran out of turns. Resume with a higher limit.
373 console.log(`Hit turn limit. Resume session ${sessionId} to continue.`);
374 } else if (message.subtype === "error_max_budget_usd") {
375 console.log("Hit budget limit.");
376 } else {
377 console.log(`Stopped: ${message.subtype}`);
378 }
379 console.log(`Cost: $${message.total_cost_usd.toFixed(4)}`);
380 }
381 }
382 ```
383</CodeGroup>
384
385## Next steps
386
387Sekarang Anda memahami loop, berikut adalah tempat untuk pergi tergantung pada apa yang Anda bangun:
388
389* **Belum menjalankan agent?** Mulai dengan [quickstart](/id/agent-sdk/quickstart) untuk mendapatkan SDK terinstal dan lihat contoh lengkap berjalan end to end.
390* **Siap untuk hook ke proyek Anda?** [Load CLAUDE.md, skills, dan filesystem hooks](/id/agent-sdk/claude-code-features) sehingga agent mengikuti project conventions Anda secara otomatis.
391* **Membangun interactive UI?** Aktifkan [streaming](/id/agent-sdk/streaming-output) untuk menampilkan live text dan tool calls saat loop berjalan.
392* **Butuh tighter control atas apa yang dapat dilakukan agent?** Lock down tool access dengan [permissions](/id/agent-sdk/permissions), dan gunakan [hooks](/id/agent-sdk/hooks) untuk audit, block, atau transform tool calls sebelum dieksekusi.
393* **Menjalankan long atau expensive tasks?** Offload isolated work ke [subagents](/id/agent-sdk/subagents) untuk keep main context Anda lean.
394
395Untuk broader conceptual picture dari agentic loop (bukan SDK-specific), lihat [How Claude Code works](/id/how-claude-code-works).