Certificación: Claude Certified Developer – Foundations

Lección 2 de 9 · 11 min de lectura

La API de Claude a fondo: endpoint, parámetros y streaming

Domina el endpoint de mensajes de Claude, los system prompts, roles de usuario y asistente, parámetros clave como max_tokens y temperature, streaming, y estrategias de manejo de errores. Todo lo que necesitas para integrar Claude en tu aplicación.

La API de Claude a fondo: endpoint, parámetros y streaming

Cuando integras Claude en una aplicación, trabajas casi siempre con un único endpoint: el de mensajes. Este es el corazón de cualquier interacción con Claude. En esta lección aprenderás cómo funciona realmente, qué parámetros controlan el comportamiento de los modelos y cómo manejar respuestas, errores y reintentos. Verás ejemplos reales de código y comprenderás las decisiones detrás de cada parámetro.

Nada de esto es teórico: el examen Developer validará que sabes implementar llamadas robustas a la API, entiendes cuándo usar cada parámetro y cómo estructurar conversaciones.

El endpoint de mensajes: tu punto de entrada

La API de Claude expone un único endpoint para crear mensajes. Desde tu cliente (Python, Node.js, etc.) realizas una solicitud POST con:

  • Modelo (model): el identificador del modelo a usar (ej. claude-3-5-sonnet-20241022).
  • Mensajes (messages): un array de objetos con el historial de conversación.
  • Parámetros opcionales: que controlan temperatura, tokens máximos, detención, streaming, etc.

Este endpoint es stateless: tú administras el historial. Cada llamada es independiente. Si quieres mantener contexto entre turnos, debes pasar todos los mensajes anteriores en cada solicitud.

from anthropic import Anthropic

client = Anthropic()

# Primera llamada: mensaje sin historial
response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "¿Cuál es la capital de Francia?"}
    ]
)

print(response.content[0].text)

Esta es la estructura mínima. El endpoint devuelve un objeto con la respuesta del asistente, número de tokens usados y metadatos.

System prompt: instrucciones globales para Claude

El system parameter define las instrucciones generales que Claude sigue en toda la conversación. No es un mensaje; es una directiva que modelan el comportamiento.

A diferencia de los mensajes usuario-asistente, el system prompt:

  • Se envía una sola vez al inicio.
  • No aparece en el historial de la conversación desde la perspectiva del usuario.
  • Establece el contexto, el tono, restricciones y responsabilidades.
response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    system="Eres un asistente especializado en derecho fiscal español. Responde en español neutro. Si no estás seguro, dilo claramente.",
    messages=[
        {"role": "user", "content": "¿Qué cambios hubo en el IVA en 2023?"}
    ]
)

Para el examen, recuerda: el system prompt es lo primero que Claude lee. Afecta a todas las respuestas. Úsalo para definir rol, restricciones, formato y tono.

Roles: user y assistant

En el array messages, cada mensaje tiene un role:

  • "user": mensaje del usuario final.
  • "assistant": respuesta previa de Claude (para mantener historial en multi-turn).

Alternando roles, construyes una conversación:

messages = [
    {"role": "user", "content": "¿Qué es la fotosíntesis?"},
    {"role": "assistant", "content": "La fotosíntesis es el proceso biológico..."},
    {"role": "user", "content": "¿Y cómo afecta al cambio climático?"}
]

response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    messages=messages
)

Cuando envías el historial, Claude lee todo y genera la respuesta siguiente. Esto es crucial: tu aplicación mantiene el estado. No hay sesiones server-side en la API.

Parámetros clave: temperature, max_tokens, stop_sequences

max_tokens

Define el número máximo de tokens que Claude puede generar en la respuesta. Es obligatorio especificarlo explícitamente (Anthropic no usa un valor por defecto global).

  • Rango típico: 1 a varios miles, dependiendo del modelo.
  • Uso: Limita costos, evita respuestas infinitas, asegura que la aplicación responda en tiempo esperado.
  • Nota: Si la respuesta alcanza max_tokens, se corta. Verifica el campo stop_reason en la respuesta.
response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=256,  # Respuesta breve
    messages=[{"role": "user", "content": "Escribe un poema"}]
)

temperature

Controla la aleatoriedad de la salida. Valores entre 0 y 1:

  • 0: respuestas deterministas, enfocadas, ideales para tareas analíticas.
  • 1: máxima creatividad, variabilidad, adecuada para generación creativa.
  • Defecto: alrededor de 1 (depende del modelo).
# Respuesta determinista para un análisis
response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    temperature=0,
    messages=[{"role": "user", "content": "Analiza este JSON..."}]
)

# Respuesta creativa para brainstorming
response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    temperature=1,
    messages=[{"role": "user", "content": "Ideas para un producto nuevo"}]
)

stop_sequences

Array de strings que detienen la generación inmediatamente al encontrarse. Útil para controlar el formato de salida.

response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    stop_sequences=["\n\n", "---"],
    messages=[{"role": "user", "content": "Lista 3 ideas"}]
)

En el examen, espera preguntas sobre cuándo usar cada parámetro: temperatura para precisión vs. creatividad, max_tokens para control de coste, stop_sequences para formatos predefinidos.

Streaming: respuestas en tiempo real

Las respuestas normales llegarán completas. Para aplicaciones interactivas (chatbots, interfaces web), el streaming devuelve texto conforme se genera, sin esperar al final.

En lugar de messages.create(), usas messages.stream():

with client.messages.stream(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Cuéntame una historia"}]
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

Cada evento de stream entrega fragmentos de texto. La aplicación los procesa en tiempo real, mejorando la experiencia de usuario.

Ventajas: Percepción de respuesta más rápida, mejor UX. Desventajas: Más complejo de manejar, no puedes revisar la respuesta completa antes de enviarla.

Para el examen: sé capaz de diferenciar cuándo es apropiado streaming (interfaces reales) vs. respuestas completas (batch processing).

Manejo de errores y reintentos

Las llamadas a la API pueden fallar por múltiples razones:

  • Rate limiting (429): Excediste el límite de solicitudes. Espera e intenta de nuevo.
  • Timeout (timeout): La solicitud tardó demasiado. Reintentar puede ayudar.
  • Authentication error (401): Clave API inválida o expirada.
  • Model not found (404): El modelo no existe o no está disponible.
  • Server error (5xx): Problema en la infraestructura de Anthropic.

La librería oficial de Anthropic incluye reintentos automáticos para errores transitorios (5xx, 429), pero tú debes gestionar la lógica de reintento con backoff exponencial para casos críticos:

import time
from anthropic import APIError, RateLimitError

def llamada_con_reintento(prompt, max_intentos=3):
    for intento in range(max_intentos):
        try:
            response = client.messages.create(
                model="claude-3-5-sonnet-20241022",
                max_tokens=1024,
                messages=[{"role": "user", "content": prompt}]
            )
            return response
        except RateLimitError:
            espera = 2 ** intento  # Backoff exponencial
            print(f"Rate limit. Esperando {espera}s...")
            time.sleep(espera)
        except APIError as e:
            print(f"Error: {e}")
            raise
    raise Exception("Máximo de intentos alcanzado")

Puntos clave:

  • Siempre captura excepciones específicas.
  • Usa backoff exponencial (esperas: 1s, 2s, 4s, etc.).
  • No reintentes errores como 401 (credenciales inválidas) o 404 (modelo no existe).
  • Log es tu amigo: registra cada intento para debugging.

Primera llamada explicada: paso a paso

Te mostramos un ejemplo completo anotado:

from anthropic import Anthropic

client = Anthropic()  # Lee ANTHROPIC_API_KEY del entorno

# 1. Preparar el request
response = client.messages.create(
    # 2. Especificar modelo
    model="claude-3-5-sonnet-20241022",
    
    # 3. System prompt (instrucciones globales)
    system="Eres un asistente de análisis de datos. Sé conciso y preciso.",
    
    # 4. Máximo de tokens en la respuesta
    max_tokens=256,
    
    # 5. Temperatura (0 = determinista)
    temperature=0,
    
    # 6. El historial de mensajes
    messages=[
        {
            "role": "user",
            "content": "¿Cuál es la media de [1, 2, 3, 4, 5]?"
        }
    ]
)

# 7. Acceder al contenido de la respuesta
print(response.content[0].text)

# 8. Ver metadatos
print(f"Tokens usados: {response.usage.input_tokens + response.usage.output_tokens}")
print(f"Stop reason: {response.stop_reason}")  # "end_turn" o "max_tokens"

Flujo:

  1. El cliente envía el request con modelo, sistema, max_tokens, temperatura y mensajes.
  2. Anthropic procesa la solicitud.
  3. Devuelve un objeto Message con la respuesta y metadatos.
  4. Accedes al texto con response.content[0].text.
  5. Verificas stop_reason para saber si la respuesta fue completa o se cortó.

Para el examen

Conceptos a dominar

  1. Endpoint de mensajes: es el único endpoint que usas para interactuar con Claude. Stateless, tú gestionas el historial.
  2. System prompt: directiva global que define rol, restricciones y tono. Se envía una sola vez, no aparece en el historial del usuario.
  3. Roles (user/assistant): alternan en el array messages para construir multi-turn conversations. La aplicación mantiene el estado.
  4. max_tokens: obligatorio, limita la longitud de la respuesta y controla costos.
  5. temperature: controla aleatoriedad (0 = determinista, 1 = creativo).
  6. stop_sequences: detiene generación al encontrar strings específicos.
  7. Streaming: apropiado para interfaces interactivas, más lento para batch.
  8. Errores y reintentos: captura excepciones específicas, usa backoff exponencial, no reintentas errores permanentes.

Preguntas tipo test

Pregunta 1: ¿Cuál es la responsabilidad principal de tu aplicación al usar la API de Claude?

A) Almacenar todos los mensajes en el servidor de Anthropic.
B) Mantener el historial de conversación y pasarlo en cada llamada.
C) Crear una sesión persistente con Anthropic.
D) Usar únicamente temperature = 0 para máxima precisión.

Respuesta correcta: B. La API es stateless. Tu aplicación es responsable de guardar y pasar el historial en cada solicitud.


Pregunta 2: ¿Qué parámetro es obligatorio en cada llamada a messages.create()?

A) system
B) temperature
C) max_tokens
D) stop_sequences

Respuesta correcta: C. Debes especificar siempre max_tokens explícitamente. No hay un valor por defecto global.


Pregunta 3: Tu aplicación necesita procesar 1000 solicitudes al mismo tiempo y obtener respuestas rápido. ¿Debería usar streaming?

A) Sí, siempre es más rápido.
B) No, streaming es para interfaces interactivas donde el usuario ve texto en tiempo real.
C) Depende del color de la interfaz.
D) El streaming no existe en la API de Claude.

Respuesta correcta: B. Streaming es útil para UX interactiva, no para batch processing masivo. Sin streaming es más simple y apropiado para este caso.


Pregunta 4: Recibiste un error 429 (RateLimitError). ¿Cuál es la acción recomendada?

A) Fallar inmediatamente.
B) Reintentar con backoff exponencial.
C) Cambiar la temperature.
D) Usar un modelo diferente.

Respuesta correcta: B. Error 429 es transitorio. Usa backoff exponencial: espera 1s, luego 2s, luego 4s, etc., y reintenta.


Pregunta 5: ¿Qué es lo primero que Claude lee cuando procesa una solicitud?

A) El primer mensaje del usuario.
B) El parámetro temperature.
C) El system prompt.
D) El max_tokens.

Respuesta correcta: C. El system prompt se procesa primero y define el contexto global para toda la conversación.


Pregunta 6: Necesitas una respuesta determinista para un análisis. ¿Qué temperature deberías usar?

A) temperature = 1
B) temperature = 0.5
C) temperature = 0
D) No importa, la temperature no afecta.

Respuesta correcta: C. temperature = 0 genera respuestas deterministas y enfocadas, ideales para análisis.

Para recordar

  • El endpoint de mensajes es stateless: tu aplicación gestiona todo el historial. Cada llamada es independiente.
  • System prompt, max_tokens y temperature son pilares: el primero define comportamiento, el segundo es obligatorio y controla costos, el tercero afecta aleatoriedad.
  • Streaming es para interactividad en tiempo real: no para batch processing. Entiende el tradeoff UX vs. complejidad.
  • Los errores transitorios (429, 5xx) se reintenta con backoff exponencial: los permanentes (401, 404) fallan inmediatamente. Siempre loguea.

Próxima lección: Prompt engineering para desarrolladores — Técnicas avanzadas para escribir prompts robustos, ejemplos (few-shot, chain-of-thought), y cómo testear y iterar prompts en producción.