Fitur ini memenuhi syarat untuk Zero Data Retention (ZDR). Ketika organisasi Anda memiliki pengaturan ZDR, data yang dikirim melalui fitur ini tidak disimpan setelah respons API dikembalikan.
"Fine-grained tool streaming" (streaming alat terperinci) mengirimkan input sebuah alat ke klien Anda saat Claude menghasilkannya, tanpa buffering atau validasi JSON di sisi server. Melewatkan langkah buffering mengurangi waktu hingga fragmen pertama dari parameter besar, seperti dokumen atau blok kode, dan fragmen-fragmen tersebut tiba melalui event Streaming messages yang sama seperti penggunaan alat standar.
Karena API tidak melakukan buffering atau memvalidasi input alat sebelum melakukan streaming, Anda mungkin menerima JSON yang parsial atau tidak valid. Respons yang berakhir dengan stop reason max_tokens juga dapat memotong parameter di tengah jalan. Akumulasikan fragmen-fragmen tersebut, lindungi proses parsing, dan lihat Menangani JSON tidak valid dalam respons alat untuk cara mengembalikan input yang tidak dapat di-parse ke Claude.
Semua model mendukung streaming alat terperinci pada Claude API, Claude Platform di AWS, Amazon Bedrock, Google Cloud, dan Microsoft Foundry. Untuk menggunakannya, atur eager_input_streaming ke true pada setiap alat yang didefinisikan pengguna di mana Anda ingin mengaktifkan streaming terperinci, dan aktifkan streaming pada permintaan Anda.
Field eager_input_streaming bersifat opsional. Mengaturnya ke true mengaktifkan streaming terperinci untuk alat tersebut, dan menghilangkannya memberi Anda streaming dengan buffering standar, di mana API melakukan buffering dan memvalidasi setiap nilai parameter sebelum melakukan streaming kembali. Pengecualiannya adalah permintaan yang masih mengirim header beta lama fine-grained-tool-streaming-2025-05-14, yang mengaktifkan streaming terperinci untuk alat yang tidak mengatur field tersebut. Field per-alat ini menggantikan header tersebut, dan nilai false yang eksplisit mempertahankan streaming dengan buffering untuk sebuah alat bahkan ketika permintaan masih mengirim header tersebut. Lihat Referensi alat untuk definisi field.
Contoh berikut mengaktifkan streaming terperinci untuk alat make_file dan meminta Claude untuk membuat puisi panjang, sehingga input alat cukup besar untuk diamati saat di-stream:
client = anthropic.Anthropic()
with client.messages.stream(
max_tokens=65536,
model="claude-opus-4-8",
tools=[
{
"name": "make_file",
"description": "Write text to a file",
"eager_input_streaming": True,
"input_schema": {
"type": "object",
"properties": {
"filename": {
"type": "string",
"description": "The filename to write text to",
},
"lines_of_text": {
"type": "array",
"description": "An array of lines of text to write to the file",
},
},
"required": ["filename", "lines_of_text"],
},
}
],
messages=[
{
"role": "user",
"content": "Can you write a long poem and make a file called poem.txt?",
}
],
) as stream:
for event in stream:
if event.type == "input_json":
print(event.partial_json, end="", flush=True)
final_message = stream.get_final_message()
print()
for block in final_message.content:
if block.type == "tool_use":
print(f"Complete tool input: {block.input}")Setiap tab mengaktifkan streaming terperinci untuk alat make_file. Tab SDK mencetak setiap fragmen input pada saat fragmen tersebut tiba, kemudian mencetak input lengkap yang terakumulasi setelah stream berakhir. Tab cURL menampilkan stream event mentah, dan tab CLI menggunakan jq untuk mencetak hanya fragmen-fragmennya. Karena fragmen yang dicetak bergabung menjadi input alat lengkap, puisi tersebut mengisi terminal Anda saat Claude menulisnya:
{"filename": "poem.txt", "lines_of_text": ["The Wanderer's Journey", "", "I.", "", "Beneath the vast and star-strewn sky,", "Where silver moonbeams softly lie,", ...
Complete tool input: {"filename": "poem.txt", "lines_of_text": ["The Wanderer's Journey", ...]}Tanpa eager_input_streaming, API melakukan buffering dan memvalidasi setiap nilai parameter sebelum melakukan streaming kembali, sehingga tidak ada yang dicetak untuk parameter besar sampai Claude selesai menghasilkannya. Dengan field tersebut, fragmen mulai tiba segera setelah Claude memulai parameter, dan fragmen-fragmen tersebut biasanya lebih panjang, dengan lebih sedikit pemotongan di tengah kata.
Kontrak akumulasi sama dengan streaming penggunaan alat standar, sehingga bagian ini berlaku dengan dan tanpa eager_input_streaming. Lihat Input JSON delta di Streaming messages untuk format event. Streaming alat terperinci mengubah apa yang dapat Anda asumsikan tentang hasilnya: server melakukan streaming fragmen tanpa memvalidasinya, sehingga string yang terakumulasi mungkin bukan JSON yang valid.
Ketika blok konten tool_use di-stream, event content_block_start awal berisi input: {} (objek kosong). Ini adalah placeholder. Input sebenarnya tiba sebagai serangkaian event input_json_delta, masing-masing membawa fragmen string partial_json. Untuk menyusun input lengkap, gabungkan fragmen-fragmen ini dan parse hasilnya ketika blok ditutup.
Jika SDK Anda menyediakan helper akumulator (seperti yang dilakukan tab Python, TypeScript, Go, Java, dan Ruby pada contoh sebelumnya), helper tersebut menangani ini untuk Anda. Pola manual ditujukan untuk SDK tanpa helper, atau ketika Anda menginginkan kontrol penuh atas bagaimana input disusun.
Kontrak akumulasi:
content_block_start dengan type: "tool_use", inisialisasi string kosong: input_json = ""content_block_delta dengan type: "input_json_delta", tambahkan: input_json += event.delta.partial_jsoncontent_block_stop, parse string yang terakumulasiLindungi proses parsing, seperti yang dilakukan contoh SDK berikut. Respons juga dapat berhenti pada max_tokens di tengah parameter. Periksa stop reason dan putuskan apakah akan mencoba ulang permintaan dengan max_tokens yang lebih tinggi atau memperbaiki input parsial.
Ketidakcocokan tipe antara input: {} awal (objek) dan partial_json (string) memang disengaja. Objek kosong menandai slot dalam array konten. String delta membangun nilai sebenarnya.
client = anthropic.Anthropic()
tool_inputs: dict[int, str] = {} # index -> accumulated JSON string
with client.messages.stream(
model="claude-opus-4-8",
max_tokens=1024,
tools=[
{
"name": "get_weather",
"description": "Get current weather for a city",
"eager_input_streaming": True,
"input_schema": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
}
],
messages=[{"role": "user", "content": "Weather in Paris?"}],
) as stream:
for event in stream:
match event.type:
case "content_block_start" if event.content_block.type == "tool_use":
tool_inputs[event.index] = ""
case "content_block_delta" if event.delta.type == "input_json_delta":
tool_inputs[event.index] += event.delta.partial_json
case "content_block_stop" if event.index in tool_inputs:
raw_input = tool_inputs[event.index]
try:
parsed = json.loads(raw_input)
except json.JSONDecodeError:
# String yang terakumulasi tidak dijamin merupakan JSON yang valid.
# Lihat "Handling invalid JSON in tool responses" di halaman ini.
print(f"Invalid tool input: {raw_input}")
else:
print(f"Tool input: {parsed}")Bereaksi terhadap fragmen dan menyusunnya adalah dua hal yang terpisah. Contoh pertama bereaksi terhadap setiap fragmen saat tiba dan tetap menyerahkan penyusunan ke SDK pada tab yang menggunakan helper akumulator. Gunakan pola manual ketika Anda tidak menggunakan helper akumulator atau ketika Anda menginginkan kontrol penuh atas penyusunan.
Dengan streaming alat terperinci, input yang terakumulasi untuk pemanggilan alat mungkin berupa JSON yang tidak valid atau tidak lengkap. Ketika hal itu terjadi, Anda tidak dapat menjalankan alat tersebut, jadi laporkan kegagalan tersebut kembali ke Claude. content dari hasil alat tidak harus berupa JSON, tetapi membungkus string mentah dalam objek JSON di bawah satu key membuat jelas bagi Claude bahwa Anda menerima JSON yang tidak valid, dan mempertahankan input asli untuk debugging:
{
"INVALID_JSON": "<the unparseable input you received>"
}Kembalikan wrapper tersebut, yang diserialisasi menjadi string, sebagai content dari blok konten tool result dengan is_error diatur ke true:
{
"type": "tool_result",
"tool_use_id": "toolu_01A09q90qw90lq917835lq9",
"is_error": true,
"content": "{\"INVALID_JSON\": \"<the unparseable input you received>\"}"
}Bangun wrapper dengan library JSON Anda daripada dengan menggabungkan string, sehingga tanda kutip dan karakter khusus lainnya dalam input yang tidak valid di-escape dengan benar.
Pahami cara kerja jendela konteks, bagaimana pemikiran diperpanjang dan penggunaan alat dihitung terhadapnya, dan cara mengelola konteks seiring berkembangnya percakapan.
Stream respons Messages API secara inkremental dengan server-sent events, termasuk delta teks, penggunaan alat, dan pemikiran diperpanjang.
Parse blok tool_use, format respons tool_result, dan tangani error dengan is_error.
Direktori alat yang disediakan Anthropic dan referensi untuk properti definisi alat opsional.
Was this page helpful?