Pemanggilan alat secara terprogram memungkinkan Claude menulis kode yang memanggil alat Anda secara terprogram di dalam kontainer code execution (eksekusi kode), alih-alih memerlukan bolak-balik melalui model untuk setiap pemanggilan alat. Hal ini mengurangi latensi untuk alur kerja multi-alat dan menurunkan konsumsi token dengan memungkinkan Claude memfilter atau memproses data sebelum data tersebut mencapai jendela konteks model. Pada benchmark pencarian agentik seperti BrowseComp dan DeepSearchQA, yang menguji riset web multi-langkah dan pengambilan informasi kompleks, menambahkan pemanggilan alat secara terprogram di atas alat pencarian dasar meningkatkan performa rata-rata sebesar 11% sambil menggunakan 24% lebih sedikit token input (lihat Improved web search with dynamic filtering).
Pertimbangkan pemeriksaan kepatuhan anggaran untuk 20 karyawan: pendekatan tradisional memerlukan 20 bolak-balik model terpisah, menarik ribuan baris item pengeluaran ke dalam konteks sepanjang prosesnya. Dengan pemanggilan alat secara terprogram, satu skrip menjalankan seluruh 20 pencarian, memfilter hasilnya, dan hanya mengembalikan karyawan yang melebihi batas mereka, menyusutkan apa yang perlu dipikirkan Claude dari ratusan kilobyte menjadi hanya beberapa baris.
Untuk pembahasan lebih mendalam tentang biaya inferensi dan konteks yang diatasi oleh pemanggilan alat secara terprogram, lihat Advanced tool use.
Fitur ini memerlukan alat eksekusi kode untuk diaktifkan.
Fitur ini tidak memenuhi syarat untuk Zero Data Retention (ZDR). Data disimpan sesuai dengan kebijakan retensi standar fitur ini.
Pemanggilan alat secara terprogram memerlukan code_execution_20260120 atau yang lebih baru, yang didukung pada model-model berikut:
| Model |
|---|
| Claude Fable 5 (claude-fable-5) |
| Claude Mythos 5 (claude-mythos-5) |
| Claude Opus 4.8 (claude-opus-4-8) |
| Claude Opus 4.7 (claude-opus-4-7) |
| Claude Opus 4.6 (claude-opus-4-6) |
| Claude Sonnet 5 (claude-sonnet-5) |
| Claude Sonnet 4.6 (claude-sonnet-4-6) |
| Claude Opus 4.5 (claude-opus-4-5-20251101) |
| Claude Sonnet 4.5 (claude-sonnet-4-5-20250929) |
Untuk matriks versi alat eksekusi kode lengkap, lihat tabel kompatibilitas model alat eksekusi kode. Pemanggilan alat secara terprogram tersedia di Claude API, Claude Platform on AWS, dan Microsoft Foundry. Di Microsoft Foundry, pemanggilan alat secara terprogram memerlukan deployment Hosted on Anthropic. Fitur ini saat ini tidak tersedia di Amazon Bedrock atau Google Cloud.
Berikut adalah contoh di mana Claude secara terprogram melakukan kueri ke database beberapa kali dan mengagregasi hasilnya:
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=4096,
messages=[
{
"role": "user",
"content": "Query sales data for the West, East, and Central regions, then tell me which region had the highest revenue",
}
],
tools=[
{"type": "code_execution_20260120", "name": "code_execution"},
{
"name": "query_database",
"description": "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.",
"input_schema": {
"type": "object",
"properties": {
"sql": {"type": "string", "description": "SQL query to execute"}
},
"required": ["sql"],
},
"allowed_callers": ["code_execution_20260120"],
},
],
)
print(response)Respons berhenti dengan stop_reason: "tool_use", sebuah ID container, dan blok tool_use untuk query_database yang field caller-nya mengidentifikasi eksekusi kode yang memanggilnya. Kembalikan hasilnya seperti yang ditunjukkan di Langkah 3 dari contoh alur kerja agar kode dapat selesai.
Ketika Anda mengonfigurasi sebuah alat agar dapat dipanggil dari eksekusi kode dan Claude memutuskan untuk menggunakan alat tersebut:
tool_usePendekatan ini sangat berguna untuk:
Alat yang mengizinkan pemanggil eksekusi kode diekspos ke kode Claude sebagai fungsi Python async, sehingga Claude dapat menjalankannya secara paralel dengan asyncio.gather. Setiap fungsi menerima satu dict argumen dan mengembalikan string: teks dari tool_result yang Anda kirim kembali. Kode Claude menunggu fungsi-fungsi ini dengan await tingkat atas dan mem-parsing hasil yang dibutuhkannya sebagai data terstruktur, misalnya rows = json.loads(await query_database({"sql": "<sql>"})).
allowed_callersField allowed_callers menentukan konteks mana yang dapat memanggil sebuah alat:
{
"name": "query_database",
"description": "Execute a SQL query against the database",
"input_schema": {
// ...
},
"allowed_callers": ["code_execution_20260120"]
}Nilai yang mungkin:
["direct"] - Claude diarahkan untuk memanggil alat ini secara langsung (default jika dihilangkan)["code_execution_20260120"] - Claude diarahkan untuk memanggil alat ini hanya dari dalam eksekusi kode["direct", "code_execution_20260120"] - Claude dapat memanggil alat ini secara langsung atau dari dalam eksekusi kodeBaik "code_execution_20260120" maupun "code_execution_20260521" diterima dalam allowed_callers dan dapat dipertukarkan: permintaan yang menggunakan salah satu versi alat eksekusi kode memenuhi alat yang mencantumkan salah satu pemanggil tersebut. Blok respons selalu menandai pemanggil sebagai code_execution_20260120 terlepas dari versi mana yang dideklarasikan oleh permintaan.
Pilih salah satu antara ["direct"] atau ["code_execution_20260120"] untuk setiap alat daripada mengaktifkan keduanya, karena ini memberikan panduan yang lebih jelas kepada Claude tentang cara terbaik menggunakan alat tersebut.
allowed_callers mengontrol bagaimana alat disajikan kepada Claude dan divalidasi terhadap tool_choice, tetapi ini bukan pemblokiran keras tingkat API terhadap pemanggilan langsung. Claude diarahkan dengan kuat untuk menghormatinya, tetapi klien Anda tetap harus siap menangani tool_use langsung untuk alat apa pun yang didefinisikannya. Jangan mengandalkan allowed_callers sebagai batas keamanan.
caller dalam responsSetiap blok tool use menyertakan field caller yang menunjukkan bagaimana alat tersebut dipanggil:
Pemanggilan langsung (penggunaan alat tradisional):
{
"type": "tool_use",
"id": "toolu_abc123",
"name": "query_database",
"input": { "sql": "<sql>" },
"caller": { "type": "direct" }
}Pemanggilan terprogram:
{
"type": "tool_use",
"id": "toolu_xyz789",
"name": "query_database",
"input": { "sql": "<sql>" },
"caller": {
"type": "code_execution_20260120",
"tool_id": "srvtoolu_abc123"
}
}tool_id adalah id dari blok server_tool_use eksekusi kode yang melakukan pemanggilan, sehingga Anda dapat mencocokkan setiap tool_use terprogram dengan eksekusi kode yang menghasilkannya.
Pemanggilan alat secara terprogram menggunakan kontainer yang sama dengan eksekusi kode:
container, bersama dengan timestamp expires_atexpires_at memberi tahu Anda berapa lama waktu yang tersisa untuk kontainer. Kontainer yang idle saat ini diklaim kembali setelah sekitar 5 menit, dan tidak ada kontainer yang dapat digunakan kembali lebih dari 30 hari setelah dibuat.Saat kode Claude sedang menunggu hasil alat terprogram, pemanggilan yang tertunda akan timeout setelah sekitar 4 menit dan memunculkan TimeoutError di dalam kode. Kembalikan setiap hasil alat jauh sebelum timestamp expires_at pada respons yang dijeda. Lihat Kedaluwarsa kontainer selama pemanggilan alat.
Berikut adalah cara kerja alur pemanggilan alat secara terprogram yang lengkap:
Kirim permintaan dengan eksekusi kode dan alat yang mengizinkan pemanggilan terprogram. Untuk mengaktifkan pemanggilan terprogram, tambahkan field allowed_callers ke definisi alat Anda.
Berikan deskripsi terperinci tentang format output alat Anda dalam deskripsi alat. Jika Anda menentukan bahwa alat mengembalikan JSON, Claude akan mencoba melakukan deserialisasi dan memproses hasilnya dalam kode. Semakin detail yang Anda berikan tentang skema output, semakin baik Claude dapat menangani respons secara terprogram.
Bentuk permintaan identik dengan contoh Mulai cepat: sertakan code_execution dalam daftar alat Anda, tambahkan allowed_callers: ["code_execution_20260120"] ke alat apa pun yang Anda ingin Claude panggil dari kode, dan kirim pesan pengguna Anda. Langkah-langkah selanjutnya dalam alur kerja ini menggunakan pesan pengguna "Query customer purchase history from the last quarter and identify our top 5 customers by revenue".
Claude menulis kode yang memanggil alat Anda. API dijeda dan mengembalikan:
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'll query the purchase history and analyze the results."
},
{
"type": "server_tool_use",
"id": "srvtoolu_abc123",
"name": "code_execution",
"input": {
"code": "import json\n\nrows = json.loads(await query_database({'sql': '<sql>'}))\ntop_customers = sorted(rows, key=lambda x: x['revenue'], reverse=True)[:5]\nprint(f'Top 5 customers: {top_customers}')"
}
},
{
"type": "tool_use",
"id": "toolu_def456",
"name": "query_database",
"input": { "sql": "<sql>" },
"caller": {
"type": "code_execution_20260120",
"tool_id": "srvtoolu_abc123"
}
}
],
"container": {
"id": "container_xyz789",
"expires_at": "2026-01-20T14:30:00Z"
},
"stop_reason": "tool_use"
}Kirim seluruh riwayat percakapan ditambah hasil alat Anda. Tiga detail penting pada permintaan ini:
tool_result. Lihat Batasan pemformatan pesan.container dari respons yang dijeda. API menolak kelanjutan yang memiliki pemanggilan alat terprogram yang tertunda tetapi tanpa ID kontainer.tools yang sama seperti permintaan asli. Alat eksekusi kode harus tetap ada agar kode yang dijeda dapat dilanjutkan, dan alat yang Anda kirim pada permintaan ini adalah definisi yang dapat digunakan Claude dan kode yang sedang berjalan untuk sisa giliran tersebut.response = client.messages.create(
model="claude-opus-4-8",
max_tokens=4096,
container="container_xyz789", # Reuse the container
messages=[
{
"role": "user",
"content": "Query customer purchase history from the last quarter and identify our top 5 customers by revenue",
},
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'll query the purchase history and analyze the results.",
},
{
"type": "server_tool_use",
"id": "srvtoolu_abc123",
"name": "code_execution",
"input": {"code": "..."},
},
{
"type": "tool_use",
"id": "toolu_def456",
"name": "query_database",
"input": {"sql": "<sql>"},
"caller": {
"type": "code_execution_20260120",
"tool_id": "srvtoolu_abc123",
},
},
],
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_def456",
"content": '[{"customer_id": "C1", "revenue": 45000}, {"customer_id": "C2", "revenue": 38000}, ...]',
}
],
},
],
# Array tools yang sama seperti permintaan awal
tools=[
{"type": "code_execution_20260120", "name": "code_execution"},
{
"name": "query_database",
"description": "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.",
"input_schema": {
"type": "object",
"properties": {
"sql": {"type": "string", "description": "SQL query to execute"}
},
"required": ["sql"],
},
"allowed_callers": ["code_execution_20260120"],
},
],
)
print(response)Kode melanjutkan dari tempat ia dijeda dan memproses hasil Anda. Setiap respons kelanjutan akan dijeda lagi dengan lebih banyak blok tool_use terprogram, atau menyelesaikan eksekusi kode dan membiarkan Claude melanjutkan giliran (Langkah 5). Periksa stop_reason dan caller dari setiap blok tool_use untuk membedakan keduanya: respons yang dijeda untuk Anda memiliki stop_reason: "tool_use" dan blok tool_use yang caller-nya menyebutkan versi eksekusi kode, dan Anda mengulangi Langkah 3 dengan tool_result untuk setiap pemanggilan terprogram yang tertunda dalam satu pesan pengguna.
Setelah eksekusi kode selesai, Claude memberikan respons akhir:
{
"content": [
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "code_execution_result",
"stdout": "Top 5 customers: [{'customer_id': 'C1', 'revenue': 45000}, {'customer_id': 'C2', 'revenue': 38000}, {'customer_id': 'C5', 'revenue': 32000}, {'customer_id': 'C8', 'revenue': 28500}, {'customer_id': 'C3', 'revenue': 24000}]",
"stderr": "",
"return_code": 0,
"content": []
}
},
{
"type": "text",
"text": "I've analyzed the purchase history from last quarter. Your top 5 customers generated $167,500 in total revenue, with Customer C1 leading at $45,000."
}
],
"stop_reason": "end_turn"
}Claude dapat menulis kode yang memproses banyak item secara efisien:
regions = ["West", "East", "Central", "North", "South"]
results = {}
for region in regions:
rows = json.loads(await query_database({"sql": f"<sql for {region}>"}))
results[region] = sum(row["revenue"] for row in rows)
# Proses hasil secara terprogram
top_region = max(results.items(), key=lambda x: x[1])
print(f"Top region: {top_region[0]} with ${top_region[1]:,} in revenue")Pola ini:
Claude dapat berhenti memproses segera setelah kriteria keberhasilan terpenuhi:
endpoints = ["us-east", "eu-west", "apac"]
for endpoint in endpoints:
status = await check_health({"endpoint": endpoint})
if status == "healthy":
print(f"Found healthy endpoint: {endpoint}")
break # Stop early, don't check remainingpath = "/tmp/example.txt"
file_info = json.loads(await get_file_info({"path": path}))
if file_info["size"] < 10000:
content = await read_full_file({"path": path})
else:
content = await read_file_summary({"path": path})
print(content)server_id = "srv-01"
log_text = await fetch_logs({"server_id": server_id})
errors = [line for line in log_text.splitlines() if "ERROR" in line]
print(f"Found {len(errors)} errors")
for error in errors[-10:]: # Only return last 10 errors
print(error)Ketika eksekusi kode memanggil sebuah alat:
{
"type": "tool_use",
"id": "toolu_abc123",
"name": "query_database",
"input": { "sql": "<sql>" },
"caller": {
"type": "code_execution_20260120",
"tool_id": "srvtoolu_xyz789"
}
}Hasil alat Anda diteruskan kembali ke kode yang sedang berjalan:
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_abc123",
"content": "[{\"customer_id\": \"C1\", \"revenue\": 45000, \"orders\": 23}, {\"customer_id\": \"C2\", \"revenue\": 38000, \"orders\": 18}, ...]"
}
]
}Ketika semua pemanggilan alat terpenuhi dan kode selesai:
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_xyz789",
"content": {
"type": "code_execution_result",
"stdout": "Analysis complete. Top 5 customers identified from 847 total records.",
"stderr": "",
"return_code": 0,
"content": []
}
}| Error | Tempat muncul | Deskripsi | Solusi |
|---|---|---|---|
invalid_tool_input | error_code pada blok error code_execution_tool_result dalam respons | Parameter yang tidak valid diteruskan ke alat eksekusi kode | Lihat error alat eksekusi kode |
invalid_request_error (pada tool_choice) | Respons error HTTP 400 | tool_choice menyebutkan alat yang allowed_callers-nya tidak menyertakan "direct" | Tambahkan "direct" ke allowed_callers alat tersebut, atau hapus alat dari tool_choice dan biarkan Claude memanggilnya dari kode |
Jika hasil alat Anda tidak tiba dalam waktu sekitar 4 menit, pemanggilan yang tertunda memunculkan TimeoutError di dalam kode Claude yang sedang berjalan. Claude melihat error tersebut di stderr dan biasanya mencoba ulang pemanggilan:
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "code_execution_result",
"stdout": "",
"stderr": "TimeoutError: Calling tool ['query_database'] timed out (no response after 270s).",
"return_code": 0,
"content": []
}
}Untuk mencegah timeout:
expires_at dalam responsJika alat Anda mengembalikan error:
{
"type": "tool_result",
"tool_use_id": "toolu_abc123",
"content": "Error: Query timeout - table lock exceeded 30 seconds"
}Kode Claude menerima error ini dan dapat menanganinya dengan tepat.
strict: true tidak didukung dengan pemanggilan terprogramtool_choicedisable_parallel_tool_use: true tidak didukung dengan pemanggilan terprogramAlat kustom yang input_schema-nya berisi $ref rekursif (siklus referensi, seperti skema yang merujuk ke dirinya sendiri) tidak dapat diaktifkan untuk pemanggilan terprogram. Menyertakan versi alat eksekusi kode dalam allowed_callers untuk alat semacam itu menyebabkan permintaan gagal dengan 400 invalid_request_error yang pesannya berisi Circular $ref detected. Skema yang sama diterima untuk pemanggilan alat langsung.
Untuk mengatasi hal ini, lakukan salah satu dari berikut:
allowed_callers (atau mengaturnya ke ["direct"]). Alat lain dalam permintaan yang sama tetap dapat menggunakan pemanggilan terprogram.description dari level terdalam, atau ganti properti rekursif dengan {"type": "object"} biasa yang description-nya menjelaskan bentuk yang diharapkan.Alat berikut tidak dapat dipanggil secara terprogram:
Saat merespons pemanggilan alat terprogram, ada persyaratan pemformatan yang ketat:
Respons hanya berisi hasil alat: Jika ada pemanggilan alat terprogram yang tertunda menunggu hasil, pesan respons Anda harus berisi hanya blok tool_result. Anda tidak dapat menyertakan konten teks apa pun, bahkan setelah hasil alat.
Tidak valid - Tidak dapat menyertakan teks saat merespons pemanggilan alat terprogram:
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01",
"content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}]"
},
{ "type": "text", "text": "What should I do next?" }
]
}Valid - Hanya hasil alat saat merespons pemanggilan alat terprogram:
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01",
"content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}]"
}
]
}Batasan ini hanya berlaku saat merespons pemanggilan alat terprogram (eksekusi kode). Untuk pemanggilan alat sisi klien biasa, Anda dapat menyertakan konten teks setelah hasil alat.
Konten hasil alat hanya teks: content dari setiap tool_result yang menjawab pemanggilan terprogram harus berupa string atau blok text. Tipe blok konten gambar, dokumen, dan lainnya ditolak.
Pemanggilan alat terprogram tunduk pada batas laju yang sama dengan pemanggilan alat biasa. Setiap pemanggilan alat dari eksekusi kode dihitung sebagai pemanggilan terpisah.
Saat mengimplementasikan alat yang didefinisikan pengguna yang akan dipanggil secara terprogram:
Pemanggilan alat secara terprogram mengurangi konsumsi token dalam tiga cara:
Misalnya, memanggil 10 alat secara langsung menggunakan ~10x token dibandingkan memanggilnya secara terprogram dan mengembalikan ringkasan.
Dalam evaluasi internal Anthropic pada model Claude produksi:
tools-nya berisi 10 hingga 49 definisi alat mengalami penghematan token tipikal sebesar 20% hingga 40% dengan pemanggilan alat secara terprogram diaktifkan.Penghematan aktual bervariasi tergantung bentuk beban kerja. Lihat Kapan menggunakan pemanggilan terprogram.
Pemanggilan alat secara terprogram menggunakan harga yang sama dengan eksekusi kode. Lihat harga eksekusi kode untuk detailnya.
Penghitungan token untuk pemanggilan alat terprogram: Hasil alat dari pemanggilan terprogram tidak dihitung terhadap penggunaan token input/output Anda. Hanya hasil eksekusi kode akhir dan respons Claude yang dihitung.
Pemanggilan alat secara terprogram menukar overhead tetap yang kecil (startup kontainer, pembuatan skrip) dengan penghematan besar pada token hasil alat dan bolak-balik model. Apakah pertukaran itu menguntungkan tergantung pada bentuk beban kerja.
Sangat cocok:
Kurang cocok:
Jika Anda tidak yakin, ukur token input yang ditagih dengan dan tanpa allowed_callers pada sampel representatif dari lalu lintas Anda sebelum mengaktifkannya secara luas.
invalid_request_error saat mengatur tool_choice
tool_choice tidak dapat menyebutkan alat yang allowed_callers-nya tidak menyertakan "direct". Tambahkan "direct" ke allowed_callers alat tersebut, atau hapus alat dari tool_choice dan biarkan Claude memanggilnya dari kode.Kedaluwarsa kontainer
expires_at dari respons yang dijeda. Kode Claude berhenti menunggu hasil setelah sekitar 4 menit, dan kontainer yang idle saat ini diklaim kembali setelah sekitar 5 menit.Hasil alat tidak di-parse dengan benar
caller untuk mengonfirmasi pemanggilan terprogramClaude dilatih pada sejumlah besar kode, sehingga menyajikan alat sebagai fungsi Python yang dapat dipanggil memungkinkannya menggunakan kekuatan tersebut:
Pemanggilan alat secara terprogram adalah pola yang dapat digeneralisasi yang juga dapat diimplementasikan pada infrastruktur Anda sendiri. Berikut perbandingan pendekatannya:
Berikan Claude alat eksekusi kode dan jelaskan fungsi apa yang tersedia di lingkungan tersebut. Ketika Claude memanggil alat dengan kode, aplikasi Anda mengeksekusinya secara lokal di tempat fungsi-fungsi tersebut didefinisikan.
Keuntungan:
Kerugian:
Gunakan ketika: Aplikasi Anda dapat mengeksekusi kode arbitrer dengan aman, Anda menginginkan implementasi terkecil, dan penawaran terkelola Anthropic tidak sesuai dengan kebutuhan Anda.
Pendekatan yang sama dari perspektif Claude, tetapi kode berjalan di kontainer sandbox dengan batasan keamanan (misalnya, tanpa egress jaringan). Jika alat Anda memerlukan sumber daya eksternal, Anda memerlukan protokol untuk mengeksekusi pemanggilan alat di luar sandbox.
Keuntungan:
Kerugian:
Gunakan ketika: Keamanan sangat penting dan solusi terkelola Anthropic tidak sesuai dengan kebutuhan Anda.
Pemanggilan alat secara terprogram dari Anthropic adalah versi terkelola dari eksekusi sandbox dengan lingkungan Python yang opinionated dan disetel untuk Claude. Anthropic menangani manajemen kontainer, eksekusi kode, dan komunikasi pemanggilan alat yang aman.
Keuntungan:
Pertimbangkan untuk menggunakan solusi terkelola Anthropic jika Anda menggunakan Claude API, Claude Platform on AWS, atau Microsoft Foundry. Di Microsoft Foundry, pemanggilan alat secara terprogram memerlukan deployment Hosted on Anthropic.
Pemanggilan alat secara terprogram dibangun di atas infrastruktur eksekusi kode dan menggunakan kontainer sandbox yang sama. Data kontainer, termasuk artefak eksekusi dan output, disimpan hingga 30 hari.
Untuk kelayakan ZDR di semua fitur, lihat API dan retensi data.
Stream input alat tanpa buffering JSON sisi server untuk aplikasi yang sensitif terhadap latensi.
Jalankan kode Python dan bash di kontainer sandbox untuk menganalisis data, menghasilkan file, dan melakukan iterasi pada solusi.
Hubungkan Claude ke alat dan API eksternal. Lihat di mana alat dieksekusi, kapan Claude memanggilnya, dan alat mana yang sesuai dengan tugas Anda.
Tentukan skema alat, tulis deskripsi yang efektif, dan kontrol kapan Claude memanggil alat Anda.
Was this page helpful?