fix(bifrost): tiers sur gpt-oss (Groq a retiré les llama) + marge de raisonnement

RAPIDE groq/llama-3.1-8b-instant → groq/openai/gpt-oss-20b ; APPROFONDI
groq/llama-3.3-70b-versatile → groq/openai/gpt-oss-120b ; replis inchangés.
Les chatbots vivaient sur le repli Gemini depuis le retrait.

gpt-oss raisonne : ses tokens de raisonnement sont décomptés de max_tokens.
REASONING_MARGIN_TOKENS (800) ajouté au budget des trois routes, et
bifrostContent() signale au journal une réponse tronquée (finish_reason
length). Le champ message.reasoning est ignoré. Défaut WORKER_MODEL aligné
sur la prod. En-têtes « Mistral Small » corrigés, PIPE-IA-DOC §11.3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AzGo8bxhHp6M9RxuAFbyLU
This commit is contained in:
Jules Neny
2026-09-28 16:48:24 +02:00
co-authored by Claude Opus 5.5
parent 288a9c9126
commit 8f94a1acda
6 changed files with 91 additions and 19 deletions
+38 -1
View File
@@ -365,7 +365,7 @@ fait ici pour ne pas tester un ALTER contre la prod sans l'avoir vérifié.
| Sujet | NAV V2 (§1-10 ci-dessus) | AEP B5 |
|---|---|---|
| LLM | Mistral Nemo, appel direct | **Bifrost** (`${BIFROST_URL}/v1/chat/completions`, header `x-bf-vk`), modèle `WORKER_MODEL` (défaut `groq/llama-3.1-8b-instant`) |
| LLM | Mistral Nemo, appel direct | **Bifrost** (`${BIFROST_URL}/v1/chat/completions`, header `x-bf-vk`), modèle `WORKER_MODEL` (défaut `groq/openai/gpt-oss-20b` depuis le 28/09, voir §11.3) |
| Scrape | crawl4ai (Python, `AsyncHTTPCrawlerStrategy`) | **fetch natif Node 22** — timeout 8 s, corps plafonné 500 Ko, extraction titre + meta description + `og:*` + texte visible tronqué à 4000 caractères, `User-Agent: AEP/2.0 contact@trans-former.fr` |
| Notification | Resend (email Jules) | **ntfy** (`POST https://ntfy.sh/$NTFY_TOPIC`) — le message ne contient JAMAIS l'email ni le texte libre du contributeur, seulement id NocoDB / nom suggéré / type / confiance |
| Seuil « 5 fiches pending » | Email si ≥ 5 en attente | **Retiré** (décision MOE : volume faible, une notif par fiche traitée suffit — à réactiver si le volume monte) |
@@ -381,3 +381,40 @@ Le mode `--dry-run` (`node enrich.js --dry-run`) lit
`worker/fixtures/dry-run-rows.json` au lieu de NocoDB, n'écrit rien, et par
défaut mock aussi le scrape et l'appel Bifrost (`DRY_RUN_LIVE=1` pour
forcer de vrais appels réseau sans jamais toucher NocoDB).
### 11.3 Modèles Groq retirés — bascule sur gpt-oss (2026-09-28)
Groq ne sert plus `llama-3.1-8b-instant` ni `llama-3.3-70b-versatile`
(404 `model_not_found` via Bifrost, constaté au test M3 du 28/09).
| Consommateur | Avant | Après | Où |
|---|---|---|---|
| Worker (`worker/enrich.js`) | `groq/llama-3.1-8b-instant` | `groq/openai/gpt-oss-20b` | prod : `WORKER_MODEL` dans `/opt/aep/.env` depuis le 28/09 ; défaut du code aligné |
| Chatbots, tier RAPIDE | `groq/llama-3.1-8b-instant` | `groq/openai/gpt-oss-20b` | `server/utils/bifrost.ts`, replis inchangés |
| Chatbots, tier APPROFONDI | `groq/llama-3.3-70b-versatile` | `groq/openai/gpt-oss-120b` | `server/utils/bifrost.ts`, replis inchangés |
| RAG Pensées (LightRAG) | `gemini-oai/models/gemini-2.5-flash-lite` | inchangé | `/opt/lightrag/.env`, hors de ce routage |
Entre le retrait et ce correctif, chaque appel chatbot partait sur le
premier repli Gemini (`stats_usage` depuis le 23/09 environ) : service
rendu, modèle primaire jamais servi.
**gpt-oss est un modèle à raisonnement.** Deux conséquences :
- la réponse porte `choices[0].message.reasoning` à côté de `content`. Les
trois routes (`chatbot`, `chatbot-reseaux`, `chatbot-taff`) et le worker ne
lisent que `content` (JSON), `usage` et `extra_fields` : le champ est
ignoré, rien n'en dépend. `chatbot-pensees` lit la réponse de LightRAG
(`response`, `references`), pas celle de Bifrost ;
- les tokens de raisonnement sont décomptés de `max_tokens`. Si le
fournisseur rend un JSON tronqué en HTTP 200, Bifrost ne bascule pas et
l'usager lit « Je n'ai pas pu analyser ta demande » (s'il le rejette en
400, le repli Gemini prend le relais : dégradé, pas cassé). Les routes chatbot ajoutent donc
`REASONING_MARGIN_TOKENS` (800) à leur budget de contenu (600 ou 700), et
`bifrostContent()` écrit un avertissement au journal quand
`finish_reason` vaut `length`. Le worker garde `max_tokens: 800` (sortie
courte, M3 passé en 1,6 s) ; à relever si `tokens_out` approche 800 dans
`stats_usage`.
**Non testé depuis Windows** (Bifrost écoute sur le loopback du VPS). Test
réel au checkpoint : un appel par route, relever `extra_fields` (modèle
réellement servi), `usage.completion_tokens`, `finish_reason`, et le
modèle inscrit dans `stats_usage` pour `/api/chatbot`.