Empezar aquí
Índice de la sección

Tu primera llamada

Anatomía de una petición a la API de mensajes: parámetros obligatorios y opcionales, forma de la respuesta, stop_reason, usage y errores.

Publicado 4 min de lectura

Una llamada a la API de mensajes es una petición HTTP con un modelo, un límite de salida y una lista de mensajes. El modelo devuelve un mensaje nuevo con rol assistant, el motivo por el que dejó de generar y el recuento de tokens consumidos. Todo lo demás (prompt de sistema, herramientas, razonamiento) son parámetros opcionales sobre esa base.

Si quieres aprenderlo con ejercicios, ve a Tu primera llamada a la API. Este artículo es la referencia.

La petición

flowchart LR
  A[Tu código] -- model, max_tokens, messages --> B[API de mensajes]
  B -- content, stop_reason, usage --> A

La API no guarda estado entre llamadas. Cada petición lleva la conversación entera que quieres que el modelo vea. Si quieres que recuerde algo, tienes que volver a enviarlo (ver La API de mensajes: roles y bloques).

Parámetros

ParámetroObligatorioTipoQué hace
modelSístringIdentificador del modelo. Ponlo en una constante.
max_tokensSíintLímite duro de tokens de salida. Si se alcanza, la respuesta se corta.
messagesSílistaConversación: objetos {"role", "content"} alternando user y assistant.
systemNostring o lista de bloquesInstrucciones fijas. Ver Prompt de sistema.
temperatureNofloatAleatoriedad del muestreo. Ver Temperatura.
stop_sequencesNolista de stringsCadenas que detienen la generación.
toolsNolistaHerramientas que el modelo puede pedir. Ver Uso de herramientas.
tool_choiceNoobjetoCómo elige herramienta. Ver tool_choice.
thinkingNoobjetoActiva el razonamiento. Ver Razonamiento y esfuerzo.
output_configNoobjetoEsfuerzo y formato de salida. Ver Salida estructurada.

Los valores típicos de cada parámetro y sus interacciones están en Parámetros: max_tokens, temperatura y compañía.

Ejemplo completo

import anthropic

MODEL = "claude-sonnet-5-5"
client = anthropic.Anthropic()

resp = client.messages.create(
    model=MODEL,
    max_tokens=512,
    system="Eres un asistente técnico. Responde en español, en tres frases como máximo.",
    messages=[{"role": "user", "content": "¿Qué es un token?"}],
)

if resp.stop_reason == "max_tokens":
    print("Aviso: respuesta cortada; sube max_tokens o pide algo más breve.")

texto = "".join(b.text for b in resp.content if b.type == "text")
print(texto)
print(resp.usage.input_tokens, resp.usage.output_tokens)
import Anthropic from "@anthropic-ai/sdk";

const MODEL = "claude-sonnet-5-5";
const client = new Anthropic();

const resp = await client.messages.create({
  model: MODEL,
  max_tokens: 512,
  system: "Eres un asistente técnico. Responde en español, en tres frases como máximo.",
  messages: [{ role: "user", content: "¿Qué es un token?" }],
});

if (resp.stop_reason === "max_tokens") {
  console.warn("Aviso: respuesta cortada; sube max_tokens o pide algo más breve.");
}

const texto = resp.content
  .filter((b) => b.type === "text")
  .map((b) => (b.type === "text" ? b.text : ""))
  .join("");
console.log(texto);
console.log(resp.usage.input_tokens, resp.usage.output_tokens);

Fíjate en dos detalles. Se concatena el texto de todos los bloques text, porque content es una lista y no tiene por qué tener un solo elemento. Y se comprueba stop_reason antes de dar la respuesta por buena.

La respuesta

CampoContenido
idIdentificador del mensaje. Guárdalo en tus trazas.
roleSiempre assistant.
contentLista de bloques: text, tool_use, thinking.
stop_reasonPor qué paró (tabla siguiente).
usageTokens de entrada, salida y caché.

stop_reason

ValorSignificaQué haces
end_turnEl modelo terminó de forma natural.Usa la respuesta.
max_tokensSe alcanzó el límite de salida.La respuesta está incompleta: sube el límite, pide menos o continúa.
stop_sequenceApareció una de tus stop_sequences.Esperado si las configuraste.
tool_useEl modelo pide ejecutar una herramienta.Ejecútala y devuelve un tool_result.
pause_turnSe pausó un turno largo (p. ej. con herramientas del servidor).Reenvía la conversación con la respuesta incluida para continuar.
refusalEl modelo se negó por motivos de seguridad.No reintentes igual; trata el caso en tu interfaz.

Más detalle en Stop reason.

usage

CampoQué cuenta
input_tokensTokens de entrada que no salen de caché.
output_tokensTokens generados, incluido el razonamiento si lo hay.
cache_creation_input_tokensTokens escritos en caché en esta llamada.
cache_read_input_tokensTokens leídos de caché.

Registra estos cuatro números en cada llamada desde el primer día. Son la base de Coste y latencia: medir antes de optimizar y de Prompt caching.

Para saber cuánto ocupa una petición antes de enviarla, usa client.messages.count_tokens(model=MODEL, messages=...) y lee .input_tokens.

Errores de la API

El SDK convierte los errores HTTP en excepciones y reintenta automáticamente algunos de ellos (límites de tasa, sobrecarga, fallos de red). El número de reintentos se configura con max_retries al crear el cliente.

HTTPCausa típicaReintentar
400Petición mal formada: roles que no alternan, tool_result sin su tool_use, parámetro inválido.No. Corrige la petición.
401Clave ausente o inválida.No.
403La clave no tiene permiso para ese recurso.No.
404Modelo o recurso inexistente.No. Revisa MODEL.
413Petición demasiado grande.No. Recorta el contexto.
429Límite de tasa superado.Sí, con espera exponencial.
500 / 529Error interno o sobrecarga temporal.Sí, con espera.
try:
    resp = client.messages.create(model=MODEL, max_tokens=256, messages=mensajes)
except anthropic.RateLimitError:
    ...  # espera y reintenta, o encola
except anthropic.APIStatusError as e:
    print(e.status_code, e.message)  # 4xx: corrige la petición
except anthropic.APIConnectionError:
    ...  # red: reintenta

La receta Reintentos y límites de tasa tiene una implementación completa con espera exponencial.

Errores frecuentes

  • Leer solo content[0].text. Falla cuando el primer bloque es thinking o tool_use. Filtra por tipo.
  • No mirar stop_reason. Una respuesta cortada por max_tokens parece válida hasta que el JSON no parsea.
  • max_tokens demasiado bajo con razonamiento activado. El razonamiento consume salida; la respuesta visible se queda sin espacio.
  • Nombres de modelo repartidos por el código. Cuando cambie el modelo, cambiarás un sitio y olvidarás tres.
  • Esperar que la API recuerde. No guarda estado: reenvía el historial.

Ver también