Al crear un Mensaje, puedes establecer "stream": true
para transmitir la respuesta de forma incremental usando eventos enviados por el servidor (SSE).
Streaming con SDKs
Nuestros SDKs de Python y TypeScript ofrecen múltiples formas de streaming. El SDK de Python permite streams tanto síncronos como asíncronos. Consulta la documentación en cada SDK para más detalles.
Tipos de eventos
Cada evento enviado por el servidor incluye un tipo de evento nombrado y datos JSON asociados. Cada evento utilizará un nombre de evento SSE (por ejemplo, event: message_stop
), e incluirá el type
de evento correspondiente en sus datos.
Cada stream utiliza el siguiente flujo de eventos:
message_start
: contiene un objeto Message
con content
vacío.
- Una serie de bloques de contenido, cada uno de los cuales tiene un
content_block_start
, uno o más eventos content_block_delta
, y un evento content_block_stop
. Cada bloque de contenido tendrá un index
que corresponde a su índice en el array final de content
del Mensaje.
- Uno o más eventos
message_delta
, indicando cambios de nivel superior en el objeto Message
final.
- Un evento final
message_stop
.
Eventos ping
Los streams de eventos también pueden incluir cualquier número de eventos ping
.
Eventos de error
Ocasionalmente podemos enviar errores en el stream de eventos. Por ejemplo, durante períodos de alto uso, puedes recibir un overloaded_error
, que normalmente correspondería a un HTTP 529 en un contexto sin streaming:
Otros eventos
De acuerdo con nuestra política de versionado, podemos agregar nuevos tipos de eventos, y tu código debe manejar los tipos de eventos desconocidos de manera elegante.
Tipos de delta
Cada evento content_block_delta
contiene un delta
de un tipo que actualiza el bloque de content
en un index
dado.
Delta de texto
Un delta de bloque de contenido text
se ve así:
Delta de JSON de entrada
Los deltas para bloques de contenido tool_use
corresponden a actualizaciones para el campo input
del bloque. Para admitir la máxima granularidad, los deltas son cadenas JSON parciales, mientras que el tool_use.input
final es siempre un objeto.
Puedes acumular los deltas de cadena y analizar el JSON una vez que recibas un evento content_block_stop
, usando una biblioteca como Pydantic para hacer análisis JSON parcial, o usando nuestros SDKs, que proporcionan ayudantes para acceder a valores incrementales analizados.
Un delta de bloque de contenido tool_use
se ve así:
Nota: Nuestros modelos actuales solo admiten la emisión de una propiedad completa de clave y valor de input
a la vez. Por lo tanto, al usar herramientas, puede haber retrasos entre los eventos de streaming mientras el modelo está trabajando. Una vez que se acumulan una clave y valor de input
, los emitimos como múltiples eventos content_block_delta
con JSON parcial fragmentado para que el formato pueda admitir automáticamente una granularidad más fina en futuros modelos.
Delta de pensamiento
Cuando se usa pensamiento extendido con streaming habilitado, recibirás contenido de pensamiento a través de eventos thinking_delta
. Estos deltas corresponden al campo thinking
de los bloques de contenido thinking
.
Para el contenido de pensamiento, se envía un evento especial signature_delta
justo antes del evento content_block_stop
. Esta firma se usa para verificar la integridad del bloque de pensamiento.
Un delta de pensamiento típico se ve así:
El delta de firma se ve así:
Respuesta HTTP Stream sin procesar
Recomendamos encarecidamente que uses nuestros SDKs de cliente cuando uses el modo streaming. Sin embargo, si estás construyendo una integración directa con la API, necesitarás manejar estos eventos por tu cuenta.
Una respuesta de stream está compuesta por:
- Un evento
message_start
- Potencialmente múltiples bloques de contenido, cada uno de los cuales contiene:
a. Un evento
content_block_start
b. Potencialmente múltiples eventos content_block_delta
c. Un evento content_block_stop
- Un evento
message_delta
- Un evento
message_stop
También puede haber eventos ping
dispersos a lo largo de la respuesta. Consulta Tipos de eventos para más detalles sobre el formato.
Solicitud básica de streaming
Solicitud de streaming con uso de herramientas
En esta solicitud, le pedimos a Claude que use una herramienta para decirnos el clima.
event: message_start
data: {"type":"message_start","message":{"id":"msg_014p7gG3wDgGV9EUtLvnow3U","type":"message","role":"assistant","model":"claude-3-haiku-20240307","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"}
Solicitud de streaming con pensamiento extendido
En esta solicitud, habilitamos el pensamiento extendido con streaming para ver el razonamiento paso a paso de Claude.
event: message_start
data: {"type": "message_start", "message": {"id": "msg_01...", "type": "message", "role": "assistant", "content": [], "model": "claude-3-7-sonnet-20250219", "stop_reason": null, "stop_sequence": null}}
event: content_block_start
data: {"type": "content_block_start", "index": 0, "content_block": {"type": "thinking", "thinking": ""}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "Let me solve this step by step:\n\n1. First break down 27 * 453"}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n2. 453 = 400 + 50 + 3"}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n3. 27 * 400 = 10,800"}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n4. 27 * 50 = 1,350"}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n5. 27 * 3 = 81"}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n6. 10,800 + 1,350 + 81 = 12,231"}}
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": "27 * 453 = 12,231"}}
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"}