Loading...
    • Construir
    • Admin
    • Modelos y precios
    • SDKs de cliente
    • Referencia de API
    Search...
    ⌘K
    Primeros pasos
    Introducción a ClaudeInicio rápido
    Construir con Claude
    Descripción general de característicasUso de Messages APIHabilidad Claude APIManejo de razones de parada
    Capacidades del modelo
    Extended thinkingAdaptive thinkingEsfuerzoPresupuestos de tareas (beta)Modo rápido (beta: vista previa de investigación)Salidas estructuradasCitasStreaming de mensajesProcesamiento por lotesResultados de búsquedaStreaming de rechazosSoporte multilingüeEmbeddings
    Herramientas
    Descripción generalCómo funciona el uso de herramientasHerramienta de búsqueda webHerramienta de obtención webHerramienta de ejecución de códigoHerramienta de asesorHerramienta de memoriaHerramienta BashHerramienta de uso de computadoraHerramienta de editor de texto
    Infraestructura de herramientas
    Referencia de herramientasBúsqueda de herramientasLlamada de herramientas programáticaStreaming de herramientas de grano fino
    Gestión de contexto
    Ventanas de contextoCompactaciónEdición de contextoAlmacenamiento en caché de promptsConteo de tokens
    Trabajar con archivos
    Files APISoporte de PDFImágenes y visión
    Habilidades
    Descripción generalInicio rápidoMejores prácticasHabilidades para empresasHabilidades en la API
    MCP
    Servidores MCP remotosConector MCP
    Ingeniería de prompts
    Descripción generalMejores prácticas de promptingHerramientas de prompting en Console
    Probar y evaluar
    Definir éxito y construir evaluacionesUsar la herramienta de evaluación en ConsoleReducir latencia
    Fortalecer barreras de seguridad
    Reducir alucinacionesAumentar consistencia de salidaMitigar jailbreaksReducir fuga de prompts
    Recursos
    Glosario
    Notas de la versión
    Claude Platform
    Console
    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
    Capacidades del modelo

    Transmisión de Mensajes

    Cómo transmitir respuestas de mensajes de forma incremental usando eventos enviados por el servidor

    Was this page helpful?

    • Transmisión con SDKs
    • Obtener el mensaje final sin manejar eventos
    • Tipos de eventos
    • Eventos ping
    • Eventos de error
    • Otros eventos
    • Tipos de delta de bloque de contenido
    • Delta de texto
    • Delta JSON de entrada
    • Delta de pensamiento
    • Respuesta de flujo HTTP completo
    • Solicitud de transmisión básica
    • Solicitud de streaming con uso de herramientas
    • Solicitud de streaming con pensamiento extendido
    • Solicitud de streaming con uso de herramienta de búsqueda web
    • Recuperación de errores
    • Claude 4.5 y anteriores
    • Claude 4.6
    • Mejores prácticas de recuperación de errores

    Al crear un Mensaje, puedes establecer "stream": true para transmitir la respuesta de forma incremental usando eventos enviados por el servidor (SSE).

    Transmisión con SDKs

    Los SDKs de Python y TypeScript ofrecen múltiples formas de transmisión. El SDK de PHP proporciona transmisión a través de createStream(). El SDK de Python permite tanto transmisiones síncronas como asincrónicas. Consulta la documentación en cada SDK para obtener más detalles.

    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)

    Obtener el mensaje final sin manejar eventos

    Si no necesitas procesar el texto a medida que llega, los SDKs proporcionan una forma de usar la transmisión bajo el capó mientras devuelven el objeto Message completo, idéntico a lo que devuelve .create(). Esto es especialmente útil para solicitudes con valores grandes de max_tokens, donde los SDKs requieren transmisión para evitar tiempos de espera HTTP.

    La llamada .stream() mantiene la conexión HTTP activa con eventos enviados por el servidor, luego .get_final_message() (Python) o .finalMessage() (TypeScript) acumula todos los eventos y devuelve el objeto Message completo. En Go, llamas a message.Accumulate(event) dentro del bucle de transmisión para construir el mismo Message completo. En Java, usa MessageAccumulator.create() y llama a accumulator.accumulate(event) en cada evento. En Ruby, llama a .accumulated_message en la transmisión. En el SDK de PHP, iteras sobre los eventos de transmisión manualmente para acumular la respuesta.

    Tipos de eventos

    Cada evento enviado por el servidor incluye un tipo de evento nombrado y datos JSON asociados. Cada evento usa un nombre de evento SSE (por ejemplo, event: message_stop), e incluye el type de evento coincidente en sus datos.

    Cada transmisión utiliza el siguiente flujo de eventos:

    1. message_start: contiene un objeto Message con content vacío.
    2. Una serie de bloques de contenido, cada uno de los cuales tiene un evento content_block_start, uno o más eventos content_block_delta, y un evento content_block_stop. Cada bloque de contenido tiene un index que corresponde a su índice en el array content del Mensaje final.
    3. Uno o más eventos message_delta, indicando cambios de nivel superior al objeto Message final.
    4. Un evento message_stop final.

    Los recuentos de tokens mostrados en el campo usage del evento message_delta son acumulativos.

    Eventos ping

    Los flujos de eventos también pueden incluir cualquier número de eventos ping.

    Eventos de error

    La API ocasionalmente puede enviar errores en el flujo 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 transmisión:

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

    Otros eventos

    De conformidad con la política de versionado, se pueden agregar nuevos tipos de eventos, y tu código debe manejar tipos de eventos desconocidos con elegancia.

    Tipos de delta de bloque de contenido

    Cada evento content_block_delta contiene un delta de un tipo que actualiza el bloque content en un index dado.

    Delta de texto

    Un delta de bloque de contenido text se ve así:

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

    Delta JSON de entrada

    Los deltas para bloques de contenido tool_use corresponden a actualizaciones para el campo input del bloque. Para soportar 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 parcial de JSON, o usando los SDKs, que proporcionan ayudantes para acceder a valores incrementales analizados.

    Un delta de bloque de contenido tool_use se ve así:

    Input JSON delta
    event: content_block_delta
    data: {"type": "content_block_delta","index": 1,"delta": {"type": "input_json_delta","partial_json": "{\"location\": \"San Fra"}}

    Nota: Los modelos actuales solo soportan emitir una propiedad de clave y valor completa de input a la vez. Como tal, cuando se usan herramientas, puede haber retrasos entre eventos de transmisión mientras el modelo está trabajando. Una vez que se acumula una clave y valor de input, se emiten como múltiples eventos content_block_delta con json parcial fragmentado para que el formato pueda soportar automáticamente una granularidad más fina en modelos futuros.

    Delta de pensamiento

    Cuando se usa pensamiento extendido con transmisión habilitada, 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 contenido de pensamiento, se envía un evento signature_delta especial justo antes del evento content_block_stop. Esta firma se usa para verificar la integridad del bloque de pensamiento.

    Cuando se establece display: "omitted" en la configuración de pensamiento, no se envían eventos thinking_delta. El bloque de pensamiento se abre, recibe un único signature_delta, y se cierra. Consulta Controlando la visualización del pensamiento.

    Un delta de pensamiento típico se ve así:

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

    El delta de firma se ve así:

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

    Respuesta de flujo HTTP completo

    Usa los SDKs de cliente cuando uses el modo de transmisión. Sin embargo, si estás construyendo una integración directa de API, necesitas manejar estos eventos tú mismo.

    Una respuesta de transmisión se compone de:

    1. Un evento message_start
    2. Potencialmente múltiples bloques de contenido, cada uno de los cuales contiene:
      • Un evento content_block_start
      • Potencialmente múltiples eventos content_block_delta
      • Un evento content_block_stop
    3. Un evento message_delta
    4. 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 de transmisión básica

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

    Solicitud de streaming con uso de herramientas

    El uso de herramientas admite streaming de grano fino para valores de parámetros. Habilítalo por herramienta con eager_input_streaming.

    Esta solicitud le pide a Claude que use una herramienta para reportar el clima.

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

    Solicitud de streaming con pensamiento extendido

    Esta solicitud habilita el pensamiento extendido con streaming para ver el razonamiento paso a paso de 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"}

    Solicitud de streaming con uso de herramienta de búsqueda web

    Esta solicitud le pide a Claude que busque en la web información actual del clima.

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

    Recuperación de errores

    Claude 4.5 y anteriores

    Para los modelos Claude 4.5 y anteriores, puedes recuperar una solicitud de streaming que fue interrumpida debido a problemas de red, tiempos de espera agotados u otros errores reanudando desde donde se interrumpió el stream. Este enfoque te ahorra reprocesar toda la respuesta.

    La estrategia básica de recuperación implica:

    1. Capturar la respuesta parcial: Guarda todo el contenido que fue recibido exitosamente antes de que ocurriera el error
    2. Construir una solicitud de continuación: Crea una nueva solicitud de API que incluya la respuesta parcial del asistente como el comienzo de un nuevo mensaje del asistente
    3. Reanudar el streaming: Continúa recibiendo el resto de la respuesta desde donde fue interrumpida

    Claude 4.6

    Para los modelos Claude 4.6, debes agregar un mensaje de usuario que instruya al modelo que continúe desde donde se quedó. Por ejemplo:

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

    Mejores prácticas de recuperación de errores

    1. Usa características del SDK: Aprovecha las capacidades integradas del SDK para acumulación de mensajes y manejo de errores
    2. Maneja tipos de contenido: Ten en cuenta que los mensajes pueden contener múltiples bloques de contenido (text, tool_use, thinking). Los bloques de uso de herramientas y pensamiento extendido no pueden recuperarse parcialmente. Puedes reanudar el streaming desde el bloque de texto más reciente.
    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)