AIAutomationPythonDevToolsEspañol

Automatizando mis proyectos con agentes de IA: cómo construí un sistema que trabaja 24/7 por mí

April 30, 202612 min read

La idea nació de una frustración concreta: tenía varios proyectos personales que quería avanzar en paralelo, pero el tiempo que podía dedicarles era fragmentado — una hora aquí, media hora allá. El contexto que perdía entre sesiones era enorme.

¿Y si en lugar de ser yo quien escribe el código, simplemente le digo a un agente qué hacer y reviso el resultado?

Eso es exactamente lo que construí.


La visión

El objetivo es simple pero ambicioso: que yo solo toque el teclado para revisar Pull Requests y dar nuevas instrucciones. Todo lo demás — clonar el repo, crear el branch, escribir el código, correr los tests, abrir el PR — lo hace un agente de IA de forma autónoma.

El flujo completo se ve así:

Yo (Telegram)
    │
    ▼
/task mi-api Implementa autenticación JWT
    │
    ▼
Task Queue (Celery + Redis)
    │
    ▼
Agent Router → asigna agente según el proyecto
    │
    ▼
Claude Agent
├── clona el repo
├── crea branch: feat/task-42-jwt-auth
├── lee el código existente
├── implementa los cambios
├── corre pytest
└── abre PR en GitHub con descripción completa
    │
    ▼
Telegram: "✅ Task #42 completada — PR listo para revisar"
          Link directo al PR
    │
    ▼
Yo reviso, apruebo, mergeo. Listo.

La arquitectura

El sistema tiene cuatro capas bien separadas.

1. El canal de instrucciones

Elegí Telegram Bot como canal principal. Es gratis, tiene una API excelente, funciona desde el celular y — lo más importante para un sistema personal — el Chat ID propio garantiza que solo yo puedo enviar instrucciones. No necesito workspace de empresa ni configuraciones complejas.

Los comandos que soporta el bot:

/task <proyecto> <descripción>
/task mi-api Implementa JWT auth --priority high
/task frontend Arregla el modal en mobile --agent claude-sonnet-4
/status
/projects

El bot parsea la instrucción, crea un registro en la base de datos con status QUEUED y encola la tarea en Celery.

2. El orquestador

El backend es FastAPI + Celery + Redis. Celery maneja la cola de tareas con soporte nativo para prioridades y reintentos. Redis actúa como broker.

El componente más interesante es el router de agentes — la pieza que decide qué agente ejecuta cada tarea. La lógica actual es simple: usa el agente configurado en el proyecto (claude-opus-4 para tareas complejas, claude-sonnet-4 para tareas simples). Si el agente principal falla, hace fallback automático al agente alternativo.

async def route_task(task: Task, project: Project) -> AgentResult:
    agent = _build_agent(task.agent or project.default_agent)

    # Clonar o actualizar el repo antes de empezar
    clone_result = clone_or_update_repo(project.repo_url, repo_path)

    result = await agent.execute(agent_task)

    # Si falló, reintenta con el agente de fallback
    if not result.success and project.fallback_agent:
        fallback = _build_agent(project.fallback_agent)
        result = await fallback.execute(agent_task)

    return result

3. El agente Claude

Este es el núcleo del sistema. El agente usa Claude API con tool use — en lugar de un script que llama a Claude para generar un diff y aplicarlo, el agente opera en un loop: recibe la tarea, decide qué herramienta usar, ejecuta la herramienta, recibe el resultado, y sigue hasta terminar.

Las herramientas disponibles son cuatro:

File tools — leer, escribir y listar archivos del repositorio. El agente puede leer el código existente antes de modificarlo.

Bash tool — ejecutar comandos shell. Corre los tests, el linter, o cualquier comando configurado en el proyecto.

Git tools — el ciclo completo de Git: crear branch, hacer commits atómicos, push al remoto y abrir el PR via GitHub API.

Search tool — buscar patrones en el codebase usando ripgrep. Útil para encontrar dónde están definidas las cosas antes de modificarlas.

El loop del agente se ve así en código simplificado:

while iterations < MAX_ITERATIONS:
    response = client.messages.create(
        model=self.model,
        tools=ALL_TOOLS,
        messages=messages,
    )

    if response.stop_reason == "end_turn":
        return self._parse_final_response(response)

    # Ejecutar cada tool que el agente pidió
    tool_results = []
    for block in response.content:
        if block.type == "tool_use":
            result = self._execute_tool(block.name, block.input, task)
            tool_results.append({
                "type": "tool_result",
                "tool_use_id": block.id,
                "content": json.dumps(result),
            })

    messages.append({"role": "user", "content": tool_results})

El system prompt es la parte más crítica — define exactamente qué debe hacer el agente y en qué orden: leer la estructura del proyecto, crear el branch, implementar los cambios, hacer commits incrementales, correr tests, hacer push.

4. La capa de Git y GitHub

Uno de los requisitos más importantes del sistema es que los agentes nunca hagan push directo a main. Cada tarea vive en su propio branch con un nombre descriptivo: feat/task-42-jwt-auth.

Al terminar, el agente hace push del branch y el worker abre el PR automáticamente via GitHub API con un título y descripción generada por el propio agente — qué hizo, por qué, cómo probarlo.

pr_result = open_pull_request(
    repo_url=project.repo_url,
    branch_name=result.branch_name,
    title=f"[Task #{task.id}] {task.description[:80]}",
    body=result.log,   # generado por el agente
    base_branch=project.base_branch,
)

Configuración por proyecto

Cada proyecto tiene su propia carpeta con dos archivos:

config.yml — define el repo, el agente preferido y los comandos:

name: mi-api
repo_url: https://github.com/adolfo/mi-api
default_agent: claude-opus-4
fallback_agent: claude-sonnet-4
base_branch: main
test_command: pytest
lint_command: ruff check .

context.md — descripción del proyecto que el agente lee al inicio de cada tarea. Incluye el stack, las convenciones del proyecto y cualquier cosa que el agente deba saber antes de tocar el código.

Esta separación es intencional: el agente tiene contexto del proyecto sin necesidad de leer todo el codebase desde cero en cada tarea.


Las reglas que siguen los agentes

Definí un conjunto de reglas explícitas en el CLAUDE.md del repositorio. Cualquier agente que opere en este sistema debe seguirlas:

  • Nunca push directo a main — siempre branches propios
  • Commits atómicos — un commit por cambio lógico, no un commit gigante al final
  • Conventional Commitsfeat(auth): add JWT token generation
  • No romper tests existentes — si hay que cambiar tests, explicarlo en el PR
  • No introducir dependencias nuevas sin mencionarlo explícitamente
  • Nunca hardcodear secrets — variables de entorno siempre
  • Ante la duda, hacer menos y documentar la duda en el PR

Este archivo actúa también como memoria persistente entre sesiones — cualquier agente nuevo puede leerlo y entender exactamente cómo operar.


El stack completo

CapaTecnología
BackendPython 3.12 + FastAPI
Cola de tareasCelery + Redis
Base de datosSQLite (dev) / PostgreSQL (prod)
Agente principalClaude API con tool use
Multi-LLM (futuro)LiteLLM
Canal de instruccionesTelegram Bot
Operaciones GitGitHub API + GitPython
InfraestructuraRailway
ContainersDocker + Docker Compose

Lo que aprendí construyendo esto

El tool use es más poderoso que generar diffs. Un agente que puede leer archivos, ejecutar comandos y hacer commits de forma iterativa toma mejores decisiones que uno que genera un parche ciego sin ver el resultado de sus acciones.

El contexto por proyecto es fundamental. Sin un context.md que describa las convenciones del proyecto, el agente toma decisiones genéricas que a veces no encajan con el estilo del codebase. Con contexto, las decisiones son mucho más acertadas.

Los archivos de memoria persisten más que las sesiones. El mayor riesgo de un sistema así es perder el hilo entre sesiones. Resolví esto con archivos de contexto versionados en el propio repositorio — PROJECT_STATE.md que refleja qué está hecho y qué sigue, y DECISIONS.md con los ADRs del proyecto.

La regla del branch obligatorio es innegociable. Que el agente nunca pueda tocar main directamente no es solo una buena práctica — es lo que hace que el sistema sea revisable y seguro. Si el agente se equivoca, el PR simplemente no se aprueba.


El estado actual y lo que viene

El MVP está completo: un agente Claude que recibe instrucciones por Telegram, trabaja en repositorios reales y abre PRs automáticamente. El siguiente paso es la prueba end-to-end con un proyecto real.

El roadmap después de eso:

Fase 2 — cola con múltiples proyectos en paralelo, contexto persistente entre tareas, comandos /status más detallados.

Fase 3 — soporte multi-agente via LiteLLM: asignar GPT-4 o Gemini según el tipo de tarea o el costo. Un router inteligente que elija el modelo correcto automáticamente.

Fase 4 — dashboard web para ver el estado de todas las tareas, reintentos automáticos, métricas de costo por tarea y tasa de éxito por agente.

El código está en GitHub si quieres explorar la implementación completa.