# Como funciona um agente em loop

Parte 2 de 2 · experimentos com agentes

← [Parte 1: MacBook velho virou servidor de contexto](https://blog-preview.imfrank.dev/pt-br/blog/macbook-velho-virou-servidor-de-contexto/)

> Como agentes sempre ligados lidam com filas, falhas e contexto, com base na aula de Lee Robinson em Stanford CS146S, seguida do meu plano de experimento.

- Author: Franklin Javier
- Published: 2026-10-11
- Language: Português (Brasil)
- Tags: ia, agentes, arquitetura, llm
- Canonical: https://blog-preview.imfrank.dev/pt-br/blog/como-funciona-um-agente-sempre-ligado/

Um agente sempre ligado executa o loop de modelo e ferramentas no servidor, salva o progresso e pode continuar a tarefa depois que você sai da conversa. A aula de Lee Robinson em Stanford CS146S explica essa arquitetura: filas de mensagens, workflows duráveis, uma VM que pode ser reconstruída, ferramentas sob demanda, helpers, cache do prompt, memória em camadas e autorização de ações. Com o [contexto compartilhado da parte 1](/pt-br/blog/macbook-velho-virou-servidor-de-contexto/) funcionando, termino com uma proposta minha para o primeiro experimento, que ainda preciso testar.

A aula [How always-on agents work, de Lee Robinson (@leerob)](https://x.com/leerob/status/2108650243365736855), foi apresentada em Stanford CS146S em 8 de outubro de 2026.

Meu outro Mac já dormiu no meio de uma tarefa. Do celular, pedi ao agente no servidor para descobrir onde ela tinha parado. Ele encontrou o histórico na memória compartilhada e conferiu no GitHub o que já tinha sido enviado.

No [vídeo](https://x.com/leerob/status/2108650243365736855): 2:35 (como chegamos aqui); 6:13 (modelos); 10:06 (arquitetura); 18:07 (harness); 27:26 (contexto); 34:26 (próximos passos).

A arquitetura vem da aula. Os relatos do MacBook vêm das experiências que contei no post anterior; os outros exemplos são hipotéticos. O plano final é uma proposta minha.

## Por que o agente não roda na máquina que você fecha

Se a tarefa depende do processo aberto no terminal, suspender o computador interrompe o trabalho. Meu MacBook resolve essa parte porque funciona como servidor em vez de laptop: fica de tampa fechada, na tomada, ligado o dia inteiro, com o modo de suspensão desativado. A aula começa pelo loop da semana 1:

```python
messages = [system_prompt, user_message]
while True:
    reply = llm(messages, tools=TOOLS)
    messages.append(reply)
    if not reply.tool_calls:
        print(reply.text); break
    for call in reply.tool_calls:
        messages.append(run_tool(call))
```

O modelo pede ferramentas, recebe os resultados e decide o próximo passo. Para continuar depois que você sai, esse loop roda no servidor, que salva cada passo. O aplicativo recebe mensagens e mostra o progresso. A VM, o computador do agente na nuvem, executa as ferramentas que precisam de uma máquina. Lee explica essa divisão [no vídeo](https://x.com/leerob/status/2108650243365736855) (a partir de 10:06).

*Diagrama: Os apps mandam eventos ao servidor, onde a entrada, a fila de cada conversa e o loop do agente salvam cada passo no estado salvo; o loop responde por SendToUser, o estado salvo manda atualizações ao vivo para os apps e as chamadas de ferramentas vão para a VM do agente, com executor de comandos, servidor de arquivos e um desktop com Chrome por agente.*

Sempre ligado também permite parar quando não há trabalho. O processo encerra após 2 minutos ocioso; um novo evento carrega o estado e inicia outro turno. Os números usados neste texto vêm dos slides da aula.

Imagine pedir uma pesquisa antes de dormir. Você fecha o laptop, mas o servidor continua a tarefa. De manhã, abre a conversa no celular e encontra o progresso salvo, sem precisar manter o terminal aberto durante a noite.

## A máquina precisa poder ser reconstruída

Um patch de segurança pode exigir reconstruir a VM. Se a conversa e o progresso existirem só nela, a manutenção vira perda de trabalho. A orientação da aula é direta: “Salve tudo no servidor. A VM sempre pode ser reconstruída.”

O servidor guarda conversas, memória, rotinas e skills. Cada usuário tem uma microVM Firecracker com Linux e navegador. Seus agentes dividem a máquina, cada um com sua tela virtual e seu Chrome.

Quando fica ociosa, a VM sincroniza os arquivos com o armazenamento na nuvem, salva um snapshot da memória e do disco e para. Nunca dorme no meio de um turno. Uma chamada de ferramenta que precise dela restaura o snapshot, incluindo ferramentas instaladas e sessões do navegador.

*Diagrama: Uma mensagem ou uma rotina inicia um turno que salva cada passo; a VM só acorda se uma ferramenta precisar dela e, depois, nada roda: o processo para após 2 minutos ocioso e a VM dorme como snapshot.*

Suponha que o agente tenha preparado uma planilha e a máquina durma. Ao pedir uma alteração, você provoca uma nova chamada de ferramenta. A VM acorda com os arquivos e o navegador preservados; o servidor mantém a conversa.

## Mensagens rápidas precisam virar um pedido só

Executar cada mensagem separadamente cria concorrência sobre o mesmo pedido. O agente pode agir antes de receber a correção seguinte.

Na aula, um roteador elimina eventos duplicados e escolhe a conversa. Cada conversa tem sua fila e executa um turno por vez. Mensagens rápidas entram em lote. Eventos de Slack, grupos, rotinas e helpers aguardam na fila, mas uma mensagem sua no chat individual pode interromper ou parar o turno atual.

*Diagrama: Mensagens suas, do Slack e de ligações, rotinas e webhooks, outros agentes e trabalho pronto ou check-ins passam por um roteador que descarta duplicatas e escolhe a conversa, depois esperam na fila dessa conversa, um turno por vez, exceto sua mensagem no chat individual, que fura a fila.*

Imagine um pedido pelo Slack: incluir alguém numa reunião, depois acrescentar outra pessoa e, por último, agradecer. Essas mensagens podem virar um único turno. Se você mudar o dia pelo chat individual, com “na verdade, faz na quinta”, a correção entra na frente e redireciona o trabalho em andamento.

## Como retomar sem repetir um pagamento

Reiniciar um job do começo depois de uma queda pode repetir uma ação já concluída. No MacBook, testei reiniciar a máquina e derrubar o Wi-Fi; os serviços voltaram sozinhos. Retomar cada etapa de uma tarefa é o teste que quero fazer agora. Em um pagamento, repetir uma etapa pode significar outra cobrança.

A aula usa Temporal para executar workflows duráveis: sequências de trabalho com cada passo registrado. Outro servidor consegue retomar do último passo salvo. As etapas também precisam ser idempotentes, isto é, uma repetição deve manter o mesmo resultado, sem criar outra ação. O motor oferece timers, cancelamento e verificações de saúde (health checks); cada helper tem seu próprio workflow.

*Diagrama: Depois de uma queda no passo 3, a fila de jobs reinicia e roda os passos 1 e 2 de novo, enquanto o workflow durável, que salvou os passos 1 e 2, retoma no passo 3.*

Num cenário hipotético, uma compra já autorizada é concluída e o servidor cai antes de salvar o resultado. Ao retomar, o passo de pagamento pode ser tentado novamente. A idempotência precisa reconhecer aquela mesma operação e impedir outra cobrança.

## Trocar de aparelho não pode duplicar a conversa

Uma conexão instável pode fazer o aplicativo reenviar a mensagem. Ao mesmo tempo, o celular e o computador precisam mostrar a mesma conversa.

O cliente exibe a mensagem e a salva localmente com um identificador único. O servidor ignora identificadores já recebidos. Outros aplicativos recebem um aviso de mudança e buscam os dados no banco. Os updates têm uma sequência; uma lacuna faz o cliente recarregar os dados.

Imagine enviar um pedido no celular e perder a conexão antes da confirmação. O aplicativo tenta de novo com o mesmo identificador, sem criar outro pedido. Quando você abre o computador, ele busca a conversa salva. Perder um aviso de atualização não apaga a mensagem.

## Ferramentas demais ocupam o espaço da tarefa

Carregar a definição completa de toda ferramenta deixa menos contexto para entender o pedido. Muitas dessas ferramentas nem serão usadas naquele turno.

A solução da aula é levar só os nomes no prompt e carregar descrição e schema sob demanda. Essa parte do harness aparece [no vídeo](https://x.com/leerob/status/2108650243365736855) (a partir de 18:07). Cada definição fica abaixo de 4.000 caracteres. O conjunto permanece estável: uma ferramenta indisponível devolve um erro claro, em vez de desaparecer. Salvar estado merece uma ferramenta própria; se o modelo passa 90% do tempo repetindo um padrão de shell, esse padrão deve virar ferramenta.

A escolha também segue uma ordem de custo crescente: contexto e memória, API do aplicativo, busca na web, navegador logado, desktop e pergunta ao usuário. Um conector quebrado exige avisar e perguntar, sem contornar a falha pelo navegador.

*Diagrama: Seis degraus do mais barato ao mais caro (o que o agente já sabe, a API do app, busca na web, o navegador logado, o desktop inteiro e perguntar a você), em que um conector quebrado leva direto a perguntar a você.*

Suponha que você peça os compromissos de amanhã. O agente carrega a ferramenta de calendário e consulta a API. Se o conector falhar, informa o problema e pede orientação. Ele não abre o navegador por conta própria para tentar recuperar acesso.

## O agente precisa saber ficar quieto

Exibir toda resposta do modelo enche o chat de comentários sobre cada tentativa e texto privado. Alguns eventos nem trazem algo útil para dizer.

No harness da aula, o código que organiza o uso do modelo e das ferramentas, `SendToUser` é a única saída visível. Texto comum e raciocínio ficam privados. O agente pode terminar um turno em silêncio. Quando precisa falar, a ferramenta envia texto, arquivos ou controles para uma decisão; a última mensagem pode encerrar o turno sem outra chamada ao modelo.

No meu servidor, o monitoramento já só me avisa no Telegram quando algo muda. Desliguei o Wi-Fi para testar, e o alerta chegou. Para o loop, quero testar esse mesmo critério: uma rotina autorizada que verifica um documento termina em silêncio se ele continuar igual e avisa quando houver uma mudança relevante.

## Delegar mantém a conversa disponível

Uma tarefa longa pode ocupar o agente principal e encher o contexto com screenshots. Você ainda precisa conseguir corrigir o pedido.

Lee separa o principal dos helpers. O principal entrega uma descrição completa da tarefa e recebe um relatório curto. Uma lista acompanha os pedidos, e ele pode consultar, orientar ou parar um helper. Cada helper executa seu próprio workflow durável.

No meu time de agentes, um orquestrador classifica o pedido e o encaminha ao bot fixo daquele projeto. Esse bot planeja o trabalho, fica responsável pelo PR e me devolve o resultado. Na aula, o agente principal passa uma tarefa a um helper e recebe um relatório de volta; no meu time, o bot continua com o projeto e mantém o contexto dele entre tarefas. Quando peço para corrigir um bug no site, por exemplo, o orquestrador passa o pedido ao bot do site, que já conhece o repositório.

O diagrama abaixo mostra a divisão entre o agente principal e os helpers na aula.

*Diagrama: Você conversa com o agente principal, que manda descrições completas de tarefas aos helpers geral, de uso de computador e de vídeo e a um helper de código na nuvem que trabalha numa VM só dele, separada da sua, e recebe relatórios curtos de volta.*

O helper de computador concentra os cliques e screenshots. Na web, pode ler a estrutura da página; para ações em pixels, a aula usa uma tela de 1280x800. Quando precisa de intervenção humana, entrega o controle. Já o cloud coding agent faz mudanças de código **numa VM só dele, separada da VM do usuário**.

Imagine pedir a revisão de um vídeo e depois perguntar sobre o prazo de outra tarefa. O helper cuida do vídeo, enquanto o principal continua disponível no chat. Ao terminar, devolve um relatório curto, sem colocar todo o material analisado na conversa principal.

## Cache: o detalhe que define o custo

Mudanças pequenas no prompt podem impedir o uso do cache e aumentar o custo. Até alterar a ordem das ferramentas pode ter esse efeito. A engenharia de contexto começa [no vídeo](https://x.com/leerob/status/2108650243365736855) (a partir de 27:26).

Na aula, o prefixo do prompt segue uma ordem fixa e fica idêntico até o próximo resumo. O histórico cresce no final. Horário e notas sobre mudanças entram na mensagem nova. Se um deploy altera a descrição de uma ferramenta, a conversa em andamento recebe uma nota, sem substituir o texto antigo. Hashes por seção ajudam a localizar mudanças; Lee trata cache miss como bug.

*Diagrama: O prompt é montado numa ordem fixa: definições de ferramentas, prompt de sistema e primeira mensagem ficam iguais até o próximo resumo, o histórico só cresce no final e só a mensagem mais nova é nova a cada chamada.*

A compactação aproveita essa estabilidade. No caso apresentado, o sistema espera cerca de 10 minutos depois de um turno que termina com o prompt acima de 100 mil tokens e resume enquanto o cache ainda está quente, numa janela de 10 a 60 minutos. Preserva as últimas mensagens ao usuário palavra por palavra. Se um trabalho em background estiver prestes a acordar o agente, pula essa compactação.

Suponha que uma pesquisa longa termine e você saia do chat. O sistema pode resumir durante a pausa usando o prefixo em cache. Seu próximo pedido começa com o resumo menor. Há perda de informação na compressão, então a qualidade desse resumo continua sendo um problema a resolver.

## Memória útil precisa caber no prompt

Guardar tudo não garante encontrar uma preferência quando ela importa. No servidor, instruo os agentes a tratar a memória como histórico e conferir o estado atual no repositório e no histórico de alterações. Foi assim que o agente conferiu o trabalho do meu outro Mac. Carregar tudo no prompt também consome o espaço da tarefa atual.

A aula divide a memória em camadas. O perfil, sempre no prompt, comporta até 100 fatos em 4.000 caracteres. O log traz eventos datados, com os 30 mais relevantes e recentes no contexto. Notas guardam detalhes de curto prazo; o restante fica disponível por busca.

Depois de cada turno, uma revisão adiciona fatos e substitui informações antigas. Ela só pode remover fatos que recebeu para examinar. A memória entra como informação, nunca como instrução com autoridade para comandar ações.

Imagine dizer que prefere reuniões à tarde. Essa preferência vai para o perfil e acompanha os próximos pedidos. Quando você precisar recuperar o motivo de uma reunião antiga, o agente busca o histórico específico, sem carregar todas as conversas para sugerir um horário.

## Um email recebido não pode autorizar uma ação

Um email de phishing pode mandar o agente enviar dinheiro e se apresentar como uma instrução urgente. Já limito as permissões dos meus agentes ao que cada um precisa. O loop também precisa preservar a origem do texto para não confundir conteúdo recebido com um pedido meu.

A aula marca textos de email e webhook como não confiáveis. Antes de uma ação arriscada, outro modelo faz o auto-review. Se o modelo bloquear a ação, o usuário recebe um pedido de aprovação. Se o usuário não responder em 15 segundos, a ação continua bloqueada.

Envios irreversíveis passam por rascunho e confirmação. O agente não manda mensagens a outras pessoas sem você pedir, e rotinas novas precisam do seu OK. Segredos ficam em variáveis de ambiente, fora do modelo.

Suponha que um email peça uma transferência para uma conta nova. O agente deve tratar a solicitação como conteúdo externo, sem tomá-la como autorização sua. Qualquer tentativa de ação arriscada passa pela revisão. Se o modelo bloquear a ação, você recebe um pedido de aprovação; sem resposta sua em 15 segundos, ela continua bloqueada. Se você pedir uma resposta por email, verá o rascunho antes de enviar.

## Minha proposta: o que eu construiria primeiro

Na parte final da [aula](https://x.com/leerob/status/2108650243365736855) (a partir de 34:26), Lee propõe “Delete the product”: construir o mínimo em volta do modelo e remover o que ele não precisa mais.

Este plano é meu, separado da aula do Lee. Eu começaria pela continuidade: uma tarefa interrompida obriga o usuário a descobrir o que já foi feito.

1. Colocar o loop no servidor e salvar conversas e progresso em Postgres. Os aplicativos buscariam o estado salvo quando recebessem um aviso de atualização.
2. Usar Temporal para retomar tarefas, com etapas idempotentes. Organizar a fila por conversa, agrupar mensagens rápidas e dar prioridade às correções no chat individual.
3. Limitar a saída visível a `SendToUser`. Carregar ferramentas conforme a necessidade e manter o prefixo estável, com memória curta e busca para detalhes antigos.
4. Começar o computador do agente com um container isolado por usuário. Adicionar helpers às tarefas longas e evoluir para snapshots quando o custo das máquinas ociosas pesar.
5. Colocar revisão automática antes das ações arriscadas e confirmação nos envios irreversíveis. Transformar cada falha real em um teste que ajude a corrigir o comportamento.

Meu primeiro cenário seria uma pesquisa que continua com o laptop fechado e aceita uma correção pelo celular. Depois eu ampliaria o acesso do agente a ações com consequências externas.

Agora tenho critérios para avaliar se uma tarefa pode continuar depois que eu saio da conversa. Ainda quero testar a retomada no ponto certo e entender como os agentes vão coordenar o trabalho entre si. No próximo capítulo, vou tratar da oficina de agentes, onde pretendo colocar vários deles rodando em loops juntos.

## Posts relacionados

- [Como compartilho links com meus agentes](https://blog-preview.imfrank.dev/pt-br/blog/como-compartilho-links-com-meus-agentes/) (2026-10-21): O xmd recebe um link (post do X, artigo ou página que depende de JavaScript) e retorna só o conteúdo em Markdown. Sem login, sem chave e sem MCP.
- [MacBook velho virou servidor de contexto](https://blog-preview.imfrank.dev/pt-br/blog/macbook-velho-virou-servidor-de-contexto/) (2026-10-08): Contexto compartilhado entre agentes, máquinas e projetos: meu MacBook de 2017 guarda sessões e resumos, com conferência no repositório antes de retomar.
- [Lisbon AI 2026: agentes, evals e segurança](https://blog-preview.imfrank.dev/pt-br/blog/lisbon-ai-2026/) (2026-09-25): Minhas notas das 32 palestras do Lisbon AI 2026, com as demos, os números e as perguntas do público.

---

Todas as páginas deste site também estão disponíveis em markdown: solicite qualquer URL com o header `Accept: text/markdown`. Veja o [llms.txt](https://blog-preview.imfrank.dev/llms.txt) e o [sitemap](https://blog-preview.imfrank.dev/sitemap.xml).
