Pourquoi Gemini pour peupler le Quiz HP (free tier)
- hpq
- gemini
- adr
- llm
- api
Le joueur n'attend jamais le LLM — les questions sont générées en arrière-plan par un script CLI. Ce pivot change tout sur le choix du provider : la latence par requête devient secondaire, le quota journalier free tier devient dominant.
Articles précédents : vision · intégration · design system.
Critère de choix après le pivot « populate »
Au départ, on imagine une génération en direct : vitesse d'inférence = critère n°1. Depuis HPQ-001, le flux est :
- Script local ou cron appelle l'API
- Questions validées → Neon Postgres
- Le joueur pioche en base — zéro appel LLM en prod
Conséquence : combien de requêtes par jour pour remplir 24 combos film × difficulté, pas combien de millisecondes par token.
Chaque question consomme deux appels : génération + validation (double passe, détaillée dans un prochain article). Peupler 50 questions ≈ 100 appels minimum, plus les rejets et doublons.
Candidats comparés
- Gemini Flash / Flash-Lite — volume free tier le plus généreux à l'écrit de l'ADR (~1500 req/jour annoncé) ; JSON structuré natif via responseSchema
- Groq (Llama) — inférence ultra-rapide, pas d'entraînement sur tes données ; quota journalier inférieur (~1000 req/jour) ; vitesse devenue secondaire
- Mistral — cap mensuel tokens élevé, privacy-first ; débit ~2 req/min en free tier → peuplement très lent même en batch
Écartés sans creuser : OpenRouter (agrégateur, pas de quota propre), Cerebras (doc JSON structuré faible).
Décision : Gemini Flash-Lite pour le populate.
JSON structuré dès le SDK
Plutôt que parser du markdown libre, j'utilise @google/generative-ai avec :
responseMimeType: application/jsonresponseSchema— objet avec statement (string), answer (boolean), sujet (string snake_case)
Le modèle est contraint à la forme. Les erreurs de format restent possibles, d'où la validation en seconde passe — mais le taux de parsing manual tombe quasi à zéro.
Modèle retenu et chaîne de repli
Modèle par défaut : gemini-3.1-flash-lite — bon compromis qualité / débit sur le free tier actuel.
En pratique (populate Film 1, juillet 2026), Google decoupe les quotas par modèle sur ai.dev/rate-limit :
- 3.1 Flash Lite — ~500 req/jour → épuisé en une session de bootstrap
- 2.5 Flash — ~20 req/jour — idem
- 3 Flash Preview — ~20 req/jour — modèle de secours utile
- 2.5 Flash Lite — souvent en 503 (surcharge)
- Modèles 2.x « classiques » — quota à 0
D'où une chaîne de repli implémentée dans le code :
- gemini-3.1-flash-lite
- gemini-3-flash-preview
- gemini-2.5-flash-lite
Quand le quota journalier d'un modèle est atteint, le script bascule au suivant. Les alias corrigent les noms dashboard vs API (ex. gemini-3-flash → gemini-3-flash-preview).
Variable optionnelle : GEMINI_MODEL ou HPQ_GEMINI_MODEL — le modèle choisi reste en tête de chaîne, les autres servent de fallback.
Où tourne Gemini (et où il ne tourne pas)
- Local — GEMINI_API_KEY dans .env.local pour npm run hpq:populate
- Prod Vercel — pas de clé Gemini pour jouer ; seulement Neon
- Futur cron — HPQ_GEMINI_API_KEY prévu pour repopulation automatique (pas urgent)
Le jeu en prod ne casse pas si Google change ses quotas : pire cas, le stock ne se regarnit plus jusqu'au prochain populate manuel.
Point privacy (accepté)
En free tier, Google peut utiliser les prompts pour l'entraînement. J'ai explicitement jugé ça acceptable : le contenu généré (questions Harry Potter publiques, grounding via fiches de faits) n'est pas sensible.
Pour du contenu confidentiel, ce ne serait pas le bon tier.
Risques assumés
- Dépendance mono-provider — pas de fallback Groq/Mistral en v1 ; surveiller les changements de quota (Google a déjà réduit le free tier sans préavis par le past)
- Qualité Flash vs Flash-Lite — Flash-Lite pour le volume ; qualité medium/hard calibrée côté prompts (article à part)
- Bootstrap long — 150 questions × 2 passes ≈ 300+ appels : prévoir plusieurs jours ou plusieurs modèles en rotation
Ce que j'ai appris en peuplant
Le quota annoncé « 1500 req/jour » ne se lit pas comme un pool unique : c'est par modèle, avec des plafonds très différents. Un bootstrap agressif le même jour épuise tout.
Stratégie réaliste pour un MVP solo :
- Lancer le populate le matin, modèle par modèle
- Laisser le script top-up avec --target=50 (stock total visé, pas batch fixe)
- Reprendre le lendemain si 429 quota journalier
Suite de la série
- Stockage Neon et dédup sujet (article dédié)
- Stratégie de repopulation (cron)
- Format JSON et double passe de validation
Quiz : andrewchicout.dev.