Chapitre 7

La curiosité en panne, puis deux rustines qui marchent à moitié

Prérequis : Chapitres 1 à 6 — jusqu'au mur du premier arbre trouvé en solo, que ce chapitre attaque pour la première fois.

Vue à la première personne dans Minecraft : l'agent explore un paysage vallonné en tournant la caméra et en s'avançant.
Le réflexe d'échantillonnage collant et de balayage de caméra en action lors de l'exploration.

Piste débutant

Le problème qu'on attaque : trouver le premier arbre, seul

Le Chapitre 6 s'est terminé sur un mur bien identifié : l'agent sait fabriquer des planches à la

perfection une fois qu'il a du bois, mais dans un vrai monde de survie généré au hasard, il ne

trouve jamais son premier arbre — 0 bûche sur 5 épisodes testés. Ce chapitre raconte la

première grande campagne pour attaquer ce mur. Spoiler honnête, comme toujours dans ce projet :

la première idée échoue proprement, et les corrections suivantes n'apportent qu'un progrès

partiel — mais chaque échec révèle quelque chose de précis sur la nature réelle du problème.

Idée n°1 : la curiosité — récompenser l'agent pour ce qui le surprend

L'idée s'appelle la curiosité artificielle. Le principe : au lieu de ne récompenser l'agent

que pour atteindre un objectif, on lui donne aussi une petite récompense chaque fois qu'il va vers

quelque chose de surprenant — un endroit que son modèle du monde connaît mal, où ses

prédictions se trompent beaucoup. L'intuition : si l'agent ne trouve jamais d'arbre parce qu'il ne

sait pas dans quelle direction chercher, le pousser vers ce qui le surprend devrait naturellement

le faire explorer plutôt que rester planté.

Concrètement, le projet a construit un petit comité de 5 « devineurs » qui essaient chacun de

prédire ce qui va se passer ensuite dans l'embedding (le résumé en nombres de l'image, Chapitre

1). Quand les 5 devineurs sont d'accord, c'est un endroit familier — rien de surprenant. Quand ils

sont en désaccord, c'est un endroit mal compris — potentiellement intéressant à explorer. Cette

idée s'appelle Plan2Explore et vient d'un vrai article de recherche.

Avant de lancer cette expérience (et toutes celles qui suivent dans ce chapitre et le suivant), le

projet a construit une petite équipe de trois agents logiciels spécialisés — un qui propose une

expérience à partir de vraies références scientifiques, un qui l'implémente sans jamais abîmer ce

qui fonctionne déjà, un qui la teste honnêtement et rapporte les vrais chiffres. Cette discipline

sert à éviter de se raconter des histoires sur ses propres résultats.

Le résultat : aucune différence, et plus lent

Comparaison sur 20 épisodes de Treechop (le mode « juste couper un arbre » du Chapitre 5), avec et

sans la curiosité activée : sans curiosité, 30% de réussite ; avec curiosité, 25% — une

différence bien trop petite pour être fiable avec seulement 20 épisodes de chaque côté, et surtout,

avec la curiosité, le jeu tourne deux fois et demi plus lentement (le comité de 5 devineurs

doit juger chacune des 512 histoires imaginées à chaque instant, Chapitre 4). Verdict honnête :

la curiosité n'a rien apporté, et elle a coûté cher en vitesse.

Pourquoi ça a échoué : le comité s'est mis d'accord trop vite

En regardant l'entraînement du comité de devineurs, l'explication apparaît clairement : dès la

troisième passe d'entraînement, les 5 devineurs se sont tous mis d'accord entre eux, et sont

restés d'accord pour le reste de l'entraînement. Un comité toujours d'accord ne peut plus jamais

signaler « ceci est surprenant » nulle part — le signal de curiosité est resté plat partout, ce qui

explique exactement pourquoi activer la curiosité n'a rien changé (à part ralentir le jeu).

La vraie cause, plus intéressante que le symptôme : la vraie méthode Plan2Explore entraîne son

comité de devineurs en continu, sur ce que l'agent découvre en explorant lui-même — un flux de

données forcément varié, puisque l'agent va sans arrêt vers des endroits nouveaux. Ce projet, lui,

a entraîné le comité une fois pour toutes, sur des enregistrements figés de parties d'experts qui

coupent toujours le même arbre de la même façon. Sur des données aussi répétitives, les 5

devineurs trouvent tous la même solution simple, et n'ont plus jamais de raison d'être en

désaccord. Le projet a reproduit la forme de la méthode sans reproduire la condition qui la

fait marcher.

Idée n°2 : arrêter de regarder par le prisme de la curiosité

Après cet échec, le projet a pris du recul et reposé la question autrement : qu'est-ce que le

planificateur (Chapitre 4) fait réellement, mécaniquement, quand aucun arbre n'est visible ?

Deux défauts très concrets sont apparus — aucun des deux n'a besoin d'apprentissage pour être

corrigé.

Défaut 1 : le planificateur ne peut même pas imaginer le bon geste. Pour chercher un arbre

invisible, le bon geste, c'est « tourner la caméra dans une direction pendant plusieurs instants

de suite ». Mais le planificateur tire ses 512 histoires imaginées en choisissant, à chaque

instant, une action complètement indépendante de la précédente — un peu comme lancer un dé à 17

faces 12 fois de suite sans mémoire. La probabilité qu'un tel tirage produise 6 fois d'affilée

l'action « tourner » est quasiment nulle. Le problème n'est pas que le planificateur choisit

mal — c'est que le bon geste n'existe même pas dans la liste de choses qu'il envisage.

La correction s'appelle l'échantillonnage collant : à chaque instant imaginé, au lieu de tirer

une action complètement neuve, on répète l'action précédente avec une certaine probabilité. Cette

seule règle fait grimper le taux de répétition consécutive de 7% (tirage indépendant) à 72%

(collant à 70%) — les 512 histoires imaginées contiennent désormais des gestes tenus dans le temps

(tourner-et-regarder, marcher-vers, frapper de façon soutenue).

Défaut 2 : l'agent ne sait même pas qu'il est perdu. Quand un arbre est visible, les 512

histoires imaginées obtiennent des scores très différents (certaines s'en approchent, d'autres

s'en éloignent). Quand rien n'est visible, les 512 scores sont quasiment identiques — le choix

final devient un tirage au sort déguisé. Cet écart entre les scores (leur écart-type) est un

signal gratuit, déjà calculé, jamais utilisé jusque-là : élevé, ça veut dire « je vois quelque

chose d'utile » ; proche de zéro, ça veut dire « je suis perdu ». Une petite règle a été ajoutée :

après plusieurs tours de suite avec ce signal proche de zéro, l'agent abandonne temporairement le

planificateur et tourne la caméra méthodiquement jusqu'à ce que le signal remonte (un arbre est

entré dans le champ de vision) ou qu'un budget de tours soit épuisé.

À prendre pour ce que c'est : ce n'est pas de l'apprentissage. C'est un réflexe écrit à la

main — le genre de chose que des méthodes plus lourdes (hors de portée d'un seul GPU grand public)

apprennent d'elles-mêmes. Mais ça n'a pas de sens d'apprendre à un agent à explorer tant qu'il ne

peut même pas tourner la tête correctement.

Les résultats : un vrai progrès sur Treechop, zéro sur le cold-start

Sur Treechop (l'agent démarre toujours en forêt), la combinaison collant+réflexe donne un résultat

nuancé : à un réglage modéré (collant à 50%), le taux de succès reste dans la fourchette normale

déjà observée au Chapitre 5, mais chaque succès rapporte environ deux fois plus de récompense — le

collant aide à creuser (continuer à couper un arbre déjà trouvé) plus qu'à chercher (trouver

plus d'arbres). À un réglage plus fort (collant à 70%), l'agent se bloque trop sur un seul geste et

le résultat empire légèrement.

Sur le vrai cold-start (spawn aléatoire, sans bois de départ) : zéro bûche coupée, dans toutes

les configurations testées. Pire, à un certain réglage du seuil, le réflexe « tourner la tête »

devient pathologique : l'agent tourne la caméra 82 à 92% du temps, littéralement en train de

tourner sur lui-même sans jamais s'arrêter. L'observation la plus révélatrice : dans certains

épisodes, l'agent se retrouve entouré d'arbres et ne les coupe toujours pas. Ce n'est donc pas

(seulement) un problème de recherche — c'est un problème d'approche et de coupe une fois la cible

trouvée.

Une variante testée pour comprendre : donner à l'agent deux « cerveaux » séparés — celui qui a fait

ses preuves sur Treechop pilote la recherche de l'arbre, le nouveau modèle prend le relais dès la

première bûche pour fabriquer. Résultat : toujours zéro bûche, mais le comportement change

nettement (des gestes de bûcheron reconnaissables au lieu d'un vagabondage confus). Un des épisodes

montre l'agent qui apparaît dans un ravin rocheux sans un seul arbre, et qui frappe la pierre à la

place — un rappel qu'un point de spawn sans bois du tout ne peut être résolu par aucun réflexe de

recherche.

Une dernière tentative avant de conclure : affiner le modèle sur plus de diversité

Dernière piste testée dans cette campagne : si le signal « je suis perdu » est flou sur le modèle

de fabrication (contrairement au modèle Treechop où il est net), c'est peut-être parce que les

démonstrations d'experts utilisées pour l'entraîner montrent rarement des moments où l'expert est

« perdu » — les experts trouvent du bois vite, ils ne traînent jamais dans le vide. En ajoutant

une vingtaine de courtes parties jouées au hasard (donc, statistiquement, souvent perdues) au jeu

de données d'entraînement, puis en réentraînant légèrement le modèle sur ce mélange, le signal

« perdu vs. trouvé » devient effectivement beaucoup plus net qu'avant.

Mais le résultat final ne change pas d'un iota : toujours zéro bûche coupée, avec ou sans cet

affinement. Rendre le signal plus net n'a pas rendu le comportement meilleur. Cette découverte

confirme ce que l'expérience des deux cerveaux avait déjà suggéré : le mur n'est pas dans la

perception (savoir qu'on est perdu), il est dans le comportement (savoir quoi faire une fois

qu'on a trouvé quelque chose, ou comment couvrir du terrain quand on ne trouve rien). Le chapitre

suivant continue cette enquête avec des outils encore plus directs.

Piste expert

Cadrage : d'une hypothèse d'exploration à un diagnostic mécanique

Le symptôme de départ (0 log sur ObtainIronPickaxeDense, 5 épisodes, docs/08_crafting.md) a

d'abord été traité comme un problème d'exploration/récompense intrinsèque, puis re-diagnostiqué

comme un défaut d'implémentation du MPC lui-même — deux lectures du même symptôme, testées dans

l'ordre.

Harness : une boucle de développement à 3 agents

Avant toute expérience : jepa-explorer (lecture seule, propose une expérience ancrée sur

docs/references/index.md §3), jepa-developer (implémente, config-gated, ne touche jamais un

checkpoint qui marche, seedé), jepa-tester (exécute les gates + play, rapporte PASS/FAIL avec

les vrais chiffres, honnête sur la variance), orchestrés par /jepa-loop.

Proposition #1 — Plan2Explore, novelty offline

Idée (Sekar et al., arXiv:2005.05960, ICML 2020) : ajouter

un bonus intrinsèque score = goalscore + λ · noveltyscore, novelty_score = désaccord d'un

ensemble de k=5 têtes de prédiction one-step conditionnées par l'action, sur le latent spatial

[D,8,8].

Implémentation : mine_jepa/ebwm/curiosity.py::DisagreementEnsemble ;

scripts/train_curiosity.py entraîne sur des latents eb-JEPA figés, optimiseur séparé, seedé,

sauvegarde vers checkpoints/curiosity_ensemble.pt, ne touche jamais ebwm.pt ;

DiscreteLatentPlanner blend la novelty z-scorée quand novelty_coeff > 0 (0.0 par défaut =

comportement original bit-for-bit).

Résultat, A/B sur MineRLTreechop-v0, N=20, même ebwm.pt (ratio 0,927) :

ConditionSuccèsReward moyenLogsfps
OFF (goal-centroid seul)6/20 = 30%0,40863
ON (novelty λ=1,0)5/20 = 25%0,25525

Écart non significatif à N=20 (variance documentée 25-50% de Treechop) ; coût 2,5× le fps

(l'ensemble tourne sur les 512 candidats à chaque replan). Verdict : FAIL.

Cause racine : collapse de l'ensemble pendant l'entraînement

epoch 1: val_disagree = 0,0613   (diversité saine)
epoch 2: val_disagree = 0,0122
epoch 3: val_disagree = 0,0017   (collapsé)
epoch 4-15: val_disagree ≈ 0,0005 (mort, ne récupère jamais)

Dès l'epoch 3, les 5 têtes convergent vers la même fonction → désaccord ≈ 0 partout → bonus de

novelty uniformément nul → planificateur identique au goal-centroid seul, juste plus lent.

Reproduction de la forme de Plan2Explore sans sa condition. Plan2Explore entraîne son

ensemble en ligne, sur un flux de données que l'agent lui-même diversifie en explorant.

Entraîner sur un jeu figé de démos Treechop (même geste de bûcheron, même arbre, même caméra) —

aussi homogène — fait converger chaque tête vers la même solution triviale à faible perte. La

qualité du signal de novelty d'un ensemble est bornée par la diversité de ses données

d'entraînement, et un entraînement offline sur latents figés issus de démos expertes détruit

précisément cette diversité.

Candidats retenus pour la suite, par ordre de pertinence : régularisation de désaccord explicite ;

RND (arXiv:1810.12894, immunisé structurellement à ce

collapse car la cible ne bouge jamais) ; self-play en ligne (la recette Plan2Explore réelle, plus

coûteuse).

Ré-analyse sans le prisme de la curiosité : deux défauts mécaniques

Défaut 1 — l'échantillonnage i.i.d. ne peut pas proposer le bon comportement. Le geste

correctif pour « rien en vue » est une action tenue (tourner la caméra sur plusieurs pas

consécutifs). La probabilité qu'une séquence i.i.d. sur 17 actions produise 6 répétitions

consécutives est (1/17)⁶ — négligeable. Fix : échantillonnage collant (sampleactions(),

mine_jepa/ebwm/planner.py, utilisé par DiscreteLatentPlanner et SwitchingCraftPlanner) :

répéter l'action précédente avec probabilité sticky_prob, sinon tirer neuf. Mesuré sur 4096

séquences : taux de répétition consécutive 7% (i.i.d.) → 72% (stickyprob=0,7). stickyprob=0,0

(défaut) reproduit l'ancien comportement bit-for-bit. Inspiration : iCEM

(arXiv:2008.06389), bruit coloré pour actions continues, ici

adapté en version discrète.

Défaut 2 — l'agent est aveugle à sa propre cécité. goalscorestd (écart-type des scores sur

les 512 candidats, déjà calculé, jamais exploité) : élevé quand un but est visible (le classement

signifie quelque chose), ≈0 quand rien n'est visible (l'argmax est du bruit). Le scan macro

(plan(..., returninfo=True) exposant goalscorestd ; scripts/playebwm.py et

scripts/play_craft.py en mode chop) déclenche, après patience replans plats consécutifs, une

action caméra-yaw fixe (a12, +10°/replan) jusqu'à récupération du signal ou expiration de

max_replans. scan.enabled: false par défaut. Honnêteté explicite : c'est un réflexe écrit à la

main, pas de l'apprentissage.

Calibration (PC, 3 épisodes Treechop, 750 replans/ép., seed 0)

SituationBande goalscorestd
Perdu (mur, ciel, herbe ouverte)0,0002 – 0,002
Errance, arbres au loin0,003 – 0,01
Arbre/canopée plein champ0,02 – 0,056

flat_threshold: 0,003 retenu (juste au-dessus de la bande "perdu"), patience: 3.

Gate (PC, 2026-07-08) — Treechop : progrès partiel

ConditionNSuccèsReward moyenfps
OFF (baseline fraîche)2045% (9/20)0,5065,9
sticky 0,7 + scan@0,0032025% (5/20)0,4565,0
sticky 0,5 + scan@0,0031040% (4/10)0,9064,6

Aucune différence significative (Fisher p=0,32 / p=1,0) mais direction cohérente : 0,7 sur-engage

(a14 à 71-97%, marche indéfiniment sur un seul geste) ; 0,5 maintient le succès dans la bande de

variance et double la récompense par succès — le collant achète de la profondeur

(continuer à couper l'arbre atteint), pas de la largeur (trouver plus d'arbres). fps inchangé.

Gate — cold-start : ÉCHEC dans toutes les configurations

ConfigNLogsNote
sticky 0,5 + scan@0,0031 (interrompu)0agent souvent dans la forêt, ne coupe pas
sticky 0,5 + scan@0,00450pathologique : a12 82-92%, 15-34 scans/ép. — l'agent tourne sur lui-même
sticky 0,5, scan off50actions variées, toujours pas de première bûche

Cause : sur craftwmv4.pt les bandes goalscorestd sont comprimées (perdu ~0,002,

arbre-visible ~0,010, médiane 0,0047 — écart ×5) contre l'écart ×10 net de Treechop. N'importe

quel seuil absolu se déclenche trop peu ou trop souvent. Constat le plus net : avec scan@0,003,

l'agent est parfois entouré d'arbres et ne coupe toujours pas — le mur n'est pas (que) la

recherche, c'est le comportement d'approche-et-coupe lui-même.

Micro-expérience — échanger la boussole du chop : utiliser le centroïde Treechop (12 056

frames reward≥0,5) encodé par l'encodeur de craftwmv4 au lieu du centroïde Obtain-demo comme

objectif de chop. Résultat : toujours 0/5. La boussole seule ne sauve pas le cold-start.

Agent à deux cerveaux (chop_model:, config-gated) : ebwm.pt pilote le chop (17 actions de

mouvement partagées), craftwmv4 prend le relais dès la première bûche. Résultat : toujours

0/5, mais comportement transformé (a14 sprint+attack 30-52% au lieu d'errance diffuse). GIF de

l'épisode le plus attaqué (a6=85%) : spawn dans un ravin rocheux sans arbre, l'agent frappe la

pierre. 2/5 épisodes meurent tôt. Le mur restant : le spawn aléatoire sans bois à proximité et le

rayon de recherche — précisément le terrain de la curiosité en ligne.

Défauts par défaut conservés : play_ebwm.yaml → sticky 0,5 + scan on (calibré, sans risque,

chops plus profonds) ; play_craft.yaml → sticky 0,5, scan off, deux-cerveaux on.

Affinage sur données de couverture (2026-07-20) — signal amélioré, résultat inchangé

Hypothèse : les bandes comprimées de craftwmv4.pt sont un artefact de couverture des données

— les 40 démos expertes montrent rarement "perdu, aucun arbre en vue" (les experts trouvent du

bois vite). Fix testé : ~20 épisodes courts (400 pas) en politique aléatoire sur

ObtainIronPickaxeDense-v0 (spawn aléatoire = diversité de biome gratuite), fusionnés aux 40

démos expertes, puis fine-tune 4 epochs à faible LR depuis une sauvegarde de craftwmv4.pt

(checkpoints/craftwmv4_coverage.pt). Aucun collapse (bvar 1,24-1,27), pas de régression de

précondition (dPlanks@craft resté entre +1,22 et +1,35 sur les epochs de fine-tune).

sauvegarde (original)couverture (fine-tuné)
Logs coupés (N=3)0/30/3
Planches fabriquées (N=3)0/30/3
goalscorestd médiane0,00340,0126 (×3,7)
Ratio p90/p10×3,2×5,4
Longueur d'épisode3000/3000/30002295/3000/1070 (2 morts précoces)

Verdict : le signal s'est amélioré, le résultat non. La séparation des bandes s'est

effectivement élargie (×3,2 → ×5,4, se rapprochant du ×10 de Treechop) — le mécanisme de

couverture-des-données est réel — mais 0/3 logs identique sur les deux checkpoints, et le

checkpoint affiné meurt plus tôt sur 2/3 épisodes (plus de mouvement exploratoire, pas plus de

coupe).

Leçon : affiner le signal « suis-je perdu ? » ne corrige pas, en soi, le comportement de

recherche-et-approche qui doit l'exploiter. Le diagnostic de l'expérience à deux cerveaux se

confirme : l'écart est comportemental (recherche/approche), pas purement perceptif. Les données

de couverture aident le modèle à mieux représenter l'état « perdu » ; elles ne lui apprennent

pas quoi en faire.

ebwm.pt, craftwmv4.pt, craftwmv4backup.pt intacts ; craftwmv4coverage.pt est un

checkpoint de comparaison séparé, pas un remplacement.

Références (vérifiées, tirées de docs/references/index.md)

  • Sekar, Rybkin, Daniilidis, Abbeel, Hafner, Pathak, Plan2Explore, arXiv:2005.05960 (ICML 2020) —

le principe de novelty par désaccord d'ensemble testé et diagnostiqué dans ce chapitre.

  • Burda, Edwards, Storkey, Klimov, RND, arXiv:1810.12894 (2018) — le candidat retenu pour la

suite, immunisé au collapse d'ensemble par construction.

  • iCEM, arXiv:2008.06389 (2020) — inspiration du bruit temporellement corrélé derrière

l'échantillonnage collant discret.