CTO no Integrar Plus • Publicado em 03 de October de 2026
A onda recente de entusiasmo com inteligência artificial conseguiu transformar o clássico fluxo condicional em um problema caro de busca em espaço latente. Desenvolvedores experientes estão substituindo quinze linhas de lógica determinística por bibliotecas de orquestração de agentes, munidas de loops de reflexão, memória vetorial e chamadas sequenciais de modelos de linguagem. O resultado dessa troca quase nunca é mais autonomia para o produto. O que chega ao ambiente de produção é uma fatura pesada de provedores de inferência e um sistema que falha de formas impossíveis de reproduzir em testes automatizados.
Parte dessa complexidade nasce de uma confusão sobre onde a inteligência realmente precisa atuar dentro de uma aplicação corporativa. Quando você analisa a anatomia de boa parte dos chamados agentes em produção, percebe que noventa por cento do trabalho deles consiste em avaliar condições que o seu próprio código já conhecia de antemão.
A discussão técnica recente em torno desse exagero expôs dois lados bem definidos na comunidade.
De um lado, desenvolvedores argumentam que delegar branches de código para um modelo de linguagem reduz a necessidade de mapear casos de borda manualmente. A justificativa comum é que entradas de dados desestruturadas e formulários imperfeitos se tornam toleráveis sem que a equipe precise escrever dezenas de expressões regulares. Para quem defende essa abordagem, a perda de determinismo seria uma troca aceitável pela flexibilidade de não manter validadores rígidos.
Do outro lado, engenheiros focados em confiabilidade apontam que essa flexibilidade esconde um perigo silencioso. Dois pontos levantados pela comunidade resumem bem esse problema:
O primeiro é o erro de categoria em buscas de dados fechados. Vi debates recentes destacando bots de suporte que tentam responder perguntas como quais faturas dos últimos trinta dias de um cliente permanecem não pagas utilizando busca vetorial. Tratar essa consulta como proximidade semântica em embeddings gera uma resposta que parece convincente, mas omite registros arbitrariamente. Um identificador de cliente somado a uma janela de datas e a um status financeiro é um filtro determinístico de banco de dados. Qualquer tentativa de resolver isso com aproximação probabilística é usar a ferramenta errada para um problema que o PostgreSQL resolve em dois milissegundos com consistência imediata.
O segundo ponto é a falha invisível de formatação. Em extrações de documentos fiscais, uma equipe muitas vezes se contenta com noventa e oito por cento de assertividade do modelo. O problema são os dois por cento restantes. Em vez de emitir um erro explícito de parsing que acionaria um alerta, o modelo reescreve um dígito do código identificador ou omite um hífen mantendo a sintaxe correta. O dado inválido é gravado no banco sem disparar nenhuma exceção técnica, e o estrago só é descoberto ciclos depois, durante uma reconciliação contábil.
Concordo inteiramente com quem rejeita usar inteligência artificial para filtros que pertencem ao SQL ou para validações que um analisador sintático executa com perfeição. Onde eu discordo de parte da comunidade é na receita sugerida como saída: colocar uma expressão regular na frente e chamar o modelo apenas no que sobrar, esperando que o fluxo se resolva sozinho.
Essa ideia de manter o modelo como uma rede de proteção genérica ignora a arquitetura do sistema. Se você entrega a decisão do próximo passo da aplicação para a saída de um prompt, você perdeu o controle sobre a máquina de transições do seu domínio.
Na prática de quem opera sistemas web em servidores próprios, a única forma de manter custos previsíveis e evitar filas de processamento entupidas é tratar o modelo de linguagem como um operador pontual, nunca como o despachante do fluxo. A regra de negócio continua sendo uma máquina de estados finitos escrita em código tradicional.
| Dimensão | Orquestração por agente autônomo | Máquina de estados determinística |
|---|---|---|
| Latência média por etapa | Segundos a minutos em múltiplos loops | Milissegundos para transição interna |
| Custo computacional | Dezenas de chamadas de API por fluxo | Custo fixo de banco e chamadas pontuais |
| Comportamento em falhas | Alucinações secundárias em tentativas de autocorreção | Transição controlada para estado de intervenção |
| Reprodutibilidade | Não determinística em ambiente de testes | Totalmente rastreável por logs e eventos |
Uma máquina de estados não elimina o uso de modelos de linguagem. Ela apenas retira deles o poder de decidir o que acontece antes e depois da execução.
Em uma aplicação comum com processamento assíncrono, a entidade de negócio possui estados explícitos gravados no banco de dados. O modelo nunca recebe permissão para alterar esse estado diretamente. Ele recebe apenas um bloco isolado de dados, executa uma transformação com contrato estrito e devolve a resposta para que o código faça a validação.
class ProcessarDocumentoFiscalJob < ApplicationJob
queue_as :documentos
def perform(documento_id)
documento = DocumentoFiscal.find(documento_id)
return unless documento.aguardando_processamento?
documento.iniciar_processamento!
resultado = ExtratorInteligente.extrair(documento.texto_bruto)
if SchemaFiscal.valido?(resultado)
documento.concluir_com_sucesso!(resultado)
else
documento.encaminhar_para_revisao_manual!(
motivo: "Inconsistência nos campos extraídos pelo modelo"
)
end
rescue ProvedorLLM::TimeoutError => erro
documento.registrar_falha_temporaria!(erro.message)
end
end
Observe que a inteligência artificial fica confinada dentro de um método estrito de extração. O fluxo não depende de um agente decidindo qual ferramenta chamar a seguir. Se o documento estiver ilegível ou se o modelo devolver uma estrutura fora da especificação esperada, a máquina de estados desvia o registro para um estado de revisão manual. A aplicação continua previsível, auditável e imune a surpresas silenciosas.
Existe uma minoria legítima de cenários onde um grafo dinâmico de agentes é justificável. Se você está desenvolvendo uma ferramenta de pesquisa aberta onde o caminho da investigação é desconhecido no momento em que a tarefa começa, planejar ações dinamicamente pode ser a única opção viável. Um exemplo é um assistente que precisa varrer fontes públicas diferentes, cruzar referências cruzadas e formular novas hipóteses com base em dados imprevistos.
Nesse caso, você não tem como antecipar os estados porque o próprio objetivo envolve navegação exploratória.
Contudo, quase todo fluxo interno corporativo é o oposto disso. Processamento de notas, triagem de chamados, atualização de cadastros e triagem de pedidos possuem regras de negócio que a empresa já estabeleceu há anos. Tratar esses fluxos como terrenos desconhecidos que exigem agentes deliberativos a cada requisição é desperdício de infraestrutura.
Antes de adicionar frameworks pesados de orquestração de agentes ao seu projeto, coloque o fluxo em um diagrama simples. Se você consegue desenhar os estados possíveis e as condições que ligam cada transição, você não tem um problema para agentes probabilísticos resolverem. Você tem um problema clássico de máquina de estados, e resolvê-lo com código determinístico é a decisão mais responsável que você pode tomar.
CTO e arquiteto full stack especializado em Ruby on Rails, Vue.js, sistemas multi-tenant e infraestrutura distribuída.