Cómo hacer un agente de IA en Claude
Construye un agente autónomo con tool use que busca, razona y ejecuta acciones usando la API de Claude.
- Python 3.9+ instalado
- Cuenta en console.anthropic.com con API key
- Créditos de API activos (mínimo 5 USD)
- Conocimientos básicos de async/await y funciones en Python
- Terminal y editor de código
- Qué es un agente de IA y cómo funciona el ciclo agéntico (loop de razonamiento-acción)
- Cómo definir herramientas (tools) que Claude puede invocar con tool use
- Cómo implementar el bucle de ejecución que conecta Claude con tus funciones reales
- Cómo dar memoria y contexto persistente al agente
- Buenas prácticas para controlar costes y evitar loops infinitos
Instalar el SDK y configurar la API key
Un agente de IA no es solo una llamada a un modelo: es un bucle donde Claude decide qué acciones tomar, ejecuta herramientas y usa los resultados para seguir razonando hasta cumplir un objetivo. Antes de programar el bucle, prepara el entorno. Instala el SDK oficial de Anthropic y guarda tu API key como variable de entorno (nunca la escribas directamente en el código). En España y LATAM el pago de créditos se hace con tarjeta en dólares; revisa que tengas saldo. Crea un entorno virtual para aislar dependencias. La variable ANTHROPIC_API_KEY es la que el SDK lee automáticamente, así que no necesitas pasarla explícitamente al cliente si la exportas.
python -m venv venv
source venv/bin/activate # En Windows: venv\Scripts\activate
pip install anthropic
export ANTHROPIC_API_KEY="sk-ant-tu-clave-aqui"Definir las herramientas del agente
Un agente útil necesita herramientas: funciones reales que Claude puede invocar. Cada tool se describe con un esquema JSON que le dice a Claude qué hace, qué parámetros acepta y de qué tipo son. Claude no ejecuta el código: decide cuándo llamarla y con qué argumentos, y tú ejecutas la función en tu entorno. Aquí definimos dos herramientas de ejemplo: una calculadora y una simulación de búsqueda meteorológica. La calidad de la descripción (description) es crítica: Claude decide cuándo usar cada tool basándose en ese texto, así que sé explícito sobre cuándo y para qué sirve. El campo input_schema sigue el estándar JSON Schema con properties y required.
tools = [
{
"name": "calcular",
"description": "Evalúa una expresión matemática y devuelve el resultado numérico. Úsala siempre que necesites hacer cálculos precisos.",
"input_schema": {
"type": "object",
"properties": {
"expresion": {
"type": "string",
"description": "Expresión matemática, ej: '2500 * 1.21'"
}
},
"required": ["expresion"]
}
},
{
"name": "obtener_clima",
"description": "Devuelve la temperatura actual de una ciudad. Úsala para preguntas sobre el tiempo.",
"input_schema": {
"type": "object",
"properties": {
"ciudad": {"type": "string", "description": "Nombre de la ciudad"}
},
"required": ["ciudad"]
}
}
]Implementar las funciones ejecutoras
Ahora escribimos el código real que se ejecuta cuando Claude decide llamar a una tool. Cada función recibe los argumentos que Claude propuso y devuelve un resultado que le enviaremos de vuelta. Aquí la calculadora usa una evaluación controlada (en producción usa una librería segura como numexpr, nunca eval directo con input no confiable) y el clima devuelve datos simulados; en un caso real llamarías a una API como OpenWeather. Lo importante es el patrón: un despachador (dispatcher) que mapea el nombre de la tool a la función correspondiente y devuelve el resultado como string. Este es el puente entre el razonamiento de Claude y el mundo real.
def calcular(expresion: str) -> str:
try:
# En producción usa numexpr o un parser seguro, no eval crudo
resultado = eval(expresion, {"__builtins__": {}}, {})
return str(resultado)
except Exception as e:
return f"Error al calcular: {e}"
def obtener_clima(ciudad: str) -> str:
# Simulado. Aquí llamarías a una API real (ej. OpenWeather)
datos = {"Madrid": "28°C", "Bogotá": "18°C", "Buenos Aires": "22°C"}
return datos.get(ciudad, "Ciudad no encontrada")
def ejecutar_tool(nombre: str, args: dict) -> str:
if nombre == "calcular":
return calcular(args["expresion"])
elif nombre == "obtener_clima":
return obtener_clima(args["ciudad"])
return "Herramienta desconocida"Construir el bucle agéntico
Aquí está el corazón del agente: el bucle. Enviamos el mensaje del usuario junto con las herramientas disponibles. Claude responde con stop_reason 'tool_use' cuando quiere ejecutar una herramienta, o 'end_turn' cuando ha terminado. El patrón es: mientras Claude pida usar tools, las ejecutamos, añadimos los resultados al historial de mensajes con role 'user' y un bloque tool_result, y volvemos a llamar. Cuando ya no pide más tools, el agente ha terminado y devolvemos su respuesta final. Añadimos un límite de iteraciones (max_iteraciones) como red de seguridad para evitar bucles infinitos que disparen tu factura. Fíjate cómo se acumula todo en la lista messages: eso da al agente memoria de todo lo que ha hecho.
import anthropic
cliente = anthropic.Anthropic()
def ejecutar_agente(pregunta: str, max_iteraciones: int = 8):
messages = [{"role": "user", "content": pregunta}]
for i in range(max_iteraciones):
respuesta = cliente.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
tools=tools,
messages=messages,
)
messages.append({"role": "assistant", "content": respuesta.content})
if respuesta.stop_reason != "tool_use":
# Claude terminó: devolvemos el texto final
return "".join(b.text for b in respuesta.content if b.type == "text")
# Ejecutamos cada tool que Claude pidió
resultados = []
for bloque in respuesta.content:
if bloque.type == "tool_use":
salida = ejecutar_tool(bloque.name, bloque.input)
resultados.append({
"type": "tool_result",
"tool_use_id": bloque.id,
"content": salida,
})
messages.append({"role": "user", "content": resultados})
return "Se alcanzó el límite de iteraciones sin respuesta final."Añadir un system prompt para guiar el comportamiento
Un agente sin instrucciones claras improvisa. El system prompt define su personalidad, objetivos y límites. Aquí le damos rol, le indicamos que use las herramientas cuando sea necesario y que responda en español. Esto es lo que separa un agente confuso de uno predecible. Puedes incluir reglas de negocio, formato de respuesta esperado y qué hacer ante ambigüedad. Modificamos la función para aceptar el parámetro system. Un buen system prompt reduce iteraciones innecesarias y mejora la precisión de las decisiones de tool use, lo que también reduce costes.
SYSTEM = """Eres un asistente experto que resuelve tareas usando herramientas.
Reglas:
- Usa la herramienta 'calcular' para cualquier operación matemática, nunca calcules mentalmente.
- Usa 'obtener_clima' para preguntas sobre el tiempo.
- Responde siempre en español, de forma clara y concisa.
- Si te falta información, pídela antes de actuar."""
# Dentro de ejecutar_agente, añade system al create:
respuesta = cliente.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
system=SYSTEM,
tools=tools,
messages=messages,
)Probar el agente de principio a fin
Momento de la verdad. Ejecutamos el agente con una pregunta que obliga a usar varias herramientas. Por ejemplo, calcular el IVA español (21%) sobre un importe y consultar el clima. Observa cómo Claude encadena las llamadas: primero decide qué tool usar, ejecuta, recibe el resultado y sigue razonando hasta dar una respuesta completa. Añade prints dentro del bucle si quieres ver cada decisión en tiempo real (útil para depurar). Si todo funciona, verás una respuesta que integra los resultados de las herramientas de forma natural.
if __name__ == "__main__":
pregunta = (
"Tengo una factura de 2500 euros sin IVA. "
"Calcula el total con el IVA español del 21% "
"y dime qué temperatura hace en Madrid."
)
resultado = ejecutar_agente(pregunta)
print("\n=== RESPUESTA DEL AGENTE ===")
print(resultado)
# Salida esperada (aprox):
# El total con el 21% de IVA es 3025 euros.
# En Madrid la temperatura actual es de 28°C.Controlar costes y añadir robustez
Un agente en producción necesita protecciones. Envuelve las llamadas a la API en try/except para manejar errores de red o rate limits. Registra el uso de tokens (disponible en respuesta.usage) para monitorizar costes: cada iteración del bucle es una llamada facturada, y las conversaciones largas acumulan tokens de entrada rápidamente. Considera usar un modelo más económico como Claude Haiku para tareas simples y reservar Opus para razonamiento complejo. Añade timeouts y limita el tamaño del historial si las conversaciones se alargan. Estas medidas evitan sorpresas en la factura, algo especialmente importante si pagas en dólares desde España o LATAM.
def ejecutar_agente_seguro(pregunta, max_iteraciones=8):
messages = [{"role": "user", "content": pregunta}]
tokens_totales = 0
for i in range(max_iteraciones):
try:
r = cliente.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
system=SYSTEM,
tools=tools,
messages=messages,
)
except anthropic.APIError as e:
return f"Error de API: {e}"
tokens_totales += r.usage.input_tokens + r.usage.output_tokens
messages.append({"role": "assistant", "content": r.content})
if r.stop_reason != "tool_use":
print(f"Tokens usados: {tokens_totales}")
return "".join(b.text for b in r.content if b.type == "text")
resultados = [
{"type": "tool_result", "tool_use_id": b.id,
"content": ejecutar_tool(b.name, b.input)}
for b in r.content if b.type == "tool_use"
]
messages.append({"role": "user", "content": resultados})
return "Límite de iteraciones alcanzado."Has construido un agente de IA funcional con Claude que razona de forma autónoma, decide cuándo usar herramientas, las ejecuta en tu entorno y encadena varios pasos hasta cumplir un objetivo. Dominas el ciclo agéntico completo: definición de tools con JSON Schema, el bucle de ejecución con tool_use y tool_result, el uso de system prompts para guiar el comportamiento, y las prácticas esenciales de control de costes y robustez. Este esqueleto es la base para agentes reales: solo tienes que sustituir las funciones de ejemplo por integraciones con APIs, bases de datos o servicios propios.
Los cursos de certificación en español de Partners Academy te llevan de principiante a builder profesional con Claude y su API.
Ver programas de Partners Academy →