bots-garden/mini-mepublic Fork
⑂ main
Commits
⬇ Clone ▾
git clone https://git.rickub.com/bots-garden/mini-me.git
git clone ssh://git@rickub.com/bots-garden/mini-me.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP
🛟 Updated. dfcd2ed · on main · k33g · 14d ago
struggling-models.md · 30 lines · 5.2 KBmarkdown
Blame HistoryOpen raw

Repérer qu'un modèle peine — explication

De quoi s'agit-il ?

mm a été écrit pour de petits modèles locaux, et les petits modèles peinent de façons reconnaissables : ils répètent le même appel qui échoue, ils écrivent des arguments d'appel d'outil illisibles ou sans fin, ils se taisent, ils appellent des outils qui n'existent pas, ils épuisent leurs tours, ils ne répondent rien. Dès le départ, mm repérait la plupart de ces cas — le détecteur de boucles, le garde-fou contre l'emballement, le watchdog, la note rendue après un appel cassé — mais il le disait au modèle (une consigne dans la sortie d'un outil) ou terminait le tour par une ligne d'erreur au milieu du reste de la conversation. La personne qui regardait devait tout lire pour savoir que le modèle tournait en rond.

Les signaux de difficulté (ticket 153) rendent ces mêmes détections visibles à l'utilisateur, à part de la réponse, dans une couleur qui dit la gravité. La liste des signaux et la façon dont chaque front end les affiche sont dans la référence du CLI.

Pourquoi c'est conçu ainsi

Deux niveaux, pas un score. Un avertissement (⚠, jaune) veut dire que mm a remarqué quelque chose et que le tour continue — le modèle a été prévenu qu'il boucle, un appel cassé lui a été rendu, le contexte est presque plein. Un signal grave (✖, rouge) veut dire que le tour a été arrêté ou a échoué à cause de lui. C'est la distinction sur laquelle on agit : attendre et regarder, ou reformuler et recommencer (ou changer de modèle).

Signalés là où ils sont détectés. Chaque détection vivait déjà à un seul endroit — le Record du détecteur de boucles, l'enveloppe des appels au modèle pour les relances et les appels cassés, la fin de Generate pour la façon dont un tour s'est terminé. Chacune y signale un ui.Struggle ; rien ne relit la conversation après coup pour deviner. Le détecteur de boucles appelle une fonction (WithReport) plutôt que de connaître l'écran : il reste un package sans connaissance des front ends.

Un événement, trois rendus, comme tout le reste de mm (architecture) : la fenêtre garde la difficulté la plus grave du tour en badge dans la barre d'état ; le mode ligne imprime une ligne colorée au moment où elle arrive ; un éditeur reçoit un court paragraphe en italique signé mm dans le message de l'agent, faute de barre d'état à nous.

Dans la fenêtre, la barre d'état, jusqu'à la question suivante. Le badge se place à droite de la barre du bas, à la place de la version : c'est ce qui sert le moins quand quelque chose ne va pas, et les raccourcis à gauche — Ctrl-C quit avant tout, la sortie d'un tour qui ne s'arrête pas — gardent leur place. Il survit au tour exprès : quand un tour finit mal, le badge dit pourquoi, et il disparaît quand la question suivante ouvre un nouveau tour. Un signal grave l'emporte sur un avertissement ; entre deux de même niveau le plus récent gagne, si bien que loop: bash ×4 remplace ×3 ; (+N) compte les autres.

Des échecs d'affilée, pas seulement des répétitions (ticket 160). Le détecteur de boucles veut le même appel avec le même résultat ; un modèle qui essaie cat config.yml, puis cat conf/config.yml, puis cat config.yaml et échoue à chaque fois peine tout autant. L'échec d'un appel n'est connu qu'à l'intérieur de chaque outil : chaque outil transmet donc maintenant son résultat au détecteur avec l'appel (record, recordFailure, recordOutcome) ; le détecteur, qui voit déjà chaque appel, compte les échecs d'affilée et signale failing: N tool calls in a row à partir du troisième. C'est seulement un avertissement : le modèle lit déjà chaque échec dans la sortie de l'outil, et un arrêt brutal couperait des tours qu'un quatrième essai aurait sauvés.

Un tour annulé n'est pas une difficulté. Échap, Ctrl-C ou /abort terminent un tour à la demande de l'utilisateur ; signaler alors stalled ou max turns reprocherait au modèle le choix de l'utilisateur.

Alternatives écartées

  • L'en-tête. Envisagé ; l'utilisateur a choisi la barre d'état, ce qui garde l'en-tête pour qui répond et le remplissage du contexte.
  • Une ligne de conversation par signal. La conversation est l'endroit de la réponse ; une boucle signalée à chaque répétition la remplirait de lignes qui répètent la sortie de l'outil. Le badge résume ; le mode ligne, qui n'a pas de barre d'état, imprime les lignes.

Liens avec le reste

Les détections elles-mêmes ne changent pas : le détecteur de boucles dit toujours au modèle de changer d'approche et arrête toujours le tour après six appels identiques ; le watchdog, le garde-fou contre l'emballement et la note après un appel cassé se comportent comme avant. Ce que renvoie le tour et ce que garde l'historique ne changent pas non plus — une difficulté est montrée, jamais enregistrée. Voir aussi la compression du contexte, qu'un avertissement context N% full précède souvent, et les modèles à raisonnement pour savoir pourquoi le watchdog reste nourri pendant qu'un modèle réfléchit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Repérer qu'un modèle peine — explication

## De quoi s'agit-il ?

`mm` a été écrit pour de petits modèles locaux, et les petits modèles peinent de façons reconnaissables : ils répètent le même appel qui échoue, ils écrivent des arguments d'appel d'outil illisibles ou sans fin, ils se taisent, ils appellent des outils qui n'existent pas, ils épuisent leurs tours, ils ne répondent rien. Dès le départ, `mm` repérait la plupart de ces cas — le détecteur de boucles, le garde-fou contre l'emballement, le watchdog, la note rendue après un appel cassé — mais il le disait au **modèle** (une consigne dans la sortie d'un outil) ou terminait le tour par une ligne d'erreur au milieu du reste de la conversation. La personne qui regardait devait tout lire pour savoir que le modèle tournait en rond.

Les signaux de difficulté (ticket 153) rendent ces mêmes détections visibles à l'**utilisateur**, à part de la réponse, dans une couleur qui dit la gravité. La liste des signaux et la façon dont chaque front end les affiche sont dans la [référence du CLI](../reference/cli.md#signaux-de-difficulté).

## Pourquoi c'est conçu ainsi

**Deux niveaux, pas un score.** Un avertissement (`⚠`, jaune) veut dire que `mm` a remarqué quelque chose et que le tour continue — le modèle a été prévenu qu'il boucle, un appel cassé lui a été rendu, le contexte est presque plein. Un signal grave (`✖`, rouge) veut dire que le tour a été arrêté ou a échoué à cause de lui. C'est la distinction sur laquelle on agit : attendre et regarder, ou reformuler et recommencer (ou changer de modèle).

**Signalés là où ils sont détectés.** Chaque détection vivait déjà à un seul endroit — le `Record` du détecteur de boucles, l'enveloppe des appels au modèle pour les relances et les appels cassés, la fin de `Generate` pour la façon dont un tour s'est terminé. Chacune y signale un `ui.Struggle` ; rien ne relit la conversation après coup pour deviner. Le détecteur de boucles appelle une fonction (`WithReport`) plutôt que de connaître l'écran : il reste un package sans connaissance des front ends.

**Un événement, trois rendus**, comme tout le reste de `mm` ([architecture](architecture.md)) : la fenêtre garde la difficulté la plus grave du tour en badge dans la barre d'état ; le mode ligne imprime une ligne colorée au moment où elle arrive ; un éditeur reçoit un court paragraphe en italique signé `mm` dans le message de l'agent, faute de barre d'état à nous.

**Dans la fenêtre, la barre d'état, jusqu'à la question suivante.** Le badge se place à droite de la barre du bas, à la place de la version : c'est ce qui sert le moins quand quelque chose ne va pas, et les raccourcis à gauche — `Ctrl-C quit` avant tout, la sortie d'un tour qui ne s'arrête pas — gardent leur place. Il survit au tour exprès : quand un tour finit mal, le badge dit pourquoi, et il disparaît quand la question suivante ouvre un nouveau tour. Un signal grave l'emporte sur un avertissement ; entre deux de même niveau le plus récent gagne, si bien que `loop: bash ×4` remplace `×3` ; `(+N)` compte les autres.

**Des échecs d'affilée, pas seulement des répétitions** (ticket 160). Le détecteur de boucles veut le même appel avec le même résultat ; un modèle qui essaie `cat config.yml`, puis `cat conf/config.yml`, puis `cat config.yaml` et échoue à chaque fois peine tout autant. L'échec d'un appel n'est connu qu'à l'intérieur de chaque outil : chaque outil transmet donc maintenant son résultat au détecteur avec l'appel (`record`, `recordFailure`, `recordOutcome`) ; le détecteur, qui voit déjà chaque appel, compte les échecs d'affilée et signale `failing: N tool calls in a row` à partir du troisième. C'est seulement un avertissement : le modèle lit déjà chaque échec dans la sortie de l'outil, et un arrêt brutal couperait des tours qu'un quatrième essai aurait sauvés.

**Un tour annulé n'est pas une difficulté.** Échap, Ctrl-C ou `/abort` terminent un tour à la demande de l'utilisateur ; signaler alors `stalled` ou `max turns` reprocherait au modèle le choix de l'utilisateur.

## Alternatives écartées

- **L'en-tête.** Envisagé ; l'utilisateur a choisi la barre d'état, ce qui garde l'en-tête pour qui répond et le remplissage du contexte.
- **Une ligne de conversation par signal.** La conversation est l'endroit de la réponse ; une boucle signalée à chaque répétition la remplirait de lignes qui répètent la sortie de l'outil. Le badge résume ; le mode ligne, qui n'a pas de barre d'état, imprime les lignes.

## Liens avec le reste

Les détections elles-mêmes ne changent pas : le détecteur de boucles dit toujours au modèle de changer d'approche et arrête toujours le tour après six appels identiques ; le watchdog, le garde-fou contre l'emballement et la note après un appel cassé se comportent comme avant. Ce que renvoie le tour et ce que garde l'historique ne changent pas non plus — une difficulté est montrée, jamais enregistrée. Voir aussi la [compression du contexte](context-compression.md), qu'un avertissement `context N% full` précède souvent, et les [modèles à raisonnement](thinking-models.md) pour savoir pourquoi le watchdog reste nourri pendant qu'un modèle réfléchit.