bots-garden/mini-mepublic Fork
⑂ v0.1.3
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. 0394624 · on v0.1.3 · k33g · Sep 21, 2026
thinking-models.md · 51 lines · 4.1 KBmarkdown
Blame HistoryOpen raw

Modèles à raisonnement — explication

Pourquoi mm affiche le raisonnement d'un modèle, d'où il vient, et pourquoi le lire n'était pas optionnel.

Ce qu'envoie un modèle à raisonnement

Un modèle à raisonnement répond en deux temps. D'abord il réfléchit — parfois longuement — puis il répond. Sur un serveur compatible OpenAI, les deux ne partagent pas le même champ :

data: {"choices":[{"delta":{"reasoning_content":"Here's a thinking process: ..."}}]}
data: {"choices":[{"delta":{"reasoning_content":" 1. Analyze the request ..."}}]}
data: {"choices":[{"delta":{"content":"Quicksort is usually faster because ..."}}]}

reasoning_content est l'orthographe de Docker Model Runner, llama.cpp, vLLM et DeepSeek ; quelques serveurs disent reasoning. mm lit les deux.

Les séparer, c'est le serveur qui rend service : un client peut afficher le raisonnement autrement, ou pas du tout, sans rien extraire de la réponse. Rien à activer — les modèles qui réfléchissent réfléchissent.

Pourquoi mm le lit lui-même sur le fil

Le greffon compatible OpenAI de Genkit ne transmet pas le raisonnement. Sa boucle de streaming construit un chunk à partir de Delta.Content et Delta.ToolCalls, puis n'appelle le gestionnaire que si ce chunk contient quelque chose. Un chunk qui ne porte que du raisonnement est jeté.

Deux choses tombaient avec lui.

Le raisonnement lui-même, évidemment — c'est pourquoi mm n'affichait rien du tout pendant qu'un modèle à raisonnement travaillait.

Et le battement du chien de garde, qui est la partie sérieuse. mm annule une génération quand aucun token n'est arrivé depuis watchdogTimeout (20 s par défaut) : une connexion pendue ne doit pas pendre l'agent. Ce battement vit dans le gestionnaire de streaming que le greffon n'appelait pas. Un modèle qui raisonnait plus longtemps que le délai était donc tué pour « stalled » alors que son serveur diffusait des tokens sans le moindre problème — mesuré sur qwen3.5-2b : 38 secondes de raisonnement ininterrompu, pas un octet de contenu.

mm lit donc le raisonnement une couche sous Genkit : un intergiciel sur le client HTTP enveloppe le corps de la réponse et analyse les lignes SSE à mesure qu'elles sont lues, en laissant passer chaque octet intact. Le greffon voit exactement le flux qu'il aurait vu.

D'où le fait que showThinking: false coupe l'affichage et rien d'autre. Le raisonnement est toujours lu, parce que le lire est ce qui garde le tour en vie.

Où il va

Façade Ce que vous voyez
Mode ligne Un bloc 💭, grisé et en italique, avant la réponse 🤖. Texte brut quand la sortie n'est pas un terminal.
Fenêtre (mm -tui) Son entrée ‣ thinking, grisée, en italique et d'une autre couleur — un aparté, visiblement pas la réponse.
Éditeur (ACP) Une mise à jour agent_thought_chunk. Le protocole connaît la notion, ce n'est donc pas une astuce d'affichage : Zed le replie sous son propre volet « Thinking ».

Trois propriétés valent partout :

  • Le raisonnement n'entre jamais dans l'historique. Le modèle ne relit pas ses propres pensées au tour suivant, une session reprise ne les rejoue pas, et elles ne pèsent pas sur le contexte comme le fait la réponse.
  • Un résumé n'affiche jamais son raisonnement. La compression se fait dans le dos de l'utilisateur ; un modèle qui réfléchit à un résumé ne doit pas déverser ça au milieu d'une conversation. Le battement, lui, continue.
  • L'écouteur voyage sur le contexte de la requête, pas dans une variable de paquet : deux tours simultanés ne peuvent pas croiser leurs raisonnements.

Ce que ce n'est pas

Ce n'est pas un réglage d'« effort de raisonnement » : mm ne demande rien et ne configure rien côté modèle. Un modèle réfléchit ou non, et mm affiche ce qui arrive.

Ce n'est pas un analyseur. Certains modèles encadrent plutôt leur raisonnement de balises <think> à l'intérieur de content. Celles-là arrivent comme du texte de réponse ordinaire et mm les affiche comme tel — les deux formes demanderaient des traitements différents, et seul le champ est géré aujourd'hui.

 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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# Modèles à raisonnement — explication

> Pourquoi `mm` affiche le raisonnement d'un modèle, d'où il vient, et pourquoi le lire n'était pas optionnel.

## Ce qu'envoie un modèle à raisonnement

Un modèle à raisonnement répond en deux temps. D'abord il réfléchit — parfois longuement — puis il répond. Sur un serveur compatible OpenAI, les deux ne partagent pas le même champ :

```
data: {"choices":[{"delta":{"reasoning_content":"Here's a thinking process: ..."}}]}
data: {"choices":[{"delta":{"reasoning_content":" 1. Analyze the request ..."}}]}
data: {"choices":[{"delta":{"content":"Quicksort is usually faster because ..."}}]}
```

`reasoning_content` est l'orthographe de Docker Model Runner, llama.cpp, vLLM et DeepSeek ; quelques serveurs disent `reasoning`. `mm` lit les deux.

Les séparer, c'est le serveur qui rend service : un client peut afficher le raisonnement autrement, ou pas du tout, sans rien extraire de la réponse. Rien à activer — les modèles qui réfléchissent réfléchissent.

## Pourquoi `mm` le lit lui-même sur le fil

Le greffon compatible OpenAI de Genkit ne transmet pas le raisonnement. Sa boucle de streaming construit un chunk à partir de `Delta.Content` et `Delta.ToolCalls`, puis n'appelle le gestionnaire que si ce chunk contient quelque chose. Un chunk qui ne porte que du raisonnement est jeté.

Deux choses tombaient avec lui.

Le raisonnement lui-même, évidemment — c'est pourquoi `mm` n'affichait rien du tout pendant qu'un modèle à raisonnement travaillait.

Et **le battement du chien de garde**, qui est la partie sérieuse. `mm` annule une génération quand aucun token n'est arrivé depuis `watchdogTimeout` (20 s par défaut) : une connexion pendue ne doit pas pendre l'agent. Ce battement vit dans le gestionnaire de streaming que le greffon n'appelait pas. Un modèle qui raisonnait plus longtemps que le délai était donc tué pour « stalled » alors que son serveur diffusait des tokens sans le moindre problème — mesuré sur `qwen3.5-2b` : 38 secondes de raisonnement ininterrompu, pas un octet de contenu.

`mm` lit donc le raisonnement une couche sous Genkit : un intergiciel sur le client HTTP enveloppe le corps de la réponse et analyse les lignes SSE à mesure qu'elles sont lues, en laissant passer chaque octet intact. Le greffon voit exactement le flux qu'il aurait vu.

D'où le fait que `showThinking: false` coupe l'*affichage* et rien d'autre. Le raisonnement est toujours lu, parce que le lire est ce qui garde le tour en vie.

## Où il va

| Façade | Ce que vous voyez |
|---|---|
| Mode ligne | Un bloc `💭`, grisé et en italique, avant la réponse `🤖`. Texte brut quand la sortie n'est pas un terminal. |
| Fenêtre (`mm -tui`) | Son entrée `‣ thinking`, grisée, en italique et d'une autre couleur — un aparté, visiblement pas la réponse. |
| Éditeur (ACP) | Une mise à jour `agent_thought_chunk`. Le protocole connaît la notion, ce n'est donc pas une astuce d'affichage : Zed le replie sous son propre volet « Thinking ». |

Trois propriétés valent partout :

- **Le raisonnement n'entre jamais dans l'historique.** Le modèle ne relit pas ses propres pensées au tour suivant, une session reprise ne les rejoue pas, et elles ne pèsent pas sur le contexte comme le fait la réponse.
- **Un résumé n'affiche jamais son raisonnement.** La compression se fait dans le dos de l'utilisateur ; un modèle qui réfléchit à un résumé ne doit pas déverser ça au milieu d'une conversation. Le battement, lui, continue.
- **L'écouteur voyage sur le contexte de la requête**, pas dans une variable de paquet : deux tours simultanés ne peuvent pas croiser leurs raisonnements.

## Ce que ce n'est pas

Ce n'est pas un réglage d'« effort de raisonnement » : `mm` ne demande rien et ne configure rien côté modèle. Un modèle réfléchit ou non, et `mm` affiche ce qui arrive.

Ce n'est pas un analyseur. Certains modèles encadrent plutôt leur raisonnement de balises `<think>` à l'intérieur de `content`. Celles-là arrivent comme du texte de réponse ordinaire et `mm` les affiche comme tel — les deux formes demanderaient des traitements différents, et seul le champ est géré aujourd'hui.