Caderno de campo: provar valor antes de automatizar
Neste laboratório, o leitor transforma a ideia de priorizar ordens de serviço com IA em um experimento reproduzível. Primeiro escreve o contrato da decisão; depois executa uma regra simples como baseline e mede seus resultados. Em seguida provoca vazamento temporal, rótulo contaminado e amostragem enviesada para observar como métricas aparentemente melhores podem enganar. Cada etapa gera arquivos, saídas e uma decisão que outra pessoa consegue auditar. O exercício termina escolhendo entre manter a regra, corrigir processo ou dados, testar um candidato em modo sombra ou encerrar a iniciativa.
Caderno de campo: provar valor antes de automatizar
Este laboratório transforma “queremos IA na triagem de ordens” em uma decisão reproduzível. Você construirá um pacote mínimo de evidência, executará um baseline não-IA, inspecionará a amostra e provocará três falhas: vazamento temporal, rótulo contaminado e amostragem enviesada.
O melhor resultado possível não é “usar IA”. É escolher corretamente entre:
- manter a regra porque ela resolve o problema;
- corrigir processo ou dados antes de experimentar;
- testar um candidato em modo sombra;
- encerrar a iniciativa por falta de ganho ou risco incompatível.
Cartão do laboratório
| Campo | Definição |
|---|---|
| objetivo | decidir se a triagem de OS precisa de IA |
| hipótese | uma regra simples já atende ao gate; um candidato não deve avançar sem ganho material |
| público | iniciante com noções de terminal e Python |
| pré-requisitos | problema, baseline, matriz de confusão e leitura básica de código |
| duração estimada | 60–90 minutos, incluindo análise e mutações |
| ambiente | Python 3.11 ou superior; somente biblioteca padrão |
| segredo necessário | nenhum |
| arquivos | triagem_baseline.py e DECISAO.md |
| saída observável | JSON por cenário, tabela comparativa e decisão assinada |
| limpeza | apagar apenas a pasta criada para o laboratório |
Os dados e limiares são didáticos. Eles não representam um benchmark de produção nem autorizam decisão operacional.
1. Escreva o contrato antes de executar
Copie e complete:
# Contrato da decisão
- Usuário: supervisor de manutenção.
- Decisão apoiada: ordenar quais OS abertas serão inspecionadas primeiro.
- Instante: imediatamente após a validação da abertura no ERP.
- Entradas permitidas: criticidade, equipamento parado, temperatura inicial,
tipo de ativo, unidade e descrição registrada naquele instante.
- Saída permitida: faixa de prioridade para revisão humana.
- Efeitos proibidos: parar ativo, reservar peça, aprovar, encerrar ou mudar OS.
- Baseline: regra versionada neste laboratório.
- População-alvo: OS das unidades Norte e Sul dentro do escopo definido.
- Resultado de valor: reduzir atraso em OS críticas.
- Métrica principal offline: recall da classe crítica.
- Guardrails: precisão, falsos positivos, cobertura por unidade e ausência de campos futuros.
- Condição de parada: manter a regra se ela cumprir todos os gates e o candidato
não produzir ganho material com custo e risco aceitáveis.Não prossiga se “crítica” ainda não possui definição operacional. Neste laboratório, o rótulo significa: a revisão posterior confirmou necessidade de intervenção crítica em até quatro horas. Em projeto real, documente quem confirma, com quais evidências e como divergências são resolvidas.
2. Fronteiras do sistema
Ler o fluxo em texto
- 1. Técnico<br/>abre OS
- 2. API valida<br/>schema e identidade
- 3. ERP<br/>fonte de verdade
- 4. Baseline<br/>regra versionada
- 5. Candidato<br/>sem efeito
- 6. Painel do supervisor
- 7. Armazém de avaliação<br/>acesso restrito
- 8. API de autorização
Marque quatro limites:
- o ERP conserva o estado oficial;
- baseline e candidato só produzem recomendação;
- a API de autorização aplica papel, unidade, estado e auditoria;
- o armazenamento de avaliação recebe somente campos necessários e possui retenção.
Se um prompt diz “apenas supervisores podem aprovar”, mas a API aceita aprovação de qualquer perfil, não existe controle. Política de acesso fica fora do modelo.
3. Crie o simulador executável
Crie uma pasta vazia e salve o código abaixo como triagem_baseline.py. Ele usa dados sintéticos embutidos e somente a biblioteca padrão do Python.
#!/usr/bin/env python3
"""Laboratório didático: baseline, qualidade, leakage e decisão de não usar IA."""
from __future__ import annotations
import argparse
import json
from collections import Counter
from dataclasses import dataclass, replace
from datetime import date
from typing import Callable, Iterable
@dataclass(frozen=True)
class Ordem:
os_id: str
aberta_em: date
unidade: str
ativo: str
criticidade: int
parado: bool
temperatura_c: float | None
descricao: str
critica_confirmada: bool
# Campo FUTURO: só existe depois do período de observação.
horas_parada_final: float
RAW = [
("OS-001", "2026-01-03", "Norte", "chiller", 5, True, 101, "compressor desligou", True, 9.0),
("OS-002", "2026-01-09", "Sul", "bomba", 2, False, 62, "ruído leve", False, 0.0),
("OS-003", "2026-01-17", "Norte", "quadro", 4, False, 70, "odor de queimado", True, 5.0),
("OS-004", "2026-01-28", "Sul", "elevador", 1, False, None, "lâmpada queimada", False, 0.0),
("OS-005", "2026-02-02", "Norte", "gerador", 3, False, 74, "teste mensal", False, 0.0),
("OS-006", "2026-02-15", "Sul", "chiller", 5, False, 96, "pressão anormal", True, 7.0),
("OS-007", "2026-02-23", "Norte", "bomba", 2, False, 60, "inspeção preventiva", False, 0.0),
("OS-008", "2026-03-04", "Sul", "quadro", 4, True, 78, "setor sem energia", True, 6.0),
("OS-009", "2026-03-12", "Norte", "elevador", 1, False, None, "porta rangendo", False, 0.0),
("OS-010", "2026-03-25", "Sul", "gerador", 3, False, 73, "vibração moderada", False, 0.0),
("OS-011", "2026-04-01", "Norte", "chiller", 5, True, 99, "parada total", True, 12.0),
("OS-012", "2026-04-16", "Sul", "bomba", 2, False, 61, "gotejamento pequeno", False, 0.0),
("OS-013", "2026-05-03", "Norte", "quadro", 4, False, 76, "aquecimento no barramento", True, 4.5),
("OS-014", "2026-05-11", "Sul", "elevador", 2, False, None, "botão intermitente", False, 0.0),
("OS-015", "2026-05-22", "Norte", "gerador", 3, False, 72, "manutenção prevista", False, 0.0),
("OS-016", "2026-06-02", "Sul", "chiller", 5, False, 98, "alta pressão", True, 8.0),
# Holdout temporal: o baseline simples continua suficiente.
("OS-017", "2026-07-01", "Norte", "bomba", 2, False, 64, "ruído leve", False, 0.0),
("OS-018", "2026-07-04", "Sul", "quadro", 5, False, 80, "fumaceou ao ligar", True, 6.0),
("OS-019", "2026-07-08", "Norte", "elevador", 1, False, None, "limpeza de trilho", False, 0.0),
("OS-020", "2026-07-12", "Sul", "chiller", 3, True, 83, "unidade parada", True, 5.0),
("OS-021", "2026-07-16", "Norte", "gerador", 3, False, 75, "vibração moderada", False, 0.0),
("OS-022", "2026-07-20", "Sul", "bomba", 4, False, 68, "selo rompeu", True, 4.0),
("OS-023", "2026-07-25", "Norte", "quadro", 2, False, 71, "ruído no contator", False, 0.0),
("OS-024", "2026-07-29", "Sul", "elevador", 5, False, None, "travou com passageiro", True, 3.0),
]
def carregar() -> list[Ordem]:
return [Ordem(os_id, date.fromisoformat(dia), unidade, ativo, criticidade,
parado, temperatura, descricao, rotulo, horas)
for os_id, dia, unidade, ativo, criticidade, parado, temperatura,
descricao, rotulo, horas in RAW]
def baseline(ordem: Ordem) -> bool:
"""Prediz crítica usando somente valores disponíveis na abertura."""
return ordem.parado or ordem.criticidade >= 4 or (
ordem.temperatura_c is not None and ordem.temperatura_c >= 95
)
def candidato_textual(ordem: Ordem) -> bool:
"""Regra candidata deliberadamente simples; não é um modelo treinado."""
sinais = ("fumac", "travou", "rompeu", "parada total", "sem energia")
return baseline(ordem) or any(sinal in ordem.descricao.lower() for sinal in sinais)
def candidato_com_vazamento(ordem: Ordem) -> bool:
"""ERRADO: usa resultado futuro e, por isso, parece perfeito offline."""
return ordem.horas_parada_final >= 3
def dividir_no_tempo(ordens: Iterable[Ordem]):
treino, validacao, teste = [], [], []
for ordem in sorted(ordens, key=lambda item: item.aberta_em):
if ordem.aberta_em < date(2026, 5, 1):
treino.append(ordem)
elif ordem.aberta_em < date(2026, 7, 1):
validacao.append(ordem)
else:
teste.append(ordem)
return treino, validacao, teste
def matriz(ordens: Iterable[Ordem], prever: Callable[[Ordem], bool]) -> dict[str, int]:
resultado = Counter(tp=0, fp=0, tn=0, fn=0)
for ordem in ordens:
previsto, real = prever(ordem), ordem.critica_confirmada
chave = "tp" if previsto and real else "fp" if previsto else "fn" if real else "tn"
resultado[chave] += 1
return dict(resultado)
def metricas(m: dict[str, int]) -> dict[str, float]:
precisao = m["tp"] / max(1, m["tp"] + m["fp"])
recall = m["tp"] / max(1, m["tp"] + m["fn"])
fpr = m["fp"] / max(1, m["fp"] + m["tn"])
return {"precisao": round(precisao, 3), "recall": round(recall, 3),
"taxa_falso_positivo": round(fpr, 3)}
def cobertura(ordens: Iterable[Ordem]) -> dict[str, int]:
return dict(sorted(Counter(ordem.unidade for ordem in ordens).items()))
def executar(mutacao: str) -> dict[str, object]:
ordens = carregar()
treino, validacao, teste = dividir_no_tempo(ordens)
aviso = None
prever_candidato = candidato_textual
if mutacao == "label-noise":
# Simula erro de rotulagem no holdout, sem alterar as entradas.
ids = {"OS-018", "OS-021"}
teste = [replace(o, critica_confirmada=not o.critica_confirmada) if o.os_id in ids else o
for o in teste]
aviso = "dois rótulos do teste foram invertidos"
elif mutacao == "sampling-bias":
# Simula uma coleta que excluiu completamente a unidade Sul.
teste = [o for o in teste if o.unidade == "Norte"]
aviso = "holdout contém apenas a unidade Norte"
elif mutacao == "leakage":
prever_candidato = candidato_com_vazamento
aviso = "candidato recebeu horas_parada_final, indisponível na abertura"
base = metricas(matriz(teste, baseline))
cand = metricas(matriz(teste, prever_candidato))
segmentos = cobertura(teste)
qualidade_ok = len(teste) >= 8 and set(segmentos) == {"Norte", "Sul"}
disponibilidade_ok = mutacao != "leakage"
baseline_atende = base["recall"] >= 0.90 and base["precisao"] >= 0.70
ganho_recall = cand["recall"] - base["recall"]
candidato_material = ganho_recall >= 0.10 and cand["taxa_falso_positivo"] <= 0.25
if not qualidade_ok:
decisao = "PARAR: corrigir amostragem/qualidade antes de comparar"
elif not disponibilidade_ok:
decisao = "PARAR: resultado inválido por vazamento temporal"
elif baseline_atende and not candidato_material:
decisao = "NÃO USAR IA: baseline atende e candidato não traz ganho material"
elif candidato_material:
decisao = "TESTAR EM SHADOW MODE: ganho candidato precisa de validação operacional"
else:
decisao = "INVESTIGAR: objetivo não atendido; não automatizar"
return {
"mutacao": mutacao,
"tamanhos": {"treino": len(treino), "validacao": len(validacao), "teste": len(teste)},
"cobertura_teste": segmentos,
"baseline": base,
"candidato": cand,
"guardrails": {"qualidade_e_representatividade": qualidade_ok,
"atributos_disponiveis_na_decisao": disponibilidade_ok},
"aviso": aviso,
"decisao": decisao,
}
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--mutation", choices=("none", "leakage", "label-noise", "sampling-bias"),
default="none")
args = parser.parse_args()
print(json.dumps(executar(args.mutation), ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()4. Execute o caminho nominal
No terminal, dentro da pasta do laboratório:
python triagem_baseline.pyResultado essencial esperado:
"tamanhos": {"treino": 12, "validacao": 4, "teste": 8}
"cobertura_teste": {"Norte": 4, "Sul": 4}
"baseline": {"precisao": 1.0, "recall": 1.0, "taxa_falso_positivo": 0.0}
"decisao": "NÃO USAR IA: baseline atende e candidato não traz ganho material"Não celebre o número perfeito. O dataset é sintético e pequeno. A conclusão correta é apenas: neste pacote didático, com esta definição e estes casos, a regra cumpre o gate; não há justificativa para acrescentar IA. Em produção, estimar incerteza, ampliar cobertura e acompanhar mudança temporal seriam obrigatórios.
O que cada partição faz
Ler o fluxo em texto
- 1. jan–abr<br/>12 casos
- 2. treino
- 3. mai–jun<br/>4 casos
- 4. validação
- 5. jul<br/>8 casos preservados
- 6. teste/holdout
- 7. baseline e candidato congelados
- 8. decisão registrada
O código não treina um modelo; as três partições existem para ensinar seus contratos. Se a equipe alterasse candidato_textual após olhar julho, o holdout deixaria de ser prova independente.
5. Inspecione o dataset antes da métrica
Preencha uma ficha:
| Pergunta | Resposta deste laboratório | Evidência real exigida |
|---|---|---|
| unidade de análise | uma OS no instante de abertura | contrato de eventos do ERP |
| população-alvo | unidades Norte e Sul | inventário de unidades/ativos |
| origem do rótulo | campo sintético | protocolo e revisão de especialistas |
| atributos futuros | horas_parada_final |
timestamp e linhagem de cada campo |
| cauda importante | falhas críticas | amostragem deliberada e métricas por segmento |
| dados pessoais | nenhum no exemplo | inventário, finalidade, base, acesso e retenção |
| retenção | arquivo descartável | política aprovada e exclusão verificável |
Agora responda: se a unidade Sul usa outro ERP, ela poderia desaparecer silenciosamente? Se os ativos sem sensor têm temperatura nula, o nulo representa ausência de risco ou ausência de observação? Se apenas ordens encerradas entram no dataset, o que acontece com casos longos ainda abertos?
6. Mutação 1 — vazamento temporal
Execute:
python triagem_baseline.py --mutation leakageO candidato usa horas_parada_final. Esse campo é fortemente relacionado ao rótulo, mas só existe depois da decisão. A métrica pode permanecer perfeita e ainda assim ser inválida.
Resultado de controle:
"atributos_disponiveis_na_decisao": false
"decisao": "PARAR: resultado inválido por vazamento temporal"Diagnóstico
- reconstrua a linha do tempo da OS;
- liste timestamp de evento, ingestão e correção de cada atributo;
- confirme a disponibilidade no serviço que fará a previsão;
- remova atributos futuros antes de qualquer split ou ajuste;
- invalide relatórios e modelos derivados do campo;
- crie teste de schema que proíba o atributo na interface online.
Evidência esperada
Uma tabela de disponibilidade:
| campo | existe na abertura? | sistema de origem | permitido? |
|---|---|---|---|
| criticidade | sim | ERP | sim |
| temperatura inicial | às vezes | telemetria | sim, com indicador de ausência |
| horas de parada final | não | relatório posterior | não |
| peça substituída | não | encerramento | não |
7. Mutação 2 — rótulo contaminado
Execute:
python triagem_baseline.py --mutation label-noiseDuas respostas do teste são invertidas. Observe que baseline e candidato parecem piores, embora suas regras não tenham mudado.
Rótulo ruim pode nascer de erro de digitação, proxy inadequado, definição ambígua, mudança de política ou feedback influenciado pela própria recomendação. A correção não é aumentar o modelo.
Protocolo mínimo de rótulos
- escreva definição positiva, negativa e casos limítrofes;
- oculte a previsão durante a revisão independente;
- duplique uma amostra entre avaliadores;
- registre divergência, adjudicação e versão da política;
- audite segmentos raros e de alto impacto;
- preserve o rótulo original e a correção com proveniência;
- não trate clique ou aceite do usuário como verdade automática.
Caso de discussão
Uma OS foi encerrada rapidamente porque não havia peça em estoque e o técnico aplicou contenção temporária. “Encerrada em quatro horas” significaria sucesso, baixa criticidade ou apenas pressão administrativa? O rótulo deve representar a decisão que se deseja apoiar, não o campo mais conveniente.
8. Mutação 3 — amostragem enviesada
Execute:
python triagem_baseline.py --mutation sampling-biasA mutação remove toda a unidade Sul. Mesmo que as métricas restantes pareçam boas, o guardrail de representatividade bloqueia a comparação:
"cobertura_teste": {"Norte": 4}
"qualidade_e_representatividade": false
"decisao": "PARAR: corrigir amostragem/qualidade antes de comparar"O exemplo usa presença de unidades como controle simples. Em projeto real, presença não basta. Compare distribuição de tipos de ativo, turnos, gravidade, idioma, versão do formulário, disponibilidade de sensores e mudanças sazonais. Defina antes quais diferenças são aceitáveis.
Ler o fluxo em texto
- 1. Métrica agregada boa
- 2. todos os segmentos críticos estão cobertos?
- 3. parar: ampliar ou redefinir população
- 4. desempenho atende por segmento?
- 5. investigar coleta, rótulo e processo
- 6. prosseguir para validação operacional
9. Matriz de decisão preenchida
| Dimensão | Gate | Baseline nominal | Candidato nominal | Decisão |
|---|---|---|---|---|
| recall crítico | ≥ 0,90 | 1,00 | 1,00 | empate |
| precisão | ≥ 0,70 | 1,00 | 1,00 | empate |
| cobertura | Norte e Sul | atende | atende | prossegue |
| disponibilidade | nenhum campo futuro | atende | atende no nominal | prossegue |
| complexidade | menor é melhor no empate | regra curta | regra adicional | baseline vence |
| ganho mínimo | +0,10 de recall | referência | +0,00 | não material |
O candidato não precisa ser literalmente IA para que o raciocínio funcione. Ele representa qualquer camada nova. Se nem uma regra textual adicional cria ganho, ainda não existe evidência para comprar, treinar ou integrar um modelo.
10. Do offline ao mundo real
Se um candidato legítimo superar o baseline, não o conecte diretamente ao ERP. Avance por degraus:
offline reproduzível
→ shadow mode sem efeito
→ revisão interna dos piores erros
→ piloto com usuários treinados
→ canário por unidade/turno
→ ampliação gradual
→ reavaliação e retirada quando necessárioCada degrau precisa de gate, responsável e rollback. Em shadow mode, compare as saídas com resultados posteriores, mas controle o feedback loop: depois que usuários veem a sugestão, suas decisões podem passar a refletir o sistema. Separe períodos ou coortes e preserve avaliações independentes.
Sinais mínimos de operação
- versão da regra, modelo, prompt e dataset;
- volume por unidade e tipo de ativo;
- recall e precisão com atraso compatível com o rótulo;
- taxa de abstenção e correção humana;
- latência de ponta a ponta e indisponibilidade;
- custo por OS corretamente auxiliada;
- distribuição de entradas e ausências;
- incidentes, override e motivo de rollback.
Logs não devem copiar descrições completas por padrão. Aplique minimização e redação antes de exportar telemetria.
11. Pré-mortem do cenário
Antes do piloto, imagine que o projeto falhou em seis meses:
| Falha | Detecção | Contenção | Teste do controle |
|---|---|---|---|
| OS crítica perdida | recall por unidade e alerta de cauda | regra de segurança + revisão humana | replay de casos críticos |
| atributo futuro reaparece | contrato de schema e linhagem | rejeitar payload | teste negativo na CI |
| unidade some da coleta | cobertura diária por origem | bloquear relatório comparativo | remover uma unidade no teste |
| rótulo muda de significado | versão da política | congelar promoção | conjunto de casos de fronteira |
| dado pessoal aparece no texto | scanner e amostra restrita | redação e quarentena | injetar CPF fictício |
| candidato indisponível | timeout e circuit breaker | retornar baseline | simular timeout |
Uma defesa como “o modelo saberá recusar” não é controle verificável. Schema, autorização, limites e fallback são aplicados pela aplicação.
12. Produza DECISAO.md
Use o modelo:
# Decisão sobre IA na triagem de OS
## Contexto
[usuário, decisão, população, instante e consequência]
## Hipótese e critérios definidos antes do teste
[métrica, alvo, guardrails e condição de parada]
## Dados
[origem, período, unidade, rótulo, amostra, split, campos proibidos,
privacidade, limitações e versão]
## Alternativas comparadas
[processo atual, baseline executável e candidato]
## Resultados
[matriz de confusão, métricas globais e por segmento, custo, latência,
piores erros e intervalo de incerteza quando aplicável]
## Mutações
[leakage, label-noise e sampling-bias; controle que detectou cada uma]
## Decisão
[manter baseline | corrigir dados/processo | shadow mode | encerrar]
## Motivo e validade
[evidência, responsável, data, escopo e data de revisão]
## Retirada
[como voltar à regra e invalidar artefatos derivados]No cenário nominal deste laboratório, a decisão correta é manter o baseline e não usar IA. Registre isso sem vergonha: o experimento poupou complexidade e criou uma fundação mensurável para reabrir a questão se a população ou o processo mudar.
13. Testes automatizados do laboratório
Salve o bloco abaixo no fim de um arquivo temporário ou execute em um REPL depois de importar triagem_baseline:
from triagem_baseline import executar
nominal = executar("none")
assert nominal["tamanhos"] == {"treino": 12, "validacao": 4, "teste": 8}
assert nominal["baseline"]["recall"] == 1.0
assert nominal["decisao"].startswith("NÃO USAR IA")
leakage = executar("leakage")
assert leakage["guardrails"]["atributos_disponiveis_na_decisao"] is False
assert "vazamento" in leakage["decisao"]
rotulo = executar("label-noise")
assert rotulo["baseline"] != nominal["baseline"]
amostra = executar("sampling-bias")
assert amostra["cobertura_teste"] == {"Norte": 4}
assert amostra["guardrails"]["qualidade_e_representatividade"] is False
print("4 cenários validados")Esse teste demonstra detecção, não qualidade estatística. Um projeto real adicionaria testes de schema, duplicação, distribuição, estabilidade do rótulo, intervalos de incerteza e replay de incidentes.
14. Casos negativos obrigatórios
Além das três mutações, discuta como o sistema deveria agir quando:
- temperatura está ausente porque o ativo não possui sensor;
- o ERP está indisponível e não confirma criticidade;
- uma OS pertence a outra unidade/tenant;
- a descrição contém instrução maliciosa para o componente de IA;
- o mesmo evento chega duas vezes;
- o candidato demora além do timeout;
- o supervisor contesta a sugestão;
- a taxonomia de criticidade muda.
Resposta segura: validar, abster quando necessário, preservar a regra, não executar efeito sem autorização, registrar motivo e tornar a limitação visível.
15. Rubrica de competência
Pontue 0, 1 ou 2 em cada linha:
| Critério | 0 | 1 | 2 |
|---|---|---|---|
| problema | “usar IA” | tarefa descrita | usuário, decisão, instante, efeito e risco |
| baseline | ausente | conceitual | executável, versionado e medido |
| hipótese | vaga | métrica sem limite | valor, alvo, guardrails e prazo |
| dados | arquivo sem contexto | origem parcial | população, amostra, rótulo, proveniência e privacidade |
| split | aleatório por hábito | divisão descrita | divisão justificada pela generalização |
| leakage | ignorado | citado | mutação detectada e bloqueada |
| representatividade | média apenas | um corte | segmentos, ausência e cauda crítica |
| decisão | preferência | resultado isolado | gate prévio e alternativa “não usar IA” |
| reprodutibilidade | relato oral | comando parcial | ambiente limpo, comandos, saída e limitações |
| transferência | copia o caso | muda nomes | aplica o método a outro domínio e justifica escolhas |
Aceite mínimo: 16/20, sem zero em baseline, dados, leakage ou decisão. A pontuação não substitui revisão por outra pessoa.
16. Evidência a entregar
Entregue um pacote contendo:
triagem_baseline.pyexatamente executável;- as quatro saídas JSON (
none,leakage,label-noise,sampling-bias); - contrato da decisão;
- ficha do dataset;
- tabela de disponibilidade dos atributos;
- matriz de decisão;
DECISAO.mdcom conclusão e validade;- uma revisão independente reproduzindo os comandos;
- um exemplo de transferência para outro problema.
“Li o capítulo” ou “cliquei em concluído” não é evidência de competência.
17. Troubleshooting
python não é reconhecido
Confirme a instalação com python --version ou tente py --version no Windows. Registre a versão usada. Não instale pacotes: o laboratório usa apenas biblioteca padrão.
A saída não coincide
Confirme que o arquivo foi copiado integralmente e que nenhum caso foi alterado. Execute primeiro sem mutação. Compare tamanhos das partições antes das métricas.
Acentos aparecem incorretos
Salve o arquivo em UTF-8 e use terminal com suporte a Unicode. O cálculo não depende dos acentos, mas a evidência precisa ser legível.
A métrica perfeita parece suspeita
Correto. Investigue dataset pequeno, regra de geração, duplicatas, leakage e facilidade do cenário. O laboratório foi desenhado para que a regra resolva o holdout; ele ensina que resultado perfeito não autoriza generalização.
O candidato com leakage parece bom
Esse é o objetivo da mutação. Métrica não supera invalidade causal. Bloqueie o campo futuro e invalide o experimento.
18. Exercícios de transferência
Exercício A — mude o futuro que o split representa
O objetivo agora é avaliar uma unidade nova, não um mês futuro. Redesenhe a divisão para manter a unidade Sul inteira fora de treino e validação. Antes de executar, escreva o que espera observar e por que um corte temporal já não responde à pergunta. Entregue a função de split, contagem por partição e uma verificação que impeça a mesma unidade de aparecer nos dois lados.
Exercício B — baseline de busca para suporte
Transfira o método para um assistente que sugere respostas a chamados. Use busca por palavras-chave e templates como baseline. Defina usuário, decisão, rótulo, amostra, holdout, um vazamento possível, dois guardrails e a condição de não usar geração por modelo. A evidência é um DECISAO.md preenchido e pelo menos 20 casos reproduzíveis.
Exercício C — projete um caso em que IA merece shadow mode
Altere somente quatro casos sintéticos de modo que a regra perca um padrão textual legítimo, disponível na abertura, e o candidato o recupere sem ultrapassar o limite de falsos positivos. Não use horas_parada_final nem consulte o teste durante o ajuste. Entregue a mutação, as métricas antes/depois e explique por que o resultado autoriza apenas shadow mode, não automação.
Exercício D — privacidade por minimização
Imagine que descrições reais contenham nome, telefone e localização precisa. Crie um inventário de campos com finalidade, necessidade, acesso, retenção e descarte. Remova um campo que parecia útil e demonstre se a métrica muda. A evidência é a comparação e uma decisão explícita sobre o custo de privacidade, não apenas texto de política.
19. Recuperação ativa
Sem olhar o código:
- Qual decisão o laboratório apoia e qual efeito permanece proibido?
- Por que julho é teste e não treino?
- O que torna
horas_parada_finalum vazamento? - Por que inverter dois rótulos muda a avaliação sem mudar o sistema?
- Por que quatro casos da unidade Norte não representam Norte e Sul?
- Qual gate faz o baseline vencer?
- Quando seria justificável iniciar shadow mode?
- Como provar que um campo existia no instante da decisão?
- Quais artefatos devem ser invalidados após descobrir leakage?
- Por que “não usar IA” é um resultado positivo deste trabalho?
Conclusão
Engenharia de IA começa com uma prova capaz de dizer “não”. Neste caderno, o baseline curto atende ao gate e o candidato não acrescenta ganho material; por isso, a decisão é manter a regra. As mutações mostram por que um número alto pode mentir: um campo futuro cria leakage, um rótulo ruim muda a prova e uma amostra incompleta esconde a população.
O pacote final — contrato, dataset documentado, split justificado, execução, mutações e decisão — é mais valioso que uma demonstração. Ele preserva conhecimento para a próxima equipe, torna a recusa auditável e permite acrescentar complexidade somente quando a evidência exigir.
Fontes primárias e oficiais
- NIST — Artificial Intelligence Risk Management Framework 1.0
- NIST — AI RMF Playbook
- Google — Rules of Machine Learning
- Google — Problem Framing: Understand the problem
- Google — Managing ML projects: Experiments
- Google — Data quality and interpretation
- scikit-learn — Common pitfalls and recommended practices
- Gebru et al. — Datasheets for Datasets
- Sambasivan et al. — Data Cascades in High-Stakes AI
- Sculley et al. — Hidden Technical Debt in Machine Learning Systems
- Governo Federal — Princípios da LGPD
Relações
Use este caderno antes dos livros de modelos, RAG e agentes. Conecte-o depois a avaliação estatística, segurança, observabilidade, MLOps e UX de supervisão. A mesma disciplina vale para um assistente generativo: busca simples e templates formam o baseline; o conjunto de casos e guardrails substitui “pareceu bom”; e ausência de ganho continua sendo razão suficiente para não adicionar IA.
Comprove o que você aprendeu
Responda todas as questões. O gabarito comentado só aparece depois do envio.