# Bifrost — routage texte par coût : état de la mesure (18/07/2026) ## Découverte clé : la mesure existe déjà Bifrost journalise TOUT dans `/volume1/docker/bifrost/data/logs.db` (SQLite, table `logs`) : `virtual_key_name`, `model`, `prompt_tokens`, `completion_tokens`, `cost` ($ réels), `latency` (ms), `status`, `error_details`, `fallback_index`, `number_of_retries`. Aucune instrumentation à développer. Lecture en RO : ``` sqlite3 'file:/volume1/docker/bifrost/data/logs.db?mode=ro' ``` Depuis mcp-nas : chemin `/mnt/docker/bifrost/data/logs.db`, via `python3 -c` (sqlite3 CLI absent). ## Requête de référence — coût 30 j par clé × modèle ```sql SELECT COALESCE(virtual_key_name,'(aucune)'), model, COUNT(*), SUM(prompt_tokens), SUM(completion_tokens), ROUND(SUM(cost),4), SUM(CASE WHEN status!='success' THEN 1 ELSE 0 END) FROM logs WHERE timestamp >= datetime('now','-30 days') GROUP BY 1,2 ORDER BY 6 DESC; ``` Coût par tâche aboutie : `AVG(cost) WHERE status='success' AND cost>0`, par modèle. ## Constats (30 j au 18/07/2026) - Dépense totale ≈ **1,47 $/30 j** (~15 % du plafond OpenCode 10 $). Pas d'urgence budgétaire. - deepseek-v4-flash : 774 succès, **1,38 m$/tâche**, 1 942 tok sortie moy, 22,6 s. - kimi-k2.6 : 93 succès, **3,99 m$/tâche** (2,9× flash) pour 909 tok sortie — confirme que le prix affiché au token ne prédit pas le coût par tâche. - 22× HTTP 429 `GoUsageLimitError` sur flash : le plafond OpenCode se fait déjà toucher. - 270 replis `fallback_index=1` sur flash ; `attempt_trail` vide → destination du repli non tracée. ## BLOQUANT attribution : une seule clé pour tout Seules 2 clés virtuelles actives (`Nabil-Key`, `Yesmine-Key`). Tous les consommateurs (hermes ×3, crons veille, n8n, apps) partagent Nabil-Key → coût par consommateur IMPOSSIBLE. `metadata` vide, `raw_request` vide. Prérequis n°1 avant tout routage : **une clé virtuelle Bifrost par consommateur** (hermes-tt / hermes-nyora / hermes-perso / n8n / veille-infra / veille-nexum / redaction-pro / family-help / nyora-veille / gsparc-mezzouna / reglement-definitif). Zéro code — config governance Bifrost + .env clients. ## Incident en cours : 879× 401 en 30 j `virtual_key_not_found` (784) + `virtual_key_required` (95), encore 4–26/jour cette semaine, pic 328 le 11/07. Le client demande `deepseek-v4-flash` avec une clé absente de la DB — probablement l'ancienne clé `yesmine-hermes-desktop` (vue dans les logs, absente de config.db) ou une clé rotée. Un service croit appeler le LLM et échoue en silence depuis des semaines. Identification : `docker logs bifrost` → IP source 172.27.x.x → container (réseau n8n). ## Protocole de mesure retenu (AVANT toute ligne de routage) 1. Créer les clés virtuelles par consommateur, distribuer dans les .env, redémarrer les clients. 2. Trouver et corriger l'émetteur des 401. 3. 7 jours de collecte attribuée, puis tableau coût/mois par consommateur (requête ci-dessus). 4. Définir les besoins texte à partir des données mesurées (piste : exécution-outils / rédaction / raisonnement-agentique / vision-OCR / extraction structurée). 5. Seulement ensuite : sélecteur type nyora_models.py côté Bifrost, avec repli journalisé. ## Pièges - `attempt_trail` est vide dans cette version de Bifrost : la cible réelle d'un repli ne se lit pas dans logs.db — journaliser côté sélecteur. - Comparer m$/tâche entre modèles n'a de sens qu'À BESOIN ÉGAL (mimo-v2.5 affiche 0,53 m$/tâche mais sur des tâches à 84 tok de sortie — biais de sélection). - config.db : clés provider en `plain_text` — ne jamais SELECT les colonnes `value` en clair. Gabarit du sélecteur : VPS hermes-nabil `/data/nyora/nyora_models.py` + section 7 de `common/hermes-nabil-images-flyers-navigateur.md`.