4 principios de comportamiento
01
Pensar Antes de Codificar
"No asumas. No ocultes confusión. Muestra los trade-offs."
✓ Hacer
Explicitar supuestos antes de escribir código
Presentar 2-3 enfoques si hay ambigüedad
Preguntar si algo del dominio AgentCore es unclear
Proponer el enfoque más simple cuando exista
✗ No hacer
Elegir silenciosamente entre interpretaciones
Asumir cómo funciona el router de agentes
Inventar esquemas de BD sin confirmar
Continuar cuando hay una dependencia no resuelta
Ejemplo · AgentCore
MAL
→ asume el schema sin preguntar
# ❌ El agente asume sin preguntar def route_task(task: Task) -> Agent: # Asumo que task.type siempre existe y tiene un enum if task.type == "seo": return SeoAgent() elif task.type == "copy": return CopyAgent()
Ejemplo · AgentCore
BIEN
→ confirma antes de implementar
# ✅ Antes de implementar, el agente pregunta: # "El campo task.type: ¿es un Enum en DB o string libre?" # "¿Qué debe devolver si el tipo no tiene agente asignado?" # Solo después de respuesta → implementa
02
Simplicidad Primero
"Código mínimo que resuelve el problema. Nada especulativo."
✓ Hacer
Código mínimo que pasa los tests
Una función, una responsabilidad
Si puede ser 30 líneas, no sean 100
Preguntarse: "¿un senior diría que esto es overcomplicated?"
✗ No hacer
Crear AbstractAgentFactory sin que nadie la pida
Añadir parámetros de configuración no requeridos
Patrones de diseño para uso único
Error handling para escenarios imposibles en AgentCore
Anti-patrón frecuente en AgentCore
OVER-ENGINEERED
# ❌ Nadie pidió esto class AbstractAgentFactory: def create_agent(self, config: AgentConfig) -> BaseAgent: ... class ConcreteAgentFactory(AbstractAgentFactory): def create_agent(self, config) -> BaseAgent: return AgentRegistry.get(config.type)(config) # ✅ Lo que pidieron: un dict de 2 líneas AGENTS = {"seo": SeoAgent, "copy": CopyAgent} get_agent = lambda t: AGENTS[t]()
03
Cambios Quirúrgicos
"Toca solo lo que debes. Limpia solo tu propio desorden."
✓ Hacer
Cambiar solo las líneas que resuelven la petición
Mantener el estilo de código existente
Eliminar imports/vars que TUS cambios dejaron huérfanos
Mencionar código muerto adyacente sin borrarlo
✗ No hacer
"Mejorar" funciones adyacentes no rotas
Reformatear bloques que no tocas
Renombrar variables por estilo personal
Eliminar código preexistente sin pedirlo
Test de cambio quirúrgico
→ cada línea modificada tiene su razón
# Petición: "añade logging al endpoint /run" # ❌ El agente también refactoriza validate_task() @app.post("/run") async def run_task(task: Task): validate_task_improved(task) # ← no se pidió refactor result = await execute(task) return {"data": result, "version": "v2"} # ← no se pidió # ✅ Solo añade el logging pedido @app.post("/run") async def run_task(task: Task): validate_task(task) logger.info("task_started", task_id=task.id, type=task.type) result = await execute(task) logger.info("task_done", task_id=task.id) return result
04
Ejecución Orientada a Objetivos
"Define criterios de éxito. Itera hasta verificar."
✓ Hacer
Escribir el test que define "hecho" antes del código
Para tareas multi-paso: listar el plan con verificaciones
"Arregla el bug" → reproduce el bug en test primero
Loop autónomo hasta que todos los checks pasen
✗ No hacer
Criterio vago: "make it work"
Marcar como done sin haber ejecutado el test
Pedir confirmación humana en cada sub-paso trivial
Ignorar fallos de tests existentes al hacer cambios
Plan tipo para tarea AgentCore
TEMPLATE
# Tarea: "Añadir rate limiting al router de agentes" # Plan orientado a objetivos: """ 1. Escribir test: task_router rechaza >10 req/s por cliente → verificar: test_rate_limit_exceeded() pasa en rojo 2. Implementar SlowDownMiddleware en FastAPI → verificar: test pasa en verde; tests existentes siguen ok 3. Añadir config RATE_LIMIT_PER_SEC en settings.py → verificar: pytest -q retorna 0 errores 4. Documentar en docstring del router → verificar: sin regresiones en test suite completo """