Детализированная потоковая передача инструментов
Передавайте входные данные инструментов потоком без буферизации JSON на стороне сервера для приложений, чувствительных к задержкам.
«Fine-grained tool streaming» (детализированная потоковая передача инструментов) доставляет входные данные инструмента вашему клиенту по мере того, как Claude их генерирует, без буферизации на стороне сервера и без валидации JSON. Пропуск этапа буферизации сокращает время до получения первого фрагмента большого параметра, например документа или блока кода, а фрагменты поступают через те же события потоковой передачи сообщений, что и при стандартном использовании инструментов.
Как использовать детализированную потоковую передачу инструментов
Все модели поддерживают детализированную потоковую передачу инструментов в Claude API, Amazon Bedrock, Claude Platform on AWS, Google Cloud и Microsoft Foundry. Чтобы использовать её, установите eager_input_streaming в значение true для любого пользовательского инструмента, для которого вы хотите включить детализированную потоковую передачу, и включите потоковую передачу в своём запросе.
Поле eager_input_streaming необязательно. Значение true включает детализированную потоковую передачу для этого инструмента, а если поле не указано, используется стандартная буферизованная потоковая передача, при которой API буферизует и проверяет каждое значение параметра перед его потоковой передачей. Исключение составляет запрос, который всё ещё отправляет устаревший бета-заголовок fine-grained-tool-streaming-2025-05-14: он включает детализированную потоковую передачу для инструментов, у которых это поле не задано. Поле на уровне инструмента заменяет этот заголовок, а явное значение false сохраняет буферизованную потоковую передачу для инструмента, даже если запрос всё ещё отправляет заголовок. Устаревший заголовок нельзя сочетать с записью набора инструментов computer use (использование компьютера) или browser use (использование браузера): API отклоняет запрос, содержащий и то и другое, поэтому удалите заголовок и установите eager_input_streaming для тех пользовательских инструментов, которым это нужно. Определение поля см. в справочнике по инструментам.
В следующем примере детализированная потоковая передача включается для инструмента make_file, а Claude просят написать длинное стихотворение, чтобы входные данные инструмента были достаточно большими и можно было наблюдать за их потоковой передачей:
client = anthropic.Anthropic()
with client.messages.stream(
max_tokens=65536,
model="claude-opus-5-5",
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}")Каждая вкладка включает детализированную потоковую передачу для инструмента make_file. Вкладки SDK выводят каждый фрагмент входных данных в момент его поступления, а после завершения потока выводят полные накопленные входные данные. Вкладка cURL показывает необработанный поток событий, а вкладка CLI использует jq, чтобы выводить только фрагменты. Поскольку выведенные фрагменты складываются в полные входные данные инструмента, стихотворение заполняет ваш терминал по мере того, как Claude его пишет:
{"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", ...]}Без eager_input_streaming API буферизует и проверяет каждое значение параметра перед его потоковой передачей, поэтому для большого параметра ничего не выводится, пока Claude не закончит его генерировать. С этим полем фрагменты начинают поступать, как только Claude приступает к параметру, и обычно они длиннее и реже обрываются посреди слова.
Накопление дельт входных данных инструмента
Контракт накопления такой же, как и для стандартной потоковой передачи при использовании инструментов, поэтому этот раздел применим как с eager_input_streaming, так и без него. Формат событий см. в разделе Дельта входного JSON на странице «Потоковая передача сообщений». Детализированная потоковая передача инструментов меняет то, что вы можете предполагать о результате: сервер передаёт фрагменты без проверки, поэтому накопленная строка может не быть допустимым JSON.
Когда передаётся блок содержимого tool_use, начальное событие content_block_start содержит input: {} (пустой объект). Это заполнитель. Фактические входные данные поступают в виде серии событий input_json_delta, каждое из которых несёт строковый фрагмент partial_json. Чтобы собрать полные входные данные, объедините эти фрагменты и разберите результат, когда блок закроется.
Если ваш SDK предоставляет «accumulator helper» (вспомогательное средство накопления), как во вкладках Python, TypeScript, Go, Java и Ruby в предыдущем примере, оно делает это за вас. Ручной подход предназначен для SDK без такого вспомогательного средства или для случаев, когда вы хотите полностью контролировать сборку входных данных.
Контракт накопления:
- При
content_block_startсtype: "tool_use"инициализируйте пустую строку:input_json = "" - Для каждого
content_block_deltaсtype: "input_json_delta"добавляйте:input_json += event.delta.partial_json - При
content_block_stopразберите накопленную строку
Защищайте разбор от ошибок, как это делается в следующих примерах SDK. Ответ также может остановиться на max_tokens посреди параметра. Проверьте причину остановки и решите, повторить ли запрос с большим значением max_tokens или восстановить частичные входные данные.
Несоответствие типов между начальным input: {} (объект) и partial_json (строка) предусмотрено намеренно. Пустой объект обозначает позицию в массиве содержимого. Строки дельт формируют реальное значение.
client = anthropic.Anthropic()
tool_inputs: dict[int, str] = {} # index -> accumulated JSON string
with client.messages.stream(
model="claude-opus-5-5",
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:
# Не гарантируется, что накопленная строка является допустимым JSON.
# См. раздел «Handling invalid JSON in tool responses» на этой странице.
print(f"Invalid tool input: {raw_input}")
else:
print(f"Tool input: {parsed}")Обработка невалидного JSON в ответах инструментов
При детализированной потоковой передаче инструментов накопленные входные данные для вызова инструмента могут оказаться невалидным или неполным JSON. В этом случае вы не можете запустить инструмент, поэтому вместо этого сообщите о сбое обратно Claude. Поле content результата инструмента не обязано быть JSON, но обёртывание необработанной строки в объект JSON под единственным ключом однозначно даёт Claude понять, что вы получили невалидный JSON, и сохраняет исходные входные данные для отладки:
{
"INVALID_JSON": "<the unparseable input you received>"
}Верните обёртку, сериализованную в строку, в качестве content блока содержимого результата инструмента с is_error, установленным в true:
{
"type": "tool_result",
"tool_use_id": "toolu_01A09q90qw90lq917835lq9",
"is_error": true,
"content": "{\"INVALID_JSON\": \"<the unparseable input you received>\"}"
}Следующие шаги
Узнайте, как работает контекстное окно, как расширенные размышления и использование инструментов учитываются в нём и как управлять контекстом по мере роста диалогов.
Получайте ответы Messages API потоком по частям с помощью server-sent events, включая дельты текста, использования инструментов и расширенных размышлений.
Разбирайте блоки tool_use, форматируйте ответы tool_result и обрабатывайте ошибки с помощью is_error.
Каталог инструментов, предоставляемых Anthropic, и справочник по необязательным свойствам определения инструментов.
Was this page helpful?