Skip to content

feat(llm): l'ordre des modèles choisi dans l'admin est appliqué littéralement - #62

Merged
ijdan merged 4 commits into
mainfrom
claude/gemini-quota-issue-w6h299
Aug 3, 2026
Merged

feat(llm): l'ordre des modèles choisi dans l'admin est appliqué littéralement#62
ijdan merged 4 commits into
mainfrom
claude/gemini-quota-issue-w6h299

Conversation

@ijdan

@ijdan ijdan commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Suite de la #61. Quatre commits, rebasés sur main après son merge.

1. L'ordre de la page admin fait autorité, sans aucune déduction

C'est le cœur de cette PR. L'ordre défini dans /admin est sollicité tel quel à chaque appel LLM : ni tri, ni purge des modèles inconnus, ni insertion automatique des nouveaux.

Le mécanisme de migration introduit dans la #61 est entièrement supprimé — MODEL_PRIORITY_VERSION, merge_model_priority() et le champ model_priority_version (Firestore, API, frontend). resolve_model_priority() le remplace, avec un seul comportement par défaut : amorcer un projet neuf sur DEFAULT_MODEL_PRIORITY quand aucun ordre n'a encore été choisi.

GET /admin/settings redevient en lecture seule : il restitue l'ordre stocké sans le réécrire. Seul le PUT (boutons ▲▼) modifie model_priority.

Un modèle hors catalogue est signalé dans les logs mais tout de même sollicité — c'est le choix de l'administrateur, pas au code de l'écarter.

Conséquences assumées :

  • modifier DEFAULT_MODEL_PRIORITY n'a plus aucun effet sur un projet existant ;
  • un nouveau modèle ajouté côté code n'apparaît pas tout seul dans la liste.

2. Les trois lecteurs de model_priority sont alignés

get_model_priority() (bouton « Régénérer le résumé IA ») lisait l'ordre brut de Firestore sans contrôle : il pouvait solliciter un autre modèle que la collecte tant que la page admin n'avait pas été ouverte.

Les trois chemins — page admin, collecte/synthèse, résumé à la demande — passent désormais par la même fonction. Vérifié par simulation sur un ordre volontairement contraire au classement par coût, pour s'assurer que rien ne le « corrige » :

Choisi dans l'admin : ['gemini-3.5-flash', 'gemma-4-26b-a4b-it', 'gemini-3.1-flash-lite']
Page admin          : identique
Bouton Résumé IA    : identique
Collecte/synthèse   : identique

3. Un 429 de débit n'est plus pris pour un compte bloqué

Régression introduite par la #61 : le marqueur billing était trop large. Tous les 429 de Gemini contiennent « check your plan and billing details », y compris un simple dépassement de débit. Un projet correctement crédité voyait donc sa cascade interrompue au premier modèle, avec un message l'invitant à recharger son compte.

Marqueurs restreints aux signaux spécifiques (crédits prépayés épuisés, compte suspendu), plus un veto explicite : un message nommant une métrique de quota décrit un débit dépassé, la cascade doit monter d'un cran. En cas de doute, on ne bloque pas.

Dette réduite au passage

DEFAULT_MODEL_PRIORITY existait en quatre exemplaires, dont un non documenté (article_summarizer.py) resté sur un ordre périmé. Il n'en reste que deux — un par service — et un test vérifie qu'ils ne divergent pas. admin.py, collector/main.py et analyze_logs.py importent.

Après le déploiement

L'ordre stocké en base est celui de juillet (gemini-3.5-flash en tête). Puisque plus rien ne le réécrit, il restera tel quel : le régler depuis la page admin est désormais le seul moyen de le changer.

Tests

11 tests ajoutés ou réécrits : ordre appliqué littéralement, aucun modèle inséré ni retiré, amorçage sur liste vide, distinction facturation / débit sur le message réel de production. Deux tests qui figeaient l'ancien comportement de migration sont remplacés.

87 passed sur la suite hors acceptance. Les 14 échecs restants sont identiques avant et après ces commits, vérifié par diff nom par nom — ils viennent de l'environnement de développement (absence de .env, d'émulateur Firestore et de réseau).


Generated by Claude Code

ijdan and others added 4 commits August 3, 2026 13:28
Le marqueur « billing » était trop large : TOUS les 429 de Gemini contiennent
« check your plan and billing details », y compris un simple dépassement de
débit. Un projet correctement crédité voyait donc sa cascade interrompue au
premier modèle avec un message l'invitant à recharger son compte.

- marqueurs de facturation restreints aux signaux spécifiques (crédits
  prépayés épuisés, compte suspendu) ;
- veto explicite : un message nommant une métrique de quota décrit un débit
  dépassé, la cascade doit monter d'un cran ;
- en cas de doute, on ne bloque pas — mieux vaut monter pour rien.

Corrige aussi les descriptions d'articles trop courtes :

- les Gemma repassent en repli de dernier recours. Les moins chers du
  catalogue, mais leurs descriptions ne tiennent pas les 4 à 6 phrases
  attendues ; la cascade ne bascule que sur erreur, jamais sur qualité, donc
  un modèle trop laconique traiterait tout le flux sans que rien ne l'indique.
  gemini-3.1-flash-lite reprend la tête (MODEL_PRIORITY_VERSION → 4) ;
- MAX_ARTICLE_CONTENT_FOR_BATCH passe de 1500 à 4000 caractères : le modèle
  n'avait pas assez de matière source pour développer. Surcoût de l'ordre de
  0,006 $ par run ;
- longueurs minimales rendues impératives dans le prompt d'enrichissement.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014s387wqjrmhJ34u8js1otm
`get_model_priority()` retournait l'ordre brut stocké en Firestore, sans
contrôle de version ni purge des modèles inconnus. Le bouton « Régénérer le
résumé IA » pouvait donc solliciter un autre modèle que la collecte tant que
la page admin n'avait pas été ouverte — c'est elle qui persiste la migration.

- `merge_model_priority()` et `MODEL_PRIORITY_VERSION` rejoignent
  `article_summarizer.py`, seule copie backend de la liste ;
- `admin.py` importe au lieu de redéfinir la liste et la logique de fusion,
  supprimant la quatrième copie ;
- `get_model_priority()` applique la même règle que les deux autres chemins.

Les trois lecteurs (page admin, collecte/synthèse, résumé à la demande)
renvoient désormais la même liste, vérifié par simulation sur un document
Firestore portant l'ordre de juillet.

Le test qui figeait l'ancien comportement est remplacé par deux cas : ordre
de l'admin respecté quand la version est à jour, migration appliquée sinon.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014s387wqjrmhJ34u8js1otm
L'ordre défini sur la page admin est désormais la seule autorité : il est
sollicité tel quel à chaque appel LLM, sans aucune déduction du code.

Suppression du mécanisme de migration introduit précédemment :

- `MODEL_PRIORITY_VERSION` et `merge_model_priority()` disparaissent, ainsi
  que le champ `model_priority_version` (Firestore, API, frontend) ;
- `resolve_model_priority()` les remplace : ni tri, ni purge des modèles
  inconnus, ni insertion automatique des nouveaux. Son seul comportement par
  défaut est d'amorcer un projet neuf sur DEFAULT_MODEL_PRIORITY quand aucun
  ordre n'a encore été choisi ;
- un modèle hors catalogue est signalé dans les logs mais tout de même
  sollicité — c'est le choix de l'administrateur, pas au code de l'écarter ;
- `GET /admin/settings` redevient en lecture seule : il ne réécrit plus
  model_priority en base, seul le PUT le fait.

Conséquence assumée : modifier DEFAULT_MODEL_PRIORITY n'a plus aucun effet
sur un projet existant. La constante ne sert qu'à l'amorçage.

Les trois chemins de lecture (page admin, collecte/synthèse, résumé à la
demande) restituent le même ordre, vérifié par simulation sur un ordre
volontairement contraire au classement par coût.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014s387wqjrmhJ34u8js1otm
Le critère 5 décrivait encore l'insertion automatique des nouveaux modèles,
et les cas limites ne couvraient ni le modèle retiré du catalogue ni le
nouveau modèle qui n'apparaît plus tout seul.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014s387wqjrmhJ34u8js1otm
@ijdan
ijdan merged commit cacd08b into main Aug 3, 2026
9 of 10 checks passed
@ijdan
ijdan deleted the claude/gemini-quota-issue-w6h299 branch August 3, 2026 13:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant