← Recursos / Claude API · Abril 2026
E
Equipo Expertos AI Builder
Builders & Creadores de contenido con IA
14 min de lectura
21 de Abril, 2026
Claude API Python Agentes IA + Código listo + Setup guiado

Tu primer agente
con Claude API
en 30 minutos

No hace falta un framework enorme. Con la API de Anthropic y 80 líneas de Python podés construir un agente que razona, usa herramientas y mantiene contexto entre turnos. Esta guía es el camino más corto al primer agente funcional.

"Un agente no es un chatbot con mejor prompt. Es un sistema que toma decisiones sobre qué herramientas usar y cuándo parar."

~80
Líneas de Python
3
Herramientas reales
30'
Para tenerlo corriendo
1

Entiende qué es un agente de verdad

Si alguna vez pagaste por una herramienta de IA que hacía exactamente lo que necesitabas, pero luego cambió de precio, desapareció o no se adaptaba a tu caso específico, esta guía es para ti. Antes de escribir una sola línea, necesitas tener claro el modelo mental correcto. Un agente no es simplemente "Claude con más instrucciones". La diferencia fundamental está en el loop de ejecución: un agente llama al modelo, evalúa si necesita usar una herramienta, la ejecuta, y vuelve a llamar al modelo con el resultado — hasta que decide que terminó.

La Claude API soporta esto nativamente con tool use (también llamado function calling). Le describes herramientas al modelo en formato JSON, y Claude decide autónomamente cuándo y cómo usarlas. Tu código solo necesita manejar el loop.

👤
Input del usuario
"Buscá el clima en Buenos Aires y guardalo en un archivo"
🧠
Claude (claude-sonnet-4-6)
Decide: usar tool_use → get_weather("Buenos Aires")
🔧
Tu código ejecuta la herramienta
Llama a la API del clima, obtiene JSON con datos
🧠
Claude recibe el resultado
Decide: usar save_file("clima.txt", datos) → respuesta final
Respuesta al usuario
"Guardé el clima de Buenos Aires en clima.txt: 22°C, parcialmente nublado."
🧠
Concepto clave: Claude no ejecuta las herramientas — te dice qué herramienta quiere usar y con qué argumentos. Vos las ejecutás y le devolvés el resultado. Esto te da control total sobre qué puede y qué no puede hacer el agente.
2

Setup en 5 minutos

Necesitás Python 3.9+ y la SDK oficial de Anthropic. Nada más. No hace falta LangChain, LlamaIndex ni ningún framework extra para este primer agente.

bash
# 1. Crear entorno virtual
python -m venv agente-env
source agente-env/bin/activate  # Mac/Linux
agente-env\Scripts\activate     # Windows

# 2. Instalar la SDK de Anthropic
pip install anthropic

# 3. Setear tu API key (obtenela en console.anthropic.com)
export ANTHROPIC_API_KEY="sk-ant-..."

# Verificar que funciona
python -c "import anthropic; print('SDK lista ✓')"
🔑
Sobre la API key: Nunca la hardcodees en el código. Usá variables de entorno o un archivo .env con python-dotenv. Si la pushás a GitHub por accidente, Anthropic la desactiva automáticamente — pero es un dolor de cabeza evitable.

El modelo recomendado para agentes en 2026 es claude-sonnet-4-6. Tiene el mejor balance entre capacidad de razonamiento, velocidad y costo. Para agentes que necesitan razonamiento complejo o múltiples pasos encadenados, considerá claude-opus-4-7.

✗ Para agentes evitá claude-haiku-4-5 — demasiado rápido para razonamiento profundo, tiende a saltear pasos en cadenas de tools complejas.
✓ Recomendado claude-sonnet-4-6 — razona bien, usa tools correctamente, velocidad aceptable, costo manejable.

💡 En Expertos AI Builder usamos esto para el agente de investigación de mercado de nuestros clientes. En lugar de pagar $200/mes por una herramienta SaaS, el cliente tiene su propio agente personalizado corriendo en su máquina, con sus herramientas específicas.

3

Definí tus herramientas

Las herramientas son funciones Python normales, pero con una descripción en JSON que le dice a Claude qué hacen y qué parámetros aceptan. La calidad de esta descripción impacta directamente en qué tan bien el modelo decide cuándo usarlas.

Para este ejemplo construimos un agente con 3 herramientas: buscar información en la web, leer un archivo y escribir un archivo. Es suficiente para tareas de investigación y síntesis reales.

python
# tools.py — Definición de herramientas para el agente

import os
import json
import urllib.request

# ── Esquemas JSON que Claude lee ──────────────────────
TOOLS = [
    {
        "name": "web_search",
        "description": """Busca información actualizada en la web.
        Usá esta herramienta cuando necesites datos que pueden
        haber cambiado recientemente o que no tenés en contexto.""",
        "input_schema": {
            "type": "object",
            "properties": {
                "query": {
                    "type": "string",
                    "description": "Consulta de búsqueda. Sé específico."
                }
            },
            "required": ["query"]
        }
    },
    {
        "name": "read_file",
        "description": "Lee el contenido de un archivo local.",
        "input_schema": {
            "type": "object",
            "properties": {
                "path": {
                    "type": "string",
                    "description": "Ruta al archivo a leer."
                }
            },
            "required": ["path"]
        }
    },
    {
        "name": "write_file",
        "description": "Escribe contenido en un archivo. Crea el archivo si no existe.",
        "input_schema": {
            "type": "object",
            "properties": {
                "path": { "type": "string" },
                "content": { "type": "string", "description": "Texto a guardar." }
            },
            "required": ["path", "content"]
        }
    }
]

# ── Implementaciones reales ────────────────────────────
def web_search(query: str) -> str:
    # DuckDuckGo Instant Answer API (sin key, gratis)
    url = f"https://api.duckduckgo.com/?q={urllib.parse.quote(query)}&format=json&no_html=1"
    with urllib.request.urlopen(url) as r:
        data = json.loads(r.read())
    abstract = data.get("AbstractText", "")
    related = [t["Text"] for t in data.get("RelatedTopics", [])[:3] if "Text" in t]
    return abstract or "\n".join(related) or "Sin resultados encontrados."

def read_file(path: str) -> str:
    if not os.path.exists(path):
        return f"Error: el archivo '{path}' no existe."
    with open(path, "r", encoding="utf-8") as f:
        return f.read()

def write_file(path: str, content: str) -> str:
    with open(path, "w", encoding="utf-8") as f:
        f.write(content)
    return f"Archivo guardado en '{path}' ({len(content)} caracteres)."

# Mapa para ejecutar tools por nombre
TOOL_MAP = {
    "web_search": lambda **kw: web_search(kw["query"]),
    "read_file":  lambda **kw: read_file(kw["path"]),
    "write_file": lambda **kw: write_file(kw["path"], kw["content"]),
}
✍️
La descripción importa más que el código: Claude decide qué herramienta usar basándose en el campo description. Invierte tiempo en escribir descripciones precisas. Incluye cuándo usarla y cuándo NO. Un ejemplo: "NO uses esta herramienta si ya tienes la información en el contexto de la conversación."
4

El loop del agente

El corazón del agente es un loop while simple. Llamás a Claude, revisás si quiere usar una herramienta, la ejecutás, añadís el resultado al historial, y volvés a llamar. El loop termina cuando Claude responde con stop_reason == "end_turn" — es decir, cuando decide que terminó.

1
Llamada a la API
Enviás el historial de mensajes + definición de tools. Claude procesa y responde.
2
¿Quiere usar una herramienta?
Si stop_reason == "tool_use", hay tool_use blocks en el response. Si es "end_turn", terminaste.
3
Ejecutar + devolver resultado
Corrés la función Python correspondiente y añadís el resultado como tool_result al historial.
Volver al paso 1
Ahora Claude tiene el resultado y decide el siguiente paso. Puede usar otra tool o concluir.
python
# agent.py — Loop principal del agente

import anthropic
from tools import TOOLS, TOOL_MAP

client = anthropic.Anthropic()

def run_agent(user_message: str, system: str = "") -> str:
    messages = [{"role": "user", "content": user_message}]

    while True:
        response = client.messages.create(
            model="claude-sonnet-4-6",
            max_tokens=4096,
            system=system,
            tools=TOOLS,
            messages=messages,
        )

        # Agente terminó — devolver texto final
        if response.stop_reason == "end_turn":
            return response.content[0].text

        # Procesar tool calls
        tool_results = []
        for block in response.content:
            if block.type == "tool_use":
                tool_fn = TOOL_MAP.get(block.name)
                result = tool_fn(**block.input) if tool_fn else "Tool no encontrada."
                print(f"  🔧 {block.name}({block.input}) → {str(result)[:80]}...")
                tool_results.append({
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": str(result),
                })

        # Añadir al historial: respuesta del asistente + resultados
        messages.append({"role": "assistant", "content": response.content})
        messages.append({"role": "user", "content": tool_results})


# Correr el agente
if __name__ == "__main__":
    resultado = run_agent(
        "Buscá información sobre Claude Sonnet 4.6, "
        "resumila en 3 puntos y guardala en resumen.txt"
    )
    print("\n✅ Agente terminó:", resultado)
⚠️
Límite de iteraciones: Siempre agregá un contador al loop: if iterations > 10: break. Un agente mal configurado puede entrar en un loop infinito de tool calls que consume tokens (y plata) rápidamente. 10 iteraciones es suficiente para el 95% de los casos.
5

El system prompt correcto para agentes

El system prompt de un agente no es el mismo que el de un chatbot. Acá no describes "cómo hablar" — describes cómo razonar: qué herramientas tiene disponibles y cuándo usarlas, cómo manejar errores, cuándo pedir clarificación y cuándo proceder.

Lo que necesita incluir el system prompt
ROL Y OBJETIVO
Qué tipo de agente es. Qué tarea principal resuelve. En una oración.
TOOLS DISPONIBLES
Descripción breve de qué hace cada tool. Claude ya tiene el schema, pero el contexto narrativo ayuda.
CÓMO RAZONAR
Antes de actuar, pensá. Descomponé la tarea. Verificá cada resultado antes del siguiente paso.
MANEJO DE ERRORES
Si una tool falla, qué debe hacer: reintentar, usar alternativa, o informar al usuario.

Sé explícito con los límites: "No ejecutes acciones destructivas sin confirmar con el usuario."

Pide razonamiento explícito: "Antes de usar una herramienta, explica en una oración por qué la necesitas."

Definí el formato de respuesta final: El agente debe saber cómo terminar. Sin esto, puede ser verbose innecesariamente.

No repitas lo que ya está en el tool schema: Evitá redundancia. Si la description de la tool ya explica cuándo usarla, no lo repitas en el system.

Todo junto: listo para correr

Este es el agente completo en un solo archivo. Cópialo, configura tu API key, y tienes un agente funcional en minutos.

python — agente_completo.py
import anthropic  # Cliente oficial de la API de Anthropic
import json       # Para manejar las respuestas de las herramientas

# Inicializar el cliente con la API key del entorno
client = anthropic.Anthropic()

# Definir las herramientas disponibles para el agente
tools = [
    {
        "name": "buscar_informacion",
        "description": "Busca información relevante en internet sobre un tema",
        "input_schema": {
            "type": "object",
            "properties": {
                "query": {
                    "type": "string",
                    "description": "El término o pregunta a buscar"
                }
            },
            "required": ["query"]  # El campo query es obligatorio
        }
    },
    {
        "name": "guardar_resultado",
        "description": "Guarda el resultado final en un archivo de texto",
        "input_schema": {
            "type": "object",
            "properties": {
                "contenido": {"type": "string"},
                "nombre_archivo": {"type": "string"}
            },
            "required": ["contenido", "nombre_archivo"]
        }
    }
]

def ejecutar_herramienta(nombre: str, parametros: dict) -> str:
    """Ejecuta la herramienta solicitada y retorna el resultado como string"""
    if nombre == "buscar_informacion":
        # En producción, aquí iría la llamada real a una API de búsqueda
        return f"Resultados encontrados para '{parametros['query']}': [resultado simulado]"
    elif nombre == "guardar_resultado":
        with open(parametros["nombre_archivo"], "w", encoding="utf-8") as f:
            f.write(parametros["contenido"])  # Guardar en disco
        return f"Archivo '{parametros['nombre_archivo']}' guardado correctamente"
    return "Herramienta no reconocida"

def correr_agente(tarea: str, max_iteraciones: int = 10) -> str:
    """
    Ejecuta el loop del agente hasta completar la tarea o alcanzar el límite.
    Retorna el resultado final como string.
    """
    mensajes = [{"role": "user", "content": tarea}]  # Historial de conversación

    for iteracion in range(max_iteraciones):
        print(f"[Iteración {iteracion + 1}]")

        # Llamar a la API de Claude con las herramientas disponibles
        respuesta = client.messages.create(
            model="claude-sonnet-4-6",      # Modelo a usar
            max_tokens=4096,                # Máximo de tokens en la respuesta
            tools=tools,                    # Herramientas disponibles
            messages=mensajes               # Historial de la conversación
        )

        # Verificar si Claude terminó de razonar
        if respuesta.stop_reason == "end_turn":
            texto_final = next(
                (b.text for b in respuesta.content if hasattr(b, "text")),
                "Tarea completada."
            )
            return texto_final  # Retornar respuesta final

        # Si Claude quiere usar una herramienta
        if respuesta.stop_reason == "tool_use":
            mensajes.append({"role": "assistant", "content": respuesta.content})

            resultados_herramientas = []
            for bloque in respuesta.content:
                if bloque.type == "tool_use":
                    print(f"  → Usando herramienta: {bloque.name}")
                    resultado = ejecutar_herramienta(bloque.name, bloque.input)

                    resultados_herramientas.append({
                        "type": "tool_result",
                        "tool_use_id": bloque.id,  # ID para correlacionar la respuesta
                        "content": resultado
                    })

            # Agregar resultados al historial para que Claude continúe
            mensajes.append({"role": "user", "content": resultados_herramientas})

    return "Límite de iteraciones alcanzado."  # Fallback si no termina

# Punto de entrada
if __name__ == "__main__":
    resultado = correr_agente("Investiga las mejores prácticas de prompting para Claude y guarda un resumen en resumen.txt")
    print(f"\nResultado final:\n{resultado}")
Captura — Output real del agente corriendo en terminal

Diseñá tu agente con Claude

Usá este prompt para que Claude te ayude a diseñar el sistema prompt y las herramientas de tu agente específico. Antes de escribir código, primero diseñá la arquitectura.

Prompt maestro — Diseño de agente

Necesito diseñar un agente con la Claude API para el siguiente caso de uso: [DESCRIPCIÓN DEL AGENTE: qué debe hacer, quién lo va a usar, en qué contexto] Ayudame a diseñar: 1. HERRAMIENTAS (tools): - Listá las herramientas mínimas necesarias - Para cada una: nombre, descripción precisa, parámetros con tipos - Indicá cuándo usarla y cuándo NO 2. SYSTEM PROMPT: - Rol del agente en una oración - Proceso de trabajo (pasos numerados) - Límites y restricciones explícitas - Formato de respuesta final 3. CASOS LÍMITE: - Qué pasa si una herramienta falla - Qué pasa si el usuario pide algo fuera del scope - Cuándo debe pedir clarificación vs proceder 4. PROMPT DE PRUEBA: - Dame 3 inputs de prueba que cubran el caso principal, un caso límite y un caso de error Contexto técnico: Python, SDK oficial de Anthropic, modelo claude-sonnet-4-6. Formato: sé específico y directo. Código donde sea útil.

[DESCRIPCIÓN DEL AGENTE] [CASO DE USO] [CONTEXTO]

Ejemplo de resultado

Agente iniciado correctamente. He analizado la tarea: necesito buscar información sobre el tema X, procesarla y generar un resumen. Comenzaré con la búsqueda. [Iteración 1] → Usando herramienta: buscar_informacion con query='mejores prácticas prompting Claude'

Flujo recomendado: Primero corre este prompt para diseñar la arquitectura. Luego usa el código base de esta guía y reemplaza las herramientas y el system prompt con lo que Claude te diseñó. En 30 minutos tienes el agente corriendo.
Bonus: debug de agentes
Prompt — Debug de tool use

Mi agente con Claude API está [PROBLEMA: no usando las tools / usando la tool equivocada / entrando en loop / respondiendo antes de terminar]. Este es mi system prompt actual: [SYSTEM PROMPT] Estas son las tools que definí: [DEFINICIÓN JSON DE TOOLS] Este es el input que falla: [INPUT DE PRUEBA] Este es el output actual (o el historial de tool calls): [OUTPUT / HISTORIAL] Diagnosticá qué está mal y decime exactamente qué cambiar. Priorizá cambios en las descriptions de las tools antes de tocar el system prompt.

[PROBLEMA] [SYSTEM PROMPT] [TOOL DEFINITIONS]

Ejemplo de resultado

Diagnóstico: el problema está en la descripción de tu tool web_search. Al decir "busca información" sin especificar cuándo NO usarla, Claude la llama en cada iteración aunque ya tenga los datos en contexto. Cambio recomendado: agrega "NO uses esta herramienta si la información ya está disponible en el historial de conversación." Eso solo debería resolver el loop.

¿Cómo aplicarlo según tu negocio?

🏢 Si tienes una agencia

Construye agentes personalizados para tus clientes como parte de tu oferta de servicio premium. Un agente de research, uno de generación de reportes, uno de monitoreo de competencia. Entregables que el cliente no puede obtener en ningún SaaS.

🛍️ Si vendes productos o servicios

Un agente que revisa tu inbox de soporte cada mañana, clasifica los tickets por urgencia y redacta las primeras respuestas. Reduces el tiempo de atención al cliente en un 60% sin perder personalización.

🎬 Si eres creador de contenido

Un agente que analiza tus métricas de la semana, identifica qué contenido funcionó mejor y genera 5 ideas de videos para la próxima semana basadas en tus propios datos de rendimiento.

Extendé tu agente

Con el agente base funcionando, estos son los próximos pasos naturales.

Prompt caching: Cacheá el system prompt con cache_control: {"type": "ephemeral"} para ahorrar hasta 90% del costo en conversaciones largas.

Streaming: Usá client.messages.stream() para mostrar la respuesta en tiempo real mientras el agente trabaja.

Memoria persistente: Guardá el historial de messages en un archivo JSON entre sesiones para que el agente recuerde conversaciones anteriores.

Logging estructurado: Loguiá cada tool call con timestamp, inputs, outputs y tokens usados. Te va a salvar en el debugging.

MCP servers: Conectá el agente a MCP servers para darle acceso a bases de datos, APIs externas o tu propio file system con permisos granulares.

Siguiente →

Setup de Claude Code con MCP servers

El paso natural después de tu primer agente.

Explorar

Ver todos los recursos →

Todas las guías esperando.

¿Quieres ir más profundo?

En la comunidad tienes el workshop completo, plantillas y soporte directo.

VER LA COMUNIDAD →

¿Querés más recursos
como este?

Todas las guías son gratis. Construidas con Claude Code, publicadas para la comunidad.

Ver todas las guías