Expérimentation autonome
Description
Une boucle structurée pour l'expérimentation autonome, pilotée par les métriques. L'agent modifie le code, mesure une métrique, conserve les améliorations, rejette les régressions, enregistre tout et recommence indéfiniment. Inspiré par karpathy/autoresearch, qui utilise ce pattern pour laisser un agent IA exécuter des expériences d'entraînement ML toute la nuit — en modifiant un script d'entraînement, en exécutant des expériences de 5 minutes, en conservant ce qui améliore val_bpb, en rejetant ce qui ne l'améliore pas.
Cette skill généralise ce pattern au-delà du ML : tout objectif d'optimisation mesurable fonctionne — performance du code, taille binaire, couverture de tests, latence de réponse, usage mémoire, scores de benchmark, ou toute métrique personnalisée définie par l'utilisateur.
Déclencheurs
- experiment
- optimize
- benchmark
- "run experiments overnight"
- "try things and keep what works"
- "improve performance"
- autoresearch
- "experiment loop"
- "try different approaches"
- ablation
Instructions
Phase de configuration
Avant de démarrer la boucle d'expérimentation, établissez ceci avec l'utilisateur :
-
Métrique — Quel nombre optimisez-vous ? Doit être lisible par machine à partir de la sortie de la commande.
- Exemples :
val_bpb,pytest --tb=no | grep passed,time ./benchmark,wc -c binary - Doit avoir une direction claire : plus bas est mieux, ou plus haut est mieux
- Exemples :
-
Fichier(s) cible(s) — Qu'est-ce que l'agent peut modifier ?
- Gardez la portée étroite. Un fichier est idéal, deux ou trois sont acceptables.
- Tout le reste est du contexte en lecture seule.
-
Commande de run — Comment mesurer la métrique après chaque changement.
- Doit être déterministe (ou moyennée sur plusieurs exécutions)
- Doit se terminer en un temps limité (définissez un timeout)
-
Contraintes — Qu'est-ce qui NE DOIT PAS se casser ?
- Tests qui doivent toujours passer
- Limites de ressources (mémoire, disque, temps)
- Préférences de style de code / complexité
-
Tag de run — Un label pour cette session d'expérimentation (ex.
mar7-perf).- Créez une branche git :
experiment/<tag>
- Créez une branche git :
-
Journal d'expérimentation — Créez
experiments.tsvavec l'en-tête :commit metric status descriptionEnregistrez la baseline en première entrée.
La boucle d'expérimentation
BOUCLE INFINIE :
-
Vérification de la baseline — Lisez la meilleure métrique actuelle dans le journal.
-
Hypothèse — Formulez UN changement spécifique à essayer. Écrivez-le avant de coder.
- Puisez dans : littérature dans les commentaires du code, proches expériences ratées précédentes du journal, combinaison de changements réussis, alternatives architecturales, balayages d'hyperparamètres, simplification (suppression de code qui ne sert à rien).
-
Implémentation — Modifiez uniquement les fichier(s) dans la portée. Gardez les changements minimes et focalisés.
- Une idée par expérience. Ne combinez jamais plusieurs hypothèses.
-
Commit —
git commitle changement avec un message descriptif. -
Run — Exécutez la commande de run, en redirigeant la sortie vers
run.log:<run_command> > run.log 2>&1NE LAISSEZ PAS la sortie inonder la fenêtre de contexte.
-
Extraction de la métrique — Parsez la métrique à partir de
run.log.- Si le run a planté :
tail -n 50 run.logpour diagnostiquer. Essayez un correctif rapide (typo, import). Si fondamentalement cassé, enregistrez commecrashet revertissez.
- Si le run a planté :
-
Décision — Comparez à la baseline :
- Amélioré : Gardez le commit. Mettez à jour la baseline. Enregistrez comme
keep. - Égal ou pire :
git reset --hard HEAD~1. Enregistrez commediscard. - Crash : Revertissez. Enregistrez comme
crash.
- Amélioré : Gardez le commit. Mettez à jour la baseline. Enregistrez comme
-
Enregistrement — Ajoutez à
experiments.tsv:<commit> <metric> <keep|discard|crash> <ce qui a été essayé> -
Répétition — Allez à l'étape 2. Ne vous arrêtez jamais. Ne demandez jamais « dois-je continuer ? »
Critère de simplicité
Emprunté à autoresearch : toutes choses égales par ailleurs, plus simple c'est mieux.
- Une petite amélioration de métrique qui ajoute de la complexité moche ? Probablement pas worth it.
- Une petite amélioration de métrique en supprimant du code ? Gardez-la définitivement.
- Métrique égale mais code beaucoup plus simple ? Gardez.
- Pesez le coût de complexité contre l'ampleur de l'amélioration.
Quand vous êtes bloqué
Si les 5+ dernières expériences ont toutes été rejetées :
- Relisez les fichiers dans la portée pour de nouveaux angles
- Examinez le journal à la recherche de patterns (quels types de changements ont fonctionné ?)
- Essayez des changements plus radicaux (architecturaux, pas juste des tweaks de paramètres)
- Essayez de combiner deux proches expériences ratées
- Essayez l'inverse de ce que vous faisiez
Gestion des timeouts et crashes
- Définissez un timeout pour chaque run (ex. 2x la durée attendue)
- Si un run dépasse le timeout, tuez-le et traitez-le comme un crash
- Si un crash est un simple bug (typo, import manquant), corrigez et réexécutez
- Si l'idée elle-même est cassée, enregistrez comme crash et continuez
- Après 3 crashes consécutifs, pausez et réévaluez votre approche
Intégration avec EloPhanto
- Utilisez
self_modify_sourcepour les changements du propre code d'EloPhanto - Utilisez
self_run_testscomme vérificateur de contraintes (les tests doivent toujours passer) - Utilisez
goal_createpour les sessions d'expérimentation longues avec checkpoints - Utilisez l'esprit autonome pour exécuter des expériences en arrière-plan
- Utilisez
knowledge_writepour sauvegarder les insights des expériences réussies
Exemples
Bon : Optimisation de performance
Utilisateur : "Optimisez le temps de réponse du routeur LLM. Lancez des expériences toute la nuit."
Agent :
1. Établit la métrique : latence moyenne de `pytest tests/test_core/test_router.py -v --tb=no`
2. Fichier cible : core/router.py
3. Crée la branche : experiment/mar7-router-perf
4. Enregistre la baseline : 145ms moyenne
5. Expérience 1 : cache des configs provider → 138ms → keep
6. Expérience 2 : résolution DNS async → 135ms → keep
7. Expérience 3 : connection pooling → 131ms → keep
8. Expérience 4 : supprimer les retries de fallback → 130ms mais tests échouent → discard
9. ... continue toute la nuit
Bon : Entraînement ML (style autoresearch)
Utilisateur : "Lancez autoresearch sur train.py. Optimisez val_bpb."
Agent :
1. Métrique : val_bpb (plus bas est mieux), extraite via `grep "^val_bpb:" run.log`
2. Cible : train.py
3. Commande de run : `uv run train.py > run.log 2>&1` (budget 5-min)
4. Expériences : changements architecturaux, balayages d'hyperparamètres, tweaks d'optimizer
5. Chaque expérience est un run d'entraînement de 5 minutes
6. ~12 expériences/heure, ~100 toute la nuit
Mauvais : Pas de métrique claire
Utilisateur : "Rendez le code meilleur"
L'agent devrait demander :
- Meilleur comment ? Plus rapide ? Plus petit ? Plus lisible ? Plus de couverture de tests ?
- Quelle métrique spécifique pouvons-nous mesurer ?
- Quel(s) fichier(s) dois-je modifier ?
Mauvais : Trop de changements à la fois
Expérience : "Changez l'optimizer, doublez le learning rate, et basculez vers une architecture différente"
Cela combine 3 hypothèses. Si ça s'améliore, vous ne savez pas quel changement a aidé.
Si ça régresse, vous ne savez pas quel changement a nui. Un changement à la fois.
Vérifier
- L'hypothèse est énoncée sous la forme « si X alors Y parce que Z » avant l'exécution de l'expérience
- La taille de l'échantillon, la durée et la métrique primaire sont engagées par écrit avant de lire les résultats
- Le contrôle et le traitement sont spécifiés concrètement (diff de config, feature flag, filtre d'audience), pas décrits abstraitement
- L'enregistrement d'expérience stocke les données de résultats brutes, pas seulement la conclusion, pour qu'il puisse être réanalysé ultérieurement
- Les résultats rapportent l'ampleur de l'effet et un intervalle de confiance (ou incertitude équivalente), pas seulement une estimation ponctuelle
- Une branche « pas de décision » ou « inconclusive » est autorisée dans le plan d'analyse ; l'agent ne force pas un gagnant
Notes
- Le journal d'expérimentation (
experiments.tsv) est la source de vérité. Enregistrez toujours. - Les branches Git gardent la branche principale propre. Toutes les expériences se font sur
experiment/<tag>. - L'agent ne doit jamais s'arrêter pour demander s'il doit continuer. L'humain interrompra quand il voudra l'arrêter.
- Ce pattern fonctionne mieux avec le mode de permission
full_autoet l'esprit autonome activé. - Pour l'auto-optimisation d'EloPhanto, combinez avec
self_run_testspour s'assurer que les expériences ne cassent pas la fonctionnalité existante. - Inspiration originale : karpathy/autoresearch — recherche ML autonome où un agent IA itère sur un script d'entraînement toute la nuit, conservant ce qui améliore la métrique de loss et rejetant ce qui ne l'améliore pas.