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

3.8 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.