Loading...
  • Разработка
  • Администрирование
  • Модели и цены
  • Клиентские SDK
  • Справочник API
Search...
⌘K
Log in
Потоковые сообщения
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...

Solutions

  • AI agents
  • Code modernization
  • Coding
  • Customer support
  • Education
  • Financial services
  • Government
  • Life sciences

Partners

  • Amazon Bedrock
  • Google Cloud's Vertex AI

Learn

  • Blog
  • Courses
  • Use cases
  • Connectors
  • Customer stories
  • Engineering at Anthropic
  • Events
  • Powered by Claude
  • Service partners
  • Startups program

Company

  • Anthropic
  • Careers
  • Economic Futures
  • Research
  • News
  • Responsible Scaling Policy
  • Security and compliance
  • Transparency

Learn

  • Blog
  • Courses
  • Use cases
  • Connectors
  • Customer stories
  • Engineering at Anthropic
  • Events
  • Powered by Claude
  • Service partners
  • Startups program

Help and security

  • Availability
  • Status
  • Support
  • Discord

Terms and policies

  • Privacy policy
  • Responsible disclosure policy
  • Terms of service: Commercial
  • Terms of service: Consumer
  • Usage policy
Разработка/Возможности модели

Потоковая передача сообщений

Узнайте, как использовать потоковую передачу для получения ответов в реальном времени с помощью server-sent events (SSE).

Was this page helpful?

  • Потоковая передача с помощью SDK
  • Получение финального сообщения без обработки событий
  • Типы событий
  • События ping
  • События ошибок
  • Другие события
  • Типы дельта блоков контента
  • Текстовая дельта
  • Дельта входного JSON
  • Дельта мышления
  • Полный ответ потока HTTP
  • Базовый запрос потоковой передачи
  • Потоковый запрос с использованием инструментов
  • Потоковый запрос с расширенным мышлением
  • Потоковый запрос с использованием инструмента веб-поиска
  • Восстановление после ошибок
  • Claude 4.5 и более ранние версии
  • Claude 4.6
  • Лучшие практики восстановления после ошибок

При создании сообщения вы можете установить "stream": true для постепенной потоковой передачи ответа с использованием server-sent events (SSE).

Потоковая передача с помощью SDK

Python и TypeScript SDK предлагают несколько способов потоковой передачи. PHP SDK обеспечивает потоковую передачу через createStream(). Python SDK поддерживает как синхронные, так и асинхронные потоки. Подробнее см. в документации каждого SDK.

client = anthropic.Anthropic()

with client.messages.stream(
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello"}],
    model="claude-opus-4-7",
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

Получение финального сообщения без обработки событий

Если вам не нужно обрабатывать текст по мере его поступления, SDK предоставляют способ использовать потоковую передачу под капотом, возвращая при этом полный объект Message, идентичный тому, что возвращает .create(). Это особенно полезно для запросов с большими значениями max_tokens, где SDK требуют потоковой передачи, чтобы избежать тайм-аутов HTTP.

Вызов .stream() поддерживает HTTP-соединение в живом состоянии с помощью server-sent events, затем .get_final_message() (Python) или .finalMessage() (TypeScript) накапливает все события и возвращает полный объект Message. В Go вы вызываете message.Accumulate(event) внутри цикла потока для построения того же полного Message. В Java используйте MessageAccumulator.create() и вызывайте accumulator.accumulate(event) для каждого события. В Ruby вызовите .accumulated_message на потоке. В PHP SDK вы вручную перебираете события потока для накопления ответа.

Типы событий

Каждое server-sent событие включает именованный тип события и связанные данные JSON. Каждое событие использует имя события SSE (например, event: message_stop) и включает соответствующий type события в своих данных.

Каждый поток использует следующий поток событий:

  1. message_start: содержит объект Message с пустым content.
  2. Серия блоков контента, каждый из которых имеет событие content_block_start, одно или несколько событий content_block_delta и событие content_block_stop. Каждый блок контента имеет index, который соответствует его индексу в массиве content финального сообщения.
  3. Одно или несколько событий message_delta, указывающих на изменения верхнего уровня в финальном объекте Message.
  4. Финальное событие message_stop.

Подсчеты токенов, показанные в поле usage события message_delta, являются кумулятивными.

События ping

Потоки событий также могут включать любое количество событий ping.

События ошибок

API может иногда отправлять ошибки в потоке событий. Например, в периоды высокой нагрузки вы можете получить overloaded_error, который обычно соответствует HTTP 529 в контексте без потоковой передачи:

Example error
event: error
data: {"type": "error", "error": {"type": "overloaded_error", "message": "Overloaded"}}

Другие события

В соответствии с политикой версионирования могут быть добавлены новые типы событий, и ваш код должен корректно обрабатывать неизвестные типы событий.

Типы дельта блоков контента

Каждое событие content_block_delta содержит delta типа, который обновляет блок content с заданным index.

Текстовая дельта

Дельта блока контента text выглядит следующим образом:

Text delta
event: content_block_delta
data: {"type": "content_block_delta","index": 0,"delta": {"type": "text_delta", "text": "ello frien"}}

Дельта входного JSON

Дельты для блоков контента tool_use соответствуют обновлениям поля input блока. Для поддержки максимальной детализации дельты являются частичными JSON-строками, тогда как финальный tool_use.input всегда является объектом.

Вы можете накапливать строковые дельты и анализировать JSON после получения события content_block_stop, используя библиотеку, такую как Pydantic, для выполнения частичного анализа JSON, или используя SDK, которые предоставляют вспомогательные функции для доступа к проанализированным пошаговым значениям.

Дельта блока контента tool_use выглядит следующим образом:

Input JSON delta
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 и закрывается. См. Управление отображением мышления.

Типичная дельта мышления выглядит следующим образом:

Thinking 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"}}

Дельта подписи выглядит следующим образом:

Signature delta
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "signature_delta", "signature": "EqQBCgIYAhIM1gbcDa9GJwZA2b3hGgxBdjrkzLoky3dl1pkiMOYds..."}}

Полный ответ потока HTTP

Используйте SDK клиента при использовании режима потоковой передачи. Однако, если вы создаете прямую интеграцию API, вам нужно обрабатывать эти события самостоятельно.

Ответ потока состоит из:

  1. События message_start
  2. Потенциально нескольких блоков контента, каждый из которых содержит:
    • Событие content_block_start
    • Потенциально несколько событий content_block_delta
    • Событие content_block_stop
  3. События message_delta
  4. События message_stop

Во всем ответе также могут быть разбросаны события ping. Подробнее см. в разделе Типы событий.

Базовый запрос потоковой передачи

Response
event: message_start
data: {"type": "message_start", "message": {"id": "msg_1nZdL29xx5MUA1yADyHTEsnR8uuvGzszyY", "type": "message", "role": "assistant", "content": [], "model": "claude-opus-4-7", "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 использовать инструмент для сообщения о погоде.

Response
event: message_start
data: {"type":"message_start","message":{"id":"msg_014p7gG3wDgGV9EUtLvnow3U","type":"message","role":"assistant","model":"claude-opus-4-7","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_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":" \"unit\": \"fah"}}

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"renheit\"}"}}

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"}

Потоковый запрос с расширенным мышлением

Этот запрос включает расширенное мышление с потоковой передачей, чтобы увидеть пошаговое рассуждение Claude.

Response
event: message_start
data: {"type": "message_start", "message": {"id": "msg_01...", "type": "message", "role": "assistant", "content": [], "model": "claude-opus-4-7", "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 выполнить поиск в интернете для получения текущей информации о погоде.

Response
event: message_start
data: {"type":"message_start","message":{"id":"msg_01G...","type":"message","role":"assistant","model":"claude-opus-4-7","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.5 и более ранних версий вы можете восстановить потоковый запрос, который был прерван из-за проблем с сетью, истечения времени ожидания или других ошибок, возобновив работу с того места, где поток был прерван. Этот подход позволяет вам избежать повторной обработки всего ответа.

Базовая стратегия восстановления включает:

  1. Захватите частичный ответ: Сохраните всё содержимое, которое было успешно получено до возникновения ошибки
  2. Составьте запрос на продолжение: Создайте новый запрос API, который включает частичный ответ ассистента в качестве начала нового сообщения ассистента
  3. Возобновите потоковую передачу: Продолжайте получать остальную часть ответа с того места, где он был прерван

Claude 4.6

Для моделей Claude 4.6 вы должны добавить сообщение пользователя, которое инструктирует модель продолжить с того места, где она остановилась. Например:

Sample prompt
Your previous response was interrupted and ended with [previous_response]. Continue from where you left off.

Лучшие практики восстановления после ошибок

  1. Используйте функции SDK: Используйте встроенные возможности SDK для накопления сообщений и обработки ошибок
  2. Обрабатывайте типы содержимого: Помните, что сообщения могут содержать несколько блоков содержимого (text, tool_use, thinking). Блоки использования инструментов и расширенного мышления не могут быть частично восстановлены. Вы можете возобновить потоковую передачу с самого последнего текстового блока.
client = anthropic.Anthropic()

with client.messages.stream(
    max_tokens=128000,
    messages=[{"role": "user", "content": "Write a detailed analysis..."}],
    model="claude-opus-4-7",
) as stream:
    message = stream.get_final_message()

print(message.content[0].text)
client = anthropic.Anthropic()

with client.messages.stream(
    model="claude-opus-4-7",
    messages=[{"role": "user", "content": "Hello"}],
    max_tokens=256,
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
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-7",
    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)
client = anthropic.Anthropic()

with client.messages.stream(
    model="claude-opus-4-7",
    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)
client = anthropic.Anthropic()

with client.messages.stream(
    model="claude-opus-4-7",
    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)