Mapa da trilha
🔍 Auditoria de 4 Eixos
Framework completo para entender qualquer dataset
📋 A Regra das 100 Linhas
Amostragem que revela 80% dos problemas
🔀 De Disparado para Unificado
Pipeline passo a passo do caos ao warehouse limpo
📊 Tabelas-Resumo + DuckDB
Implementação passo a passo para agentes
👁️ Monitoramento e Gestão
Não seja pego de surpresa quando o pipeline quebra
🔔 Painel de Alertas
Visibilidade total antes que os problemas explodam
🔍 Auditoria de 4 Eixos na Prática
O framework de 4 dimensões que todo engenheiro usa para entender qualquer dataset em menos de uma hora.
O Eixo Volume mede a magnitude do dataset — quantas linhas existem, quantas colunas, qual o tamanho em disco e quantas tabelas compõem o conjunto de dados.
Volume determina sua estratégia de processamento. 500 linhas cabe no Excel; 5 milhões exige DuckDB ou Spark. Saber antes evita escolhas erradas de ferramenta.
Contagem de linhas (COUNT), contagem de colunas (len(df.columns)), tamanho em MB (df.memory_usage(deep=True).sum()), número de tabelas no banco.
O Eixo Schema mapeia a estrutura do dataset: nomes das colunas, tipos de dados declarados vs reais, e percentual de valores nulos por coluna.
Colunas com tipo errado causam falhas silenciosas. Uma coluna "valor" com tipo string vai quebrar qualquer soma. Nulos acima de 30% geralmente indicam campo não-obrigatório ou problema de ingestão.
df.dtypes, df.isnull().mean() * 100, inspeção de tipos declarados vs observados, detecção de colunas com nomes duplicados ou vazios.
O Eixo Snippet é a inspeção visual de 100 linhas representativas — topo, meio aleatório e bordas estranhas — para detectar padrões que estatísticas agregadas não revelam.
Nenhum describe() ou info() substitui o olhar humano em dados reais. O snippet revela JSONs embutidos em células, moedas misturadas, valores hardcoded e padrões de nomeação inconsistentes.
Amostragem estratificada, df.sample(100), df.head(10) + df.tail(10), inspecionar células de alta cardinalidade, identificar valores outlier visualmente.
O Eixo Distribuição analisa como os valores se distribuem em cada coluna — mínimo, mediana, máximo para numéricos; categorias principais e frequências para strings.
Distribuições revelam outliers reais (receita de $0 é erro ou cliente grátis?), concentrações de dados (top 10 clientes = 80% da receita) e anomalias de negócio.
df.describe(), df['coluna'].value_counts(), percentis (p5, p25, p75, p95), detecção de valores extremos, análise de cardinalidade de colunas categóricas.
Aplicação real dos 4 eixos em 5 fontes da BrightPath Advisory: Stripe (18k registros com JSON embutido em "description"), HubSpot (12k contatos, headers custom, nulls em "source"), Time Tracker (3 abas por consultor com datas em formatos diferentes), QuickBooks (P&L inconsistentes) e founder-master-tracker.
Ver o framework aplicado em dados reais bagunçados é mais valioso que qualquer descrição teórica. Cada fonte da BrightPath tem um tipo diferente de problema — juntas, cobrem 90% do que você vai encontrar em projetos reais.
JSON embutido em célula CSV, headers personalizados que quebram o parse, múltiplas abas com schemas incompatíveis, arquivos P&L sem padrão de período, datas mistas (datetime vs date vs string).
O prompt exato para delegar a auditoria completa ao Claude Code, incluindo instrução de não modificar os dados raw e salvar o resultado em lugar sensato.
Com o prompt certo, você vai do zero à auditoria completa de 4 eixos em minutos. O prompt errado gera um relatório genérico inútil. A diferença está nos detalhes de instrução.
Referenciar o CLAUDE.md, especificar a fonte alvo, declarar os 4 eixos explicitamente, exigir snippet salvo, proibir modificação do raw. Formato: "Leia o Claude MD... rode audit pass... quero volume, schema, distribuição e snippet de 100 linhas salvo... Não modifique nada no raw."
📋 A Regra das 100 Linhas — Amostragem que Revela Tudo
100 linhas escolhidas corretamente revelam 80% dos problemas de um dataset com milhões de registros.
100 linhas é o tamanho ideal de amostra para inspeção manual: grande o suficiente para revelar padrões e pequeno o suficiente para ser lido com atenção em 5-10 minutos.
10 linhas perdem anomalias raras; 1.000 linhas sobrecarregam a atenção. 100 é o sweet spot empírico que engenheiros experientes convergem após anos de prática.
Capacidade de atenção humana, frequência de anomalias raras (1 em 200 linhas = invisível em 10 linhas, visível em 100), custo cognitivo de revisar 1.000 linhas vs benefício marginal.
A estratégia de amostragem em 3 camadas: 30 linhas do topo (primeiros registros, muitas vezes os mais antigos), 40 linhas aleatórias do meio, e 30 linhas das "bordas estranhas" (outliers por valor ou data).
df.sample(100) não é suficiente — seleciona aleatoriamente e pode perder problemas concentrados no topo (importações antigas) ou nas bordas (valores extremos). A estratégia de 3 camadas garante cobertura.
Amostragem estratificada, df.head(30), df.sample(40, random_state=42), df.nlargest(15, 'valor') + df.nsmallest(15, 'valor'), concatenar as 3 camadas em um único DataFrame de análise.
O checklist de inspeção: linhas duplicadas idênticas, NAs em colunas críticas, colunas numéricas com strings misturadas, valores que claramente são placeholders ("N/A", "0", "TBD", "null" como texto).
Cada categoria de problema tem uma solução diferente. Saber o que procurar evita perder tempo inspecionando o que não importa e ignorar o que vai quebrar o pipeline.
Duplicatas reais vs duplicatas parciais, NAs verdadeiros vs strings "null", valores hardcoded que precisam ser mapeados, mistura de tipos em colunas numéricas (ex: "1,500.00" e "1500" na mesma coluna).
Exemplos reais: moedas misturadas (EUR, USD, JPY, INR na mesma coluna "valor"), JSON embutido em célula de texto, linhas completamente em branco por erro de exportação, datas em 3 formatos diferentes na mesma coluna, idades negativas por bug de migração.
Esses casos parecem improváveis até você os encontrar pela primeira vez às 23h antes de uma entrega. Conhecer os padrões comuns acelera o diagnóstico de horas para minutos.
Símbolo de moeda embutido no valor numérico, JSON como string em célula CSV, exportação com linhas em branco entre registros, Unix timestamp vs ISO 8601 vs DD/MM/YYYY, overflow de integer gerando negativos.
Os critérios para expandir a amostra: dataset com alta variabilidade (muitas categorias raras), dados temporais com sazonalidade forte, ou quando a análise estatística exige potência suficiente para detectar diferenças pequenas.
100 linhas é o ponto de partida, não o ponto final. Saber quando escalar evita diagnósticos incompletos em datasets complexos e evita desperdício de tempo em datasets simples.
Alta cardinalidade (>1.000 categorias únicas), sazonalidade diária/semanal/mensal, análise de cohort exige representação mínima por grupo, teste estatístico precisa de N mínimo para potência 0.8.
O processo de mascarar ou remover Informações Pessoalmente Identificáveis (PII) — nomes, emails, CPFs, telefones — antes de enviar a amostra para análise por agentes de IA.
Dados de clientes reais não devem ser enviados para modelos de linguagem sem consentimento. Uma linha de código de mascaramento protege você legalmente e protege seus clientes.
Mascaramento com faker (ex: faker.name() substitui nome real), hash de emails para análise de unicidade, tokenização de IDs sensíveis, remoção de colunas PII antes do envio, uso de datasets sintéticos gerados para testes.
🔀 De Disparado para Unificado — Pipeline Passo a Passo
5 fontes bagunçadas, formatos incompatíveis, datas inconsistentes — e um warehouse limpo ao final. O procedimento completo.
O estado caótico inicial: 5 arquivos ou APIs com formatos, encodings, separadores e convenções de data completamente diferentes — o ponto de partida real de todo projeto de engenharia de dados.
A tentação é ir direto para o código. O engenheiro experiente passa 30 minutos entendendo o estado inicial antes de escrever uma linha — e economiza horas de retrabalho.
Inventário de fontes, detecção de encoding (UTF-8 vs Latin-1), separadores (vírgula vs ponto-e-vírgula vs tab), formatos de data (ISO vs DD/MM/YYYY vs Unix), chaves de junção potenciais entre tabelas.
Aplicar os 4 eixos (Volume, Schema, Snippet, Distribuição) em cada fonte separadamente antes de qualquer tentativa de junção. Cada fonte recebe seu próprio relatório de auditoria.
Tentar juntar fontes antes de entender cada uma individualmente é a causa número 1 de erros silenciosos em pipelines. O JOIN parece funcionar mas os dados estão errados.
Auditoria fonte por fonte, relatório individual por arquivo, identificação de chaves candidatas (IDs, emails, nomes normalizados), marcação de colunas problemáticas antes da normalização.
A etapa de transformação: converter todas as datas para ISO 8601, todos os valores monetários para uma moeda base com taxa definida, e todos os tipos de coluna para o tipo correto declarado no schema alvo.
Para moedas há 3 opções com trade-offs diferentes: taxa fixa atual (simples, impreciso para histórico), taxa da data da transação via API (preciso, dependência externa), taxa semanal fornecida pelo cliente (equilibrado). Cada projeto requer uma decisão explícita.
pd.to_datetime() com format inferido, conversão de moeda com fator de câmbio, Decimal vs float para valores financeiros, normalização de strings (strip, lower, replace de caracteres especiais).
Criar ou identificar chaves que permitam juntar tabelas de fontes diferentes — pode ser email normalizado, ID de cliente padronizado, ou uma chave composta criada a partir de campos em comum.
Sem chave de junção confiável, qualquer análise cross-source é invenção. A maioria dos projetos reais não tem IDs universais — você precisa criar a chave a partir dos dados disponíveis.
Chave natural vs surrogate key, normalização de email como chave fuzzy, hash MD5 de campos compostos, detecção de fanout em JOINs (1:N vs N:N), validação de integridade referencial antes do JOIN.
Identificar e remover colunas com 95%+ de nulos, colunas com valor único constante, e colunas que existem apenas como artefato de migrações antigas de sistemas que não existem mais.
Colunas mortas aumentam o tamanho do dataset, confundem agentes e analistas, e criam false positives em análises de completude. Um warehouse limpo tem apenas o necessário.
Threshold de nulos para eliminar (>95%), detecção de colunas com variance zero, colunas "_old", "_backup", "_v1" de migrações passadas, documentar o que foi removido e por quê antes de deletar.
O entregável final: warehouse com tabelas nomeadas consistentemente, data dictionary com descrição de cada coluna, script de carga reproduzível, e nota sobre decisões tomadas (ex: qual taxa de câmbio foi usada e por quê).
Um warehouse sem documentação é inútil em 6 meses — nem você vai lembrar o que cada campo significa. A documentação é parte do entregável, não um bônus.
Data dictionary (nome, tipo, descrição, exemplo), README do pipeline com instruções de carga, registro de decisões (ADR), testes de validação automáticos antes da entrega, versionamento do schema.
📊 Tabelas-Resumo + DuckDB — Implementação Passo a Passo
Como transformar dados brutos em tabelas que um agente consegue consultar sem gastar uma fortuna em tokens.
Uma tabela-resumo é uma VIEW pré-computada: em vez de o agente calcular "receita por cliente por mês" toda vez que perguntado, você pré-calcula e salva. O agente só lê o resultado — sem processar milhões de linhas a cada consulta.
Jogar 18.000 linhas no contexto de um LLM custa tokens, é lento e frequentemente ultrapassa o limite de contexto. Uma tabela-resumo bem desenhada tem 50-200 linhas e responde 90% das perguntas do cliente.
Pre-aggregation, materialização de views, grain da tabela (nível de granularidade), separação entre dados raw (imutáveis) e dados resumidos (recalculáveis), latência aceitável de atualização.
Grain é o nível de granularidade de cada linha da tabela-resumo. Se o cliente pergunta "qual foi a receita do trimestre?", o grain mínimo é mensal. Se pergunta "qual consultor foi mais produtivo esta semana?", o grain é semanal.
Grain muito grosseiro (anual) impede análises mensais. Grain muito fino (diário) gera tabelas grandes sem necessidade. A regra: escolha o grain mais granular que o cliente vai perguntar.
Grain declaration (uma linha por cliente por mês), agregação com GROUP BY período, DATE_TRUNC para normalizar datas, escolha entre semana ISO vs semana calendário, alinhamento com ciclos de negócio do cliente.
Fatos são medidas numéricas (receita, horas, quantidade). Dimensões são os contextos (cliente, projeto, período, consultor). A tabela-resumo junta fatos com dimensões no grain correto.
Misturar fatos e dimensões no mesmo nível causa fanout (linhas duplicadas) e resultados incorretos em somas. Separar os conceitos garante que cada agregação faça sentido matemático.
Tabela de fatos (medidas numéricas + chaves estrangeiras), tabela de dimensão (atributos descritivos + chave primária), star schema simplificado, additive vs non-additive measures (receita vs taxa de conversão).
O procedimento completo: instalar DuckDB, criar o arquivo .duckdb, carregar todos os CSVs com CREATE TABLE AS SELECT, verificar integridade e executar as primeiras queries de validação.
DuckDB é o SQLite analítico: zero configuração, roda localmente, suporta arquivos de gigabytes sem problema. É a ferramenta padrão para engenharia de dados em escala média em 2025.
duckdb.connect('engagement.duckdb'), CREATE TABLE AS SELECT * FROM read_csv_auto('arquivo.csv'), DESCRIBE TABLE para verificar schema inferido, PRAGMA table_info para inspeção rápida, export para Parquet para performance.
Traduzir perguntas de negócio em SQL no DuckDB: "qual foi a receita do trimestre?" vira SELECT SUM(revenue) GROUP BY quarter; "top 5 clientes" vira ORDER BY revenue DESC LIMIT 5. O agente escreve o SQL e o DuckDB retorna o resultado sem jogar 18k linhas no contexto.
SQL é a linguagem universal de dados. Um agente com acesso ao DuckDB consegue responder qualquer pergunta ad-hoc sem precisar que você pré-compute tudo. É a combinação mais produtiva disponível hoje.
Window functions para rankings, CTEs para legibilidade, DATE_TRUNC para agregações temporais, QUALIFY para filtragem pós-window function, exportação de resultados para CSV ou JSON para entrega ao cliente.
A arquitetura mínima: agente recebe pergunta do usuário, gera SQL, executa no DuckDB local, formata resultado como texto e responde. Três componentes: LLM + DuckDB + schema description no system prompt.
Esta é a arquitetura real de sistemas de BI conversacional. Entender os três componentes permite construir, debugar e escalar. Sem entender a arquitetura, você é dependente de ferramentas que não entende.
Text-to-SQL, schema description no system prompt (nomes de tabelas, colunas, tipos, exemplos), tool use para execução de SQL, formatação de resultados tabulares em linguagem natural, tratamento de queries inválidas.
👁️ Monitoramento e Gestão de Dados — Passo a Passo
Um pipeline que funciona hoje mas ninguém monitora vai quebrar silenciosamente. O guia para não ser pego de surpresa.
O campo generated_at é um timestamp UTC adicionado automaticamente a cada tabela-resumo no momento do processamento. Ele registra exatamente quando os dados foram computados pela última vez.
O generated_at é o seu GPS temporal. Sem ele, você não sabe se está olhando para dados de ontem ou de seis meses atrás. Quando o agente responde ao cliente, ele precisa saber a "validade" dos dados.
datetime.utcnow() no momento da geração, persistência junto com os dados agregados, exposição no system prompt do agente ("dados atualizados em: {generated_at}"), comparação com now() para calcular frescor.
O sistema de versionamento de tabelas-resumo: cada reprocessamento gera uma nova versão (v1, v2, v3...) com registro de quando foi gerada, por quê foi reprocessada, e qual era a versão anterior.
Quando o cliente diz "os números mudaram desde ontem", você precisa saber por quê. Sem versionamento, você não tem como comparar a versão atual com a anterior.
Tabela de metadados de processamento (run_id, timestamp, motivo, status), comparação de duas versões com EXCEPT ou anti-join, rollback para versão anterior quando o novo processamento é suspeito.
Os 4 sinais clássicos: volume muito abaixo do esperado (falha de ingestão), schema drift (nova coluna aparece sem aviso), aumento abrupto de nulos, e valores fora do range histórico (receita negativa, datas futuras).
Dado podre que chega ao cliente é o pior cenário: você perde credibilidade e o cliente perde confiança no sistema. Detectar antes é infinitamente melhor que explicar depois.
Volume esperado vs observado (desvio padrão de 3 semanas), schema comparison entre versões, null rate por coluna vs baseline histórico, range checks (BETWEEN expected_min AND expected_max), alertas automáticos em thresholds definidos.
Service Level Agreement de dados: o contrato interno que define com que frequência os dados serão atualizados, qual percentual mínimo de completude é aceitável, e o que acontece quando o SLA é violado.
Sem SLA, não há critério para saber se o pipeline está "OK" ou "quebrado". Um SLA transforma "acho que tá funcionando" em "está dentro do contrato" ou "está fora do contrato".
Frequência de atualização (diária, horária, semanal), completude mínima por coluna crítica (ex: >98%), freshness máximo (ex: dados nunca mais velhos que 26h), procedimento de escalada quando SLA é violado.
Configurar Claude Code para detectar falhas de qualidade e reprocessar automaticamente: quando o dado podre é detectado, o agente executa o script de reprocessamento, verifica o resultado e notifica o engenheiro.
Monitoramento manual é insustentável. Um agente que detecta e reage automaticamente elimina o trabalho repetitivo e garante que o SLA seja mantido mesmo durante fins de semana ou férias.
Script de verificação com saída estruturada (JSON com status OK/FAIL + detalhes), agente com tool use para execução de scripts, notificação via email ou Slack quando reprocessamento é acionado, log de reprocessamentos automáticos.
A documentação mínima obrigatória: CLAUDE.md do projeto com descrição de cada fonte, data dictionary atualizado, diagrama de dependências entre tabelas, e procedimento de reprocessamento manual para quando a automação falha.
Documentação bem feita permite que outro engenheiro (ou o próprio agente) mantenha o pipeline sem precisar de você. É a diferença entre um projeto sustentável e um projeto que só você consegue operar.
CLAUDE.md com inventário de fontes e anomalias, data dictionary vivo (atualizado a cada schema change), diagrama de fluxo do pipeline (fonte → raw → processed → summary), runbook para reprocessamento manual emergencial.
🔔 Painel de Monitoramento e Alertas
Da teoria ao painel real: como construir visibilidade sobre seus dados e ser avisado antes que os problemas explodam.
As 4 métricas essenciais: Volume (registros hoje vs média histórica), Frescor (horas desde última atualização), Nulos (% acima do threshold definido no SLA), Schema (drift detectado: coluna nova, coluna removida, tipo alterado).
Monitorar tudo é ruído; não monitorar nada é cegueira. Essas 4 métricas cobrem 95% das falhas reais de pipelines de dados em produção.
Baseline de volume (média das últimas 4 semanas ± 2 desvios), freshness threshold (definido no SLA), null threshold por coluna crítica, schema hash para detecção de drift automático.
Construir um painel de monitoramento usando apenas Python + DuckDB: queries de saúde dos dados, output em HTML simples ou Streamlit, atualizado a cada execução do pipeline.
Ferramentas complexas de monitoramento (Grafana, DataDog) são overkill para projetos de dados de médio porte. Um painel em Python/Streamlit roda em 30 minutos e resolve 90% dos casos.
Streamlit para UI rápida, DuckDB como backend de queries, atualização periódica com st.rerun(), cards de status (verde/amarelo/vermelho), tabela de histórico de verificações.
A lógica de alertas: threshold fixo (ex: nulos > 5%) ou dinâmico (ex: volume menor que média - 2σ), com cooldown para evitar spam, e severidade categorizada (warning vs critical).
Alertas sem threshold definido geram ruído. Alertas sem cooldown spamam. A lógica correta é: condição específica + threshold numérico + cooldown + canal de notificação + responsável.
Threshold estático vs dinâmico (z-score), cooldown de 1h para não duplicar alertas, severidade (WARNING vs CRITICAL vs INFO), deduplição de alertas idênticos, escalada automática se alerta não for resolvido em X horas.
Fazer o agente receber o alerta, investigar a causa raiz consultando o DuckDB, e notificar o engenheiro com um diagnóstico já pronto — não apenas "algo quebrou", mas "a coluna X tem 23% de nulos, acima do threshold de 5%, provável causa: ingestão de ontem falhou às 03h."
Alertas sem diagnóstico geram trabalho de investigação. Um agente com acesso ao DuckDB consegue entregar o diagnóstico automaticamente, reduzindo o tempo de resposta de horas para minutos.
Agente com tool use para DuckDB, prompt de diagnóstico com contexto do alerta, formatação de notificação para Slack/email (severidade + causa + ação recomendada), loop de investigação com múltiplas queries se necessário.
MVP: 4 cards de status (volume, frescor, nulos, schema) + tabela de alertas ativos + botão de reprocessamento. Completo: histórico de métricas, gráficos de tendência, análise de causa raiz assistida por IA, integração com tickets.
O MVP cobre 90% das necessidades reais de projetos de dados. O dashboard completo é útil para times grandes e pipelines críticos, mas é over-engineering para projetos menores. Saber onde parar economiza semanas de trabalho.
4 cards de status com semáforo (verde/amarelo/vermelho), tabela de alertas ativos com timestamp e severidade, botão manual de reprocessamento com confirmação, histórico de 30 dias das métricas principais.
Casos documentados: cliente de consultoria com relatório semanal automático detectou queda de 40% no volume de transações na quinta — que era sexta com fuso horário errado; engenheiro detectou schema drift da API do Stripe que quebraria o pipeline na segunda-feira seguinte.
Casos reais demonstram o ROI concreto do monitoramento. É difícil justificar o investimento em monitoramento sem histórias de quando ele fez diferença — esses casos são os argumentos que convencem clientes e gestores.
Detecção de fuso horário errado via anomalia de volume, schema drift de API externa detectado antes da produção, falha silenciosa de ingestão detectada por freshness threshold, relatório de cliente com dados incorretos evitado por range check automático.