Dark Intelligence Dark Intelligence

Automação · MLOps · Agentes de IA Automation · MLOps · AI Agents

Um time de agentes que compete no Kaggle sozinho A team of agents that competes on Kaggle by itself

São quatro agentes especializados (coleta, modelagem, submissão e monitoramento) organizados por um loop determinístico. Ele roda sem supervisão, sabe exatamente de onde retomar em cada execução e respeita os limites da própria plataforma em que está competindo. There are four specialized agents (collection, modeling, submission and monitoring) organized by a deterministic loop. It runs unsupervised, knows exactly where to pick back up on every run, and respects the limits of the platform it competes on.

690klinhas no datasetrows in dataset
29features pós-encodingfeatures post-encoding
4agentes especializadosspecialized agents
6hciclo de automaçãoautomation cycle

fig. 01 · o loop dos quatro agentesfig. 01 · the four-agent loop

01 coletorcollector 02 modeladormodeler 03 submissorsubmitter 04 monitormonitor meta atingida, encerragoal reached, stops sem melhora, retreina (até 3×)no improvement, retrains (up to 3×)

o estado circula pelos quatro agentes; no fim, o orquestrador decide entre retreinar ou parar state flows through all four agents; at the end, the orchestrator decides to retrain or stop

01

O problemaThe problem

Levar uma competição Kaggle a sério não é treinar um modelo uma vez e esperar. É um ciclo inteiro: baixar os dados, entender o que tem de nulo, criar features novas, treinar com validação cruzada, gerar as predições, formatar a submissão, ver como ela se saiu no leaderboard e decidir se vale a pena treinar de novo. Tudo isso repetido dia após dia, sem estourar o limite diário de envios da plataforma. Taking a Kaggle competition seriously isn't training a model once and hoping for the best. It's a full cycle: download the data, figure out what's missing, engineer new features, train with cross-validation, generate predictions, format the submission, check how it did on the leaderboard, and decide whether another round of training is worth it. All of that repeated day after day, without blowing past the platform's daily submission cap.

Fazer isso à mão cansa e é fácil de esquecer um passo. A ideia deste projeto foi simples de enunciar e mais difícil de resolver: dá pra montar um time de agentes que toque esse ciclo inteiro sozinho, de forma confiável, mesmo rodando numa VM que esquece tudo assim que termina? Doing this by hand gets tiring and it's easy to drop a step. The idea behind this project was easy to state and harder to pull off: could a team of agents run this whole cycle on its own, reliably, even on a VM that forgets everything the moment it finishes?

02

A arquiteturaThe architecture

Cada agente cuida de uma coisa só e passa adiante o mesmo objeto de estado que recebeu. O orquestrador é determinístico de propósito: nenhuma decisão sobre "o que fazer agora" depende de um LLM, é apenas uma máquina de estados simples, fácil de acompanhar e de prever. Os pontos onde um agente com IA poderia decidir algo (o modelador escolhendo que feature vale a pena criar, por exemplo) foram deixados para uma etapa futura, sem precisar mexer nesse loop central. Each agent handles one thing and passes along the same state object it received. The orchestrator is deterministic on purpose: no "what happens next" decision depends on an LLM, it's just a plain state machine that's easy to follow and predict. The spots where an AI-driven agent could eventually decide something (the modeler picking which feature is worth engineering, say) were left for a later stage, without needing to touch this core loop.

orchestrator.py · o coração do loop· the heart of the loop

if state.current_model_id is None or self._should_retrain(state):
    state = self.modeler.train(state)
    continue

if state.predictions_path is None or self._is_new_model_unsubmitted(state):
    state = self.modeler.predict(state)
    state = self.submitter.run(state)
    continue

state = self.monitor.check_leaderboard(state)
if self.monitor.goal_reached(state):
    break  # top 20% do leaderboard
03

O problema da memória zeroThe zero-memory problem

Toda execução do GitHub Actions nasce numa VM nova: sem dados baixados, sem modelo treinado, sem histórico de nada. A saída foi separar estado de artefatos. Tudo que importa para dar continuidade (score, hiperparâmetros já testados, histórico de submissões, log da execução) fica em state.json e é commitado de volta no repositório a cada checkpoint. Every GitHub Actions run is born on a brand new VM: no downloaded data, no trained model, no history of anything. The way around it was splitting state from artifacts. Everything that matters for continuity (score, hyperparameters already tried, submission history, run log) lives in state.json and gets committed back to the repo at every checkpoint.

fig. 02 · execuções efêmeras, um estado que persistefig. 02 · ephemeral runs, one state that persists

state.json, persiste entre execuçõesstate.json, persists across runs run 1 00:00 run 2 06:00 run 3 12:00 run 4 18:00

cada VM nasce, carrega o state.json, trabalha, salva e some. a próxima nem sabe que a anterior existiu each VM spins up, loads state.json, works, saves and disappears. the next one has no idea the last one existed

04

Respeitando o limite da plataformaRespecting the platform's own limits

A Kaggle limita quantas submissões cada time pode enviar por dia, por competição. Um agente ingênuo bateria nesse limite e simplesmente quebraria. Este time trata isso como um evento esperado, não como um bug: captura a exceção, registra em linguagem clara o que aconteceu, salva o estado e para de forma limpa, sabendo que a próxima execução agendada retoma exatamente dali. Kaggle caps how many submissions a team can send per day, per competition. A naive agent would hit that limit and simply crash. This team treats it as an expected event rather than a bug: it catches the exception, logs plainly what happened, saves state and stops cleanly, knowing the next scheduled run will pick up right where it left off.

[orchestrator] Limite diário de submissões atingido. Resposta da Kaggle: "allowance (10) today, try again tomorrow". Isso é esperado, não é bug. Parando por aqui, a próxima execução agendada continua de onde este estado ficou salvo. Daily submission limit reached. Kaggle's response: "allowance (10) today, try again tomorrow". This is expected, not a bug. Stopping here, the next scheduled run continues from where this state was saved.

Existe um segundo limite, max_submissions_per_run=5, que protege cada execução individual. Isso importa porque o workflow roda a cada 6 horas, e sem esse teto local o time conseguiria esbarrar sozinho no limite diário, sem nem precisar de vários dias para isso. There's a second cap, max_submissions_per_run=5, protecting each individual run. That matters because the workflow runs every 6 hours, and without this local ceiling the team could hit the daily limit entirely on its own, without even needing several days to do it.

05

Do dado cru à feature prontaFrom raw column to finished feature

O dataset da competição Playground Series S6E7 tem 690.088 linhas, 15 colunas cruas e um alvo categórico chamado health_condition. Boa parte dos campos vem com nulos (alguns passam de 10% de missing), então o modelador primeiro imputa o que falta, depois cria variáveis derivadas como calorias por passo e déficit de sono, e por fim faz one-hot encoding das 7 colunas categóricas. O resultado são 29 features prontas para o LightGBM, validado com 5-fold cross-validation. The dataset from the Playground Series S6E7 competition has 690,088 rows, 15 raw columns and a categorical target called health_condition. Plenty of fields come with nulls (some over 10% missing), so the modeler first imputes what's missing, then builds derived variables like calories per step and sleep deficit, and finally one-hot encodes the 7 categorical columns. What comes out the other end is 29 features ready for LightGBM, validated with 5-fold cross-validation.

fig. 03 · montando o vetor de featuresfig. 03 · assembling the feature vector

sleep_duration 11% nulos11% null imputaçãoimputation sleep_deficit feature derivadaderived feature encodingencoding vetor final: 29 featuresfinal vector: 29 features

14 colunas numéricas mais 7 categóricas viram, depois do encoding, 29 colunas por linha 14 numeric columns plus 7 categorical ones become, after encoding, 29 columns per row

06

Resultado até agoraResult so far

0,9496melhor CV scorebest CV score
0,94799melhor score públicobest public score
top 20%meta de leaderboardleaderboard target

Foram três variações de hiperparâmetros testadas até agora, todas girando perto de CV ≈ 0,95. Isso é um bom sinal de diagnóstico: o teto atual provavelmente está mais em feature engineering e na escolha do modelo do que em ajuste fino de parâmetros. A competição continua aberta e o time segue rodando a cada 6 horas atrás da meta. Three hyperparameter variants have been tested so far, all hovering around CV ≈ 0.95. That's a useful diagnostic signal: the current ceiling likely sits more in feature engineering and model choice than in fine-tuning parameters. The competition is still open and the team keeps running every 6 hours chasing the target.

fig. 04 · três tentativas, o mesmo tetofig. 04 · three attempts, the same ceiling

0,9496 c020e7ad 0,9496 bc5e2b73 0,9490 a38e6901 modelo em uso agoracurrent model paciência de retreinoretrain patience 1 de 3 sem melhora1 of 3, no gain eixo começa em 0,948 para deixar a diferença visívelaxis starts at 0.948 to make the gap visible

as três rodadas de treino convergem quase para o mesmo valor, sinal de que ajustar hiperparâmetro sozinho não vai destravar muito mais all three training rounds converge to nearly the same value, a sign that tuning hyperparameters alone won't unlock much more

07

LimitaçõesLimitations

Isso aqui é um relato honesto de um sistema em produção, não um case fechado com laço de fita. This is an honest account of a system in production, not a case closed with a bow on top.

O resultado mais sólido aqui não é o score final. É a infraestrutura: um time de agentes que sobrevive a VMs efêmeras, retoma o estado entre execuções e trata os próprios limites da plataforma como parte do design, não como uma exceção a ser tratada depois. The most solid result here isn't the final score. It's the infrastructure: a team of agents that survives ephemeral VMs, resumes state across runs and treats the platform's own limits as part of the design, not an exception to handle later.