O problema

Empresas que participam de licitações públicas dependem de monitorar constantemente portais de compras e diários oficiais para não perder oportunidades — e cada edital publicado precisa ser lido, interpretado e avaliado contra critérios como risco, localização, margem e viabilidade operacional. Feito manualmente, esse trabalho consome horas do time comercial e jurídico todos os dias, e a qualidade da triagem varia de pessoa para pessoa.

O objetivo era claro: reduzir o esforço manual de triagem e padronizar a avaliação, sem perder a capacidade de julgamento que um analista experiente aplica ao ler um edital.

Decisões de arquitetura

A primeira decisão importante foi não resolver o problema com um único prompt gigante jogado em um LLM. Optei por dividir o fluxo em agentes especializados, cada um com uma responsabilidade estreita:

Essa separação em pipeline, em vez de um agente monolítico, trouxe três ganhos práticos: rastreabilidade (dá para auditar em qual etapa uma interpretação errada aconteceu), controle de custo (cada etapa usa o modelo e o tamanho de contexto que realmente precisa) e pontos de revisão humana bem definidos entre as etapas, em vez de uma caixa-preta fim a fim.

Outra decisão deliberada foi normalizar o conteúdo do edital antes de enviá-lo ao LLM de interpretação. Documentos de portais públicos vêm em formatos muito inconsistentes; passar HTML ou PDF bruto direto para o modelo aumentava alucinação e custo de tokens. Um estágio de engenharia de dados dedicado a limpar e estruturar esse texto reduziu drasticamente os dois problemas.

Dar contexto limpo para o LLM custa engenharia upfront, mas é muito mais barato do que corrigir decisões erradas depois.

Desafios & aprendizados

O maior aprendizado foi sobre onde colocar o humano no loop. A primeira versão tentava automatizar a decisão final de "participar ou não" da licitação. Rapidamente ficou claro que o time comercial não confiava numa recomendação sem justificativa — e com razão: decisão de ir ou não a uma licitação tem implicações comerciais e jurídicas que vão além do que o agente enxerga.

A solução foi reposicionar a IA como camada de triagem e priorização, não de decisão. O agente de aderência passou a devolver um score com a justificativa explícita (quais critérios pesaram a favor e contra), permitindo que o time revisasse rapidamente os editais de maior prioridade em vez de ler tudo do zero. Isso preservou o julgamento humano onde ele importa e eliminou o trabalho repetitivo de triagem inicial.

Outro aprendizado foi a necessidade de observabilidade sobre as saídas dos agentes: registrar cada interpretação e score gerado permitiu identificar padrões de erro (por exemplo, editais com formatação atípica gerando extração incorreta) e refinar os prompts e o pipeline de normalização de forma iterativa, com dados reais em vez de suposição.

Resultado

Com o pipeline em produção, o esforço manual de triagem caiu de forma consistente, a avaliação de oportunidades passou a seguir critérios padronizados (em vez de depender de quem estava lendo o edital naquele dia) e o monitoramento de portais e diários passou a acontecer em escala, sem depender de alguém acompanhando manualmente cada publicação.

Stack utilizada

Python para orquestração dos agentes, LLMs para interpretação e scoring, AWS para hospedagem serverless com custo variável conforme volume de editais, e uma camada de engenharia de dados para normalização de documentos.