Claude Platform Docs
MensajesDesarrollar con Claude

Rechazos y fallback

Cómo los modelos Claude Fable, los modelos Claude Opus, Claude Sonnet 5.5 y Claude Haiku 5.5 devuelven rechazos del clasificador y cómo reintentar las solicitudes rechazadas en un modelo de fallback.

Claude Fable 5.1, Claude Fable 5, Claude Opus 5.5, Claude Opus 5, Claude Sonnet 5.5 y Claude Haiku 5.5 incluyen clasificadores de seguridad que pueden rechazar una solicitud. Cuando eso ocurre, recibes una respuesta normal, no un error, con stop_reason: "refusal". Su stop_details.category indica el área de política (consulta Cómo se ve un rechazo). Por lo general, aún puedes obtener una respuesta enviando la misma solicitud a otro modelo de Claude. Esta página te muestra cómo reconocer un "refusal" (rechazo) y cómo configurar ese reintento.

Lee esta página cuando construyas sobre cualquiera de estos modelos y quieras que las solicitudes declinadas pasen automáticamente a otro modelo. También aplica cuando has visto "refusal" en una respuesta y quieres saber qué hacer a continuación.

Páginas relacionadas:

La configuración más sencilla, en beta en la Claude API: establece fallbacks en "default", y la API reintenta una solicitud rechazada en el modelo de fallback que Anthropic recomienda para su categoría de rechazo. Para las categorías sin un fallback recomendado, el rechazo se mantiene. Claude Haiku 5.5 no tiene fallback del lado del servidor, así que para él usa fallback del lado del cliente con el middleware del SDK o escribe el reintento tú mismo.

client = Anthropic()

response = client.beta.messages.create(
    model="claude-fable-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello, Claude"}],
    fallbacks="default",
    betas=["server-side-fallback-2026-07-01"],
)
print(response.model)

Las siguientes secciones cubren qué contiene una respuesta de rechazo, cuándo usar fallback del lado del servidor o del lado del cliente, y cómo se factura cada uno.

Cómo se ve un rechazo

Un rechazo es una respuesta HTTP 200 exitosa con stop_reason: "refusal":

{
  "id": "msg_01XFUDYJgAACzvnptvVoYEL",
  "type": "message",
  "role": "assistant",
  "model": "claude-fable-5",
  "content": [],
  "stop_reason": "refusal",
  "stop_details": {
    "type": "refusal",
    "category": "cyber",
    "explanation": "This request was declined because it could enable cyber harm."
  },
  "usage": {
    "input_tokens": 412,
    "output_tokens": 0
  }
}

El objeto stop_details explica la declinación:

  • category: nombra el área de política que activó el clasificador.
  • explanation: una descripción legible para humanos. El texto no es estable, así que muéstralo en lugar de analizarlo.
  • recommended_model: presente solo en solicitudes que establecen fallbacks (fallback del lado del servidor, beta). Nombra un modelo para reintentar directamente cuando la API omitió el intento de fallback (por ejemplo, el modelo de fallback alcanzó su límite de velocidad), y es null en caso contrario. Es una sugerencia, no una garantía.
  • category y explanation son ambos null cuando el rechazo no corresponde a una categoría con nombre. Ese null es un valor normal y permanente, no un marcador de posición.
  • stop_details en sí es null para todos los motivos de parada distintos de refusal.
categoryQué significaSe factura antes de cualquier salida
"cyber"La solicitud podría facilitar daño cibernético, como el desarrollo de malware o exploits. El trabajo benigno de ciberseguridad también puede activar esta categoría.No
"bio"La solicitud podría facilitar daño biológico, como métodos de laboratorio peligrosos. El trabajo beneficioso en ciencias de la vida también puede activar esta categoría.Sí
"frontier_llm"La solicitud podría ayudar al desarrollo de modelos de IA competidores, lo cual está restringido bajo los términos comerciales de Anthropic. El trabajo benigno de aprendizaje automático también puede activar esta categoría.Sí
"reasoning_extraction"La solicitud pide al modelo que reproduzca su razonamiento interno en el texto de la respuesta. Para obtener el razonamiento en forma estructurada, usa pensamiento adaptativo. Consulta Mantén el razonamiento en bloques de pensamiento.Sí
"general_harms"La solicitud cae dentro de un área de la política de uso fuera de las cuatro categorías con nombre. El trabajo benigno también puede activar esta categoría.No

Un rechazo puede llegar antes de cualquier salida, o a mitad del stream después de una salida parcial. En cualquier caso, trata cualquier salida parcial como incompleta y descártala.

Mantén el razonamiento en bloques de pensamiento

Un rechazo reasoning_extraction suele provenir de un prompt que pide al modelo que ponga su pensamiento o razonamiento en la salida, ya sea textualmente o en un formato fijo. Ejemplos comunes:

  • Una sección <thinking>, <reasoning> o de borrador que el modelo completa antes de responder
  • Un campo reasoning, thinking o trace en la salida JSON o en la entrada de una herramienta
  • Las notas privadas del modelo, o un registro continuo de su razonamiento
  • Razonamiento solicitado textualmente o de forma completa

La redacción puede estar en una indicación del sistema, una skill o la descripción de una herramienta, así que revisa también esos lugares.

Aún puedes pedirle a Claude que explique su respuesta. Pide una explicación breve, la evidencia detrás de un resultado o un resumen de las acciones que realizó. Para ver cómo razonó el modelo, establece display: "summarized" y lee los bloques thinking. Esta categoría no tiene un modelo de fallback recomendado, así que cambia el prompt en lugar de reintentar la solicitud. Si una solicitud reformulada sigue siendo rechazada, contacta al soporte e incluye el ID de solicitud.

Cómo se facturan los rechazos

Estas reglas de facturación se aplican en todas las plataformas: la Claude API, Amazon Bedrock, Claude Platform on AWS, Google Cloud y Microsoft Foundry.

Rechazos antes de cualquier salida: Para frustrar los intentos de eludir las salvaguardas de Anthropic a gran escala, un rechazo que llega antes de cualquier salida se factura cuando su stop_details.category es "bio", "frontier_llm" o "reasoning_extraction". Estas son las categorías en las que Anthropic mide volúmenes bajos de falsos positivos, a septiembre de 2026. Estos rechazos se facturan como cualquier otra solicitud, a las tarifas del modelo que la ejecutó. Un rechazo antes de cualquier salida en cualquier otra categoría, o con una categoría null, no se factura. En cualquier caso, content está vacío y los conteos de tokens aparecen en usage. La solicitud aún cuenta contra tus límites de velocidad.

Rechazos a mitad del stream: Un rechazo a mitad del stream factura los tokens de entrada y la salida ya transmitida a las tarifas normales.

Fallback: Cuando usas fallback, el rechazo que lo activó se factura, además de la solicitud de fallback, cuando llegó a mitad del stream o pertenece a una de las categorías facturadas. El crédito de fallback compensa el fallo de caché de prompts de la solicitud de fallback, para que no pagues dos veces por almacenar en caché la conversación. Un rechazo de Claude Haiku 5.5 no incluye crédito de fallback, así que un fallback posterior paga el costo completo de escribir la caché de prompts del modelo de fallback. Para saber cómo el fallback del lado del servidor reporta cada intento, consulta Facturación y límites de velocidad.

Las categorías facturadas pueden cambiar a medida que Anthropic sigue midiendo y refinando las tasas de falsos positivos de sus salvaguardas. La columna Se factura antes de cualquier salida de la tabla de categorías de rechazo enumera las categorías facturadas.

Elegir un enfoque de fallback

Hay tres formas de reintentar una solicitud rechazada en otro modelo. La correcta depende de dónde estés ejecutando y cuánto control necesites.

Tu situaciónUsaPor qué
Claude API, configuración más simpleFallback del lado del servidorUna solicitud, una respuesta. La API maneja el reintento.
Cualquier plataforma, usando un SDK de AnthropicEl middleware del SDKConfigúralo una vez en el cliente. Los reintentos ocurren automáticamente.
HTTP directo o lógica de reintento personalizadaUn reintento manual con crédito de fallbackControl total. El crédito de fallback mantiene bajo el costo.

El fallback del lado del servidor y el middleware del SDK aplican el crédito de fallback por ti. Solo necesitas la página de Crédito de fallback cuando construyes el reintento tú mismo. Claude Haiku 5.5 no tiene fallback del lado del servidor ni crédito de fallback, así que usa el middleware del SDK o un reintento manual.

Fallback del lado del servidor

El fallback del lado del servidor reintenta una solicitud rechazada dentro de una sola llamada a la API. En el modo predeterminado, cuando el modelo principal declina y la categoría de rechazo tiene un fallback recomendado, la API ejecuta la misma solicitud en el modelo que Anthropic recomienda para esa categoría. En su lugar, puedes nombrar hasta tres modelos de fallback propios. De cualquier forma, recibes una sola respuesta que nombra el modelo que respondió, de modo que tu usuario obtiene una respuesta en un solo viaje de ida y vuelta.

Realizar la solicitud

Establece el parámetro fallbacks en la cadena "default" y envía el encabezado beta server-side-fallback-2026-07-01. La API entonces aplica el enrutamiento predeterminado definido por el servidor para el modelo solicitado, que selecciona un modelo de fallback recomendado según la categoría de rechazo que reporta el clasificador, de modo que las solicitudes rechazadas se atienden sin que tengas que mantener una lista de modelos a medida que cambian las recomendaciones.

El enrutamiento predeterminado nunca provoca el rechazo anticipado por imagen sobredimensionada para modelos que no elegiste: un modelo enrutado que redimensionaría una imagen marcada con "oversized_image": "error" se elimina del enrutamiento en su lugar, de modo que una imagen marcada nunca se sirve redimensionada.

client = Anthropic()

response = client.beta.messages.create(
    model="claude-fable-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello, Claude"}],
    fallbacks="default",
    betas=["server-side-fallback-2026-07-01"],
)

# Una entrada fallback_message en usage.iterations indica que se ejecutó un modelo de respaldo;
# combínala con stop_reason para confirmar que el respaldo sirvió la respuesta.
fallback_ran = any(
    iteration.type == "fallback_message"
    for iteration in response.usage.iterations or []
)
served_by_fallback = fallback_ran and response.stop_reason != "refusal"

print(
    json.dumps(
        {
            "stop_reason": response.stop_reason,
            "model": response.model,
            "served_by_fallback": served_by_fallback,
        }
    )
)

Anthropic establece salvaguardas para cada modelo individualmente y para cada categoría de política, de acuerdo con la capacidad del modelo: dependiendo de la categoría, una solicitud marcada puede recurrir a un modelo menos capaz o ser declinada. El modo "default" codifica por ti estas recomendaciones por modelo y por categoría, de modo que una solicitud rechazada se reintenta en el modelo que Anthropic recomienda para esa categoría. Los fallbacks son visibles de cualquier forma: la respuesta nombra el modelo que la atendió, y el bloque de contenido fallback marca el traspaso.

El enrutamiento se aplica del lado del servidor y no se publica por modelo en la Models API. Para ver qué modelo atendió una solicitud rechazada, revisa el campo model de nivel superior de la respuesta y busca una entrada fallback_message en usage.iterations, como lo hacen los ejemplos de esta página.

Solo una declinación del clasificador de seguridad activa el fallback. Un límite de velocidad, una sobrecarga o un error del servidor en el modelo solicitado se te devuelve tal cual.

Nombrar tus propios modelos de fallback

En lugar del enrutamiento predeterminado, puedes establecer fallbacks en una lista de hasta tres modelos. Cuando el modelo solicitado declina, la API ejecuta el siguiente modelo de la cadena con la misma solicitud. Usa esta forma cuando quieras controlar exactamente qué modelos atienden las solicitudes rechazadas, como fijar un modelo que tu aplicación ha calificado.

Los modelos de fallback nombrados cuentan para la verificación de imagen sobredimensionada: una solicitud cuyo bloque de imagen establece "oversized_image": "error" se verifica de antemano contra el modelo solicitado y cada fallback nombrado, se rechaza si cualquiera de ellos redimensionaría esa imagen, y el objetivo de reescalado reportado en el rechazo se ajusta a todos ellos.

Las líneas resaltadas son la única diferencia con respecto a la solicitud de enrutamiento predeterminado.

client = Anthropic()

response = client.beta.messages.create(
    model="claude-fable-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello, Claude"}],
    fallbacks=[{"model": "claude-opus-4-8"}],
    betas=["server-side-fallback-2026-07-01"],
)
print(response.model)

Algunas reglas aplican a la lista fallbacks:

  • Las entradas se prueban en orden. Cada una debe ser distinta de las demás entradas y del modelo solicitado.
  • Cada entrada debe ser uno de los destinos permitidos del modelo solicitado. Con el encabezado beta establecido, esa lista se publica como allowed_fallback_models en la entrada del modelo en la Models API.
  • Cada entrada indica un model y puede sobrescribir max_tokens, thinking, output_config y speed solo para ese intento.
  • La solicitud debe ser válida como solicitud directa a cada modelo nombrado. Si un modelo de respaldo no admite una función que usa la solicitud, la API rechaza la solicitud de antemano. Con el encabezado 2026-07-01, thinking: {"type": "between_tools"} es la excepción: cuando una solicitud a Claude Sonnet 5.5 pasa a Claude Sonnet 5, el intento de respaldo se ejecuta con thinking: {"type": "disabled"} y display: "omitted". Con 2026-06-01, establece thinking en la entrada de Claude Sonnet 5, o la solicitud se rechaza de antemano.
  • Al igual que en el modo predeterminado, solo un rechazo del clasificador de seguridad activa el respaldo. Un límite de velocidad, una sobrecarga o un error del servidor en el modelo solicitado se te devuelve tal cual.
  • Si un modelo de respaldo alcanza su límite de velocidad o está sobrecargado, el intento de respaldo no se realiza y en su lugar se devuelve el rechazo anterior. El stop_details.recommended_model del rechazo indica entonces un modelo al que reintentar directamente. Dimensiona los límites de velocidad del modelo de respaldo para el volumen de rechazos que esperas, o los respaldos se degradarán a rechazos bajo carga.

La respuesta tiene la misma forma en ambos modos: el modelo que atendió el turno aparece en el campo model de nivel superior, un bloque de contenido fallback marca el traspaso, y usage.iterations registra cada intento.

Qué contiene la respuesta

La respuesta se ve como cualquier otro mensaje, con dos adiciones:

  • El campo model de nivel superior reporta el modelo que produjo el mensaje devuelto, ya sea el modelo solicitado o un fallback.
  • Un bloque de contenido fallback marca cada punto en content donde la salida de un modelo da paso al siguiente: {"type": "fallback", "from": {"model": ...}, "to": {"model": ...}}.
    • from.model repite la cadena de modelo que enviaste cuando el salto que declina es el modelo solicitado.
    • to.model es siempre el ID resuelto del modelo que continúa.

En un rechazo antes de cualquier salida, el bloque fallback es el primer bloque de contenido. Por ejemplo, cuando el enrutamiento predeterminado selecciona Claude Opus 4.8 para la categoría del rechazo:

{
  "id": "msg_01XFUDYJgAACzvnptvVoYEL",
  "type": "message",
  "role": "assistant",
  "model": "claude-opus-4-8",
  "content": [
    {
      "type": "fallback",
      "from": { "model": "claude-fable-5" },
      "to": { "model": "claude-opus-4-8" }
    },
    { "type": "text", "text": "Hi! How can I help you today?" }
  ],
  "stop_reason": "end_turn",
  "stop_details": null,
  "usage": {
    "input_tokens": 412,
    "output_tokens": 264,
    "cache_read_input_tokens": 0,
    "cache_creation_input_tokens": 0,
    "iterations": [
      {
        "type": "message",
        "model": "claude-fable-5",
        "input_tokens": 535,
        "output_tokens": 0,
        "cache_read_input_tokens": 0,
        "cache_creation_input_tokens": 0
      },
      {
        "type": "fallback_message",
        "model": "claude-opus-4-8",
        "input_tokens": 412,
        "output_tokens": 264,
        "cache_read_input_tokens": 0,
        "cache_creation_input_tokens": 0
      }
    ]
  }
}

El arreglo usage.iterations registra cada intento. Un modelo que declinó aparece como una entrada message ordinaria, y el modelo que atendió el turno aparece como una entrada fallback_message. Si todos los modelos de la cadena declinan, la respuesta es el rechazo del último modelo, con una entrada message por cada salto anterior y una entrada fallback_message para el último.

El enrutamiento persistente puede enviar un turno posterior directamente al modelo de fallback. Dicho turno no lleva ningún bloque de contenido fallback, porque ningún modelo declinó ese turno. Identifícalo por la entrada fallback_message en usage.iterations, la ausencia de una entrada message para el modelo solicitado, y el campo model de la respuesta.

Continuar la conversación

En el siguiente turno, envía de vuelta el contenido del asistente tal como lo recibiste. Después de un fallback a mitad de la salida, content puede incluir tipos de bloque que el modelo que declinó produjo antes del traspaso. La siguiente tabla cubre cuáles conservar y cuáles descartar cuando repites el turno.

Tipo de bloqueEn el siguiente turno
fallbackConsérvalo exactamente donde apareció. La API usa su posición para validar los bloques de pensamiento a su alrededor, por lo que una solicitud que repite bloques de pensamiento de ambos lados del límite se rechaza si el bloque se omite o se mueve.
textConservar.
Cualquier bloque después del bloque fallback finalConservar.
thinking, redacted_thinking o connector_text antes del bloque fallback finalDescartar.
tool_use del lado del cliente antes del bloque fallback finalDescartar.
server_tool_use antes del bloque fallback finalConservar cuando está emparejado con su resultado. Descartar cuando no tiene un resultado correspondiente.

Streaming

En una solicitud con streaming, el reintento ocurre en el mismo stream, y nada de lo que ya recibiste se invalida. Lo que ves depende de cuándo ocurre la declinación.

Cuando la declinación ocurre antes de cualquier salida:

  • message_start nombra el modelo de fallback, y el bloque fallback es el primer bloque de contenido.
  • Debido a que message_start espera a que comience el intento de fallback, el tiempo hasta el primer byte incluye el intento declinado.

Cuando la declinación ocurre a mitad de la salida:

  • El bloque de contenido abierto se cierra, y el bloque fallback (un par ordinario de content_block_start y content_block_stop sin deltas) marca el límite.
  • El modelo de fallback continúa desde la salida parcial. Solo los bloques text de la salida parcial se pasan al modelo de fallback como contexto. Los demás tipos de bloque permanecen en content.
  • message_start ya nombró el modelo solicitado, así que lee el modelo que atiende desde el to.model del bloque fallback y desde la entrada fallback_message en el usage.iterations del message_delta final.

Respuestas sin streaming

En una solicitud sin streaming, una declinación a mitad de la salida se comporta de manera diferente: la respuesta omite la salida parcial del modelo declinado, y el modelo de fallback responde desde cero. El resultado se ve como una declinación antes de cualquier salida, con el bloque fallback primero. El intento declinado y sus tokens de salida aún aparecen en usage.iterations.

Facturación y límites de velocidad

Cada intento sigue las reglas de Cómo se facturan los rechazos, a las tarifas del modelo que lo ejecutó. Un intento que declinó antes de producir cualquier salida se factura solo cuando su categoría de rechazo es facturable, y sus tokens se reportan en su entrada de usage.iterations en cualquier caso. Cada intento que produjo salida, incluido uno que declinó a mitad de su respuesta, se factura por separado. El arreglo usage.iterations es el registro por intento de lo que se te factura. Los conteos de usage de nivel superior describen solo el intento que produjo el mensaje devuelto. Los tokens de diferentes modelos nunca se suman en un solo campo.

Cada intento que se ejecuta, incluido uno que declinó, cuenta contra los límites de velocidad de su propio modelo.

Enrutamiento persistente

Después de que una conversación recurre al fallback, la API registra qué modelo la atendió. Las solicitudes posteriores de esa conversación que incluyen fallbacks van directamente a ese modelo de fallback, sin ejecutar el modelo solicitado. Este "sticky routing" (enrutamiento persistente) evita pagar por un intento que previsiblemente sería declinado de nuevo en cada turno.

Algunas propiedades de la decisión de enrutamiento:

  • Se conserva durante aproximadamente 1 hora y está limitada a tu organización.
  • Se almacena como un hash de contenido del prefijo de la conversación más el modelo que la atendió. El contenido del mensaje en sí no se almacena.
  • Es de mejor esfuerzo, por lo que tu código debe manejar que el modelo solicitado se vuelva a probar en cualquier momento.

El enrutamiento persistente aplica tanto a solicitudes con streaming como sin streaming. En una solicitud con streaming, la decisión de enrutamiento se toma antes de que se abra el stream, por lo que el campo model del evento message_start ya lleva el ID del modelo de fallback.

Fallback del lado del cliente con el middleware del SDK

El SDK incluye un middleware de fallback ante rechazos. Lo configuras una vez en el cliente con tu lista de modelos de fallback. Las llamadas a través de client.beta.messages reintentan entonces las solicitudes rechazadas automáticamente, en cualquier plataforma. El middleware también envía el encabezado beta fallback-credit-2026-07-01 en cada solicitud que maneja, de modo que los reintentos se vuelven a tarificar sin configuración por solicitud. Un rechazo de Claude Haiku 5.5 no incluye crédito de fallback, así que un reintento posterior paga el costo completo de escribir la caché de prompts del modelo de fallback.

Configurarlo

Pasa BetaRefusalFallbackMiddleware al constructor del cliente, y comparte una instancia de BetaFallbackState entre las solicitudes de una conversación.

from anthropic import Anthropic, BetaFallbackState, BetaRefusalFallbackMiddleware

# Ante un rechazo, el middleware reintenta con el modelo de respaldo indicado y
# envía automáticamente el encabezado beta fallback-credit en cada solicitud que maneja.
client = Anthropic(
    middleware=[BetaRefusalFallbackMiddleware([{"model": "claude-opus-4-8"}])],
)

state = BetaFallbackState()  # pins follow-ups to the model that accepted

# Streaming: ante un rechazo, el middleware reintenta con el modelo de respaldo y
# empalma sus eventos en el stream abierto.
with (
    state,
    client.beta.messages.stream(
        max_tokens=1024,
        model="claude-fable-5",
        messages=[{"role": "user", "content": "Hello, Claude"}],
    ) as stream,
):
    for text in stream.text_stream:
        print(text, end="", flush=True)
    final_message = stream.get_final_message()
print(f"\nserved by: {final_message.model}")

# Sin streaming: reutilizar el estado mantiene la conversación fijada.
with state:
    message = client.beta.messages.create(
        max_tokens=1024,
        model="claude-fable-5",
        messages=[{"role": "user", "content": "Hello, Claude"}],
    )
print(f"served by: {message.model}")

Cómo se comporta

  • Los reintentos recorren tu lista de respaldo en orden. Un modelo de respaldo que a su vez rechaza pasa la solicitud a la siguiente entrada.
  • Cuando todos los modelos de la lista han rechazado, el middleware devuelve el rechazo final (la respuesta de rechazo del último modelo) en lugar de generar un error.
  • Los bloques de pensamiento de Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5, Claude Haiku 5.5 o Claude Fable 5 pasan sin cambios. Cada reintento reenvía el cuerpo de tu solicitud original, y los únicos bloques que el middleware elimina del historial de la conversación en solicitudes posteriores son los bloques de límite fallback que él mismo agregó. El modelo de fallback no puede leer los bloques de Claude Fable 5.1, que solo leen Claude Fable 5.1 y Claude Mythos 5.1, así que la API los descarta. La API también descarta los bloques de Claude Opus 5.5 para todos los modelos de fallback excepto Claude Fable 5.1 y Claude Mythos 5.1 (consulta Cambiar de modelo a mitad de la conversación). También descarta los bloques de Claude Sonnet 5.5, para todos los modelos de fallback excepto Claude Opus 5.5 en la Claude API y Google Cloud. Claude Opus 5.5 y Claude Sonnet 5.5 leen los bloques de Claude Haiku 5.5 en la Claude API y Google Cloud, y la API los descarta para un modelo de fallback que no puede leerlos.
  • Las respuestas atendidas a través del middleware incluyen un bloque de contenido fallback en cada límite entre modelos, igual que las respuestas del respaldo del lado del servidor. El middleware gestiona esos bloques por ti en solicitudes posteriores.
  • El modelo que aceptó se registra en BetaFallbackState, de modo que las solicitudes de seguimiento que comparten el estado permanecen fijadas a él en lugar de volver a preguntar a un modelo que rechazó.

Escribir el reintento tú mismo

Sobre HTTP directo o con lógica de reintento personalizada, implementa el patrón que el middleware envuelve:

  1. Detecta el rechazo

    Revisa la respuesta en busca de stop_reason: "refusal".

  2. Reenvía en un modelo de respaldo

    Envía la misma solicitud con model establecido en un modelo de respaldo, como Claude Opus 4.8. Si la solicitud rechazada envió thinking: {"type": "between_tools"}, cambia thinking primero: solo Claude Sonnet 5.5 acepta ese valor, así que omite thinking o establece un valor que el modelo de respaldo acepte. El fallback del lado del servidor con el encabezado 2026-07-01 hace este cambio por ti cuando pasa a Claude Sonnet 5. Otro modelo normalmente puede atender una solicitud que Claude Fable 5.1 o Claude Fable 5 rechaza. Cómo manejes el historial de la conversación depende de si canjeas un crédito de respaldo:

    • Sin canjear un crédito: puedes dejar los bloques thinking y redacted_thinking anteriores en su lugar o eliminarlos para ahorrar tokens de entrada. El modelo de fallback normalmente no puede usarlos en ningún caso: solo Claude Fable 5.1 y Claude Mythos 5.1 leen los bloques de Claude Fable 5.1, y solo esos dos modelos, además de Claude Fable 5 y Claude Mythos 5, leen los bloques de Claude Fable 5, así que para cualquier otro modelo de fallback la API los descarta. La API también descarta los bloques de Claude Opus 5.5 para todos los modelos de fallback excepto Claude Fable 5.1 y Claude Mythos 5.1 (consulta Cambiar de modelo a mitad de la conversación). También descarta los bloques de Claude Sonnet 5.5, para todos los modelos de fallback excepto Claude Opus 5.5 en la Claude API y Google Cloud. Un reintento después de un rechazo de Claude Haiku 5.5 siempre corresponde a este caso. Claude Opus 5.5 y Claude Sonnet 5.5 leen los bloques de Claude Haiku 5.5 en la Claude API y Google Cloud, así que deja esos bloques en su lugar cuando pases a cualquiera de esos dos modelos en esas plataformas. Para un modelo de fallback que no puede leerlos, la API los descarta sin facturarlos.
    • Canjeando un crédito: envía el cuerpo sin cambios, porque el canje requiere una coincidencia exacta. El servidor maneja los bloques de pensamiento del modelo anterior en un canje, así que no los elimines (consulta Campos que deben coincidir con la solicitud rechazada).
  3. Permanece en el modelo de respaldo

    En conversaciones de varios turnos, sigue usando el modelo de respaldo en los turnos siguientes en lugar de volver al anterior.

Un reintento manual escribe la caché de prompts del modelo de fallback desde cero, lo cual cuesta más que leer una caché existente. El crédito de fallback reembolsa ese costo; canjéalo en cada reintento que construyas tú mismo. Un rechazo de Claude Haiku 5.5 no incluye crédito de fallback, así que un reintento posterior paga el costo completo de escribir la caché de prompts del modelo de fallback.

Rechazos en Message Batches

Una solicitud rechazada en un Message Batch regresa como result.type: "succeeded" con stop_reason: "refusal". Los resultados de lote llevan el mismo objeto stop_details que las respuestas síncronas, por lo que puedes detectar rechazos a través de stop_reason o de stop_details.type. Una diferencia: los rechazos en lote no emiten créditos de fallback, por lo que stop_details en un resultado de lote nunca incluye un fallback_credit_token.

El fallback del lado del servidor no está disponible para lotes (una solicitud de lote que incluye fallbacks produce un resultado con error por elemento). Para reintentar los elementos de lote rechazados:

  1. Recopila los elementos rechazados de los resultados.
  2. Deja en su lugar los bloques de pensamiento de los historiales de varios turnos, o elimínalos para ahorrar tokens de entrada. Para un modelo de fallback que no puede leerlos, la API los descarta sin facturarlos, como en un reintento manual.
  3. Si un elemento rechazado envió thinking: {"type": "between_tools"}, omite thinking o establece un valor que el modelo de fallback acepte. Solo Claude Sonnet 5.5 acepta between_tools.
  4. Reenvíalos en un modelo de fallback como un nuevo lote o como solicitudes directas.

Errores comunes

  • Reintenta en un modelo diferente. Reenviar una solicitud rechazada al mismo modelo generalmente obtiene otro rechazo. Dirige el reintento al modelo de fallback.
  • Presupuesta los reintentos por solicitud, no por turno ni por sesión. Un solo turno puede producir varios rechazos, por ejemplo un agente más sus subagentes.
  • Configura el fallback en cada ruta de solicitud. Los manejadores de reintento, las ramas de recuperación de errores y los workers en segundo plano lo necesitan. Un manejador que vuelve a emitir una solicitud sin fallback pierde la protección exactamente en las solicitudes que más probablemente la necesiten.
  • Da a las llamadas de subagentes su propio fallback. El parámetro fallbacks no se propaga a las llamadas a modelos realizadas desde dentro de la ejecución de herramientas.
  • Haz del fallback una propiedad de la solicitud, no del estado ambiental. Una bandera compartida, un valor de configuración en caché o un interruptor global pueden desincronizarse y dejar silenciosamente una solicitud sin protección. Cuando no puedas confirmar que el fallback está activo, configúralo en lugar de asumir que está activado.
  • Instrumenta los rechazos como su propia señal. Un rechazo es un HTTP 200, por lo que el monitoreo basado en tasas de error o respuestas 5xx nunca lo ve. Emite un evento por rechazo y uno por respuesta atendida mediante fallback (la entrada fallback_message en usage.iterations marca esta última), y luego alerta sobre la diferencia entre los dos conteos.
  • Ramifica según stop_reason o stop_details.type, no según content ni los campos internos de stop_details. El objeto stop_details siempre está presente en un rechazo, pero sus campos category y explanation pueden ser null. Verifica directamente que stop_reason sea igual a "refusal".

Próximos pasos

Evita pagar dos veces el costo de la caché de prompts cuando construyes el reintento tú mismo.

Cada valor de stop_reason y cómo manejarlo.

Cómo funciona el middleware del SDK, incluido el asistente de fallback ante rechazos.

Migra una aplicación existente a Claude Fable 5.1.

Was this page helpful?