El 90% del código en Anthropic lo escriben agentes Claude. No ingenieros escribiendo en una ventana de chat. Son agentes autónomos ejecutando bucles, llamando herramientas y enviando código mientras el equipo duerme.
Sigue mi Substack para recibir información actualizada sobre IA:
Esta es la configuración exacta. Paso a paso. Desde la primera llamada a la API hasta un agente funcional que puedes apuntar a cualquier tarea.
Este artículo cubrirá:
1 - por qué la mayoría de los "agentes" que la gente construye no son agentes
2 - las 5 partes que todo agente funcional necesita
3 - cómo construir cada parte con Claude, con código
4 - los errores que matan a los agentes antes de que se implementen
Guarda esto en favoritos. Cada bloque de código a continuación funciona.
01. La mayoría de los "agentes de IA" no son agentes
He construido y roto más agentes de los que puedo contar. Los he visto quemar tokens toda la noche y no producir nada. Los he visto reescribir el mismo archivo 30 veces. Los he visto pasar su propia prueba eliminando la prueba.

Cada fracaso me enseñó la misma lección: el modelo no es el problema. La arquitectura a su alrededor sí lo es. Esta guía es todo lo que aprendí, comprimido en la ruta más corta que puedo darte.
Esto es lo que la mayoría construye cuando dice "agente de IA":
1while True:2 user_input = input("> ")3 response = call_claude(user_input)4 print(response)
Eso es un chatbot. Espera por ti. Hace lo que dices. Olvida todo entre sesiones. Cuando cierras la pestaña, se detiene.
Un agente es un sistema que trabaja hacia un objetivo sin que estés sentado frente a él. Descubre qué hay que hacer, hace un plan, ejecuta, verifica el resultado y, si no está terminado, lo intenta de nuevo. Tú marcas la dirección. El agente hace el trabajo.
"Claude Code pasó de cero a $400 millones en ingresos en pocos meses. Comenzó como un proyecto de hackathon. Y todavía usa solo la API pública." -
Boris Cherny, Director de Claude Code
La misma API a la que tienes acceso ahora. Los mismos modelos. La diferencia es la arquitectura alrededor del modelo.

02. Las 5 partes de un agente real
Todo agente funcional (Claude Code, Devin, Codex o cualquier cosa que construyas tú mismo) se ensambla a partir de cinco partes. Si falta una, se rompe.

03. La capa de API
Todo comienza aquí. Llamas a Claude, Claude responde. Pero la forma en que lo llamas determina si obtienes un chatbot o un agente.

Tres cosas importan: el prompt del sistema, la salida estructurada y la temperatura.
El prompt del sistema no es un saludo. Es el manual de operación de tu agente. Aquí van todas las reglas, restricciones y comportamientos. Sin él, Claude adivina lo que quieres. Con él, Claude sigue tu especificación.
1import anthropic23client = anthropic.Anthropic()45response = client.messages.create(6 model="claude-sonnet-4-6",7 max_tokens=4096,8 system="""Eres un agente de revisión de código.910Reglas:11- Lee todo el diff antes de comentar12- Señala solo errores reales, no preferencias de estilo13- Si no hay nada incorrecto, di "LGTM" y detente14- Nunca sugieras cambios que no hayas probado mentalmente15- Formato de salida: array JSON de {file, line, issue, fix}""",16 messages=[{"role": "user", "content": diff_content}]17)
La salida estructurada hace que la respuesta de tu agente sea legible por máquina. Si Claude devuelve texto libre, tu código tiene que analizarlo. Si Claude devuelve JSON, tu código puede usarlo directamente.
1# Forzar salida JSON indicando a Claude la forma exacta2system = """Devuelve SOLO JSON válido. Sin markdown. Sin explicación.3Esquema:4{5 "status": "pass" | "fail",6 "issues": [{"file": str, "line": int, "issue": str}],7 "summary": str8}"""
Temperatura. Ponla a 0 para agentes deterministas. Ponla entre 0.3 y 0.5 para trabajo creativo. El valor por defecto (1.0) añade aleatoriedad que casi nunca quieres en un agente.
04. Herramientas
Un modelo sin herramientas puede razonar pero no puede actuar. Puede decirte qué archivo editar pero no puede editarlo. Puede describir una consulta pero no puede ejecutarla.

El uso de herramientas de Claude te permite definir funciones que el modelo puede llamar. Tú describes la función. Claude decide cuándo llamarla. Tú la ejecutas y devuelves el resultado. Claude usa el resultado para seguir razonando.
1tools = [{2 "name": "run_sql",3 "description": "Ejecutar una consulta SQL de solo lectura contra la base de datos",4 "input_schema": {5 "type": "object",6 "properties": {7 "query": {8 "type": "string",9 "description": "Consulta SQL SELECT a ejecutar"10 }11 },12 "required": ["query"]13 }14},15{16 "name": "write_file",17 "description": "Escribir contenido en un archivo en el disco",18 "input_schema": {19 "type": "object",20 "properties": {21 "path": {"type": "string"},22 "content": {"type": "string"}23 },24 "required": ["path", "content"]25 }26}]
La descripción de la herramienta importa más de lo que crees. Claude la lee para decidir cuándo y cómo usar la herramienta. Una descripción vaga significa llamadas incorrectas. Una descripción precisa significa llamadas acertadas.
Empieza con 3-5 herramientas. Leer archivo, escribir archivo, ejecutar comando, buscar y una herramienta específica de dominio para tu caso de uso. Eso cubre el 90% de las tareas del agente.

05. El bucle
Esta es la parte que convierte un script en un agente. Sin un bucle, tu código llama a Claude una vez y se detiene. Con un bucle, tu código llama a Claude, verifica el resultado y vuelve a llamar hasta que el trabajo está hecho.

Tres componentes:
- Verificador. Algo que compruebe si la salida es buena. Un conjunto de pruebas, un verificador de tipos, un linter, una segunda llamada a Claude con criterios estrictos. Sin esto, el agente se da la razón a sí mismo en bucle.
- Estado. Un registro de lo que sucedió. Lo que funcionó, lo que falló, qué probar a continuación. Sin estado, el agente comete el mismo error en cada iteración.
- Condición de parada. El objetivo se cumple, o un límite duro dice "después de N intentos, detente e informa". Sin esto, el bucle se ejecuta para siempre y agota tu cuenta.
1import json2from pathlib import Path34def run_agent(task: str, max_attempts: int = 5):5 state = {"task": task, "attempts": [], "done": False}67 for i in range(max_attempts):8 # Construir contexto desde el estado9 context = build_prompt(state)1011 # Llamar a Claude con herramientas12 result = call_claude(context, tools)1314 # Ejecutar cualquier llamada a herramienta15 output = execute_tools(result)1617 # Verificar el resultado18 check = verify(output)1920 # Actualizar el estado21 state["attempts"].append({22 "attempt": i + 1,23 "action": result.summary,24 "passed": check.passed,25 "reason": check.reason26 })2728 if check.passed:29 state["done"] = True30 break3132 # Guardar el estado para la siguiente ejecución33 Path("state.json").write_text(json.dumps(state, indent=2))34 return state
Este es el esqueleto completo. Cada agente de producción es una variación de este patrón. Los detalles cambian. La forma no.
06. Memoria
Sin memoria, cada sesión comienza desde cero. El agente redescubre la estructura de tu proyecto. Vuelve a aprender tus convenciones. Vuelve a cometer los errores que cometió ayer.

Los agentes Claude usan tres capas de memoria:
CLAUDE.md es un archivo markdown en la raíz de tu proyecto. Claude Code lo lee automáticamente al inicio de cada sesión. Tus reglas, tu stack, tus convenciones. Escríbelo una vez, léelo siempre.
1# CLAUDE.md23## Proyecto4API de gestión de tareas. Python 3.12, FastAPI, PostgreSQL.56## Reglas7- Todas las respuestas: esquema {data, error, meta}8- Se requieren pruebas para cada nuevo endpoint9- Mensajes de commit: tipo(ámbito): descripción10- Nunca uses print() para registrar. Usa structlog.1112## Problemas conocidos13- El middleware de autenticación espera x-auth-token, no Authorization14- El conjunto de pruebas tarda 45s completo. Usa --filter para iterar.
Skills capturan flujos de trabajo completos. No solo prompts, sino la forma completa: formato de entrada, pasos, formato de salida, reglas de validación. La primera ejecución tarda 20 minutos. La reproducción tarda 30 segundos.
El archivo de aprendizajes es un registro continuo de errores. El agente escribe en él después de cada sesión. La siguiente sesión lo lee. Los errores se repiten hasta que se escriben. Luego dejan de repetirse.
1# learnings.md23- La API de pagos espera la clave de idempotencia en el encabezado, no en el cuerpo4- PostgreSQL NOTIFY necesita LISTEN explícito en el pool de conexiones5- El limitador de tasa cuenta por clave, no por IP. Las pruebas necesitan claves únicas.
07. La puerta de verificación
La puerta es la parte más difícil de construir y la más fácil de omitir. La mayoría la omite. Por eso la mayoría de los agentes se rompen en producción.

Una puerta de verificación es algo que comprueba el trabajo del agente sin que el agente se califique a sí mismo. El modelo que escribió el código es demasiado generoso al calificar su propia tarea. Necesitas una segunda verificación.
Tres patrones que funcionan:
1. Pruebas automatizadas. El agente escribe código. El conjunto de pruebas se ejecuta. Si las pruebas fallan, el agente recibe la salida del error y lo intenta de nuevo. Así es como funciona Claude Code internamente.
1def verify(output):2 # Ejecutar el conjunto de pruebas3 result = subprocess.run(4 ["pytest", "tests/", "-x", "--tb=short"],5 capture_output=True, text=True6 )7 return {8 "passed": result.returncode == 0,9 "reason": result.stdout if result.returncode != 0 else "todas las pruebas pasan"10 }
2. Verificador de tipos / linter. Ejecuta mypy, ruff o tsc --noEmit después de cada cambio. Detecta categorías enteras de errores sin escribir una sola prueba.
3. Segundo modelo como revisor. Usa una llamada separada a Claude con un prompt de sistema estricto que solo busque problemas. El escritor es rápido y barato. El revisor es lento y estricto. Esa separación es la mayor parte de la calidad.
1# Prompt del revisor - separado del constructor2reviewer_system = """Eres un revisor de código estricto.3Tu ÚNICO trabajo es encontrar problemas.45Verifica:6- ¿El código coincide con la especificación?7- ¿Hay casos extremos no detectados?8- ¿Todas las pruebas realmente prueban lo correcto?910Si todo es correcto, responde: {"passed": true}11Si algo está mal, responde: {"passed": false, "issues": [...]}1213No sugieras mejoras. Solo señala errores reales."""
El escritor es rápido y barato. El revisor es lento y estricto. Esa separación es la mayor parte de la calidad.
08. Poniéndolo todo junto
Aquí hay un agente completo que toma una URL de issue de GitHub, lee el issue, escribe el código, ejecuta las pruebas y abre un PR. Cinco partes trabajando juntas.
1import anthropic, subprocess, json2from pathlib import Path34client = anthropic.Anthropic()5CLAUDE_MD = Path("CLAUDE.md").read_text()6LEARNINGS = Path("learnings.md").read_text()78SYSTEM = f"""Eres un agente de codificación.9Lee el issue. Escribe la corrección. Ejecuta las pruebas.1011Contexto del proyecto:12{CLAUDE_MD}1314Problemas conocidos:15{LEARNINGS}1617Reglas:18- Lee el código completo antes de cambiar nada19- Escribe pruebas para cada cambio20- Si las pruebas fallan, corrige el código, no las pruebas21- Detente cuando todas las pruebas pasen"""2223TOOLS = [24 read_file_tool,25 write_file_tool,26 run_command_tool,27 search_codebase_tool,28]2930def run(issue_text, max_attempts=5):31 messages = [{"role": "user", "content": issue_text}]3233 for attempt in range(max_attempts):34 # Llamar a Claude35 response = client.messages.create(36 model="claude-sonnet-4-6",37 max_tokens=8192,38 system=SYSTEM,39 tools=TOOLS,40 messages=messages41 )4243 # Ejecutar llamadas a herramientas44 messages = handle_tool_use(response, messages)4546 # Verificar: ejecutar pruebas47 test_result = subprocess.run(48 ["pytest", "-x", "--tb=short"],49 capture_output=True, text=True50 )5152 if test_result.returncode == 0:53 print(f"Completado en {attempt + 1} intentos")54 return True5556 # Alimentar el fallo de vuelta al bucle57 messages.append({58 "role": "user",59 "content": f"Las pruebas fallaron:\n{test_result.stdout}\nCorrige y reintenta."60 })6162 return False
Eso es un agente funcional. Capa de API con prompt de sistema y CLAUDE.md. Herramientas para operaciones de archivos. Un bucle con reintento. Memoria de learnings.md. Una puerta de verificación mediante pytest.
Menos de 50 líneas. La misma arquitectura que Claude Code usa internamente.
**
09. Los 5 errores que rompen todo agente
- Sin puerta de verificación. El agente califica su propia tarea. Escribe código, dice "se ve bien" y sigue adelante. La salida parece correcta y se rompe en producción.
- Sin condición de parada. El bucle se ejecuta hasta que tu factura de API es de $200. Sin un límite duro, el agente reintenta para siempre, reescribiendo el mismo archivo 40 veces. Siempre establece max_attempts. Siempre.
- Sin archivo de estado. El mismo error en el intento #1 y en el intento #50. El agente no sabe lo que ya intentó. Propone la misma corrección rota tres veces seguidas porque nada registra el fallo.
- Demasiadas herramientas. Le das a Claude 20 herramientas y elige la incorrecta. Un modelo con 5 herramientas claras toma mejores decisiones que uno con 20 superpuestas. Empieza con poco. Añade herramientas solo cuando el agente se encuentre con un muro.
- Prompt de sistema vago. "Sé un buen asistente de codificación" te da una salida genérica. "Todas las respuestas deben ser JSON válido, pruebas requeridas para cada cambio, nunca modifiques archivos fuera de /src" te da un agente que se comporta.
Conclusión:
Un agente funcional no es un prompt mejor. Es un sistema: API + herramientas + bucle + memoria + puerta de verificación. Cinco partes. Si falta una, se rompe.
La mayoría leerá esto, lo guardará en favoritos y seguirá usando Claude como chatbot. Pegarán una pregunta a la vez y copiarán la respuesta en su código a mano.
Los que construyan el bucle enviarán trabajo mientras duermen. El mismo modelo. La misma API. El mismo precio. Diferente arquitectura.
Los bloques de código de arriba funcionan todos. Cópialos. Ejecútalos. Modifícalos para tu caso de uso.
Construye un agente esta semana. Apúntalo a una tarea que hagas todos los días. Déjalo ejecutar.





