Por que agentes de IA quebram em produção (e como FSMs e 'minions' podem resolver isso)
Fala gurizada!
Tenho acompanhado muita gente tentando colocar agentes de IA para rodar tarefas complexas em produção, e quase todo mundo acaba batendo na mesma parede: o fluxo funciona lindo em 3 ou 4 testes manuais, mas quando entra em loop contínuo, o agente alucina transições, chama ferramentas fora de hora, entra em retry infinito e drena o orçamento de tokens.
Recentemente andei estudando a arquitetura do Starnet (androoAGI) e achei a tese deles muito precisa em um ponto: a morte do agente monolítico.
Em vez de você ter um "mega-agente" com um system prompt gigantesco tentando planejar, executar, refletir e tomar decisões críticas de uma vez só, o Starnet aborda a decomposição em minions — sub-agentes descartáveis, hiper-focados e com escopo cirúrgico.
Mas há um problema de engenharia que nem mesmo a divisão em minions resolve se a fundação for frágil: o controle de fluxo probabilístico.
Onde a maioria dos frameworks (LangChain, CrewAI, etc.) erra a mão
O grande erro da primeira onda de frameworks de agentes foi deixar a máquina de estados dentro da cabeça do LLM.
Eles tratam a esteira como um loop aberto no estilo ReAct: o modelo recebe o estado, decide o que fazer, escolhe a tool e, pior, decide quando terminou ou para onde vai.
Só que LLM é um motor de inferência estocástico. Se você deixa o modelo decidir a transição de fluxo da sua aplicação:
- Você perde o determinismo: Uma variação de temperatura ou uma resposta inesperada da API faz o modelo pular etapas cruciais de validação.
- Alucinação de Tool-Calling: Se você expõe 15 ferramentas de uma vez no contexto, o modelo eventualmente invoca uma ferramenta destrutiva em momento indevido.
- Falta de isolamento: Transbordamento de contexto entre passos anteriores e etapas atuais.
Para construir sistemas autônomos que realmente aguentam o tranco, a regra de ouro de sistemas distribuídos precisa ser aplicada: o LLM nunca deve mandar no fluxo de controle da aplicação.
A virada de chave: FSM (Máquina de Estados Finitos) + Capability Gates
A abordagem que realmente escala e dá garantias de sistema é amarrar a execução em uma FSM determinística:
- Quem transiciona o estado é código estrito (Python, Go, Rust): A aplicação define os estados válidos (ex:
PARSING->VALIDATING->EXECUTING->COMMITTING). O LLM opera estritamente dentro de um estado para realizar uma computação delimitada. Quem valida a saída e aciona o gatilho da próxima etapa é código determinístico. - Capability Gates dinâmicos: Cada estado da FSM só injeta no contexto as ferramentas estritamente permitidas para aquela etapa específica. Se o agente está no estado de leitura, ferramentas de escrita ou de rede sequer existem na lista de schemas enviada ao modelo. Isso anula na raiz boa parte dos riscos de prompt injection indireto e tool-calling indevido.
- Persistência atômica: Transições de estado gravadas de forma transacional (como em um SQLite WAL local), permitindo pausar, inspecionar e retomar execuções sem loops efêmeros na memória.
O que estou construindo no Hyades: Função sobre Estética
É exatamente em cima desse problema que tenho trabalhado no Hyades, um projeto de orquestração determinística de agentes que extrai a essência do Starnet.
Minha postura nesse desenvolvimento tem sido focar 100% na função e na engenharia de raiz, sem perder tempo com firula estética ou interfaces vazias antes que o motor esteja blindado:
- Core FSM desacoplado: Toda a máquina de estados roda orientada a contratos rígidos de transição.
- Modelo de Daemon com IPC dedicado: O orquestrador roda como um daemon de background desacoplado das interfaces, conversando via protocolo IPC limpo.
- Auditoria de Recursos na Raiz: Em vez de deixar o runtime engordar silenciosamente, meço o consumo de memória (
VmRSS) diretamente via/procpara garantir que o processo permaneça enxuto e sem vazamentos de memória durante execuções longas. - Interfaces Locais Operacionais: CLI robusta e TUI construída em Textual para controle de terminal em tempo real, além de uma bridge em Starlette para o cockpit web.
- Mascaramento e Redação de Segredos: Filtragem estrita de credenciais (
sk-, chaves de API e tokens) diretamente na camada de payload de eventos, impedindo que segredos vazem para históricos de sessão ou transcrições de log.
O projeto ainda está em desenvolvimento ativo e fechado enquanto estou estabilizando as esteiras de CI, os gates de tipagem e a confiabilidade das invariantes de memória.
Minha ideia é ir documentando essa jornada técnica por aqui, pelo LinkedIn e, principalmente, pelos meus artigos em zvorky.github.io.
Assim que a fundação estiver verdadeiramente "testada em batalha", abrirei o código-fonte para a comunidade fuçar e usar.
E vocês, como têm lidado com isso?
Queria puxar esse debate com vocês que estão construindo agentes ou ferramentas com LLMs por aqui:
Como vocês estão delimitando as fronteiras de estado hoje? Ainda estão confiando na orquestração nativa de frameworks de prompt ou já sentiram a necessidade de descer o nível para código determinístico?