Files
nas-runbooks/common/bifrost-routage-par-cout.md
T

6.7 KiB
Raw Blame History

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

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 426/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.


DÉPLOIEMENT FAIT (18/07/2026, session vacances)

13 clés virtuelles créées et actives : vk-hermes-tt/nyora/perso, vk-n8n, vk-veille-infra, vk-veille-nexum, vk-redaction-pro, vk-family-help, vk-nyora-veille, vk-gsparc-mezzouna, vk-reglement-definitif, vk-nyora-doc-api, vk-nyora-notes (les 2 derniers = consommateurs découverts dans les logs, absents de l'inventaire initial). Valeurs dans /volume1/docker/hermes-platform/.env (BIFROST_VK_*). Providers clonés de Nabil-Key.

Pilote actif : redaction-pro route sur vk-redaction-pro (nginx.conf, backup .bak_vk_20260718). Premier consommateur attribuable dans logs.db. Comparer coût/qualité à J+7.

Pièges rencontrés

  • L'API governance IGNORE allow_all_keys en POST ET en PUT (stocké 0) → fix obligatoire : UPDATE governance_virtual_key_provider_configs SET allow_all_keys=1 WHERE virtual_key_id IN (SELECT id FROM governance_virtual_keys WHERE name LIKE 'vk-%') + restart bifrost (config governance cachée en mémoire, l'UPDATE seul ne suffit pas). Sans ça : 400 "no keys found for provider".
  • mcp-nas ne peut pas écrire les fichiers root de /mnt/docker → édition via container éphémère : docker run --rm -v /volume1/docker:/w alpine sh -c '...' (clé lue depuis .env dans le container, jamais affichée).
  • SSH mcp-nas → NAS : la clé existe dans /root/.ssh/mcp-nas-bestof avec alias ssh nas-host (config déjà en place — ne pas conclure trop vite à la clé perdue).
  • bifrost-proxy log des [emerg] "host not found in upstream" à chaque boot NAS (course avec bifrost) mais s'auto-répare via restart:always ~20 min après. Pas d'action requise, ne pas paniquer sur ces logs.
  • /volume1/docker/hermes-platform/.env est en 777 (piège chmod documenté) — à corriger avec précaution (vérifier qui lit le fichier et sous quel uid) au retour.

401 : état après enquête

Émetteurs (96 h) : redaction-pro (31 — clé pourtant VALIDE : autre chemin de code à trouver, l'attribution par clé rendra le coupable visible), nyora-doc-api (12), nyora-notes (8), veille-backend (3), n8n (2). Pas une clé morte unique : plusieurs chemins de code défaillants. La bascule par consommateur est le bon outil de diagnostic.

SÉCURITÉ — rotations requises (exposition en clair le 18/07)

  1. Clé provider OpenCode (BIFROST_OPENCODE_KEY) — affichée dans un traceback.
  2. Token Cloudflare Workers AI (redaction-pro nginx.conf, location /api/cf/) — affiché malgré masquage partiel. Rotation des deux au retour + mise à jour .env/nginx.conf.

Reste à faire (retour de vacances)

  • Basculer hermes ×3 (localiser où chaque agent stocke sa clé Bearer), n8n (credential), gsparc, family-help, nyora-veille, veille-infra/nexum, doc-api, notes → chacun sa clé.
  • Élucider le chemin 401 de redaction-pro (la moitié de son trafic échoue).
  • J+7 : tableau coût/consommateur (requête de référence ci-dessus) puis définition des besoins.