YADRO proíbe a LLM de mexer nos números e publica mais de 10 relatórios por dia sem intervenção humana
O analista de negócios sênior da YADRO Egor Shliupikov e o colega Egor Kataev montaram em três meses um serviço de análise de TI em que a LLM não vê nenhum número do relatório. Toda manhã, mais de uma dezena de relatórios em HTML para cinco departamentos saem sem participação humana: um script em Python calcula as métricas, o modelo escreve as conclusões e o código insere os valores. A solução surgiu depois de uma falha. Ao receber o resumo, o modelo transferia os números para o texto por conta própria e, certa vez, passou a exibir valores desatualizados de um snapshot que estava na base de conhecimento do Dify. Agora ele recebe apenas algumas dezenas de indicadores-chave e devolve o texto com marcadores no lugar dos valores. • O Trino une a réplica do Naumen.ITAM e os snapshots diários no ClickHouse em uma única tabela com histórico, além de dados do NetBox, do 1C e do Jira. • Se o modelo estiver indisponível, o relatório sai mesmo assim, mas sem as conclusões em texto. • Os preços ausentes de equipamentos são estimados por imputação por coortes e exibidos separadamente dos valores reais.
Processado por IA de Habr AI; editado por Hamidun News
Na YADRO, a equipe que gerencia o parque de equipamentos de TI construiu em três meses um serviço que publica diariamente mais de uma dezena de relatórios analíticos para cinco departamentos. Não há pessoas envolvidas no processo. A principal regra de engenharia: todos os números são calculados pelo código, enquanto o modelo de linguagem escreve apenas os comentários em texto e nunca vê nenhum indicador em estado bruto. O projeto foi feito pelo analista de negócios sênior Egor Shliupikov e pelo colega Egor Kataev, embora ninguém na equipe GRID tivesse conduzido antes um desenvolvimento em escala industrial.
De um experimento com exportação de dados a um serviço próprio
Tudo começou com uma tarefa de abril: avaliar o estoque de um dos armazéns e propor como dar destino aos equipamentos parados. Na época, a empresa acompanhava a métrica aged, ou seja, a fatia dos ativos que ficam estocados por mais de um ou dois anos. Shliupikov pegou uma exportação do Naumen.ITAM, removeu os dados sensíveis (pessoas jurídicas, nomes de armazéns) e pediu a uma rede neural que montasse um relatório em HTML. Surgiram muitos recortes; cada um, isolado, tinha pouco valor, mas juntos respondiam a uma grande quantidade de perguntas. O gestor aprovou o desenvolvimento da ideia dentro do ambiente da empresa.
A primeira versão rodava na plataforma low-code Dify: o contexto de negócios foi conectado como base de conhecimento e, por causa dos limites de contexto, passou-se a enviar ao modelo não os dados brutos, mas um resumo preparado por um script em Python. Mesmo com o resumo, porém, o modelo errava. Ele transferia os números para o texto seguindo as regras do prompt, e os mesmos valores apareciam fora de lugar nos comentários. Descobriu-se que eram valores do snapshot de ativos do dia em que a base de conhecimento foi conectada, e não dados atuais.
Marcadores no lugar dos números
Daí nasceu uma separação rígida. O script prepara dois conjuntos de dados: um completo, usado para montar os gráficos e o template, e um compacto, com algumas dezenas de números-chave. O modelo vê apenas o compacto. Ele devolve observações, interpretações e alertas, e no lugar dos números coloca marcadores. Os valores são inseridos na montagem do relatório, pelas mesmas regras do template. Distorcer um indicador por meio do modelo é fisicamente impossível.
Há ainda uma vantagem na economia de tokens: o contexto recebe dezenas de números, e não massas de linhas. A chamada ao modelo fica em um cliente separado, de modo que é possível trocá-lo sem mexer no pipeline. A aparência dos relatórios fica nos templates. Se o modelo estiver indisponível ou responder de forma incorreta, o relatório sai no prazo e com os números corretos, apenas sem as conclusões em texto.
A equipe teve de abandonar o Dify por causa do controle de acesso, do armazenamento dos parâmetros de conexão com o banco nas configurações do pipeline e da ausência de agendamento, estatísticas e notificações.
Trino como elo no tempo e entre sistemas
Quando as fontes se multiplicaram, toda a camada de dados foi para uma máquina virtual separada com Trino. Os autores admitem que, naquele momento, isso era excessivo, mas foi uma forma de garantir folga para o futuro. O Trino resolve dois problemas.
- Junção no tempo. No Naumen.ITAM, o estado atual fica na réplica do banco de produção, e o histórico chega ao ClickHouse em snapshots diários. Uma única consulta federada busca o ponto de hoje na réplica, e o de ontem e todo o histórico no ClickHouse. Limitação: o passo do histórico é de um dia, então os status que mudam ao longo do dia não aparecem, e por isso a velocidade dos processos é calculada com cautela.
- Junção entre sistemas. O Naumen.ITAM sabe a qual equipe um servidor pertence, e o NetBox sabe em qual rack do data center ele está. A consulta cruza os dois e mostra como os custos por rack se distribuem entre as equipes.
Os geradores de relatórios não sabem de onde vêm os dados, então conectar uma nova fonte não exige reescrever os relatórios. As fontes atuais são: Naumen.ITAM, ClickHouse DWH, 1C, a plataforma BI/CPM (número de novos funcionários e orçamento), o Jira (solicitações de equipamentos) e o NetBox.
Pipeline e proteção contra os próprios erros
A cadeia funciona assim: o Airflow (que substituiu o cron) dispara a DAG, os dados são lidos via Trino, o Python calcula os indicadores, o Dify devolve os comentários, o template renderiza o HTML, o relatório é salvo com carimbo de data e hora e o link para a versão mais recente é atualizado. O acesso passa pelo Keycloak corporativo e por uma verificação de permissões no validator, com papéis de proprietários, administradores, usuários e superusuários. Pelo Mattermost é possível solicitar acesso, atualizar relatórios e consultar estatísticas.
O código fica no GitLab corporativo, e as alterações só são aceitas por merge request aprovado por alguém que não seja o autor. Cada atualização roda por um dia em um ambiente de testes separado; se falhar na aceitação, o rollback é automático.
Dados que não existiam
O serviço expôs lacunas nos dados. Ninguém havia calculado antes o valor operacional do estoque dos armazéns, e o preço no Naumen.ITAM não está preenchido em todos os itens. A solução foi a imputação por coortes (tipo de equipamento, modelo, fabricante, ano de fabricação). O preço médio dos itens que têm preço é estendido aos demais. No relatório, o custo real e a estimativa aparecem separados. Se uma coorte não tem nenhum preço, ela é ampliada ou fica sem estimativa, com uma observação. A conferência com a contabilidade mostrou valores comparáveis.
O que dá para aproveitar
O padrão se aplica a qualquer relatório: quem calcula é um código determinístico, e o modelo recebe agregados e devolve texto com placeholders. Isso sai mais barato em tokens, facilita a auditoria e não derruba o relatório se o modelo falhar. O próximo passo da equipe é um construtor de relatórios em que o usuário descreve o recorte em palavras, o modelo monta a descrição das métricas e o SQL é gerado pela camada semântica Cube, com base em medidas predefinidas. Também nesse caso o modelo não toca nem nas consultas nem nos números.
Perguntas frequentes sobre a notícia
O que se sabe sobre De um experimento com exportação de dados a um serviço próprio?
Tudo começou com uma tarefa de abril: avaliar o estoque de um dos armazéns e propor como dar destino aos equipamentos parados. Na época, a empresa acompanhava a métrica aged, ou seja, a fatia dos ativos que ficam estocados por mais de um ou dois anos. Shliupikov pegou uma exportação do Naumen.ITAM, removeu os dados sensíveis (pessoas jurídicas, nomes de armazéns) e pediu a uma rede neural que montasse um relatório em HTML. Surgiram muitos recortes; cada um, isolado, tinha pouco valor, mas juntos respondiam a uma grande quantidade de perguntas. O gestor aprovou o desenvolvim
O que se sabe sobre Marcadores no lugar dos números?
Daí nasceu uma separação rígida. O script prepara dois conjuntos de dados: um completo, usado para montar os gráficos e o template, e um compacto, com algumas dezenas de números-chave. O modelo vê apenas o compacto. Ele devolve observações, interpretações e alertas, e no lugar dos números coloca marcadores. Os valores são inseridos na montagem do relatório, pelas mesmas regras do template. Distorcer um indicador por meio do modelo é fisicamente impossível. Há ainda uma vantagem na economia de tokens: o contexto recebe dezenas de números, e não massas de linhas. A chamada ao
O que se sabe sobre Trino como elo no tempo e entre sistemas?
Quando as fontes se multiplicaram, toda a camada de dados foi para uma máquina virtual separada com Trino. Os autores admitem que, naquele momento, isso era excessivo, mas foi uma forma de garantir folga para o futuro. O Trino resolve dois problemas. Junção no tempo. No Naumen.ITAM, o estado atual fica na réplica do banco de produção, e o histórico chega ao ClickHouse em snapshots diários. Uma única consulta federada busca o ponto de hoje na réplica, e o de ontem e todo o histórico no ClickHouse. Limitação: o passo do histórico é de um dia, então os status que mudam ao long
Build & Ship Production AI Agents Without Boilerplate Code
Start your free 72-hour trial at Hamidun Academy (academy.hamidun.com) — interactive lessons on Claude Code & Cursor, live Tech Radar, and production agent templates.
O essencial da IA — uma vez por semana
Sete histórias que realmente importaram, escolhidas a dedo. Sem ruído nem releases.
Pronto! Verifique seu e-mail para a confirmação.