autoresearch

Par factory-ai · factory-plugins

Boucle d'expérimentation autonome pour la recherche en optimisation. À utiliser lorsque l'utilisateur souhaite : - Optimiser une métrique par expérimentation systématique (loss d'entraînement ML, vitesse de test, taille du bundle, temps de build, etc.) - Exécuter une boucle de recherche automatisée : tester une idée, la mesurer, conserver les améliorations, annuler les régressions, répéter - Mettre en place une autorecherche sur n'importe quelle base de code avec une cible d'optimisation mesurable Implémente le pattern autoresearch avec scoring de confiance basé sur la MAD, isolation par branche git et journalisation structurée des expériences.

npx skills add https://github.com/factory-ai/factory-plugins --skill autoresearch

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 :

  1. Suivez le nombre d'expériences dans la session actuelle. Après environ 15 expériences, le contexte devient lourd.
  2. 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.
  3. Quand le contexte s'épuise : mettez à jour autoresearch.md avec les découvertes actuelles, validez les fichiers d'état et arrêtez. La session suivante lit les fichiers et continue.
  4. En reprenant : lisez autoresearch.md, autoresearch.jsonl et git log --oneline -20 pour 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.

Skills similaires