Engenharia de IA · Python · AWS
Prumo
A taxa real de acerto de uma IA em produção: poucos rótulos humanos corrigem o viés do juiz LLM, e o prompt volta sozinho quando a qualidade cai.
- Cliente
- Projeto pessoal open source
- Cargo
- Engenheiro de Software — projeto independente
- Ano
- 2026
- Tecnologias
- Python
- FastAPI
- Amazon Bedrock
- AWS Lambda
- AWS CDK
- Step Functions
- DynamoDB
- AppConfig
- CloudWatch
- Pydantic
- NumPy
- pytest
- GitHub Actions































Contexto
Serviço open source em Python 3.12 que mede a taxa real de acerto de uma IA em produção. A IA (Amazon Nova Lite no Bedrock) classifica leads em QUENTE, MORNO ou FRIO, um juiz LLM confere 100% das decisões, uma amostra aleatória vai para revisão humana e a estatística corrige o viés do juiz. Todos os dados são sintéticos. O projeto continua o Easy Control, em que a IA pré-qualifica os leads e o CEO revisa cada QUENTE ou MORNO antes do primeiro contato, porque o volume ainda permite.
Desafio
Com um volume 50 vezes maior, revisar tudo deixa de ser possível. Confiar só no juiz LLM também não basta: ele erra de forma sistemática, e quando um prompt novo faz a IA errar mais, nada quebra, nenhum alerta dispara e a nota do juiz quase não se mexe. O desafio era manter a automação sob controle com poucos rótulos humanos, saber a taxa real com uma margem de erro que continue honesta mesmo consultada a cada hora, e reverter o prompt sem depender de alguém perceber.
Resultados
- simulações em que a queda de 92% para 76% foi detectada e revertida, enquanto o juiz seguia em cerca de 91% (benchmark prumo bench)
- 10/10
- rollbacks indevidos da v3, a versão que melhora a IA, em todas as configurações do benchmark
- 0/10
- de acerto real da Nova Lite no teste na AWS com 30 leads sintéticos, contra 70% aprovados pelo juiz Nova Pro, que deixou passar 4 classificações erradas
- 60%
- testes automatizados: 205 no app, com 94% de cobertura, e 56 na infraestrutura em CDK
- 261
Principais entregas
- 01Implementei em Python puro, com os módulos math e statistics da biblioteca padrão, a Prediction-Powered Inference (PPI e PPI++), que usa uma amostra aleatória de rótulos humanos para descontar o viés do juiz LLM e entrega a taxa real de acerto com faixa de confiança, além de uma sequência de confiança válida a qualquer momento (Waudby-Smith et al., 2024) para leituras de hora em hora.
- 02Arquitetei na AWS, com CDK em Python, o fluxo completo: API em FastAPI na Lambda (via Mangum), classificador e juiz no Bedrock pela Converse API com tool use forçado, DynamoDB single-table com contadores atômicos e TTL de 180 dias, e revisão humana no Step Functions com waitForTaskToken.
- 03Automatizei o rollback do prompt: o estimador horário publica a métrica em EMF no CloudWatch, e o alarme de 2 leituras seguidas abaixo da meta (SLO de 85%) aciona, pelo EventBridge, uma Lambda que reverte a versão no AppConfig com compare-and-swap, com o próprio estimador como rede de segurança.
- 04Desenvolvi o painel web em FastAPI com um simulador sem custo de AWS e o benchmark prumo bench, que reproduz uma versão de prompt que derruba a IA de 92% para 76% enquanto o juiz segue em cerca de 91%, comparando métodos e volumes de rótulos por hora.
- 05Criei 261 testes automatizados (205 no app, com 94% de cobertura, e 56 na infraestrutura), incluindo propriedades com Hypothesis, simulações de Monte Carlo em NumPy que validam a cobertura do intervalo e adaptadores AWS testados com Stubber e moto, sob mypy strict, ruff e CI no GitHub Actions.
- 06Protegi a operação com token administrativo gerado pelo Secrets Manager e lido no cold start, deploy pelo GitHub Actions com OIDC sem chave de acesso guardada, alarmes no SNS com fila SQS de mensagens mortas para o rollback e dados exclusivamente sintéticos.
Telas e componentes
O juiz e a taxa real
Depois do incidente, a nota do juiz quase não se mexe, a taxa real estimada cai com a v2 e o prompt volta sozinho para a v1. O painel é do simulador, com dados fictícios.

O incidente
Durante o incidente, o juiz segue perto de 91% enquanto a taxa real estimada da v2 cai abaixo da meta de 85%, e o status muda para Abaixo da meta. Simulador com dados fictícios.

Indicadores no celular
No celular, os indicadores separam o que o juiz diz, 90,8%, da taxa real estimada, 77,2%, com a faixa de confiança e a taxa de queima do orçamento logo ao lado. Dados fictícios.
Revisão humana e eventos
Na fila de revisão, a pessoa diz se a IA acertou e vê o gabarito do simulador; os eventos registram deploys, alarmes e rollbacks com data e hora. Dados fictícios.
Fundamentos do design system
Dez tokens de cor em claro e escuro, tipografia, raios e espaçamentos sustentam o painel em Jinja2 e JavaScript sem framework, dos botões em cada estado aos status do SLO.

Componentes de domínio
Os componentes de domínio põem o juiz ao lado da taxa real, mostram o status do SLO, as 48 leituras e os eventos de deploy, alarme e rollback e organizam a revisão humana, nos dois temas. Dados fictícios.

Como a conta funciona
Num exemplo de 20 decisões, o juiz aprova 90%, a amostra humana mostra 75% e a faixa abaixo da meta aciona o rollback. A sequência de confiança continua válida mesmo consultada a cada hora.

Arquitetura na AWS
O quadro segue o lead de 1 a 12: API Gateway, Lambda com FastAPI, Bedrock com o juiz, DynamoDB, revisão humana no Step Functions, estimador de hora em hora, alarme no CloudWatch e rollback do prompt no AppConfig por compare-and-swap, tudo em CDK Python.

API documentada
A API em FastAPI documenta com OpenAPI as rotas de qualidade, prompts, decisões e revisão humana, inclusive deploy e rollback do prompt.

Resultados
O benchmark roda 10 simulações por linha, e o teste real na AWS usou 30 leads sintéticos: a IA acertou 60%, e o juiz aprovou 70%.

Funcionalidades e as dores que resolvem
Cada funcionalidade nasceu de um problema real da operação.
01
Taxa real com faixa de confiança
- Dor
- O juiz LLM confere 100% das decisões, mas erra sempre para o mesmo lado: a nota dele não é a taxa real de acerto, e revisar tudo à mão não escala.
- Solução
- Uma amostra aleatória rotulada por pessoas mede o erro do juiz, e a Prediction-Powered Inference (PPI e PPI++) desconta esse erro da nota dele, entregando a taxa real com faixa de confiança. A estimativa usa só somas e somas de quadrados, então ler a qualidade custa O(1).
Impacto: O intervalo de 95% contém a verdade entre 92% e 98% das vezes (400 simulações de Monte Carlo)
02
Sequência de confiança
- Dor
- Um intervalo de confiança comum vale para uma consulta; lido a cada hora, a chance de alarme falso cresce a cada leitura.
- Solução
- O método padrão (ppi_cs) usa uma sequência de confiança assintótica (Waudby-Smith et al., 2024), que continua válida mesmo consultada para sempre, e exige ao menos 30 rótulos antes de qualquer decisão. Detecta mais devagar que o intervalo comum, em troca de uma garantia real contra alarme falso.
Impacto: Consultada a cada hora por 30 horas, erra no máximo α + 2%
03
Rollback automático do prompt
- Dor
- Uma versão de prompt que piora a IA não gera exceção nem alerta: sem medição, a regressão fica no ar até alguém notar.
- Solução
- Se a faixa inteira fica abaixo da meta (SLO de 85%) em 2 leituras seguidas, o alarme do CloudWatch aciona, pelo EventBridge, uma Lambda que volta o prompt para a versão anterior no AppConfig, sem novo deploy de código.
Impacto: Rollback em 28, 17 e 11 h (mediana) com 10, 20 e 40 rótulos por hora; v2 detectada 10/10
04
Dois gatilhos, uma troca atômica
- Dor
- O EventBridge só avisa na transição para ALARM: se essa tentativa falha, o alarme fica parado sem gerar evento novo, e um alarme reentregue poderia voltar duas versões.
- Solução
- O estimador horário aplica a mesma regra como rede de segurança, e a troca é compare-and-swap sobre a versão medida: alarme reentregue, clique manual simultâneo ou os dois gatilhos juntos nunca voltam duas versões. Evento que falha vai para uma fila SQS de mensagens mortas, com alarme.
Impacto: 0/10 rollbacks indevidos da v3 em todas as configurações do benchmark
05
Revisão humana no Step Functions
- Dor
- Se só os casos duvidosos forem revisados, a correção do viés do juiz fica enviesada, e um rótulo gravado duas vezes contaria em dobro na estimativa.
- Solução
- As decisões sorteadas entram numa máquina do Step Functions que espera o revisor com waitForTaskToken, por até 72 h. A API recusa rótulo em decisão que não foi sorteada, e a gravação no DynamoDB é condicional, o que impede rotular a mesma decisão duas vezes.
06
Classificação com Bedrock
- Dor
- Pedir JSON ao modelo e torcer pelo formato quebra o fluxo na primeira resposta fora do padrão, e o texto do lead pode trazer instruções injetadas.
- Solução
- Classificador e juiz chamam o Bedrock pela Converse API com a ferramenta forçada (tool use) e temperatura 0, e a saída ainda é validada com Pydantic. O prompt manda ignorar instruções dentro do lead, e o Bedrock Guardrails pode ser ligado por configuração.
Impacto: Teste real com 30 leads sintéticos: 0 erros HTTP e cerca de 2,6 s por lead
07
Painel e simulador
- Dor
- Uma queda silenciosa de qualidade é difícil de explicar sem ver o juiz e a taxa real lado a lado, e testar a ideia direto na AWS custa dinheiro.
- Solução
- O painel mostra a nota do juiz, a taxa real estimada com a faixa, a taxa de queima do orçamento de erro e os eventos. No modo simulado, sem AWS e sem custo, dá para publicar a v2, mudar os rótulos por hora, ligar ou desligar o rollback e rotular decisões.
Impacto: A mesma lógica roda no simulador e na AWS, por portas e adaptadores
08
Benchmark de métodos
- Dor
- Sem comparar métodos, não dá para saber quantos rótulos por hora bastam nem quanto custa, em horas, cada garantia estatística.
- Solução
- O comando prumo bench roda 10 simulações por linha: a v1 no ar, a v2 que derruba a IA de 92% para 76% e a v3 que a melhora para 93%, medindo detecção, horas até o rollback e rollbacks indevidos para ppi_cs e ppi_ci com 10, 20 e 40 rótulos por hora.
Impacto: ppi_ci reverte em 14, 5 e 4 h; um monitor só do juiz nunca alarma
09
Infraestrutura como código
- Dor
- Montar Lambda, Step Functions, alarmes e AppConfig à mão no console não se reproduz, e chave de acesso guardada no CI é risco de vazamento.
- Solução
- Uma única stack em AWS CDK (Python) cria todos os recursos da aplicação, com testes que travam as invariantes do template. O GitHub Actions repete lint, tipos e testes antes de assumir, por OIDC, um role preso ao environment de produção, e o deploy só sai com disparo manual.
Impacto: Deploy da stack em cerca de 3,5 min
10
Dados pessoais e segredos
- Dor
- O texto do lead é dado pessoal (LGPD), e um token em variável de ambiente fica visível para quem lê a configuração da Lambda.
- Solução
- O texto da decisão expira em 180 dias pelo TTL do DynamoDB, enquanto as somas da estimativa ficam. O token administrativo é gerado pelo Secrets Manager e lido no cold start; sem ele, as rotas protegidas recusam o pedido.
Impacto: Nenhum dado de cliente: todos os leads são sintéticos




















