Heartbeats

O Modelo Mental
Uma rotina é sistemática — o mesmo script roda todo dia às 7h. Um heartbeat é proativo — o agente acorda, observa e decide se deve agir. Cada execução de heartbeat responde a uma única pergunta:Dado o estado atual do meu domínio, devo trabalhar agora ou pular?O agente retorna um veredicto em JSON. Se
action: work, o dispatcher deixa o agente executar seus turnos. Se action: skip, a execução termina imediatamente com custo próximo de zero.
Anatomia de um Heartbeat
Heartbeats vivem emconfig/heartbeats.yaml (fonte da verdade) e são espelhados no banco do dashboard. Cada entrada tem:
Início Rápido
1. Crie um heartbeat
No Claude Code, use a skillcreate-heartbeat:
“Crie um heartbeat de 4 horas para atlas-project que triagem PRs e issues parados.”A skill conduz pelos campos, deixa
enabled: false por padrão e chama POST /api/heartbeats. A entrada aparece na página Heartbeats do dashboard como desabilitada.
Alternativamente, edite config/heartbeats.yaml diretamente e chame POST /api/heartbeats/reindex para espelhar no banco.
2. Dry-run antes de habilitar
No dashboard, clique em Run now no card (ou chamePOST /api/heartbeats/{id}/run). Isso dispara uma execução manual única, independente do relógio do interval. Inspecione o resultado:
- O agente retornou JSON válido?
- A decisão foi razoável?
- Ficou dentro de
max_turnsetimeout_seconds?
3. Monitore as execuções
Cada execução registrastarted_at, finished_at, status, tokens_input, tokens_output, cost_usd e o decision_json parseado. A página Heartbeats no dashboard mostra as últimas 10 execuções por card e o custo agregado de 7 dias.
Wake Triggers
Um heartbeat acorda em qualquer um dos triggers listados emwake_triggers:
- interval — o scheduler dispara a cada
interval_seconds. Quase sempre incluído. - manual — alguém clica em “Run now” ou chama a API. Permite a operadores debugar.
- mention — um
@agent-slugnum comentário de ticket dispara um mention trigger (se o agente tiver um heartbeat habilitado commentionnos wake_triggers). Máximo 3 mentions por comentário. - new_task — uma task de goal criada com este agente como
assignee_agentacorda o heartbeat. - approval_decision — uma solicitação de aprovação foi decidida (feature futura).
Controle de Custo
Como heartbeats queimam tokens em cada execução, coloque guardrails:- Comece com
enabled: false. Sempre. Revise a primeira execução manual antes de habilitar. - Use um
decision_promptafiado. Se o agente escreve um parágrafo quando devia escrever JSON, você desperdiça tokens. - Tenda ao
skip. Treine o prompt para pular a menos que haja urgência genuína. Um heartbeat de 4 horas que pula 4 das 6 execuções diárias está fazendo seu trabalho. - Mantenha
max_turnsbaixo para heartbeats puramente de triagem (5–10). Só aumente para agentes que podem precisar agir em múltiplos itens. - Acompanhe
cost_7dno card do dashboard. Se um heartbeat sobe consistentemente, o prompt provavelmente está muito leniente — aperte os critérios de skip.
Debugando
Um heartbeat não está disparando
- Cheque o
enableddo heartbeat — está individualmente ligado? - Cheque o log do dispatcher (
journalctl -u evo-nexus -fou os logs do serviço do dashboard) para registro do interval. - Chame
POST /api/heartbeats/{id}/run— uma execução manual funciona? Se sim, é problema de scheduler; se não, é problema do agente ou prompt.
Uma execução falhou
Olhe ostderr_tail e stdout_tail da execução. Causas comuns:
required_secretsfaltando no.envdecision_promptnão forçou JSON — o parser não conseguiu extrair o veredicto- O agente bateu em
max_turnsantes de retornar (aumente o limite ou aperte o prompt) - O agente bateu em
timeout_seconds(chamada de integração foi lenta — aumente o timeout ou adicione um retry dentro do agente)
Drift entre YAML e banco
Se você editouconfig/heartbeats.yaml à mão e o dashboard ainda mostra o estado antigo:
Skills do CLI
Relacionados
docs/goals.md— ligar um heartbeat a um goal para injeção de contextodocs/tickets.md—@mentionsem tickets acordam heartbeats- Código:
dashboard/backend/heartbeat_dispatcher.py,dashboard/backend/routes/heartbeats.py,dashboard/backend/heartbeat_schema.py