3.8 KiB
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
GoUsageLimitErrorsur flash : le plafond OpenCode se fait déjà toucher. - 270 replis
fallback_index=1sur flash ;attempt_trailvide → 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)
- Créer les clés virtuelles par consommateur, distribuer dans les .env, redémarrer les clients.
- Trouver et corriger l'émetteur des 401.
- 7 jours de collecte attribuée, puis tableau coût/mois par consommateur (requête ci-dessus).
- Définir les besoins texte à partir des données mesurées (piste : exécution-outils / rédaction / raisonnement-agentique / vision-OCR / extraction structurée).
- Seulement ensuite : sélecteur type nyora_models.py côté Bifrost, avec repli journalisé.
Pièges
attempt_trailest 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 colonnesvalueen clair.
Gabarit du sélecteur : VPS hermes-nabil /data/nyora/nyora_models.py + section 7 de
common/hermes-nabil-images-flyers-navigateur.md.