Files
nas-runbooks/common/migration-mimo-v25-cerveau-hermes.md

266 lines
19 KiB
Markdown

# Migration cerveau Hermes DeepSeek V4 Flash -> Mimo V2.5 (perso, HARNESS/dsh-vps, tt, nyora)
**Date** : 2026-08-17
**Portee** : hermes-perso, hermes-HARNESS (dsh-vps, VPS Contabo), hermes-tt, hermes-nyora.
## Pourquoi
Changement tarifaire DeepSeek V4 Flash cote OpenCode. Mimo V2.5 deja valide en
production sur d'autres usages (extraction documentaire nyora-convert-api,
scoring broll_coherence_qc.py, et deja pilote comme cerveau sur hermes-nyora
depuis le 15/07 -- voir `hermes-nyora/verdict-pilote-mimo-v25.md`). Cette
migration etend son role au cerveau par defaut des 4 instances Hermes.
## Ce qui a ete decouvert en route (motif transverse, meme cause a chaque fois)
Chaque instance a livre une surprise differente de ce que la config versionnee
(git) ou la doc annoncait -- **meme cause a chaque fois : des valeurs de
configuration jamais revalidees contre le comportement reel du provider.**
1. **Git desynchronise du live** (nyora, puis perso, puis tt) -- le fichier
`data/config.yaml` commite ne refletait pas la config reellement chargee
par le conteneur (bascules faites en live sans commit). Reconciliation
faite instance par instance avant toute nouvelle ecriture.
2. **Mecanisme d'auth key_env casse sur le chemin Bifrost `provider: custom`**
(tente sur hermes-nyora) -- substituer `api_key` litteral par `key_env` a
casse l'authentification Bifrost (`401 virtual_key_not_found`, fallback
silencieux vers deepseek-v4-flash). Rollback propre effectue. Root cause
probable : construction differente du header (`Authorization: Bearer` vs
`x-bf-vk`) selon le champ utilise -- **non resolu**, cf `bifrost-access.md`
(Bifrost exige `x-bf-vk`, rejette `Authorization: Bearer` en 401). A
reprendre cote code/config Hermes avant nouvelle tentative. Le secret
`bfk-...` reste donc en clair dans le `config.yaml` live de nyora --
dette assumee, pas corrigee de force.
3. **`context_length: 128000` / `max_tokens: 8192` herites de DeepSeek, jamais
recalibres pour mimo-v2.5** -- objet du present runbook (detail ci-dessous).
## Pattern de bascule retenu (Pattern A)
Pour perso/tt/nyora : `model.default` -> `provider: opencode-go`, `api_key`/
`base_url` vides (resolution automatique via `OPENCODE_GO_API_KEY`), PAS
`provider: custom`/`bifrost-proxy` (chemin casse, cf point 2 ci-dessus).
Seul hermes-HARNESS (dsh-vps) route reellement via Bifrost par construction
(`provider: bifrost` dans `settings.yaml`, VK `vk-dsh-vps`) -- c'est le
pattern attendu et documente pour cette instance, aucune ambiguite.
## Correction context_length / max_tokens (2026-08-17)
**Symptome** : le couple `mimo-v2.5`/`opencode-go` dans la table Bifrost
`governance_model_pricing` est **totalement vide** (aucune limite renseignee)
-- ce n'est donc pas une source fiable pour calibrer le yaml. La valeur
`128000`/`8192` presente sur toutes les instances etait une copie du bloc
DeepSeek d'origine, jamais revalidee.
**Source de verite retenue** : specs constructeur croisees (Xiaomi officiel,
OpenRouter, HuggingFace, Requesty) -- convergent sur un contexte tres
superieur (262k a 1M tokens selon l'hebergeur) et un plafond de sortie de
l'ordre de 131k tokens. **Ne pas reprendre les valeurs deepseek-v4-flash**
(1M / 384k) -- specs d'un autre modele, les copier aurait cree une nouvelle
valeur fausse dans l'autre sens (plafond de sortie surdeclare ~3x).
**Valeurs appliquees** (bloc `model:`, `key_env`/`api_key` non touches) :
```
context_length: 1048576
max_tokens: 131000 # dsh-vps : contextWindow / maxTokens (meme valeurs)
```
**Resultat par instance** (ordre de bascule : perso -> HARNESS -> tt -> nyora) :
| Instance | Avant | Apres | Verification |
|---|---|---|---|
| hermes-perso | 128000/8192 | 1048576/131000 | `model_used=mimo-v2.5` confirme, `finish_reason=stop`, aucune erreur. Commit `bolbol/hermes-perso@0c64f40`. |
| hermes-HARNESS (dsh-vps) | contextWindow 131072/maxTokens 8192 | 1048576/131000 | Logs Bifrost (`vk-dsh-vps`) : appels post-restart `model=mimo-v2.5, status=success`, aucune erreur. Pas de repo git pour ce fichier (volume Docker nomme, sauvegarde horodatee `.bak-ctxfix-20260817` seule trace). UID/GID VPS = `1001:1001` (PAS la convention NAS `1026:100`). |
| hermes-tt | 128000/8192 | 1048576/131000 | Logs internes gateway : `API call #1: model=mimo-v2.5 provider=opencode-go ... finish_reason=stop`. **Piege methodologique** : le modele s'est auto-declare a tort `deepseek-v4-flash` quand on lui demandait son propre nom en JSON -- l'auto-declaration d'un LLM sur son identite n'est PAS une source fiable, toujours verifier par les logs internes/gateway. Commit `bolbol/hermes-tt@0015ab5`. |
| hermes-nyora | 128000/8192 | 1048576/131000 | Logs Bifrost (`Nabil-Key`) : `model=mimo-v2.5, status=success, stop_reason=stop`. Secret en clair (`api_key: bfk-...`) laisse intact (dette separee, point 2). Commit `bolbol/hermes-nyora@4067a85`. |
Aucun repli necessaire sur aucune instance -- 1048576/131000 accepte partout
sans erreur de limite cote opencode-go/Bifrost au premier essai.
## Points restes ouverts (proprietaire a designer, pas noyes dans ce runbook)
- **Secret Bifrost en clair sur hermes-nyora** (`api_key: bfk-...`, x2 dans le
yaml live) + **mecanisme d'auth key_env casse sur le chemin Bifrost custom**
+ **VK dediee `BIFROST_VK_HERMES_NYORA` provisionnee le 18/07 jamais cablee**
-- trois symptomes du meme sujet non traite (routage Bifrost/Nabil-Key de
nyora jamais finalise proprement). A cadrer en session dediee.
- **Few-shot des skills AO/RLA sur hermes-tt** (`dco-generation-tt`,
`courriers-officiels-tt`, `gsd-ao-evaluation`) -- la regle anti-inference
est deja en place et confirmee respectee par mimo-v2.5 en test reel, mais
les exemples few-shot restent a peupler avec Nabil (`references/exemples-
valides/`, note deja ecrite dans les skills eux-memes -- explicitement pas
a faire par un agent seul).
## Voir aussi
`hermes-nyora/verdict-pilote-mimo-v25.md`, `hermes-tt/passation-pj-hermes-tt-deepseek-mimo.md`,
`common/bifrost-access.md`, `common/bifrost-vk-incidents.md`, `common/opencode-go-migration.md`.
## Yesmine-Key (VK Bifrost, hermes-desktop-yesmine — client pas encore actif)
**Perimetre** : uniquement la VK Bifrost `Yesmine-Key` (id `028c7103-cc9f-4139-96a1-3d5420b2d2dd`).
Aucune instance NAS ni fichier agent — toute la config vit en DB Bifrost
(`governance_virtual_key_provider_configs`).
**Etat trouve (Phase 1, verifie en live, rien suppose)** :
- `allowed_models` (provider `opencode`, row id=38) = `["deepseek-v4-flash"]` uniquement —
mimo-v2.5 absent malgre une decision anterieure supposee (audit du 17/08). `allow_all_keys`
deja a 1 (pas de correction necessaire la-dessus).
- Aucun concept de "modele par defaut" par VK cote Bifrost : schema `governance_virtual_keys`
n'a pas de champ modele ; `routing_rules`/`routing_targets` ne referencent aucun `virtual_key_id`
scope sur Yesmine-Key. Seul filtre existant = `allowed_models`. Le seul enregistrement scope
sur cette VK dans `governance_model_configs` est un rate-limit generique (`model_name='*'`), pas
un modele par defaut.
- Pas de concept context_length/max_output au niveau VK — ces valeurs sont globales par modele
(`governance_model_pricing`), deja documente vide pour `mimo-v2.5/opencode-go` plus haut dans ce
runbook. Hors perimetre de corriger cette table globale ici (deja couverte par les valeurs en dur
1048576/131000 appliquees sur les yaml de la flotte ; Bifrost lui-meme ne bloque pas sur cette
table vide, confirme par le test Phase 3 ci-dessous).
**Correction appliquee (Phase 2, edition DB directe — PAS l'API governance, piege `allow_all_keys`
reset connu)** :
```sql
UPDATE governance_virtual_key_provider_configs
SET allowed_models = '["mimo-v2.5"]'
WHERE id = 38 AND virtual_key_id = '028c7103-cc9f-4139-96a1-3d5420b2d2dd' AND provider = 'opencode';
```
`docker restart bifrost` obligatoire (chargement DB au boot, memoire vive garde l'ancien etat sinon)
— confirme healthy apres ~50s.
**Test Phase 3 (controle minimal, hors tool-calling — pas de client reel a simuler)** :
- Appel direct `x-bf-vk` vers `mimo-v2.5` : `resolved_model_used: mimo-v2.5`, `finish_reason: stop`,
aucune erreur.
- Verification du retrait reel (pas juste un ajout) : appel `deepseek-v4-flash` sur la meme VK →
rejete (`could not auto resolve a provider for the request`) — confirme que le retrait est effectif,
pas seulement documentaire.
**Trace** : ce changement n'existe qu'en DB Bifrost (`config.db`, table
`governance_virtual_key_provider_configs`), aucun fichier Git associe — pas de repo pour cette
config, contrairement aux instances Hermes. Cette entree de runbook est la seule trace ecrite du
changement, a ne pas oublier lors d'une future migration modele generale sur Bifrost.
**Point ouvert** : `Yesmine-Key` reste provisionnee sans consommateur actif — aucun agent/client
n'appelle cette cle aujourd'hui (`hermes-desktop-yesmine` n'existe pas encore cote Windows/Claude
Desktop). A reevaluer (usage reel, cout, modele par defaut souhaite) quand ce client devient actif.
## Suite (2026-08-18) — Straggler nyora-veille (traduction titres) + Nabil-Key/Tirith a trancher
**Contexte** : sweep demande par Nabil pour reperer tout reliquat DeepSeek V4 Flash apres la
migration cerveau du 17/08 ci-dessus. Analyse logs Bifrost (`logs.db`) sur une fenetre test
07h02-07h12 (heure locale) -> 44 appels `deepseek-v4-flash` releves, 2 sources distinctes.
**Trouvaille 1 (fixee)** : `nyora-veille/backend/routers/opportunites.py`, fonction
`_translate_titre_fr()` (traduction des titres d'articles a l'ingestion) avait
`"model": "deepseek-v4-flash"` code en dur, hors de la constante `MODEL = "mimo-v2.5"` deja
utilisee par le reste du service -- oubli isole, pas un choix delibere. En corrigeant, **meme
piege deja documente le 17/08** (context_length/max_tokens herites) : `max_tokens: 120` etait
insuffisant pour mimo-v2.5 (modele reasoning, ~150-190 tok de raisonnement consommes avant le
contenu final) -> reponse tronquee -> repli silencieux sur le titre original a chaque appel (le
`except: return titre` avale l'echec sans logger). Corrige a `max_tokens: 500`, verifie en
direct (traduction correcte, log Bifrost confirme `model=mimo-v2.5`). **Latence x8-10** (1-2s ->
11-18s/appel) a surveiller sur le prochain run 3x/jour (boucle sequentielle dans `ingest_batch`,
pas de parallelisation). Commit `bolbol/nyora-veille@08cd09e`.
**Trouvaille 2 (PAS touchee, decision a prendre avec Nabil)** : virtual key `Nabil-Key`, prompt
"security reviewer for an AI coding agent" (garde-fou Tirith avant execution de commande shell)
-- toujours sur `deepseek-v4-flash`. Source introuvable sur le filesystem NAS (grep infructueux
dans hermes-platform/*/config, workspace, scripts) -- probablement cuit dans l'image agent, pas
dans un fichier monte/versionne. **Volontairement pas migre** : c'est un garde-fou de securite
sur le chemin critique (avant CHAQUE commande shell), et mimo-v2.5 ajoute 10-15s de latence par
appel (reasoning) -- risque de ralentir/bloquer visiblement les agents si applique sans
reflexion prealable. A trancher : cout (raison de la migration globale, cf tarification
DeepSeek en tete de ce runbook) vs latence sur un chemin de securite. Ne pas migrer sans
validation explicite de Nabil.
**Regle generale retenue** : apres toute migration de modele par defaut, chercher aussi les
appels Bifrost HORS de la config centrale (model code en dur dans du code applicatif, comme
ici) -- une migration "config.yaml" ne couvre pas ces cas ; seul un balayage des logs Bifrost
(`logs.db`, table `logs`, colonnes `model`/`virtual_key_name`/`timestamp`) sur une fenetre
temporelle les revele de facon fiable.
## DECISION -- Tirith reste sur DeepSeek V4 Flash, exception assumee (2026-08-18)
Nabil valide : le garde-fou Tirith (`Nabil-Key`, reviewer de securite avant execution de
commande shell) **reste sur `deepseek-v4-flash`**, ce n'est pas un oubli a corriger mais une
exception deliberee. Chiffres qui ont motive la decision (verifies en base Bifrost `logs.db`,
pas estimes) : journee la plus chargee recente (17/08, migration cerveau en cours) = 245 appels
Tirith pour 0,49$ au total, latence moyenne deja 5-15s cote DeepSeek selon la commande revue.
Extrapolation pire cas ~15$/mois -- marginal face au motif de la migration globale (tarification
DeepSeek). Migrer vers mimo-v2.5 (reasoning, +10-15s/appel mesures) degraderait la latence sur
le chemin le plus chaud de la flotte (avant CHAQUE commande shell, sans exception), pour un gain
cout negligeable. Argument de fond independant du prix : Tirith fait de la classification rapide
(commande dangereuse ou non, vigilance injection de prompt), pas du raisonnement multi-etapes --
profil de tache ou un modele rapide est mieux adapte qu'un modele reasoning.
**Condition de reevaluation, posee explicitement par Nabil** : revisiter ce choix si le cout de
Tirith sur DeepSeek V4 Flash devient juge insupportable (pas de seuil chiffre fixe a ce jour --
a definir si/quand la question se represente, en comparant le cout reel cumule DeepSeek vs
l'estimation cout+latence d'un passage a mimo-v2.5). Tant que ce seuil n'est pas atteint, ne pas
rouvrir cette question sans element nouveau (hausse tarifaire DeepSeek, volume Tirith en forte
hausse, etc.).
## État au 2026-08-17 — dette ouverte (consolidation, verification finale)
Section unique de cloture, verifiee le 2026-08-18 en reprise de session (rate limit interrompu
puis reinitialise) -- regroupe tout ce qui etait jusqu'ici disperse entre plusieurs sections de
ce runbook, sans rien ajouter de nouveau sur le fond. Chaque ligne ci-dessous est verifiable
individuellement -- fait confirme distingue de ce qui reste suppose.
**Les 5 cibles migrees et confirmees** (detail complet plus haut dans ce runbook) :
hermes-perso, hermes-HARNESS (dsh-vps), hermes-tt, hermes-nyora, Yesmine-Key (VK Bifrost).
**Phase 1 -- Coherence git/live, verification finale (2026-08-18)** : comparaison directe entre
le dernier commit pousse sur `bolbol/hermes-<instance>:data/config.yaml` et l'etat reellement
charge dans le conteneur (`model.default`, `context_length`, `max_tokens`), sur les 3 instances
Hermes concernees (dsh-vps hors sujet, pas de repo git pour ce fichier). **Aucun ecart trouve** :
- hermes-tt : commit `5aa8199` = live (`mimo-v2.5` / `opencode-go` / `1048576` / `131000`).
- hermes-perso : commit `5c055eb` = live (memes valeurs).
- hermes-nyora : commit `a4d35f4` = live sur les champs cibles ; seul `api_key` differe par
construction (placeholder `REDACTED-live-only...` en git vs secret litteral en live) -- ecart
deliberement maintenu, deja documente ci-dessus (point 2), pas un nouvel ecart.
**Phase 2 -- Plafond de sortie confirme en usage reel (hermes-tt)** : demande de generation
longue et structuree (document technique 12 sections, via l'interface habituelle, prompt neutre
sans donnee metier). Resultat : `completion_tokens: 18831`, `finish_reason: stop` -- generation
effective d'un document de 60 Ko sans troncature, tres au-dela de l'ancien plafond de 8192.
Confirme en usage reel, pas seulement en absence d'erreur sur un appel minimal.
**Phase 3 -- Test Baserow en conditions reelles, lecture seule (perso / tt / nyora)** : question
posee via l'interface habituelle de chaque agent, avec consigne explicite de verifier en
direct plutot que de repondre depuis la memoire.
- **hermes-perso** : appel outil reel confirme (`prompt_tokens: 185368`), chiffres precis croises
sur 2 bases Baserow / 6 tables (ex. 57/56/55 marches selon la table). Pas un snapshot fige.
- **hermes-nyora** : reponse explicite *"requete directe sur Baserow (JWT, pas de memoire)"*,
memes chiffres croises retrouves independamment (`prompt_tokens: 256913`).
- **hermes-tt** : cas le plus demonstratif -- le modele a lui-meme distingue son snapshot fige
embarque (55) de la valeur live obtenue par appel reel (56), et l'a signale explicitement dans
sa reponse (*"le snapshot embarque indiquait 55 -- il y en a maintenant 56"*). Confirme sans
ambiguite que l'agent interroge Baserow en direct en usage courant, pas seulement en test isole.
Les trois appels de Phase 3 ont depasse tres largement l'ancien plafond `context_length: 128000`
(jusqu'a 689638 tokens de prompt sur un appel tt) -- preuve vivante supplementaire, en usage
reel cette fois, que la correction de la Phase 2 (17/08) etait necessaire et pas cosmetique.
**Items restes hors perimetre ce soir (constat, pas de correction tentee)** :
| Item | Raison du report | Ce qu'il faudra pour debloquer |
|---|---|---|
| Secret Bifrost en clair sur hermes-nyora (`api_key: bfk-...` x2 dans le yaml live) | Necessite un vrai correctif du mecanisme d'auth key_env/Bifrost (cf point 2 plus haut), pas une nouvelle tentative ce soir -- la premiere tentative a casse l'authentification et a ete rollback proprement | Investigation cote code/config Hermes sur la construction du header (`Authorization: Bearer` vs `x-bf-vk`) selon le champ utilise, avant nouvel essai |
| Session few-shot AO/RLA sur hermes-tt (`dco-generation-tt`, `courriers-officiels-tt`, `gsd-ao-evaluation`) | Necessite Nabil directement (deja ecrit dans les skills eux-memes : "pas depuis mcp-nas seul") -- pas un blocage technique, une decision deja prise de le faire en session dediee | Selection de 2-3 documents Zone Sud deja valides par type, avec Nabil |
| VK dediee `BIFROST_VK_HERMES_NYORA` provisionnee le 18/07, jamais cablee dans `config.yaml` (nyora continue d'utiliser `Nabil-Key` partagee) | Decision a trancher (basculer nyora sur sa propre VK dediee), pas a executer ce soir -- lie au meme sujet non traite que le secret en clair | Decision explicite : basculer maintenant, ou assumer `Nabil-Key` partagee plus longtemps |
| Panne `nvidia_nim` sur Bifrost (404 sur tout appel, reconfirme en direct le 17/08 lors du refus d'ajouter des "gratuits nvidia_nim" a Yesmine-Key) | Dette preexistante deja documentee ailleurs (memoire infra `bifrost-keys-config-json`, 38 jours), reconfirmee mais pas retentee ce soir -- aucun modele nvidia_nim gratuit ou payant ne repond via Bifrost actuellement | Diagnostic du routage `nvidia_nim` cote Bifrost (`base_url: https://integrate.api.nvidia.com/v1`) -- hors perimetre de cette migration |
**Note de coherence** : le sujet "Suite (2026-08-18)" plus bas dans ce runbook (straggler
nyora-veille + decision Tirith) est **deja resolu**, pas un 5e item ouvert -- mentionne ici
uniquement pour eviter toute confusion entre ce qui reste a trancher (tableau ci-dessus) et ce
qui a deja ete tranche par Nabil le meme jour.
**ports-registry.md** : les 3 lignes hermes-agent-tt/nyora/perso affichaient deja "Mimo V2.5"
au moment de cette verification (fichier modifie le 18/08 a 15:30, avant la reprise de cette
session a 21:16 -- probablement une edition manuelle anterieure, pas cette tache). Contenu
confirme exact (backup du 25/07 confirmant qu'il indiquait bien "DeepSeek V4 Flash" avant),
seule la date d'en-tete etait restee a "12/07/2026" -- corrigee.