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.6Guía de migraciónModelos deprecadosPrecios
    Crear con Claude
    Descripción general de característicasUsar la API de MessagesManejar razones de paradaMejores prácticas de prompting
    Gestión de contexto
    Ventanas de contextoCompactaciónEdición de contexto
    Capacidades
    Almacenamiento en caché de promptsPensamiento extendidoPensamiento adaptativoEsfuerzoStreaming 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ácticasSkills para empresasUsar 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 a Claude un rol (prompts del sistema)Encadenar 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 APIResidencia de datosEspacios de trabajoAPI de uso y costosAPI de Claude Code AnalyticsRetención de datos cero
    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
    Crear con Claude

    Manejo de razones de parada

    Aprende a interpretar y manejar los valores de stop_reason en las respuestas de la API de Mensajes de Claude para construir aplicaciones más robustas.

    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": "Aquí está la respuesta a tu pregunta..."
        }
      ],
      "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 manera natural.

    if response.stop_reason == "end_turn":
        # Procesar 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 sucede 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, así que termina su turno para seguir el patrón)
    • Enviar la respuesta completada de Claude sin agregar nada (Claude ya decidió que está hecho, así que permanecerá hecho)

    Cómo prevenir respuestas vacías:

    # INCORRECTO: Agregar texto inmediatamente después de tool_result
    messages = [
        {"role": "user", "content": "Calcula la suma de 1234 y 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": "Aquí está el resultado"  # No agregues texto después de tool_result
            }
        ]}
    ]
    
    # CORRECTO: Enviar resultados de herramientas directamente sin texto adicional
    messages = [
        {"role": "user", "content": "Calcula la suma de 1234 y 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-opus-4-6",
            max_tokens=1024,
            messages=messages
        )
    
        # Verificar 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: Agregar un mensaje de continuación en un NUEVO mensaje de usuario
            messages.append({"role": "user", "content": "Por favor continúa"})
    
            response = client.messages.create(
                model="claude-opus-4-6",
                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. Usar 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-opus-4-6",
        max_tokens=10,
        messages=[{"role": "user", "content": "Explica la física cuántica"}]
    )
    
    if response.stop_reason == "max_tokens":
        # La respuesta fue truncada
        print("La respuesta fue cortada en el límite de tokens")
        # Considera hacer otra solicitud para continuar

    stop_sequence

    Claude encontró una de tus secuencias de parada personalizadas.

    response = client.messages.create(
        model="claude-opus-4-6",
        max_tokens=1024,
        stop_sequences=["END", "STOP"],
        messages=[{"role": "user", "content": "Genera texto hasta que digas END"}]
    )
    
    if response.stop_reason == "stop_sequence":
        print(f"Parado en la secuencia: {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-opus-4-6",
        max_tokens=1024,
        tools=[weather_tool],
        messages=[{"role": "user", "content": "¿Cuál es el clima?"}]
    )
    
    if response.stop_reason == "tool_use":
        # Extraer y ejecutar la herramienta
        for content in response.content:
            if content.type == "tool_use":
                result = execute_tool(content.name, content.input)
                # Devolver resultado a Claude para la respuesta final

    pause_turn

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

    response = client.messages.create(
        model="claude-opus-4-6",
        max_tokens=1024,
        tools=[{"type": "web_search_20250305", "name": "web_search"}],
        messages=[{"role": "user", "content": "Busca las últimas noticias de IA"}]
    )
    
    if response.stop_reason == "pause_turn":
        # Continuar la conversación
        messages = [
            {"role": "user", "content": original_query},
            {"role": "assistant", "content": response.content}
        ]
        continuation = client.messages.create(
            model="claude-opus-4-6",
            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-opus-4-6",
        max_tokens=1024,
        messages=[{"role": "user", "content": "[Solicitud insegura]"}]
    )
    
    if response.stop_reason == "refusal":
        # Claude se negó a responder
        print("Claude no pudo procesar esta solicitud")
        # 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 de API para usar Sonnet 4 (claude-sonnet-4-20250514), que tiene restricciones de uso diferentes. Aprende más sobre entender los filtros de seguridad de API de Sonnet 4.5.

    Para aprender más sobre rechazos desencadenados por filtros de seguridad de API para Claude Sonnet 4.5, consulta Entender los Filtros de Seguridad de 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 la mayor cantidad posible
    response = client.messages.create(
        model="claude-opus-4-6",
        max_tokens=64000,  # Tokens de salida máximos del modelo
        messages=[{"role": "user", "content": "Entrada grande que usa la mayoría de la ventana de contexto..."}]
    )
    
    if response.stop_reason == "model_context_window_exceeded":
        # La respuesta alcanzó el límite de la ventana de contexto antes de max_tokens
        print("La respuesta alcanzó el límite de la ventana de contexto del modelo")
        # 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:
            # Manejar end_turn y otros casos
            return response.content[0].text

    2. Manejar 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: Advertir al usuario sobre el límite específico
            if response.stop_reason == "max_tokens":
                message = "[Respuesta truncada debido al límite de max_tokens]"
            else:
                message = "[Respuesta truncada debido al límite de la ventana de contexto]"
            return f"{response.content[0].text}\n\n{message}"
    
            # Opción 2: Continuar la generación
            messages = [
                {"role": "user", "content": original_prompt},
                {"role": "assistant", "content": response.content[0].text}
            ]
            continuation = client.messages.create(
                model="claude-opus-4-6",
                max_tokens=1024,
                messages=messages + [{"role": "user", "content": "Por favor continúa"}]
            )
            return response.content[0].text + continuation.content[0].text

    3. Implementar lógica de reintento para pause_turn

    Para herramientas de 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-opus-4-6",
                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(...)
        
        # Manejar respuesta exitosa con stop_reason
        if response.stop_reason == "max_tokens":
            print("La respuesta fue truncada")
        
    except anthropic.APIError as e:
        # Manejar errores reales
        if e.status_code == 429:
            print("Límite de velocidad excedido")
        elif e.status_code == 500:
            print("Error del servidor")

    Consideraciones de streaming

    Cuando se usa streaming, 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"El stream terminó con: {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-opus-4-6",
                messages=messages,
                tools=tools
            )
    
            if response.stop_reason == "tool_use":
                # Ejecutar herramientas y continuar
                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-opus-4-6",
                messages=messages,
                max_tokens=4096
            )
    
            full_response += response.content[0].text
    
            if response.stop_reason != "max_tokens":
                break
    
            # Continuar desde donde se quedó
            messages = [
                {"role": "user", "content": prompt},
                {"role": "assistant", "content": full_response},
                {"role": "user", "content": "Por favor continúa desde donde te quedaste."}
            ]
    
        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 conteo de tokens de entrada:

    def get_max_possible_tokens(client, prompt):
        """
        Obtener la mayor cantidad de tokens posibles dentro de la ventana de contexto del modelo
        sin necesidad de calcular el conteo de tokens de entrada
        """
        response = client.messages.create(
            model="claude-opus-4-6",
            messages=[{"role": "user", "content": prompt}],
            max_tokens=64000  # Establecer 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"Se generaron {response.usage.output_tokens} tokens (límite de contexto alcanzado)")
        elif response.stop_reason == "max_tokens":
            # Obtuviste exactamente los tokens solicitados
            print(f"Se generaron {response.usage.output_tokens} tokens (max_tokens alcanzado)")
        else:
            # Finalización natural
            print(f"Se generaron {response.usage.output_tokens} tokens (finalización natural)")
    
        return response.content[0].text

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

    Was this page helpful?

    • ¿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. Manejar respuestas truncadas con elegancia
    • 3. Implementar lógica de reintento para pause_turn
    • Razones de parada vs. errores
    • Razones de parada (respuestas exitosas)
    • Errores (solicitudes fallidas)
    • Consideraciones de streaming
    • 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