"""Garde-fou de non-régression pour l'équilibrage du corpus (voir `training_data.py`'s propre commentaire de tête) : un textcat entraîné sur des classes très inégales en nombre d'exemples est une source réelle de classifications confiantes mais fausses sur une phrase jamais vue (constaté en pratique — voir l'historique Git de ce fichier). `_MIN_UTTERANCES_PER_LOCALE` est volontairement `12`, pas `20` : la génération vise `20` (`augment_utterances.py`'s `_TARGET`) mais s'arrête avant si la technique n'a pas assez de vocabulaire distinctif propre (`synonyms`) pour l'atteindre sans retomber massivement sur des tournures génériques partagées par toutes les classes — une première version de ce script forçait `20` partout via ce mécanisme et a mesurablement *dégradé* `test/recipe-matching/tech-step-eval.test.ts` (F1 agrégé) plutôt que de l'améliorer, en réduisant la séparabilité entre classes plus qu'en ajoutant un vrai signal. `12` reste très au-dessus du plancher d'origine (3-7) tout en laissant `augment_utterances.py` s'arrêter honnêtement plutôt que de forcer un compte rond au prix de la qualité.""" from intent_service.training_data import TECH_STEP_TRAINING_DATA _MIN_UTTERANCES_PER_LOCALE = 12 def test_every_technique_has_at_least_the_minimum_utterances_per_locale(): short = [ (entry.uid, locale, len(getattr(entry, locale).utterances)) for entry in TECH_STEP_TRAINING_DATA for locale in ("fr", "en") if len(getattr(entry, locale).utterances) < _MIN_UTTERANCES_PER_LOCALE ] assert short == [], ( f"{len(short)} (uid, locale) pair(s) below the {_MIN_UTTERANCES_PER_LOCALE}-utterance " f"floor: {short}" )