Loading...
    • Guía para desarrolladores
    • Referencia de API
    • MCP
    • Recursos
    • Notas de la versión
    Search...
    ⌘K
    Primeros pasos
    Introducción a ClaudeInicio rápido
    Modelos y precios
    Descripción general de modelosElegir un modeloNovedades en Claude 4.5Migración a Claude 4.5Deprecación de modelosPrecios
    Construir con Claude
    Descripción general de característicasUsar la API de MessagesVentanas de contextoMejores prácticas de prompting
    Capacidades
    Almacenamiento en caché de promptsEdición de contextoPensamiento extendidoEsfuerzoStreaming de MessagesProcesamiento por lotesCitasSoporte multilingüeConteo de tokensEmbeddingsVisiónSoporte de PDFAPI de FilesResultados de búsquedaSalidas estructuradas
    Herramientas
    Descripción generalCómo implementar el uso de herramientasStreaming de herramientas de grano finoHerramienta BashHerramienta de ejecución de códigoLlamada de herramientas programáticaHerramienta de uso de computadoraHerramienta de editor de textoHerramienta de búsqueda webHerramienta de búsqueda webHerramienta de memoriaHerramienta de búsqueda de herramientas
    Agent Skills
    Descripción generalInicio rápidoMejores prácticasUsar Skills con la API
    Agent SDK
    Descripción generalInicio rápidoSDK de TypeScriptTypeScript V2 (vista previa)SDK de PythonGuía de migración
    MCP en la API
    Conector MCPServidores MCP remotos
    Claude en plataformas de terceros
    Amazon BedrockMicrosoft FoundryVertex AI
    Ingeniería de prompts
    Descripción generalGenerador de promptsUsar plantillas de promptsMejorador de promptsSer claro y directoUsar ejemplos (prompting multishot)Dejar que Claude piense (CoT)Usar etiquetas XMLDar un rol a Claude (prompts del sistema)Rellenar la respuesta de ClaudeEncadenar prompts complejosConsejos de contexto largoConsejos de pensamiento extendido
    Probar y evaluar
    Definir criterios de éxitoDesarrollar casos de pruebaUsar la herramienta de evaluaciónReducir latencia
    Fortalecer protecciones
    Reducir alucinacionesAumentar consistencia de salidaMitigar ataques de jailbreakRechazos de streamingReducir fuga de promptsMantener a Claude en personaje
    Administración y monitoreo
    Descripción general de Admin APIAPI de uso y costoAPI de Claude Code Analytics
    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
    • Catalog
    • 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
    • Catalog
    • 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
    Documentation

    Manejo de razones de parada

    Comprende los valores de stop_reason en las respuestas de la API de Mensajes de Claude y cómo manejarlos correctamente en tus aplicaciones.

    Cuando realizas una solicitud a la API de Mensajes, la respuesta de Claude incluye un campo stop_reason que indica por qué el modelo dejó de generar su respuesta. Comprender estos valores es crucial para construir aplicaciones robustas que manejen diferentes tipos de respuestas de manera apropiada.

    Para obtener detalles sobre stop_reason en la respuesta de la API, consulta la referencia de la API de Mensajes.

    ¿Qué es stop_reason?

    El campo stop_reason es parte de cada respuesta exitosa de la API de Mensajes. A diferencia de los errores, que indican fallos en el procesamiento de tu solicitud, stop_reason te indica por qué Claude completó exitosamente la generación de su respuesta.

    Respuesta de ejemplo
    {
      "id": "msg_01234",
      "type": "message",
      "role": "assistant",
      "content": [
        {
          "type": "text",
          "text": "Here's the answer to your question..."
        }
      ],
      "stop_reason": "end_turn",
      "stop_sequence": null,
      "usage": {
        "input_tokens": 100,
        "output_tokens": 50
      }
    }

    Valores de stop_reason

    end_turn

    La razón de parada más común. Indica que Claude terminó su respuesta de forma natural.

    if response.stop_reason == "end_turn":
        # Procesa la respuesta completa
        print(response.content[0].text)

    Respuestas vacías con end_turn

    A veces Claude devuelve una respuesta vacía (exactamente 2-3 tokens sin contenido) con stop_reason: "end_turn". Esto típicamente ocurre cuando Claude interpreta que el turno del asistente está completo, particularmente después de resultados de herramientas.

    Causas comunes:

    • Agregar bloques de texto inmediatamente después de resultados de herramientas (Claude aprende a esperar que el usuario siempre inserte texto después de resultados de herramientas, por lo que termina su turno para seguir el patrón)
    • Enviar la respuesta completada de Claude sin agregar nada (Claude ya decidió que está hecho, por lo que permanecerá hecho)

    Cómo prevenir respuestas vacías:

    # INCORRECTO: Agregar texto inmediatamente después de tool_result
    messages = [
        {"role": "user", "content": "Calculate the sum of 1234 and 5678"},
        {"role": "assistant", "content": [
            {
                "type": "tool_use",
                "id": "toolu_123",
                "name": "calculator",
                "input": {"operation": "add", "a": 1234, "b": 5678}
            }
        ]},
        {"role": "user", "content": [
            {
                "type": "tool_result",
                "tool_use_id": "toolu_123",
                "content": "6912"
            },
            {
                "type": "text",
                "text": "Here's the result"  # No agregues texto después de tool_result
            }
        ]}
    ]
    
    # CORRECTO: Envía resultados de herramientas directamente sin texto adicional
    messages = [
        {"role": "user", "content": "Calculate the sum of 1234 and 5678"},
        {"role": "assistant", "content": [
            {
                "type": "tool_use",
                "id": "toolu_123",
                "name": "calculator",
                "input": {"operation": "add", "a": 1234, "b": 5678}
            }
        ]},
        {"role": "user", "content": [
            {
                "type": "tool_result",
                "tool_use_id": "toolu_123",
                "content": "6912"
            }
        ]}  # Solo el tool_result, sin texto adicional
    ]
    
    # Si aún obtienes respuestas vacías después de corregir lo anterior:
    def handle_empty_response(client, messages):
        response = client.messages.create(
            model="claude-sonnet-4-20250514",
            max_tokens=1024,
            messages=messages
        )
    
        # Verifica si la respuesta está vacía
        if (response.stop_reason == "end_turn" and
            not response.content):
    
            # INCORRECTO: No simplemente reintentar con la respuesta vacía
            # Esto no funcionará porque Claude ya decidió que está hecho
    
            # CORRECTO: Agrega un mensaje de continuación en un NUEVO mensaje del usuario
            messages.append({"role": "user", "content": "Please continue"})
    
            response = client.messages.create(
                model="claude-sonnet-4-20250514",
                max_tokens=1024,
                messages=messages
            )
    
        return response

    Mejores prácticas:

    1. Nunca agregues bloques de texto inmediatamente después de resultados de herramientas - Esto enseña a Claude a esperar entrada del usuario después de cada uso de herramienta
    2. No reintentar respuestas vacías sin modificación - Simplemente enviar la respuesta vacía de vuelta no ayudará
    3. Usa mensajes de continuación como último recurso - Solo si las correcciones anteriores no resuelven el problema

    max_tokens

    Claude se detuvo porque alcanzó el límite de max_tokens especificado en tu solicitud.

    # Solicitud con tokens limitados
    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=10,
        messages=[{"role": "user", "content": "Explain quantum physics"}]
    )
    
    if response.stop_reason == "max_tokens":
        # La respuesta fue truncada
        print("Response was cut off at token limit")
        # Considera hacer otra solicitud para continuar

    stop_sequence

    Claude encontró una de tus secuencias de parada personalizadas.

    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=1024,
        stop_sequences=["END", "STOP"],
        messages=[{"role": "user", "content": "Generate text until you say END"}]
    )
    
    if response.stop_reason == "stop_sequence":
        print(f"Stopped at sequence: {response.stop_sequence}")

    tool_use

    Claude está llamando a una herramienta y espera que la ejecutes.

    Para la mayoría de implementaciones de uso de herramientas, recomendamos usar el ejecutor de herramientas que maneja automáticamente la ejecución de herramientas, el formato de resultados y la gestión de conversaciones.

    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=1024,
        tools=[weather_tool],
        messages=[{"role": "user", "content": "What's the weather?"}]
    )
    
    if response.stop_reason == "tool_use":
        # Extrae y ejecuta la herramienta
        for content in response.content:
            if content.type == "tool_use":
                result = execute_tool(content.name, content.input)
                # Devuelve el resultado a Claude para la respuesta final

    pause_turn

    Se utiliza con herramientas del servidor como búsqueda web cuando Claude necesita pausar una operación de larga duración.

    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=1024,
        tools=[{"type": "web_search_20250305", "name": "web_search"}],
        messages=[{"role": "user", "content": "Search for latest AI news"}]
    )
    
    if response.stop_reason == "pause_turn":
        # Continúa la conversación
        messages = [
            {"role": "user", "content": original_query},
            {"role": "assistant", "content": response.content}
        ]
        continuation = client.messages.create(
            model="claude-sonnet-4-5",
            messages=messages,
            tools=[{"type": "web_search_20250305", "name": "web_search"}]
        )

    refusal

    Claude se negó a generar una respuesta debido a preocupaciones de seguridad.

    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=1024,
        messages=[{"role": "user", "content": "[Unsafe request]"}]
    )
    
    if response.stop_reason == "refusal":
        # Claude se negó a responder
        print("Claude was unable to process this request")
        # Considera reformular o modificar la solicitud

    Si encuentras razones de parada refusal frecuentemente mientras usas Claude Sonnet 4.5 u Opus 4.1, puedes intentar actualizar tus llamadas a la API para usar Sonnet 4 (claude-sonnet-4-20250514), que tiene restricciones de uso diferentes. Aprende más sobre comprender los filtros de seguridad de la API de Sonnet 4.5.

    Para aprender más sobre rechazos desencadenados por filtros de seguridad de la API para Claude Sonnet 4.5, consulta Comprender los filtros de seguridad de la API de Sonnet 4.5.

    model_context_window_exceeded

    Claude se detuvo porque alcanzó el límite de la ventana de contexto del modelo. Esto te permite solicitar el máximo de tokens posibles sin conocer el tamaño exacto de la entrada.

    # Solicitud con tokens máximos para obtener lo máximo posible
    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=64000,  # Tokens de salida máximos del modelo
        messages=[{"role": "user", "content": "Large input that uses most of context window..."}]
    )
    
    if response.stop_reason == "model_context_window_exceeded":
        # La respuesta alcanzó el límite de la ventana de contexto antes de max_tokens
        print("Response reached model's context window limit")
        # La respuesta sigue siendo válida pero fue limitada por la ventana de contexto

    Esta razón de parada está disponible por defecto en Sonnet 4.5 y modelos más nuevos. Para modelos anteriores, usa el encabezado beta model-context-window-exceeded-2025-08-26 para habilitar este comportamiento.

    Mejores prácticas para manejar razones de parada

    1. Siempre verifica stop_reason

    Acostúmbrate a verificar el stop_reason en tu lógica de manejo de respuestas:

    def handle_response(response):
        if response.stop_reason == "tool_use":
            return handle_tool_use(response)
        elif response.stop_reason == "max_tokens":
            return handle_truncation(response)
        elif response.stop_reason == "model_context_window_exceeded":
            return handle_context_limit(response)
        elif response.stop_reason == "pause_turn":
            return handle_pause(response)
        elif response.stop_reason == "refusal":
            return handle_refusal(response)
        else:
            # Maneja end_turn y otros casos
            return response.content[0].text

    2. Maneja respuestas truncadas con elegancia

    Cuando una respuesta se trunca debido a límites de tokens o ventana de contexto:

    def handle_truncated_response(response):
        if response.stop_reason in ["max_tokens", "model_context_window_exceeded"]:
            # Opción 1: Advierte al usuario sobre el límite específico
            if response.stop_reason == "max_tokens":
                message = "[Response truncated due to max_tokens limit]"
            else:
                message = "[Response truncated due to context window limit]"
            return f"{response.content[0].text}\n\n{message}"
    
            # Opción 2: Continúa la generación
            messages = [
                {"role": "user", "content": original_prompt},
                {"role": "assistant", "content": response.content[0].text}
            ]
            continuation = client.messages.create(
                model="claude-sonnet-4-5",
                max_tokens=1024,
                messages=messages + [{"role": "user", "content": "Please continue"}]
            )
            return response.content[0].text + continuation.content[0].text

    3. Implementa lógica de reintento para pause_turn

    Para herramientas del servidor que pueden pausarse:

    def handle_paused_conversation(initial_response, max_retries=3):
        response = initial_response
        messages = [{"role": "user", "content": original_query}]
        
        for attempt in range(max_retries):
            if response.stop_reason != "pause_turn":
                break
                
            messages.append({"role": "assistant", "content": response.content})
            response = client.messages.create(
                model="claude-sonnet-4-5",
                messages=messages,
                tools=original_tools
            )
        
        return response

    Razones de parada vs. errores

    Es importante distinguir entre valores de stop_reason y errores reales:

    Razones de parada (respuestas exitosas)

    • Parte del cuerpo de la respuesta
    • Indican por qué la generación se detuvo normalmente
    • La respuesta contiene contenido válido

    Errores (solicitudes fallidas)

    • Códigos de estado HTTP 4xx o 5xx
    • Indican fallos en el procesamiento de solicitudes
    • La respuesta contiene detalles del error
    try:
        response = client.messages.create(...)
        
        # Maneja respuesta exitosa con stop_reason
        if response.stop_reason == "max_tokens":
            print("Response was truncated")
        
    except anthropic.APIError as e:
        # Maneja errores reales
        if e.status_code == 429:
            print("Rate limit exceeded")
        elif e.status_code == 500:
            print("Server error")

    Consideraciones de transmisión

    Cuando se usa transmisión, stop_reason es:

    • null en el evento inicial message_start
    • Proporcionado en el evento message_delta
    • No proporcionado en ningún otro evento
    with client.messages.stream(...) as stream:
        for event in stream:
            if event.type == "message_delta":
                stop_reason = event.delta.stop_reason
                if stop_reason:
                    print(f"Stream ended with: {stop_reason}")

    Patrones comunes

    Manejo de flujos de trabajo de uso de herramientas

    Más simple con ejecutor de herramientas: El ejemplo a continuación muestra manejo manual de herramientas. Para la mayoría de casos de uso, el ejecutor de herramientas maneja automáticamente la ejecución de herramientas con mucho menos código.

    def complete_tool_workflow(client, user_query, tools):
        messages = [{"role": "user", "content": user_query}]
    
        while True:
            response = client.messages.create(
                model="claude-sonnet-4-5",
                messages=messages,
                tools=tools
            )
    
            if response.stop_reason == "tool_use":
                # Ejecuta herramientas y continúa
                tool_results = execute_tools(response.content)
                messages.append({"role": "assistant", "content": response.content})
                messages.append({"role": "user", "content": tool_results})
            else:
                # Respuesta final
                return response

    Asegurar respuestas completas

    def get_complete_response(client, prompt, max_attempts=3):
        messages = [{"role": "user", "content": prompt}]
        full_response = ""
    
        for _ in range(max_attempts):
            response = client.messages.create(
                model="claude-sonnet-4-5",
                messages=messages,
                max_tokens=4096
            )
    
            full_response += response.content[0].text
    
            if response.stop_reason != "max_tokens":
                break
    
            # Continúa desde donde se quedó
            messages = [
                {"role": "user", "content": prompt},
                {"role": "assistant", "content": full_response},
                {"role": "user", "content": "Please continue from where you left off."}
            ]
    
        return full_response

    Obtener tokens máximos sin conocer el tamaño de entrada

    Con la razón de parada model_context_window_exceeded, puedes solicitar el máximo de tokens posibles sin calcular el tamaño de entrada:

    def get_max_possible_tokens(client, prompt):
        """
        Obtén tantos tokens como sea posible dentro de la ventana de contexto del modelo
        sin necesidad de calcular el conteo de tokens de entrada
        """
        response = client.messages.create(
            model="claude-sonnet-4-5",
            messages=[{"role": "user", "content": prompt}],
            max_tokens=64000  # Establece a los tokens de salida máximos del modelo
        )
    
        if response.stop_reason == "model_context_window_exceeded":
            # Obtuviste el máximo de tokens posibles dado el tamaño de entrada
            print(f"Generated {response.usage.output_tokens} tokens (context limit reached)")
        elif response.stop_reason == "max_tokens":
            # Obtuviste exactamente los tokens solicitados
            print(f"Generated {response.usage.output_tokens} tokens (max_tokens reached)")
        else:
            # Finalización natural
            print(f"Generated {response.usage.output_tokens} tokens (natural completion)")
    
        return response.content[0].text

    Al manejar correctamente los valores de stop_reason, puedes construir aplicaciones más robustas que manejen con elegancia diferentes escenarios de respuesta y proporcionen mejores experiencias de usuario.

    • ¿Qué es stop_reason?
    • Valores de stop_reason
    • end_turn
    • max_tokens
    • stop_sequence
    • tool_use
    • pause_turn
    • refusal
    • model_context_window_exceeded
    • Mejores prácticas para manejar razones de parada
    • 1. Siempre verifica stop_reason
    • 2. Maneja respuestas truncadas con elegancia
    • 3. Implementa lógica de reintento para pause_turn
    • Razones de parada vs. errores
    • Razones de parada (respuestas exitosas)
    • Errores (solicitudes fallidas)
    • Consideraciones de transmisión
    • Patrones comunes
    • Manejo de flujos de trabajo de uso de herramientas
    • Asegurar respuestas completas
    • Obtener tokens máximos sin conocer el tamaño de entrada