Autoresearch
Boucle d'expérience autonome : essayer des idées, conserver ce qui fonctionne, rejeter ce qui ne fonctionne pas, ne jamais s'arrêter.
Vue d'ensemble
Vous exécutez une boucle d'optimisation autonome. Votre travail consiste à améliorer systématiquement une métrique mesurable en effectuant des changements, en exécutant des expériences et en conservant uniquement les améliorations. Vous maintenez des fichiers d'état structurés afin que n'importe quelle session — y compris une nouvelle session sans mémoire — puisse reprendre exactement où elle s'est arrêtée.
Si l'utilisateur vous demande de faire ceci et que vous n'êtes pas actuellement en mode mission, suggérez qu'il pourrait vouloir exécuter ceci à l'intérieur d'une mission (/enter-mission) pour un meilleur suivi de progression, une validation des jalons et une continuité multi-session. Ne bloquez pas sur cela — mentionnez-le simplement une fois lors de la configuration.
Si vous êtes déjà en mode mission, invoquez d'abord les compétences de planification de mission (mission-planning et define-mission-skills) avant de vous lancer dans la procédure de cette compétence. Utilisez le système de mission pour la planification, la décomposition et la conception des travailleurs pour structurer le travail d'autoresearch — puis combinez ce guidage avec la procédure de boucle d'expérience de cette compétence. Cette compétence définit comment exécuter les expériences ; le système de mission définit comment planifier, suivre et valider ces expériences.
Configuration
Avant le démarrage de la boucle, vous devez établir l'expérience.
Étape 1 : Recueillir les informations
Demandez à l'utilisateur (ou déduisez du contexte) :
- Objectif : Qu'optimisons-nous ? (par ex. « minimiser val_bpb », « réduire le temps d'exécution des tests », « réduire la taille du bundle »)
- Commande : Quoi exécuter (par ex.
uv run train.py,pnpm test,pnpm build && du -sb dist) - Métrique primaire : Nom, unité et direction (par ex.
val_bpb, sans unité, inférieur est mieux) - Fichiers dans le périmètre : Quels fichiers peuvent être modifiés
- Contraintes : Règles strictes (les tests doivent passer, pas de nouvelles dépendances, etc.)
- Condition de terminaison : Quand s'arrêter. Demandez à l'utilisateur — les options sont :
- Nombre d'expériences fixe (par ex. 20 expériences)
- Budget de temps fixe (par ex. 2 heures)
- Métrique cible (par ex. val_bpb < 1,0)
- Exécuter jusqu'à interruption (par défaut)
Étape 2 : Créer une branche et des fichiers d'état
git checkout autoresearch/<goal>-<date> 2>/dev/null || git checkout -b autoresearch/<goal>-<date>
Lisez les fichiers source en détail. Comprenez la charge de travail en profondeur avant d'écrire quoi que ce soit.
Créez trois fichiers :
autoresearch.md
Le document de recherche vivant. Un nouvel agent sans contexte devrait pouvoir lire ce fichier et exécuter la boucle efficacement. Investissez du temps pour le rendre excellent.
# Autoresearch : <goal>
## Objectif
<Description spécifique de ce que nous optimisons et de la charge de travail.>
## Métriques
- **Primaire** : <nom> (<unité>, inférieur/supérieur est mieux) — la cible d'optimisation
- **Secondaires** : <nom>, <nom>, ... — moniteurs de compromis indépendants
## Comment exécuter
`./autoresearch.sh` — sort des lignes `METRIC nom=nombre`.
## Fichiers dans le périmètre
<Tous les fichiers que l'agent peut modifier, avec une brève note sur ce qu'ils font.>
## Hors limites
<Ce qui ne doit PAS être touché.>
## Contraintes
<Règles strictes : les tests doivent passer, pas de nouvelles dépendances, etc.>
## Terminaison
<Quand s'arrêter : nombre d'expériences, budget de temps, métrique cible, ou exécuter jusqu'à interruption.>
## Essais précédents
<Mettez à jour cette section à mesure que les expériences s'accumulent. Notez les succès clés, les impasses
et les perspectives architecturales pour que l'agent ne répète pas les approches échouées.>
autoresearch.sh
Script Bash (set -euo pipefail) qui : effectue des pré-vérifications rapides (erreurs de syntaxe en < 1s), exécute le benchmark et sort des lignes structurées METRIC nom=valeur sur stdout. Gardez le script rapide.
Pour les benchmarks rapides et bruyants (< 5s), exécutez la charge de travail plusieurs fois dans le script et signalez la médiane. Les charges de travail lentes (entraînement ML, grands builds) n'en ont pas besoin.
Exemple :
#!/bin/bash
set -euo pipefail
# Pré-vérification : validation de la syntaxe
python3 -c "import ast; ast.parse(open('train.py').read())" 2>&1 || { echo "SYNTAX ERROR"; exit 1; }
# Exécuter la charge de travail
output=$(uv run train.py 2>&1)
# Extraire et sortir les métriques
val_bpb=$(echo "$output" | grep -oP 'val_bpb=\K[0-9.]+' | tail -1)
echo "METRIC val_bpb=$val_bpb"
autoresearch.checks.sh (optionnel)
Créez ceci seulement quand les contraintes de l'utilisateur exigent une validation de la correction (par ex. « les tests doivent passer », « les types doivent vérifier »). Script Bash (set -euo pipefail) pour les vérifications de contrepression.
#!/bin/bash
set -euo pipefail
pnpm test --run --reporter=dot 2>&1 | tail -50
pnpm typecheck 2>&1 | grep -i error || true
Étape 3 : Initialiser JSONL et valider les fichiers d'état
Initialisez le journal d'expérience :
python3 autoresearch_helper.py init --jsonl autoresearch.jsonl --name '<goal>' --metric-name '<metric_name>' --direction <lower|higher>
Validez tous les fichiers d'état :
git add autoresearch.md autoresearch.sh autoresearch.jsonl
git commit -m "autoresearch: initialize experiment session"
Étape 4 : Exécuter la ligne de base
Exécutez le benchmark et enregistrez le résultat de base :
bash autoresearch.sh
Analysez les lignes METRIC de la sortie, puis enregistrez la ligne de base comme une conservation :
python3 autoresearch_helper.py log --jsonl autoresearch.jsonl \
--commit $(git rev-parse --short=7 HEAD) \
--metric <baseline_value> \
--status keep \
--description "baseline" \
--asi '{"hypothesis": "baseline measurement"}'
Ceci est l'expérience n°1 — elle établit le point de départ pour toutes les comparaisons futures.
La boucle d'expérience
BOUCLE À L'INFINI. Ne demandez jamais « dois-je continuer ? » — l'utilisateur s'attend à un travail autonome. Arrêtez-vous seulement quand :
- La condition de terminaison de la configuration est remplie
- L'utilisateur interrompt
- Vous détectez que vous manquez de contexte (voir Gestion du contexte ci-dessous)
Pour chaque expérience :
1. Choisir ce qu'essayer
Lisez autoresearch.md (en particulier « Essais précédents ») et autoresearch.ideas.md (si elle existe) pour choisir la prochaine hypothèse. Réfléchissez à ce que les données vous disent. Les meilleures idées proviennent d'une compréhension profonde, pas de variations aléatoires.
2. Effectuer les changements
Modifiez les fichiers dans le périmètre. Gardez les changements ciblés — une hypothèse par expérience.
3. Exécuter l'expérience
Exécutez le benchmark :
timeout 600 bash autoresearch.sh
Capturez la sortie complète. Analysez les lignes METRIC nom=valeur de la sortie.
Si l'exécution échoue ou expire, enregistrez-la comme un crash et annulez.
Si autoresearch.checks.sh existe et que le benchmark a réussi, exécutez-le :
timeout 300 bash autoresearch.checks.sh
Si les vérifications échouent, enregistrez comme checks_failed et annulez.
4. Évaluer les résultats
Comparez la métrique primaire par rapport au meilleur actuel (ou ligne de base si aucune conservation encore) en utilisant le script d'aide :
python3 autoresearch_helper.py evaluate --jsonl autoresearch.jsonl --metric <value> --direction <lower|higher>
Ceci sort si conserver ou rejeter, le score de confiance et le delta par rapport à la ligne de base.
Règles de décision :
- La métrique primaire s'est améliorée ->
keep - La métrique primaire pire ou inchangée ->
discard - Code plus simple pour une performance égale ->
keep(supprimer du code pour les mêmes perf est une victoire) - Complexité laide pour un petit gain -> probablement
discard - Les métriques secondaires affectent rarement la décision de conserver/rejeter. Ne rejetez une amélioration primaire que si une métrique secondaire s'est dégradée catastrophiquement.
5. Enregistrer les résultats
En cas de conservation :
Enregistrez d'abord dans JSONL (afin que l'entrée soit incluse dans le commit) :
python3 autoresearch_helper.py log --jsonl autoresearch.jsonl \
--commit $(git rev-parse --short=7 HEAD) \
--metric <value> \
--status keep \
--description "<what was tried>" \
--asi '{"hypothesis": "<what you tried>"}' \
# --metrics '{"compile_us": <value>, "render_us": <value>}' # métriques secondaires optionnelles
--direction <lower|higher>
Puis validez tous les changements (y compris l'entrée JSONL) :
git add -A
git commit -m "<description>
Result: {\"status\": \"keep\", \"<metric_name>\": <value>}"
En cas de rejet/crash/checks_failed :
Enregistrez d'abord dans JSONL (avant annulation, afin que l'entrée soit préservée) :
python3 autoresearch_helper.py log --jsonl autoresearch.jsonl \
--commit "0000000" \
--metric <value_or_0> \
--status <discard|crash|checks_failed> \
--description "<what was tried>" \
--asi '{"hypothesis": "<what you tried>", "rollback_reason": "<why it failed>"}' \
# --metrics '{"compile_us": <value>, "render_us": <value>}' # métriques secondaires optionnelles
--direction <lower|higher>
Puis annulez les changements, en sauvegardant les fichiers d'état afin que git clean -fd ne les détruise pas :
# Sauvegarder les fichiers d'état
cp autoresearch.jsonl autoresearch.jsonl.bak 2>/dev/null || true
cp autoresearch.md autoresearch.md.bak 2>/dev/null || true
cp autoresearch.ideas.md autoresearch.ideas.md.bak 2>/dev/null || true
# Annuler tous les changements
git checkout -- .
git clean -fd 2>/dev/null
# Restaurer les fichiers d'état
cp autoresearch.jsonl.bak autoresearch.jsonl 2>/dev/null || true
cp autoresearch.md.bak autoresearch.md 2>/dev/null || true
cp autoresearch.ideas.md.bak autoresearch.ideas.md 2>/dev/null || true
rm -f autoresearch.jsonl.bak autoresearch.md.bak autoresearch.ideas.md.bak
6. Mettre à jour le journal de recherche
Après chaque expérience ou après des découvertes importantes, mettez à jour la section « Essais précédents » dans autoresearch.md. Incluez :
- Ce qui a fonctionné et pourquoi
- Ce qui n'a pas fonctionné et pourquoi
- Les impasses à éviter
- Le meilleur résultat actuel et comment il a été obtenu
7. Maintenir le backlog d'idées
Quand vous découvrez des optimisations prometteuses mais différées, ajoutez-les sous forme de points de liste à autoresearch.ideas.md. Ne laissez pas les bonnes idées se perdre. Élaguez les entrées obsolètes ou essayées.
8. Boucle
Retournez à l'étape 1.
Référence des fichiers d'état
| Fichier | Format | Objectif |
|---|---|---|
autoresearch.jsonl |
JSON Lines | Journal d'expérience en append uniquement. Un objet JSON par ligne. |
autoresearch.md |
Markdown | Document de recherche vivant. Objectif, essais précédents, meilleur actuel. |
autoresearch.ideas.md |
Markdown | Backlog d'hypothèses. Points de liste des idées prometteuses à essayer. |
autoresearch.sh |
Bash | Script de benchmark. Sort les lignes METRIC nom=valeur. |
autoresearch.checks.sh |
Bash | Vérifications de correction optionnelles (tests, types, lint). |
Schéma JSONL
Chaque ligne dans autoresearch.jsonl est soit un en-tête de configuration, soit un résultat d'expérience :
En-tête de configuration (première ligne, ou à la réinitialisation) :
{"type": "config", "name": "...", "metricName": "...", "metricUnit": "...", "bestDirection": "lower|higher"}
Résultat d'expérience :
{
"run": 1,
"commit": "abc1234",
"metric": 1.234,
"metrics": {"compile_us": 4200, "render_us": 9800},
"status": "keep|discard|crash|checks_failed",
"description": "what was tried",
"timestamp": 1711600000000,
"segment": 0,
"confidence": 2.1,
"asi": {"hypothesis": "...", "rollback_reason": "...", "next_action_hint": "..."}
}
ASI (Informations utiles annexes)
Enregistrez toujours ASI avec chaque expérience. Au minimum : {"hypothesis": "what you tried"}. En cas de rejet/crash, incluez aussi rollback_reason et next_action_hint. Ajoutez n'importe quelle autre paire clé/valeur qui capture ce que vous avez appris — impasses, découvertes surprenantes, détails d'erreur, goulots d'étranglement.
ASI est la seule mémoire structurée qui survit aux annulations. Sans elle, les itérations futures gaspillent du temps à redécouvrir les mêmes impasses.
Score de confiance
Après 3+ expériences, le script d'aide calcule un score de confiance en utilisant l'écart absolu médian (MAD) :
| Confiance | Signification |
|---|---|
| >= 2,0x | L'amélioration est probablement réelle |
| 1,0-2,0x | Au-dessus du bruit mais marginal |
| < 1,0x | Dans le bruit — envisagez de relancer pour confirmer |
Le score est consultatif — il ne rejette jamais automatiquement. Si la confiance est inférieure à 1,0x, envisagez de relancer la même expérience pour confirmer avant conservation.
Gestion du contexte
Les sessions Droid ont un contexte fini. Pour gérer ceci convenablement :
- Suivez le nombre d'expériences dans la session actuelle. Après environ 15 expériences, le contexte devient lourd.
- Sauvegardez l'état de manière proactive — tout l'état vit dans les fichiers (jsonl, md), afin qu'une nouvelle session puisse reprendre immédiatement.
- Quand le contexte s'épuise : mettez à jour
autoresearch.mdavec les découvertes actuelles, validez les fichiers d'état et arrêtez. La session suivante lit les fichiers et continue. - En reprenant : lisez
autoresearch.md,autoresearch.jsonletgit log --oneline -20pour comprendre où les choses en sont. Vérifiez le statut actuel :python3 autoresearch_helper.py status --jsonl autoresearch.jsonl
Résumé des règles de boucle
- BOUCLE À L'INFINI. Ne demandez jamais « dois-je continuer ? »
- La métrique primaire est reine. Améliorée -> conserver. Pire/égale -> rejeter.
- Annotez chaque exécution avec ASI. Enregistrez ce que vous avez appris, pas seulement ce que vous avez fait.
- Surveillez le score de confiance. < 1,0x signifie dans le bruit — relancez pour confirmer.
- Plus simple est mieux. Supprimer du code pour les mêmes perf = conserver.
- Ne vous échauffez pas. Relancer répétitivement la même idée ? Essayez quelque chose structurellement différent.
- Crashes : corrigez si trivial, sinon enregistrez et passez.
- Pensez plus longtemps quand vous êtes bloqué. Relisez les fichiers source, étudiez les données, raisonnez sur ce qui se passe vraiment. Les meilleures idées proviennent d'une compréhension profonde.
- Reprendre : lisez autoresearch.md + git log, continuez la boucle.
Finalisation
Quand la boucle d'expérience se termine (condition de terminaison remplie, utilisateur interrompt, ou contexte épuisé), finalisez les résultats en branches propres et révisables. C'est la dernière phase d'une session autoresearch.
Étape 1 : Résumer les résultats
python3 autoresearch_helper.py summary --jsonl autoresearch.jsonl
Vérifiez le journal git pour les commits réels :
git log --oneline --stat $(git merge-base HEAD main)..HEAD
Étape 2 : Grouper les changements
Groupez les expériences conservées en ensembles de changements logiques. Chaque groupe devrait :
- Représenter une optimisation ou un changement cohérent unique
- Ne pas partager de fichiers modifiés avec d'autres groupes (afin que les branches puissent fusionner indépendamment)
- Avoir une description claire de ce qu'il réalise et de l'amélioration de métrique
Présentez le groupage proposé à l'utilisateur pour approbation :
Groupe 1 : « Réduire la profondeur du modèle de 8 à 6 »
Fichiers : train.py (DEPTH, HEAD_DIM, N_EMBED)
Amélioration de métrique : val_bpb 1,15 -> 1,08 (-6,1%)
Expériences : #3, #7, #12
Groupe 2 : « Passer à une planification LR cosinus »
Fichiers : train.py (lr_schedule, warmup_steps)
Amélioration de métrique : val_bpb 1,08 -> 1,05 (-2,8%)
Expériences : #15, #18
Attendez la confirmation de l'utilisateur avant de continuer. En mode travailleur de mission, procédez avec le meilleur groupage sans attendre de confirmation.
Étape 3 : Résoudre les conflits de fichiers
Si les groupes partagent des fichiers, résolvez avant de créer des branches :
- Fusionnez les groupes en un (si les changements sont liés)
- Divisez plus soigneusement les changements de fichiers (s'il s'agit vraiment de modifications indépendantes sur différentes parties)
- Demandez à l'utilisateur quel groupe a la priorité
Les groupes ne doivent pas partager de fichiers — chaque branche doit être fusionnable indépendamment. Si tous les changements touchent le même fichier et ne peuvent pas être séparés, créez une seule branche finalisée avec tous les améliorations combinées.
Étape 4 : Créer des branches propres
Pour chaque groupe :
merge_base=$(git merge-base HEAD main)
git checkout -b autoresearch/finalize/<group-name> $merge_base
git checkout autoresearch/<session-branch> -- <file1> <file2> ...
git commit -m "<group description>
Autoresearch results:
- Metric: <name> improved from <baseline> to <best> (<delta>%)
- Confidence: <score>x noise floor
- Experiments: <count> total, <kept> kept"
Étape 5 : Vérifier et rapporter
Pour chaque branche finalisée, exécutez le benchmark pour confirmer que l'amélioration tient bon, exécutez les vérifications si applicable, et vérifiez qu'elle fusionne proprement avec main.
Présentez un résumé à l'utilisateur :
Créées 2 branches propres à partir de 20 expériences :
autoresearch/finalize/reduce-depth
val_bpb : 1,15 -> 1,08 (-6,1%)
Prête pour révision
autoresearch/finalize/cosine-schedule
val_bpb : 1,08 -> 1,05 (-2,8%)
Prête pour révision
Branche d'expérience originale conservée : autoresearch/<session-branch>
La branche d'expérience originale est toujours préservée — la finalisation crée de nouvelles branches.
Mode travailleur de mission
En fonctionnant comme travailleur de mission, la description de la fonctionnalité spécifie l'objectif d'optimisation, la condition de terminaison, les fichiers dans le périmètre et les contraintes. Lisez-le attentivement, suivez la même procédure de boucle ci-dessus et respectez la condition de terminaison. Quand la condition est remplie, exécutez la finalisation et signalez les résultats dans la remise.