Claude Platform Docs
  • Mensajes
  • Agentes gestionados
  • Administración

Search...
⌘K
Primeros pasos
Introducción a ClaudeInicio rápido
Desarrollar con Claude
Descripción general de funcionesUso de la API de MensajesMotivos de detención y respaldoRechazos y respaldoCrédito de respaldo
Capacidades del modelo
Pensamiento extendidoPensamiento adaptativoEsfuerzoPresupuestos de tareas (beta)Modo rápido (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 herramientasTutorial: Crear un agente que usa herramientasDefinir herramientasGestionar llamadas a herramientasUso de herramientas en paraleloTool Runner (SDK)Uso de herramientas estrictoHerramientas de servidorHerramienta de búsqueda webHerramienta de obtención webHerramienta de ejecución de códigoHerramienta de asesorHerramienta de búsqueda de herramientasHerramienta de memoriaHerramienta BashHerramienta de editor de textoHerramienta de uso de computadoraSolución de problemas
Infraestructura de herramientas
Referencia de herramientasGestionar el contexto de herramientasCombinaciones de herramientasUso de herramientas con almacenamiento en caché de promptsLlamadas programáticas a herramientasStreaming detallado de herramientas
Gestión de contexto
Ventanas de contextoCompactaciónEdición de contextoAlmacenamiento en caché de promptsMensajes del sistema a mitad de conversaciónCrear un modo de orquestaciónDiagnóstico de caché (beta)Conteo de tokens
Trabajar con archivos
API de archivosCompatibilidad con PDF
Habilidades
Descripción generalInicio rápidoMejores prácticasHabilidades para empresasHabilidades en la API
MCP
Servidores MCP remotosConector MCP
Claude en plataformas en la nube
Amazon BedrockAmazon Bedrock (heredado)Claude Platform en AWSGoogle CloudMicrosoft Foundry

Log in
Motivos de detención y respaldo
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Claude Platform Docs

Solutions

  • AI agents
  • Code modernization
  • Coding
  • Customer support
  • Education
  • Financial services
  • Government
  • Life sciences

Partners

  • Claude on AWS
  • Claude on Google Cloud

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
Mensajes/Desarrollar con Claude

Razones de detención y respaldo

Aprende qué significa cada valor de stop_reason y cómo manejar el truncamiento, el uso de herramientas, los turnos pausados y los rechazos en tu aplicación.

Cada respuesta de la API de Messages incluye un campo stop_reason que te indica por qué Claude dejó de generar. Revisa este campo para decidir si usar la respuesta tal cual, continuar la conversación, reintentar o recurrir a otro modelo como respaldo.

Para ver el esquema completo de la respuesta, consulta la referencia de la API de Messages.

Referencia rápida

ValorCuándo ocurreQué hacer
end_turnClaude terminó su respuesta de forma natural.Usa la respuesta.
max_tokensLa respuesta alcanzó tu límite de max_tokens.Aumenta max_tokens o continúa la respuesta.
stop_sequenceClaude emitió una de tus stop_sequences.Lee stop_sequence para ver cuál se activó.
tool_useClaude está llamando a una herramienta.Ejecuta la herramienta y devuelve el resultado. Una llamada a herramienta de servidor a la que aún le falta su bloque de resultado se completa en una respuesta posterior.
pause_turnUn bucle de herramientas de servidor alcanzó su límite de iteraciones.Envía de vuelta el contenido del asistente para continuar.
refusalClaude se negó a responder.Lee stop_details y reintenta con un modelo de respaldo.
model_context_window_exceededLa respuesta llenó la ventana de contexto del modelo.Trata la respuesta como truncada.

El campo stop_reason

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

Example response
{
  "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,
  "stop_details": null,
  "usage": {
    "input_tokens": 100,
    "output_tokens": 50
  }
}

Valores de stop_reason

end_turn

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

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}],
)
if response.stop_reason == "end_turn":
    # Procesa la respuesta completa
    print(response.content[0].text)

max_tokens

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

client = anthropic.Anthropic()
# Solicitud con tokens limitados
response = client.messages.create(
    model="claude-opus-4-8",
    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 detención personalizadas.

client = anthropic.Anthropic()
response = client.messages.create(
    model="claude-opus-4-8",
    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 las implementaciones de uso de herramientas, usa el tool runner, que maneja automáticamente la ejecución de herramientas, el formato de resultados y la gestión de la conversación.

client = anthropic.Anthropic()
weather_tool = {
    "name": "get_weather",
    "description": "Get the current weather in a given location",
    "input_schema": {
        "type": "object",
        "properties": {
            "location": {"type": "string", "description": "City and state"},
        },
        "required": ["location"],
    },
}


def execute_tool(name, tool_input):
    """Execute a tool and return the result."""
    return f"Weather in {tool_input.get('location', 'unknown')}: 72°F"


response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    tools=[weather_tool],
    messages=[{"role": "user", "content": "What is the weather in San Francisco?"}],
)

if response.stop_reason == "tool_use":
    # Extrae y ejecuta la herramienta
    for block in response.content:
        if block.type == "tool_use":
            result = execute_tool(block.name, block.input)
            # Devuelve el resultado a Claude para la respuesta final

Una respuesta tool_use también puede contener un bloque server_tool_use cuyo id no tiene un bloque de resultado correspondiente. Esa llamada a herramienta de servidor no ha terminado, y esta respuesta no incluye su resultado. En el caso común, Claude llama a una herramienta de servidor y a una de tus herramientas de cliente en el mismo grupo de llamadas paralelas a herramientas: la API devuelve la respuesta sin ejecutar la herramienta de servidor para que puedas ejecutar primero las herramientas de cliente. No hay ningún otro marcador para este estado; detéctalo verificando el id de cada bloque server_tool_use o mcp_tool_use en busca de un bloque de resultado correspondiente.



Con la llamada programática a herramientas, la misma forma de respuesta significa algo diferente. El bloque tool_use de cliente proviene de código que se está ejecutando en la herramienta code_execution en lugar de provenir directamente de Claude, y su campo caller nombra el bloque code_execution que lo llamó. Ese código ya ha comenzado: está pausado esperando tus bloques tool_result, y enviarlos reanuda la ejecución en lugar de iniciar una herramienta diferida. El propio bloque de resultado del bloque code_execution llega una vez que el código termina, lo cual puede requerir más de una ronda de resultados de herramientas. El mensaje de usuario de seguimiento en sí es el mismo en ambos casos; con la llamada programática a herramientas, también devuelve el id del campo container de la respuesta, como muestra esa página.

A mixed tool_use response
{
  "stop_reason": "tool_use",
  "content": [
    {
      "type": "server_tool_use",
      "id": "srvtoolu_01HxbWnMRmbWyMfUtJKC45rA",
      "name": "web_fetch",
      "input": { "url": "https://example.com/article" }
    },
    {
      "type": "tool_use",
      "id": "toolu_01PjgRJLbXrXEMZwDNYLnBqk",
      "name": "run_command",
      "input": { "command": "uname -a" }
    }
  ]
}

La continuación es un mensaje de usuario compuesto por bloques tool_result, uno por cada bloque tool_use en la respuesta (consulta Manejar llamadas a herramientas), con dos reglas adicionales: ese mensaje no debe contener nada excepto los bloques tool_result, y la solicitud debe mantener el mismo arreglo tools. Una solicitud de reanudación que ya no define la herramienta de servidor en espera falla con un error 400 cuyo mensaje termina en but no `web_fetch` tool was provided. La API adjunta tus resultados al turno del asistente aún abierto, ejecuta la herramienta de servidor diferida (en el caso de ejecución de código pausada, la reanuda) y continúa el turno. Para una herramienta de servidor que Claude llamó directamente, el content de la siguiente respuesta comienza con el bloque de resultado que responde al id del server_tool_use de la respuesta anterior.

The follow-up user message
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01PjgRJLbXrXEMZwDNYLnBqk",
      "content": "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux"
    }
  ]
}

Agregar cualquier cosa después de los bloques tool_result en ese mensaje de usuario, como texto, finaliza el turno del asistente; para una herramienta de servidor que Claude llamó directamente, la solicitud entonces falla con un error 400 invalid_request_error que nombra la herramienta de servidor sin resolver:

`web_fetch` tool use with id `srvtoolu_01HxbWnMRmbWyMfUtJKC45rA` was found without a corresponding `web_fetch_tool_result` block

Omitir un tool_result, o colocar uno después de otro contenido, falla antes con el error estándar tool_use ids were found without tool_result blocks immediately after en su lugar. Para darle a Claude más entrada, envíala como un mensaje de usuario separado después de que el turno se complete.

pause_turn

Se devuelve cuando el bucle de muestreo del lado del servidor alcanza su límite de iteraciones mientras ejecuta herramientas de servidor como búsqueda web o recuperación web. El límite predeterminado es de 10 iteraciones por solicitud.

Cuando esto sucede, la respuesta puede contener un bloque server_tool_use sin un bloque de resultado correspondiente. Para permitir que Claude termine de procesar, continúa la conversación enviando la respuesta de vuelta tal cual. Una respuesta que deja un bloque tool_use de cliente esperando por ti nunca tiene un stop_reason de pause_turn: cuando Claude se detiene para llamar a tus herramientas, stop_reason es tool_use, y la continúas enviando los bloques tool_result de cliente en lugar de la respuesta misma.

response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=4096,
    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 enviando la respuesta de vuelta
    messages = [
        {"role": "user", "content": "Search for latest AI news"},
        {"role": "assistant", "content": response.content},
    ]
    continuation = client.messages.create(
        model="claude-opus-4-8",
        max_tokens=4096,
        messages=messages,
        tools=[{"type": "web_search_20250305", "name": "web_search"}],
    )


Tu aplicación debe manejar pause_turn en cualquier bucle de agente que use herramientas de servidor. Agrega la respuesta del asistente a tu arreglo de mensajes y realiza otra solicitud a la API para permitir que Claude continúe.

refusal

Claude se negó a generar una respuesta. En Claude Fable 5, los clasificadores de seguridad devuelven esta razón de detención como una respuesta HTTP 200 normal, no como un error.

client = anthropic.Anthropic()
response = client.messages.create(
    model="claude-opus-4-8",
    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 detención refusal con frecuencia al usar Claude Sonnet 4.5 u Opus 4.1 (obsoleto), puedes intentar actualizar tus llamadas a la API para usar Haiku 4.5 (claude-haiku-4-5-20251001), que tiene restricciones de uso diferentes. Obtén más información sobre cómo entender los filtros de seguridad de la API de Sonnet 4.5.

En un rechazo, el objeto stop_details identifica la categoría de política que lo activó. Las categorías y la forma completa de la respuesta de rechazo se cubren en Rechazos y respaldo. stop_details es null para todas las razones de detención distintas de refusal.

Una solicitud rechazada en Claude Fable 5 generalmente puede atenderse reintentando en otro modelo de Claude, y Rechazos y respaldo muestra cómo configurar ese reintento, del lado del servidor o en tu cliente. Crédito de respaldo cubre cómo evitar pagar dos veces el costo de la caché de prompts cuando construyes el reintento tú mismo.

model_context_window_exceeded

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



Esta razón de detención actualmente solo está tipada en el espacio de nombres beta de los SDK, por lo que los siguientes ejemplos llaman a client.beta.messages y usan los tipos con prefijo Beta. En Sonnet 4.5 y modelos más recientes, la API devuelve este valor sin un encabezado beta. Para modelos anteriores, agrega el encabezado beta model-context-window-exceeded-2025-08-26 para habilitarlo.

# Solicitud con el máximo de tokens para obtener tanto como sea posible
response = client.beta.messages.create(
    model="claude-opus-4-8",
    max_tokens=20000,  # Python SDK requires streaming for max_tokens above ~21k (Opus 4.8 supports 128k with streaming)
    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

Mejores prácticas para manejar razones de detención

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

Maneja las respuestas truncadas con elegancia

Cuando una respuesta se trunca debido a límites de tokens o a la ventana de contexto, agrega un aviso para que el lector sepa que la salida está incompleta. Para continuar generando desde donde quedó la respuesta, consulta Asegurar respuestas completas.

def handle_truncated_response(response):
    if response.stop_reason in ["max_tokens", "model_context_window_exceeded"]:
        if response.stop_reason == "max_tokens":
            note = "[Response truncated due to max_tokens limit]"
        else:
            note = "[Response truncated due to context window limit]"
        return f"{response.content[0].text}\n\n{note}"
    return response.content[0].text

Implementa lógica de reintento para pause_turn

Al usar herramientas de servidor, la API puede devolver pause_turn si el bucle de muestreo del lado del servidor alcanza su límite de iteraciones (10 por defecto). Maneja esto continuando la conversación:

def handle_server_tool_conversation(client, user_query, tools, max_continuations=5):
    """
    Handle server tool conversations that may require multiple continuations.

    The server runs a sampling loop when executing server tools. If the loop
    reaches its iteration limit, the API returns pause_turn. Continue the
    conversation by sending the response back to let Claude finish.
    """
    messages = [{"role": "user", "content": user_query}]

    for _ in range(max_continuations):
        response = client.messages.create(
            model="claude-opus-4-8", max_tokens=4096, messages=messages, tools=tools
        )

        if response.stop_reason != "pause_turn":
            # Claude terminó de procesar - devuelve la respuesta final
            return response

        # pause_turn: reemplaza la lista completa de mensajes para mantener roles alternados
        messages = [
            {"role": "user", "content": user_query},
            {"role": "assistant", "content": response.content},
        ]

    # Se alcanzó el máximo de continuaciones - devuelve la última respuesta
    return response

Razones de detención vs. errores

Es importante distinguir entre los valores de stop_reason y los errores reales:

Razones de detención (respuestas exitosas)

  • Forman 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 la solicitud
  • La respuesta contiene detalles del error
client = anthropic.Anthropic()

try:
    response = client.messages.create(
        model="claude-opus-4-8",
        max_tokens=1024,
        messages=[{"role": "user", "content": "Hello!"}],
    )

    # Manejar respuesta exitosa con stop_reason
    if response.stop_reason == "max_tokens":
        print("Response was truncated")

except anthropic.APIStatusError as e:
    # Manejar errores reales
    if e.status_code == 429:
        print("Rate limit exceeded")
    elif e.status_code == 500:
        print("Server error")

Consideraciones de streaming

Al usar streaming, stop_reason es:

  • null en el evento inicial message_start
  • Proporcionado en el evento message_delta
  • No proporcionado en ningún otro evento
client = anthropic.Anthropic()

with client.messages.stream(
    model="claude-opus-4-8",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}],
) 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 tool runner: El siguiente ejemplo muestra el manejo manual de herramientas. Para la mayoría de los casos de uso, el tool runner 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-8", max_tokens=1024, 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-8", 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": "Please continue from where you left off."},
        ]

    return full_response

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

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

def get_max_possible_tokens(client, prompt):
    """
    Get as many tokens as possible within the model's context window
    without needing to calculate input token count
    """
    response = client.beta.messages.create(
        model="claude-opus-4-8",
        messages=[{"role": "user", "content": prompt}],
        max_tokens=20000,  # Python SDK requires streaming for max_tokens above ~21k
    )

    if response.stop_reason == "model_context_window_exceeded":
        # Se obtuvo el máximo de tokens posible dado el tamaño de entrada
        print(
            f"Generated {response.usage.output_tokens} tokens (context limit reached)"
        )
    elif response.stop_reason == "max_tokens":
        # Se obtuvo exactamente la cantidad de tokens solicitada
        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

Próximos pasos

Rechazos y respaldo

Reintenta solicitudes rechazadas en un modelo de respaldo, del lado del servidor o en tu cliente.


Tool Runner (SDK)

Deja que el SDK gestione el bucle de tool_use, el formato de resultados y los reintentos por ti.


Mensajes con streaming

Lee stop_reason desde el evento message_delta al usar streaming.


Errores

Maneja errores HTTP 4xx y 5xx, que son distintos de las razones de detención.

Was this page helpful?

  • Referencia rápida
  • El campo 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 detención
  • Siempre verifica stop_reason
  • Maneja las respuestas truncadas con elegancia
  • Implementa lógica de reintento para pause_turn
  • Razones de detención vs. errores
  • Razones de detención (respuestas exitosas)
  • Errores (solicitudes fallidas)
  • Consideraciones de streaming
  • Patrones comunes
  • Manejo de flujos de trabajo de uso de herramientas
  • Asegurar respuestas completas
  • Obtener el máximo de tokens sin conocer el tamaño de la entrada
  • Próximos pasos