При создании сообщения (Message) вы можете установить "stream": true, чтобы инкрементально получать ответ с помощью server-sent events (SSE).
SDK для Python и TypeScript предлагают несколько способов потоковой передачи. SDK для PHP предоставляет потоковую передачу через createStream(). Python SDK поддерживает как синхронные, так и асинхронные потоки. Подробности см. в документации каждого SDK.
client = anthropic.Anthropic()
with client.messages.stream(
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
model="claude-opus-4-8",
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)Если вам не нужно обрабатывать текст по мере его поступления, SDK предоставляют способ использовать потоковую передачу «под капотом», возвращая при этом полный объект Message, идентичный тому, что возвращает .create(). Это особенно полезно для запросов с большими значениями max_tokens, где SDK требуют потоковой передачи, чтобы избежать тайм-аутов HTTP.
client = anthropic.Anthropic()
with client.messages.stream(
max_tokens=128000,
messages=[{"role": "user", "content": "Write a detailed analysis..."}],
model="claude-opus-4-8",
) as stream:
message = stream.get_final_message()
print(message.content[0].text)Вызов .stream() поддерживает HTTP-соединение активным с помощью server-sent events, затем .get_final_message() (Python) или .finalMessage() (TypeScript) накапливает все события и возвращает полный объект Message. В Go вы вызываете message.Accumulate(event) внутри цикла потока, чтобы построить такой же полный объект Message. В Java используйте MessageAccumulator.create() и вызывайте accumulator.accumulate(event) для каждого события. В C# используйте await для метода расширения .Aggregate() потока, чтобы получить полный объект Message, или передайте MessageContentAggregator в .CollectAsync(), чтобы агрегировать данные во время обработки событий. В Ruby вызовите .accumulated_message на потоке. В PHP SDK вы итерируете по событиям потока вручную, чтобы накопить ответ.
Каждое событие server-sent event включает именованный тип события и связанные данные JSON. Каждое событие использует имя события SSE (например, event: message_stop) и включает соответствующий type события в своих данных.
Каждый поток использует следующую последовательность событий:
message_start: содержит объект Message с пустым content.content_block_start, одно или несколько событий content_block_delta и событие content_block_stop. Каждый блок контента имеет index, который соответствует его индексу в итоговом массиве content объекта Message. Одно исключение: во время ответов server-side fallback (резервного переключения на стороне сервера) блок контента fallback поступает на каждой границе модели в виде пары content_block_start и content_block_stop без дельт между ними.message_delta, указывающих на изменения верхнего уровня в итоговом объекте Message.message_stop.Счётчики токенов, показанные в поле usage события message_delta, являются кумулятивными.
Потоки событий также могут включать любое количество событий ping.
API может иногда отправлять ошибки в потоке событий. Например, в периоды высокой нагрузки вы можете получить overloaded_error, который в контексте без потоковой передачи обычно соответствовал бы HTTP 529:
event: error
data: {"type": "error", "error": {"type": "overloaded_error", "message": "Overloaded"}}В соответствии с политикой версионирования могут добавляться новые типы событий, и ваш код должен корректно обрабатывать неизвестные типы событий.
Каждое событие content_block_delta содержит delta определённого типа, которая обновляет блок content по заданному index.
Дельта блока контента text выглядит так:
event: content_block_delta
data: {"type": "content_block_delta","index": 0,"delta": {"type": "text_delta", "text": "ello frien"}}Дельты для блоков контента tool_use соответствуют обновлениям поля input блока. Для поддержки максимальной гранулярности дельты представляют собой частичные строки JSON, тогда как итоговый tool_use.input всегда является объектом.
Вы можете накапливать строковые дельты и разбирать JSON после получения события content_block_stop, используя библиотеку вроде Pydantic для частичного разбора JSON, или используя SDK, которые предоставляют вспомогательные функции для доступа к разобранным инкрементальным значениям.
Дельта блока контента tool_use выглядит так:
event: content_block_delta
data: {"type": "content_block_delta","index": 1,"delta": {"type": "input_json_delta","partial_json": "{\"location\": \"San Fra"}}}Примечание: текущие модели поддерживают выдачу только одной полной пары ключ-значение из input за раз. Поэтому при использовании инструментов могут возникать задержки между событиями потоковой передачи, пока модель работает. Как только ключ и значение input накоплены, они выдаются в виде нескольких событий content_block_delta с фрагментированным частичным JSON, чтобы формат мог автоматически поддерживать более тонкую гранулярность в будущих моделях.
При использовании расширенного мышления с включённой потоковой передачей вы будете получать контент мышления через события thinking_delta. Эти дельты соответствуют полю thinking блоков контента thinking.
Для контента мышления специальное событие signature_delta отправляется непосредственно перед событием content_block_stop. Эта подпись используется для проверки целостности блока мышления.
Когда в конфигурации мышления установлено display: "omitted", события thinking_delta не отправляются. Блок мышления открывается, получает одно событие signature_delta и закрывается. См. Управление отображением мышления.
Типичная дельта мышления выглядит так:
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "I need to find the GCD of 1071 and 462 using the Euclidean algorithm.\n\n1071 = 2 × 462 + 147"}}Дельта подписи выглядит так:
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "signature_delta", "signature": "EqQBCgIYAhIM1gbcDa9GJwZA2b3hGgxBdjrkzLoky3dl1pkiMOYds..."}}При использовании режима потоковой передачи используйте клиентские SDK. Однако если вы создаёте прямую интеграцию с API, вам нужно обрабатывать эти события самостоятельно.
Ответ потока состоит из:
message_startcontent_block_startcontent_block_deltacontent_block_stopmessage_deltamessage_stopПо всему ответу также могут быть рассредоточены события ping. Подробнее о формате см. в разделе Типы событий.
client = anthropic.Anthropic()
with client.messages.stream(
model="claude-opus-4-8",
messages=[{"role": "user", "content": "Hello"}],
max_tokens=256,
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)event: message_start
data: {"type": "message_start", "message": {"id": "msg_1nZdL29xx5MUA1yADyHTEsnR8uuvGzszyY", "type": "message", "role": "assistant", "content": [], "model": "claude-opus-4-8", "stop_reason": null, "stop_sequence": null, "usage": {"input_tokens": 25, "output_tokens": 1}}}
event: content_block_start
data: {"type": "content_block_start", "index": 0, "content_block": {"type": "text", "text": ""}}
event: ping
data: {"type": "ping"}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "text_delta", "text": "Hello"}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "text_delta", "text": "!"}}
event: content_block_stop
data: {"type": "content_block_stop", "index": 0}
event: message_delta
data: {"type": "message_delta", "delta": {"stop_reason": "end_turn", "stop_sequence":null}, "usage": {"output_tokens": 15}}
event: message_stop
data: {"type": "message_stop"}
Использование инструментов поддерживает детализированную потоковую передачу для значений параметров. Включите её для каждого инструмента с помощью eager_input_streaming.
Этот запрос просит Claude использовать инструмент для сообщения о погоде.
client = anthropic.Anthropic()
tools = [
{
"name": "get_weather",
"description": "Get the current weather in a given location",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA",
}
},
"required": ["location"],
},
}
]
with client.messages.stream(
model="claude-opus-4-8",
max_tokens=1024,
tools=tools,
tool_choice={"type": "any"},
messages=[
{"role": "user", "content": "What is the weather like in San Francisco?"}
],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)event: message_start
data: {"type":"message_start","message":{"id":"msg_014p7gG3wDgGV9EUtLvnow3U","type":"message","role":"assistant","model":"claude-opus-4-8","stop_sequence":null,"usage":{"input_tokens":472,"output_tokens":2},"content":[],"stop_reason":null}}
event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
event: ping
data: {"type": "ping"}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Okay"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":","}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" let"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"'s"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" check"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" the"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" weather"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" for"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" San"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Francisco"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":","}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" CA"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":":"}}
event: content_block_stop
data: {"type":"content_block_stop","index":0}
event: content_block_start
data: {"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"toolu_01T1x1fJ34qAmk2tNTrN7Up6","name":"get_weather","input":{}}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"location\":"}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" \"San"}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" Francisc"}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"o,"}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" CA\"}"}}
event: content_block_stop
data: {"type":"content_block_stop","index":1}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"output_tokens":89}}
event: message_stop
data: {"type":"message_stop"}Этот запрос включает расширенное мышление с потоковой передачей. Настройка display: "summarized" передаёт сжатое резюме рассуждений Claude вместо полной цепочки мыслей.
client = anthropic.Anthropic()
with client.messages.stream(
model="claude-opus-4-8",
max_tokens=20000,
thinking={"type": "adaptive", "display": "summarized"},
messages=[
{
"role": "user",
"content": "What is the greatest common divisor of 1071 and 462?",
}
],
) as stream:
for event in stream:
if event.type == "content_block_delta":
if event.delta.type == "thinking_delta":
print(event.delta.thinking, end="", flush=True)
elif event.delta.type == "text_delta":
print(event.delta.text, end="", flush=True)event: message_start
data: {"type": "message_start", "message": {"id": "msg_01...", "type": "message", "role": "assistant", "content": [], "model": "claude-opus-4-8", "stop_reason": null, "stop_sequence": null}}
event: content_block_start
data: {"type": "content_block_start", "index": 0, "content_block": {"type": "thinking", "thinking": "", "signature": ""}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "I need to find the GCD of 1071 and 462 using the Euclidean algorithm.\n\n1071 = 2 × 462 + 147"}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n462 = 3 × 147 + 21"}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n147 = 7 × 21 + 0"}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\nThe remainder is 0, so GCD(1071, 462) = 21."}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "signature_delta", "signature": "EqQBCgIYAhIM1gbcDa9GJwZA2b3hGgxBdjrkzLoky3dl1pkiMOYds..."}}
event: content_block_stop
data: {"type": "content_block_stop", "index": 0}
event: content_block_start
data: {"type": "content_block_start", "index": 1, "content_block": {"type": "text", "text": ""}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 1, "delta": {"type": "text_delta", "text": "The greatest common divisor of 1071 and 462 is **21**."}}
event: content_block_stop
data: {"type": "content_block_stop", "index": 1}
event: message_delta
data: {"type": "message_delta", "delta": {"stop_reason": "end_turn", "stop_sequence": null}}
event: message_stop
data: {"type": "message_stop"}Этот запрос просит Claude выполнить поиск в интернете для получения актуальной информации о погоде.
client = anthropic.Anthropic()
with client.messages.stream(
model="claude-opus-4-8",
max_tokens=1024,
tools=[{"type": "web_search_20250305", "name": "web_search", "max_uses": 5}],
messages=[
{"role": "user", "content": "What is the weather like in New York City today?"}
],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)event: message_start
data: {"type":"message_start","message":{"id":"msg_01G...","type":"message","role":"assistant","model":"claude-opus-4-8","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":2679,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":3}}}
event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"I'll check"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" the current weather in New York City for you"}}
event: ping
data: {"type": "ping"}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"."}}
event: content_block_stop
data: {"type":"content_block_stop","index":0}
event: content_block_start
data: {"type":"content_block_start","index":1,"content_block":{"type":"server_tool_use","id":"srvtoolu_014hJH82Qum7Td6UV8gDXThB","name":"web_search","input":{}}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"query"}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\":"}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" \"weather"}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" NY"}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"C to"}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"day\"}"}}
event: content_block_stop
data: {"type":"content_block_stop","index":1 }
event: content_block_start
data: {"type":"content_block_start","index":2,"content_block":{"type":"web_search_tool_result","tool_use_id":"srvtoolu_014hJH82Qum7Td6UV8gDXThB","content":[{"type":"web_search_result","title":"Weather in New York City in May 2025 (New York) - detailed Weather Forecast for a month","url":"https://world-weather.info/forecast/usa/new_york/may-2025/","encrypted_content":"Ev0DCioIAxgCIiQ3NmU4ZmI4OC1k...","page_age":null},...]}}
event: content_block_stop
data: {"type":"content_block_stop","index":2}
event: content_block_start
data: {"type":"content_block_start","index":3,"content_block":{"type":"text","text":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":3,"delta":{"type":"text_delta","text":"Here's the current weather information for New York"}}
event: content_block_delta
data: {"type":"content_block_delta","index":3,"delta":{"type":"text_delta","text":" City:\n\n# Weather"}}
event: content_block_delta
data: {"type":"content_block_delta","index":3,"delta":{"type":"text_delta","text":" in New York City"}}
event: content_block_delta
data: {"type":"content_block_delta","index":3,"delta":{"type":"text_delta","text":"\n\n"}}
...
event: content_block_stop
data: {"type":"content_block_stop","index":17}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":10682,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":510,"server_tool_use":{"web_search_requests":1}}}
event: message_stop
data: {"type":"message_stop"}Для моделей Claude 4.5 и более ранних вы можете восстановить запрос с потоковой передачей, который был прерван из-за сетевых проблем, тайм-аутов или других ошибок, возобновив его с того места, где поток был прерван. Этот подход избавляет вас от повторной обработки всего ответа.
Базовая стратегия восстановления включает:
Для моделей Claude 4.6 и более поздних применяется та же стратегия сохранения и возобновления, но шаг 2 меняется: вместо размещения частичного ответа в сообщении ассистента добавьте сообщение пользователя, которое инструктирует модель продолжить с того места, где она остановилась.
Your previous response was interrupted and ended with [previous_response]. Continue from where you left off.text, tool_use, thinking). Блоки использования инструментов и расширенного мышления не могут быть частично восстановлены. Вы можете возобновить потоковую передачу с самого последнего текстового блока.Обрабатывайте каждое значение stop_reason после завершения потока.
Передавайте входной JSON инструментов без буферизации на стороне сервера для снижения задержки.
Передавайте вывод расширенного мышления с помощью событий thinking_delta и signature_delta.
Используйте официальные SDK, которые обрабатывают потоковую передачу, накопление и переподключение за вас.
Обрабатывайте большие объёмы запросов асинхронно, когда вам не нужны ответы в реальном времени.
Was this page helpful?