Saltar para o conteúdo
← Inforjota
Cursos Inforjota English

Lição 5 de 6 · 15 min · Verificado em 10 de Outubro de 2026

Projecto final: um sistema que trabalha sozinho, com travões

No fim desta lição vais conseguir:

  • Construir um agente que todas as manhãs compara uma página com a da véspera e escreve um resumo
  • Pôr quatro travões: caixa própria, tecto de gasto, registo e botão de paragem
  • Agendar e desagendar o agente com o cron ou com o schtasks
  • Testar cada travão antes de deixar o sistema a correr sozinho

A junta de freguesia publica avisos numa página: cortes de água, horário do barco, obras na estrada. O Sr. Manuel quer saber todas as manhãs se há novidades, sem abrir a página e comparar de cabeça com a de ontem.

Hoje constróis esse vigia, com uma página de teste tua, que mudas à mão para simular os avisos.

Antes de começar: o que é «pronto»

O projecto está pronto quando:

  1. existe a pasta experiencias/vigia com Git e uma página de teste;
  2. o vigia guarda uma cópia por dia e compara-a com a anterior;
  3. quando há mudanças, um agente escreve um resumo em resumos/;
  4. cada execução deixa uma linha no registo, com o que fez e o custo estimado;
  5. os quatro travões foram testados um a um;
  6. o vigia correu agendado e depois tiraste o agendamento.

Os quatro travões:

  • Caixa própria: só trabalha na sua pasta, com o agente sem ferramentas e sem rede além da chamada ao modelo.
  • Tecto de gasto: um por execução e outro por mês; cada execução só pode gastar o que sobra do mês, e duas execuções não correm ao mesmo tempo.
  • Registo: uma linha por dia com o que fez e quanto custou.
  • Botão de paragem: se existir um ficheiro PARAR, a próxima execução não arranca. Uma execução já a meio pára-se pelo processo.

Cuidado

O vigia não envia emails nem mensagens. Se um dia quiseres um aviso no telemóvel, o agente escreve o rascunho e uma pessoa decide se sai.

Isto é como está a 6 de Outubro de 2026; se o ecrã for diferente, procura o botão com o mesmo nome. Guias: Agent SDK, crontab, schtasks.

Passo 1: a pasta e a página de teste

Cria experiencias/vigia, corre git init e abre o agente lá dentro:

Cria pagina/index.html: uma página simples de «Avisos da Junta» com três avisos inventados,
cada um com data e uma frase. Cria também um .gitignore com .env, .venv/ e historico/.
Não instales nada.

Confirma: a página abre no browser e o .gitignore tem as três linhas.

Se não deu: se a página não abre, confirma que se chama index.html e está dentro de pagina/.

Passo 2: o vigia sem modelo

Primeiro, a parte previsível, só com código:

Cria vigia.py, em Python, sem pacotes extra. Por esta ordem:
1. Se existir o ficheiro PARAR, escreve no registo «parado» e sai.
2. Se existir o ficheiro A_CORRER, escreve «já a correr» e sai; senão cria-o e apaga-o no fim, aconteça o que acontecer.
3. Lê config.json (tecto_execucao_usd, tecto_mes_usd, max_voltas). Soma os custos do mês em registo.csv,
   incluindo as linhas de erro. O que sobra é tecto_mes_usd menos essa soma; se for zero ou menos,
   escreve «tecto do mês» e sai. O tecto desta execução é o menor entre tecto_execucao_usd e o que sobra;
   escreve-o no registo.
4. Copia pagina/index.html para historico/AAAA-MM-DD.html.
5. Compara com a cópia anterior. Sem cópia anterior ou sem diferenças: escreve isso no registo e sai.
6. Com diferenças, por agora, só imprime o diff.
Cada linha de registo.csv tem: data, hora, o que fez, custo estimado.
Aceita --data AAAA-MM-DD para eu testar dias diferentes. Cria config.json com valores baixos que eu ajusto.
Mostra-me o plano antes de escrever.

Confirma: corre python vigia.py --data 2026-10-01, muda um aviso na página, corre com --data 2026-10-02. A segunda vez imprime o diff.

Se não deu: se a segunda corrida diz «sem diferenças», confirma que gravaste a página antes de correr.

Passo 3: o agente que resume

Agora ligas o modelo, só para o que o código não sabe fazer: explicar as mudanças em português.

Instala claude-agent-sdk num ambiente virtual .venv. No passo 6 do vigia.py, chama o Agent SDK
com o diff no pedido e estas opções: cwd igual à pasta do vigia, permission_mode="dontAsk",
disallowed_tools=["*"], max_turns=max_voltas e max_budget_usd igual ao tecto desta execução (o menor entre
tecto_execucao_usd e o que sobra do mês). Pede um resumo curto em português europeu, sem inventar nada.
O vigia.py grava o resumo em resumos/AAAA-MM-DD.md e o total_cost_usd no registo.
O próprio script lê a chave do .env e nunca a mostra.
Se o SDK parar com erro, regista o motivo e o custo que vier na resposta e sai. Se não vier custo nenhum,
regista «custo desconhecido» e cria o ficheiro PARAR, para eu rever antes da próxima execução.
Acrescenta --simular ok|tecto|indisponivel, que não chama o modelo: devolve um resumo fixo com custo 0,01,
um fim por error_max_budget_usd com custo, ou um erro de ligação sem custo.

A chave fica no .env, como na lição 1/06. O "*" tira ao agente todas as ferramentas: recebe o diff, devolve texto, e quem grava é o teu código. Sem isto, no modo dontAsk ainda podia ler ficheiros da pasta, incluindo o .env.

Se não deu: «Invalid API key» quer dizer que o script não está a ler o .env; confirma o nome ANTHROPIC_API_KEY.

Dica

O custo no registo é uma estimativa, e os tectos do SDK também são aproximados: contam custos estimados e são verificados entre voltas. O travão de verdade é o limite de gasto na consola do fornecedor (lição 1/06). Corre uma vez, vê o custo no registo e ajusta os tectos do config.json.

Passo 4: testar os travões

Primeiro pede a previsão:

Sem mudar código, diz-me o que o vigia.py faz e que linha escreve no registo em cada caso:
existe PARAR; o tecto do mês foi atingido; a página não mudou.

Depois prova:

  1. Cria o ficheiro PARAR e corre. O registo diz «parado», sem custo.
  2. Apaga o PARAR, põe o tecto_mes_usd abaixo do que já gastaste e corre. O registo diz «tecto do mês».
  3. Repõe o valor e corre num dia sem mudanças. Não há chamada ao modelo nem custo.
  4. Num dia com mudanças, corre com --simular tecto. O registo mostra o fim por error_max_budget_usd e o custo.
  5. Põe o tecto_execucao_usd acima do que sobra do mês e corre com --simular ok. O registo mostra o tecto desta execução igual ao que sobra.
  6. Corre com --simular indisponivel. O registo diz «custo desconhecido» e o PARAR aparece; apaga-o.
  7. Lança duas execuções ao mesmo tempo com --simular ok. Uma corre; a outra escreve «já a correr».

Se não deu: se o resultado não bate com a previsão, mostra ao agente a linha do registo e pede que corrija só esse ponto.

Passo 5: agendar

Mostra-me como correr o vigia todos os dias às 7h00 com o .venv desta pasta: no Linux ou no macOS,
uma linha de crontab; no Windows, um correr.bat e o comando schtasks. Não agendes nada: faço eu.

No Linux ou no macOS, corre crontab -e e junta a linha, com o teu caminho:

0 7 * * * cd /caminho/para/experiencias/vigia && .venv/bin/python vigia.py >> cron.log 2>&1

Os cinco campos são minuto, hora, dia, mês e dia da semana. O crontab -l mostra o que está agendado. O cron arranca com um ambiente mínimo, por isso o script tem de ler o .env sozinho.

No Windows, com o correr.bat que o agente escreveu:

schtasks /create /tn vigia /tr "C:\caminho\experiencias\vigia\correr.bat" /sc daily /st 07:00
schtasks /query /tn vigia

Dica

Para desagendar: no cron, crontab -e e apaga só essa linha; no Windows, schtasks /delete /tn vigia /f. Não uses crontab -r para isto: apaga todas as linhas, não só a do vigia.

Se não deu: se nada acontece às 7h00, vê o cron.log; o erro mais comum é um caminho errado.

Exercício

Como sei que ficou bem há uma cópia por dia em historico/, um resumo só nos dias com mudanças, uma linha por dia no registo com o custo, e o crontab -l (ou o schtasks /query) já não mostra o vigia.

Se não deu

  • Resumos com coisas que não estão na página: reforça no pedido «resume só o que está no diff» e confirma que o diff vai no pedido.
  • O registo tem duas linhas no mesmo dia: o vigia correu duas vezes; vê o crontab -l.
  • O custo do mês não bate com a consola: o do registo é uma estimativa; manda a consola.

O que levas deste projecto

Um sistema que trabalha sozinho e que sabes travar: o código faz o previsível, o agente só o que precisa de linguagem, tudo fica registado e nada sai sem uma pessoa.

Vídeos

Agent Loops: Complete Guide (Claude Code + Codex)
Owain Lewis · 20 min · EN · legendas · Ver no YouTube
Ciclos de agentes na prática com Claude Code e Codex: um ciclo gestor que lê o backlog e um ciclo trabalhador, com skills, verificação e limites (guardrails) no fim.

Testa o que aprendeste

1. O vigia corre todas as manhãs e queres impedir que volte a correr, antes de perceberes um resultado estranho. Qual é o caminho mais rápido e seguro?
2. O agente sugere enviar o resumo por email ao presidente da junta todas as manhãs, «para poupar trabalho». O que respondes?
3. O registo mostra o mesmo custo em dias em que a página não mudou. Qual é a melhor correcção?

Correcções a esta lição (1)
  • : Depois de uma segunda revisão externa: cada execução só pode gastar o que sobra do mês, as linhas de erro contam para a soma, um custo desconhecido cria o `PARAR`, e duas execuções não correm ao mesmo tempo; o `PARAR` impede as próximas execuções, não interrompe uma a meio (pára-se o processo); os testes ganharam quatro casos simulados, sem chamadas pagas.