Heartbeats y rutinas: agentes que trabajan solos
El problema de los agentes que esperan
Un agente sin heartbeat es como un empleado que solo trabaja cuando alguien le da un tap en el hombro. Técnicamente funciona, pero no es lo que prometió la promesa de la IA autónoma.
Los heartbeats son el mecanismo que hace que los agentes sean proactivos. En lugar de esperar a que tú asignes manualmente cada tarea, los agentes se despiertan según un schedule, revisan qué hay que hacer, y lo hacen. Tú solo revisas el dashboard por las mañanas.
Entender los heartbeats correctamente es quizás la habilidad más importante para sacar provecho real de Paperclip.
Qué es un heartbeat
Un heartbeat es una configuración que dice: “cada vez que se cumpla esta condición, despierta a este agente con este contexto”.
La condición puede ser:
- Temporal (cron): Cada lunes a las 9am, cada 5 minutos, el primer día de cada mes.
- Basada en eventos: Cuando se asigne una tarea a este agente, cuando alguien lo @mencione, cuando entre un ticket de alta prioridad.
- Manual: Cuando el Board o un manager lo active explícitamente desde la UI.
Cuando el heartbeat se dispara, Paperclip:
- Verifica que el agente no está ya corriendo (para evitar ejecuciones paralelas del mismo agente).
- Construye el contexto completo del agente (company context + skills + heartbeat payload).
- Invoca al agente a través de su adapter.
- Registra el inicio de la ejecución en el audit log.
- Espera el resultado y lo registra también.
Anatomía de un heartbeat
graph TD
HC[Heartbeat Config] --> S[Schedule: cron o evento]
HC --> T[Tipo: cron / event / manual]
HC --> P[Payload: contexto inicial]
HC --> LIM[Límites: timeout, max retries]
S --> Trigger{Se cumple la condición}
Trigger -->|sí| Check{¿Agente ya corriendo?}
Check -->|no| Invoke[Invocar al agente]
Check -->|sí| Skip[Skipped - log y continuar]
Invoke --> Result[Registrar resultado]
Result --> Next[Calcular próxima ejecución]
Los campos principales de configuración de un heartbeat:
# Ejemplo de configuración de heartbeat en YAML
heartbeat:
id: hb_ceo_daily_review
agentId: agent_ceo_felipe
# Tipo y schedule
type: cron
schedule: "0 9 * * 1-5" # 9am de lunes a viernes
# Qué decirle al agente cuando se despierta
payload: |
Buenos días. Es el momento de tu revisión diaria.
Por favor:
1. Revisa el estado de todas las iniciativas activas
2. Prioriza las tareas en el backlog según los goals
3. Asigna work a tu equipo si hay tareas listas para ejecutar
4. Identifica bloqueantes y escálalos si es necesario
5. Prepara un resumen de 3 líneas para el Board
# Configuración de ejecución
timeout: 1800000 # 30 minutos máximo
maxRetries: 2 # Reintentar hasta 2 veces si falla
retryDelay: 300000 # Esperar 5 minutos entre reintentos
# Estado
enabled: true
# Restricciones opcionales
runOnlyIf:
budgetRemainingUsd: 2.00 # Solo correr si queda al menos $2
previousRunStatus: success # Solo correr si el anterior fue exitoso
Sintaxis cron para heartbeats
Los heartbeats de tipo cron usan la sintaxis estándar de cinco campos:
┌────────── Minuto (0-59)
│ ┌──────── Hora (0-23)
│ │ ┌────── Día del mes (1-31)
│ │ │ ┌──── Mes (1-12)
│ │ │ │ ┌── Día de la semana (0-7, 0 y 7 = domingo)
│ │ │ │ │
* * * * *
Ejemplos para DevCo:
# CEO - revisión diaria de mañana (lunes a viernes a las 9am)
"0 9 * * 1-5"
# CTO - revisión de PRs (cada 2 horas en horario laboral)
"0 9,11,13,15,17 * * 1-5"
# Ingeniero - check de tareas asignadas (cada 30 minutos)
"*/30 * * * 1-5"
# Agente de soporte L1 - siempre activo (cada 5 minutos)
"*/5 * * * *"
# Reporte semanal del CEO al Board (viernes a las 17:00)
"0 17 * * 5"
# Backup de base de datos (medianoche cada día)
"0 0 * * *"
# Análisis de métricas mensuales (primer día del mes a las 8am)
"0 8 1 * *"
Paperclip incluye un validador de cron en la UI que te muestra las próximas 5 ejecuciones del schedule que configures. Úsalo siempre antes de activar un heartbeat para confirmar que el timing es el que esperas.
Tipos de eventos que despiertan agentes
Los heartbeats basados en eventos se disparan cuando algo específico ocurre en el sistema. Esto permite respuestas reactivas sin polling constante.
Los eventos disponibles en Paperclip:
task_assigned — Una tarea fue asignada a este agente
task_mentioned — El agente fue @mencionado en una tarea
task_escalated — Una tarea fue escalada a este agente
task_priority_changed — La prioridad de una tarea del agente cambió
initiative_created — Se creó una nueva iniciativa
initiative_updated — Una iniciativa del agente fue actualizada
budget_warning — El presupuesto llegó al 80%
budget_exhausted — El presupuesto se agotó
company_goal_updated — Los goals de la empresa cambiaron
board_override — El Board activó este agente directamente
report_requested — El Board o un manager pidió un reporte
Configuración de un heartbeat basado en eventos:
heartbeat:
id: hb_cto_on_task_assigned
agentId: agent_cto_ana
type: event
triggers:
- event: task_assigned
- event: task_escalated
- event: task_mentioned
payload: |
Has recibido una nueva asignación o mención.
Revisa tu bandeja de entrada de tareas y procesa la más prioritaria.
Si es una escalación, trátala con urgencia.
# Debounce: esperar antes de activar para agrupar múltiples eventos
debounceMs: 30000 # Esperar 30 segundos, procesar como batch
timeout: 900000
enabled: true
El campo debounceMs es útil cuando podrían llegar múltiples eventos seguidos. Sin debounce, si se asignan 5 tareas en rápida sucesión, el agente se activaría 5 veces. Con debounce de 30 segundos, el agente se activa una vez y procesa todas las tareas pendientes.
Ciclo de vida de un heartbeat
stateDiagram-v2
[*] --> scheduled : Heartbeat creado y habilitado
scheduled --> running : Se cumple el trigger
running --> success : Agente completa sin error
running --> failure : Timeout o error del adapter
running --> skipped : Agente ya estaba corriendo
success --> scheduled : Programar próxima ejecución
failure --> retrying : Si maxRetries > 0
retrying --> running : Después del retryDelay
retrying --> failed_final : Después de maxRetries intentos
failed_final --> scheduled : Programar próxima ejecución
failed_final --> disabled : Si configured para disable-on-failure
skipped --> scheduled : Registrado, programar próxima ejecución
scheduled --> disabled : Board pausa el agente
disabled --> scheduled : Board re-activa el agente
El estado failed_final merece atención especial. Cuando un heartbeat falla repetidamente, Paperclip puede configurarse para:
- Notificar al Board: Email inmediato con el log de error
- Deshabilitar el heartbeat: Evita seguir gastando presupuesto en errores
- Escalar al manager: Crear una tarea de escalación para el manager del agente
Rutina 1: Revisión diaria del CEO
Esta es la rutina más importante para la mayoría de deployments. El CEO se despierta cada mañana, revisa el estado de la empresa, y organiza el trabajo del día.
# heartbeat: CEO daily standup
heartbeat:
id: hb_ceo_morning_standup
agentId: agent_ceo_felipe
type: cron
schedule: "0 9 * * 1-5"
payload: |
## Daily Standup - DevCo CEO
Es tu revisión matinal. Tienes acceso completo al sistema.
### Tu agenda para hoy:
**1. Estado de iniciativas (5 min)**
Revisa el progreso de las 4 iniciativas activas. ¿Alguna está bloqueada?
¿Alguna va adelantada o atrasada?
**2. Backlog review (10 min)**
Revisa las tareas en backlog sin asignar. Prioriza las top 3 según los
goals de la empresa y asígnalas a los agentes apropiados.
**3. Escalaciones pendientes (5 min)**
¿Hay algo que tus managers necesitan de ti? ¿Alguna decisión pendiente?
**4. Reporte para el Board (5 min)**
Crea un resumen de 5 líneas con:
- Estado general: verde/amarillo/rojo
- Logro más importante de ayer
- Principal bloqueante actual
- Una decisión que tomes hoy
- Presupuesto consumido este mes
Crea el reporte como una tarea completada con tag "board-report".
### Contexto del presupuesto
Tu presupuesto mensual es $20. Hoy es día {{ day_of_month }}.
Gasta proporcionalmente.
timeout: 2700000 # 45 minutos
maxRetries: 1
enabled: true
Rutina 2: Agente de soporte 24/7
El agente de soporte L1 necesita estar siempre disponible. No puede depender de un cron que se dispare cada hora porque los tickets de soporte tienen expectativa de respuesta rápida.
La estrategia correcta es un cron frecuente combinado con eventos:
# Polling frecuente: revisa si hay tickets nuevos
heartbeat:
id: hb_support_poll
agentId: agent_support_bot
type: cron
schedule: "*/10 * * * *" # Cada 10 minutos
payload: |
Revisión de tickets pendientes.
Procesa todos los tickets en estado "new" o "waiting_agent"
asignados a ti. Para cada ticket:
1. Lee el problema del cliente
2. Consulta tu FAQ y procedures
3. Si puedes resolverlo: responde y cierra el ticket
4. Si no puedes: escala al Head of Support con resumen del problema
Límite: procesa máximo 5 tickets en esta ejecución.
timeout: 600000 # 10 minutos
enabled: true
---
# Evento: reacción inmediata a ticket de alta prioridad
heartbeat:
id: hb_support_urgent
agentId: agent_support_bot
type: event
triggers:
- event: task_assigned
filter:
priority: critical
payload: |
ALERTA: Ticket crítico asignado.
Procesa este ticket con máxima urgencia. Si no puedes resolverlo
en 5 minutos, escala inmediatamente al Head of Support.
debounceMs: 0 # Sin debounce para críticos
timeout: 300000 # 5 minutos máximo
enabled: true
Rutina 3: Reporte semanal automatizado
Al final de cada semana laboral, el CEO genera un reporte ejecutivo para el Board. Este reporte no requiere intervención: se genera solo, se crea como una tarea completada, y el Board recibe una notificación.
heartbeat:
id: hb_ceo_weekly_report
agentId: agent_ceo_felipe
type: cron
schedule: "0 17 * * 5" # Viernes a las 17:00
payload: |
## Weekly Executive Report
Es el fin de semana. Genera el reporte ejecutivo semanal para el Board.
### Estructura del reporte (usa esta plantilla exacta):
# DevCo Weekly Report - Semana {{ week_number }}
## Resumen ejecutivo
[2-3 frases sobre el estado general de la empresa esta semana]
## Progreso por iniciativa
[Para cada iniciativa activa: % completado, bloqueantes, ETA]
## Métricas clave
- Tareas completadas esta semana: X
- Tareas abiertas: X
- Presupuesto consumido: $X de $200 (X%)
- Incidencias de soporte: X tickets, X% resueltos en <2h
## Decisiones tomadas esta semana
[Lista de decisiones significativas con su justificación]
## Semana próxima
[Top 3 prioridades para la semana que viene]
## Solicitudes al Board
[Si necesitas autorización, presupuesto adicional, o input del Board]
### Instrucciones:
1. Consulta el historial de tareas de esta semana
2. Consulta el estado actual de todas las iniciativas
3. Consulta el resumen de costos de la semana
4. Genera el reporte completo
5. Crea una tarea completada con título "Weekly Report Semana X"
y tag "board-report"
El Board recibirá notificación automática cuando el reporte esté listo.
timeout: 3600000 # 1 hora
enabled: true
Rutina 4: Monitoreo de infraestructura
El ingeniero senior puede tener un heartbeat de monitoreo que revise la salud del sistema y cree tickets automáticamente cuando encuentra problemas:
heartbeat:
id: hb_infra_monitor
agentId: agent_eng_rafa
type: cron
schedule: "*/30 * * * *" # Cada 30 minutos
payload: |
Revisión de infraestructura rutinaria.
Verifica:
1. Estado de los servicios críticos (API, DB, workers)
2. Tiempos de respuesta de los endpoints clave
3. Errores en los logs de las últimas 30 minutos
4. Uso de recursos (CPU, memoria, disco)
Si encuentras anomalías:
- CRÍTICO (servicio caído, error rate > 5%):
Crea ticket de prioridad critical y escala al CTO inmediatamente
- ADVERTENCIA (tiempo de respuesta degradado, disco > 80%):
Crea ticket de prioridad high y asígnate a ti mismo
- OK: Registra log corto, sin ticket
Herramientas disponibles: curl, pg_isready, df, free, tail
timeout: 300000 # 5 minutos
runOnlyIf:
budgetRemainingUsd: 1.00
enabled: true
Heartbeats vs agentes continuos
Una distinción conceptual importante: los heartbeats despiertan al agente, hacen trabajo, y luego el agente “duerme” hasta el próximo heartbeat. No es un agente que corre permanentemente en background.
graph LR
subgraph "Heartbeat (Paperclip)"
H1[Duerme] -->|cron trigger| H2[Despierta]
H2 --> H3[Trabaja]
H3 --> H4[Termina]
H4 -->|hasta próximo trigger| H1
end
subgraph "Agente continuo (no Paperclip)"
C1[Corre siempre] -->|nuevo input| C2[Procesa]
C2 --> C1
end
Los agentes continuos (como un servidor que está siempre escuchando) son más difíciles de gestionar, costosos de mantener, y problemáticos para el control de presupuesto. Los heartbeats son la forma que Paperclip tiene de hacer que los agentes sean activos pero controlados.
Para casos donde necesitas baja latencia de respuesta (ej: soporte), la solución es un cron muy frecuente (cada 1-2 minutos) en lugar de un agente continuo. Es funcionalmente equivalente para la mayoría de casos de uso, con la ventaja de que cada ejecución es independiente, trazada, y dentro del modelo de presupuesto.
Debugging de heartbeats
Cuando un heartbeat no funciona como esperas, hay varias herramientas de diagnóstico:
Ver el historial de ejecuciones:
Company → Agents → [Agente] → Heartbeats → [Heartbeat] → Execution History
Cada ejecución muestra:
- Timestamp de inicio y fin
- Status (success/failure/skipped)
- Log de output del agente
- Costo de esa ejecución
- Qué tareas se crearon o modificaron
Trigger manual de un heartbeat: Desde la misma pantalla, el botón Trigger Now ejecuta el heartbeat inmediatamente, ignorando el schedule. Útil para probar la configuración sin esperar al próximo trigger programado.
Modo debug: Activa el modo debug para ver exactamente qué contexto se le envía al agente:
Company → Agents → [Agente] → Heartbeats → [Heartbeat] → Debug Mode: ON
Con debug activo, la próxima ejecución registra el payload completo enviado al agente (incluyendo todas las skills inyectadas), lo cual permite verificar que el agente recibe el contexto correcto.
Logs del sistema:
# Logs de heartbeats del servidor
tail -f ~/.paperclip/logs/agents.log | grep heartbeat
# Filtrar por agente específico
tail -f ~/.paperclip/logs/agents.log | grep "agent_ceo_felipe"
# Ver errores de los últimos 30 minutos
grep "ERROR" ~/.paperclip/logs/agents.log | tail -50
Problemas comunes y soluciones:
graph TD
P1[Heartbeat no se dispara] --> S1{Schedule correcto?}
S1 -->|no| Fix1[Verificar cron syntax con validator]
S1 -->|sí| S2{Agente enabled?}
S2 -->|no| Fix2[Board → Agents → Enable]
S2 -->|sí| S3{Budget agotado?}
S3 -->|sí| Fix3[Board → Budget → Reset o ajustar]
S3 -->|no| Fix4[Ver logs del sistema]
P2[Heartbeat se dispara pero falla] --> E1{Timeout?}
E1 -->|sí| Fix5[Aumentar timeout o simplificar payload]
E1 -->|no| E2{Error del adapter?}
E2 -->|sí| Fix6[Verificar configuración del adapter]
E2 -->|no| Fix7[Revisar output del agente]
Heartbeat que se saltea (skipped):
Si ves muchos skipped en el historial, significa que el agente todavía estaba corriendo cuando el siguiente heartbeat se intentó disparar. Soluciones:
- Aumentar el intervalo entre heartbeats
- Reducir el timeout del agente
- Simplificar el payload para que el agente haga menos trabajo por ejecución
Gestión del ciclo de vida de los heartbeats
Los heartbeats son configuración dinámica: puedes habilitarlos, deshabilitarlos, y modificarlos sin reiniciar el servidor.
# Via API directamente
# Deshabilitar temporalmente (ej: durante mantenimiento)
curl -X PATCH http://localhost:3100/api/heartbeats/hb_ceo_daily_review \
-H "Content-Type: application/json" \
-d '{"enabled": false}'
# Habilitar de nuevo
curl -X PATCH http://localhost:3100/api/heartbeats/hb_ceo_daily_review \
-d '{"enabled": true}'
# Trigger manual
curl -X POST http://localhost:3100/api/heartbeats/hb_ceo_daily_review/trigger \
-d '{"reason": "manual_test"}'
# Ver estado de todos los heartbeats
curl http://localhost:3100/api/heartbeats?companyId=company_devco
Cuando pausas un agente desde el Board, todos sus heartbeats se deshabilitan automáticamente. Cuando lo reactivas, los heartbeats vuelven a su estado previo.
Esta interacción entre el control del Board y los heartbeats es fundamental: el Board siempre tiene el poder de parar cualquier agente instantáneamente, y ese poder se refleja automáticamente en todos sus mecanismos de ejecución.
Con los heartbeats configurados, tu empresa de agentes está operando de forma autónoma. El siguiente paso es entender el sistema de tickets con más profundidad: cómo fluye el trabajo desde la asignación hasta el cierre, y cómo el audit log te da visibilidad completa de lo que está pasando.