Cómo construir tu primer agente con la API de Anthropic: guía paso a paso con código real

Cómo construir tu primer agente con la API de Anthropic: guía paso a paso con código real
Foto de Xinyi Wen en Unsplash

El problema con los agentes de IA que nadie te cuenta

La mayoría de los tutoriales sobre agentes de IA te muestran el resultado final y omiten los detalles que realmente importan: cómo estructuras el bucle de razonamiento, cómo manejas errores de herramientas y por qué el 80% de los agentes fallan en producción por una mala gestión del contexto. Este artículo no hace eso.

Vamos a construir un agente funcional con la API de Anthropic (Claude) desde cero, usando Python, con código real que puedes ejecutar hoy. El agente podrá buscar información en la web, hacer cálculos y decidir cuándo ya tiene suficiente contexto para responder. Eso es un agente real, no un chatbot con nombre bonito.

Por qué Anthropic y no otra API

Claude destaca en una capacidad concreta que importa para agentes: el seguimiento de instrucciones complejas con contextos largos. Su ventana de contexto de hasta 200K tokens y su soporte nativo para tool use (uso de herramientas) lo hacen especialmente adecuado para bucles agénticos donde el modelo necesita razonar en múltiples pasos sin perder el hilo. No es marketing; es una decisión arquitectónica que se nota cuando el agente lleva 10 iteraciones encadenadas.

Requisitos previos

  • Python 3.9+
  • Una clave de API de Anthropic (ANTHROPIC_API_KEY)
  • Librería oficial: pip install anthropic

Arquitectura del agente: el bucle ReAct

El patrón más robusto para agentes simples es ReAct (Reason + Act): el modelo razona sobre qué herramienta usar, la ejecuta, observa el resultado e itera hasta tener una respuesta final. Con la API de Anthropic, esto se implementa mediante el campo tools en la llamada y el manejo de tool_use en la respuesta.

Paso 1: Definir las herramientas disponibles

Las herramientas son funciones que el modelo puede invocar. Las defines con un esquema JSON que Claude interpreta para saber cuándo y cómo usarlas.

tools = [
    {
        "name": "calcular",
        "description": "Evalúa una expresión matemática simple. Usa esto para cualquier cálculo numérico.",
        "input_schema": {
            "type": "object",
            "properties": {
                "expresion": {
                    "type": "string",
                    "description": "Expresión matemática a evaluar, e.g. '15 * 4 + 200'"
                }
            },
            "required": ["expresion"]
        }
    },
    {
        "name": "buscar_dato",
        "description": "Recupera un dato simulado de una base de conocimiento interna.",
        "input_schema": {
            "type": "object",
            "properties": {
                "clave": {
                    "type": "string",
                    "description": "Clave del dato a recuperar, e.g. 'precio_producto_A'"
                }
            },
            "required": ["clave"]
        }
    }
]

Paso 2: Implementar las funciones reales

def ejecutar_herramienta(nombre: str, inputs: dict) -> str:
    if nombre == "calcular":
        try:
            resultado = eval(inputs["expresion"], {"__builtins__": {}}, {})
            return str(resultado)
        except Exception as e:
            return f"Error al calcular: {e}"

    if nombre == "buscar_dato":
        base_conocimiento = {
            "precio_producto_A": "450 euros",
            "stock_producto_A": "120 unidades",
            "margen_objetivo": "0.35"
        }
        return base_conocimiento.get(inputs["clave"], "Dato no encontrado")

    return "Herramienta no reconocida"

Nota de seguridad: el uso de eval aquí es solo demostrativo. En producción, usa librerías como sympy o numexpr para evaluar expresiones matemáticas de forma segura.

Paso 3: El bucle agéntico principal

import anthropic

client = anthropic.Anthropic()

def ejecutar_agente(pregunta_usuario: str) -> str:
    mensajes = [{"role": "user", "content": pregunta_usuario}]

    while True:
        respuesta = client.messages.create(
            model="claude-opus-4-5",
            max_tokens=1024,
            tools=tools,
            messages=mensajes
        )

        # Si el modelo quiere usar herramientas
        if respuesta.stop_reason == "tool_use":
            # Añadir la respuesta del modelo al historial
            mensajes.append({"role": "assistant", "content": respuesta.content})

            # Procesar cada herramienta solicitada
            resultados_herramientas = []
            for bloque in respuesta.content:
                if bloque.type == "tool_use":
                    resultado = ejecutar_herramienta(bloque.name, bloque.input)
                    resultados_herramientas.append({
                        "type": "tool_result",
                        "tool_use_id": bloque.id,
                        "content": resultado
                    })

            # Devolver los resultados al modelo
            mensajes.append({"role": "user", "content": resultados_herramientas})

        else:
            # El modelo tiene una respuesta final
            for bloque in respuesta.content:
                if hasattr(bloque, "text"):
                    return bloque.text

# Ejemplo de uso
respuesta = ejecutar_agente(
    "¿Cuánto ingreso generaría vender todo el stock del producto A al precio actual?"
)
print(respuesta)

Qué hace el agente en este ejemplo

Ante la pregunta sobre ingresos, Claude razona que necesita dos datos: el precio y el stock. Llama a buscar_dato dos veces, recibe «450 euros» y «120 unidades», luego invoca calcular con la expresión 450 * 120 y finalmente responde: «Vender todo el stock generaría 54.000 euros». Todo en un bucle automático, sin que el usuario intervenga.

Conclusión y siguiente paso

Con menos de 60 líneas de código tienes un agente que razona, actúa y observa. La arquitectura que acabas de implementar escala directamente: puedes añadir herramientas de búsqueda web, acceso a bases de datos o llamadas a APIs externas simplemente ampliando el diccionario de herramientas y la función ejecutar_herramienta.

El siguiente paso concreto: añade una herramienta de búsqueda real usando la API de Brave Search o Tavily, limita el número máximo de iteraciones del bucle a 10 para evitar bucles infinitos en producción, y registra cada llamada a herramienta en un log estructurado. Con eso, tienes un agente listo para entornos reales.