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 estructuradasComplemento de Google Sheets
    Herramientas
    Descripción generalCómo implementar el uso de herramientasUso eficiente de herramientas en tokensStreaming 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
    Habilidades del agente
    Descripción generalInicio rápidoMejores prácticasUsar habilidades con la API
    SDK del agente
    Descripción generalSDK de TypeScriptSDK de PythonGuía de migración
    Guías
    Entrada de streamingManejo de permisosGestión de sesionesSalidas estructuradas en el SDKAlojamiento del SDK del agenteModificar prompts del sistemaMCP en el SDKHerramientas personalizadasSuagentes en el SDKComandos de barra en el SDKHabilidades del agente en el SDKSeguimiento de costos y usoListas de tareasComplementos en el SDK
    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 promptsSé claro y directoUsar ejemplos (prompting multishot)Dejar pensar a Claude (CoT)Usar etiquetas XMLDale 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 costosAPI de análisis de Claude Code
    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

    Aprende cómo manejar las diferentes razones de parada en las respuestas de la API de Messages de Claude para construir aplicaciones más robustas.
    • ¿Qué es stop_reason?
    • Valores de razón de parada
    • 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 verificar stop_reason
    • 2. Manejar respuestas truncadas con gracia
    • 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
    • Manejar flujos de trabajo de uso de herramientas
    • Asegurar respuestas completas
    • Obtener tokens máximos sin conocer el tamaño de entrada

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

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

    ¿Qué es stop_reason?

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

    Example response
    {
      "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 razón de parada

    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 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 de vuelta sin agregar nada (Claude ya decidió que terminó, por lo que permanecerá terminado)

    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-sonnet-4-20250514",
            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 terminó
    
            # CORRECTO: Agregar un prompt de continuación en un NUEVO mensaje de usuario
            messages.append({"role": "user", "content": "Por favor continúa"})
    
            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 reintentes respuestas vacías sin modificación - Simplemente enviar la respuesta vacía de vuelta no ayudará
    3. Usa prompts 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": "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-sonnet-4-5",
        max_tokens=1024,
        stop_sequences=["FIN", "PARAR"],
        messages=[{"role": "user", "content": "Genera texto hasta que digas FIN"}]
    )
    
    if response.stop_reason == "stop_sequence":
        print(f"Se detuvo en la secuencia: {response.stop_sequence}")

    tool_use

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

    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=1024,
        tools=[weather_tool],
        messages=[{"role": "user", "content": "¿Cómo está 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 respuesta final

    pause_turn

    Usado 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-sonnet-4-5",
        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-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": "[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 a la API para usar Sonnet 4 (claude-sonnet-4-20250514), que tiene diferentes restricciones de uso. Aprende más sobre entender los filtros de seguridad de la API de Sonnet 4.5.

    Para aprender más sobre rechazos activados por filtros de seguridad de la API para Claude Sonnet 4.5, consulta Entendiendo 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 tanto como sea posible
    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=64000,  # Tokens máximos de salida del modelo
        messages=[{"role": "user", "content": "Entrada grande que usa la mayor parte 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 verificar stop_reason

    Haz un hábito de 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 gracia

    Cuando una respuesta es truncada 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 ventana de contexto]"
            return f"{response.content[0].text}\n\n{message}"
    
            # Opción 2: Continuar 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": "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 pausar:

    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 fallas 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 tasa excedido")
        elif e.status_code == 500:
            print("Error del servidor")

    Consideraciones de streaming

    Cuando usas 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"Stream terminó con: {stop_reason}")

    Patrones comunes

    Manejar flujos de trabajo de uso de herramientas

    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":
                # 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-sonnet-4-5",
                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 tamaño de entrada:

    def get_max_possible_tokens(client, prompt):
        """
        Obtener 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  # Establecer a los tokens máximos de salida del modelo
        )
    
        if response.stop_reason == "model_context_window_exceeded":
            # Obtuvo el máximo de tokens posibles dado el tamaño de entrada
            print(f"Generó {response.usage.output_tokens} tokens (límite de contexto alcanzado)")
        elif response.stop_reason == "max_tokens":
            # Obtuvo exactamente los tokens solicitados
            print(f"Generó {response.usage.output_tokens} tokens (max_tokens alcanzado)")
        else:
            # Completación natural
            print(f"Generó {response.usage.output_tokens} tokens (completación natural)")
    
        return response.content[0].text

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