Sans contexte, le modele rendait « Playwright » en « PlayWreck », « iCloud » en « Auriclaw », « Supabase » en « Supabass », « Vercel » en « Versell » : 4 termes sur 5 faux, mesure sur audio reel. Avec l'amorce (initial_prompt), les 5 sont corrects, sans changer de modele ni ralentir (1,3 s). Passer a large-v3-turbo a ete teste et ecarte : PIRE sur le meme echantillon (« commit sur Gitea » -> « commis sur JTA », « Stripe » -> « Trip »), pour 1,5 Go de plus. C'est l'amorce qui paie, pas la taille du modele. VOCABULAIRE est une simple liste a completer dans core.py. Whisper ne lit que ~224 tokens d'amorce et tronque le reste EN SILENCE : la longueur est donc bornee explicitement, pour qu'un ajout de termes ne soit jamais sans effet a l'insu de celui qui l'ecrit (47 termes = 416 caracteres sur 800). 34 tests passent (27 + 7 nouveaux). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
51 lines
1.8 KiB
Python
51 lines
1.8 KiB
Python
"""Amorce de vocabulaire passee a Whisper.
|
|
|
|
Contexte (bug du 2026-08-21) : sans contexte, le modele rend « Playwright » en
|
|
« PlayWreck », « iCloud » en « Auriclaw », « Supabase » en « Supabass » et
|
|
« Vercel » en « Versell » — mesure sur audio reel, 4 termes sur 5 faux. En
|
|
passant la liste des termes metier en initial_prompt, les 5 redeviennent
|
|
corrects sans changer de modele.
|
|
|
|
Contrainte : Whisper ne lit que ~224 tokens d'amorce et TRONQUE le reste en
|
|
silence. La longueur est donc bornee, sinon les derniers termes ajoutes ne
|
|
servent a rien sans qu'on le sache.
|
|
"""
|
|
from core import CONFIG, VOCABULAIRE, PROMPT_MAX_CARACTERES, build_initial_prompt
|
|
|
|
|
|
def test_le_prompt_contient_les_termes_qui_avaient_echoue():
|
|
p = build_initial_prompt()
|
|
for terme in ("Playwright", "iCloud", "Supabase", "Vercel", "Convex"):
|
|
assert terme in p
|
|
|
|
|
|
def test_le_prompt_tient_sur_une_seule_ligne():
|
|
# un retour a la ligne coupe l'amorce cote Whisper
|
|
assert "\n" not in build_initial_prompt()
|
|
|
|
|
|
def test_le_prompt_respecte_la_borne():
|
|
assert len(build_initial_prompt()) <= PROMPT_MAX_CARACTERES
|
|
|
|
|
|
def test_une_liste_trop_longue_est_tronquee_pas_ignoree():
|
|
p = build_initial_prompt(["Terme%03d" % i for i in range(500)])
|
|
assert len(p) <= PROMPT_MAX_CARACTERES
|
|
assert "Terme000" in p # les premiers termes survivent
|
|
|
|
|
|
def test_les_doublons_sont_retires_en_gardant_l_ordre():
|
|
p = build_initial_prompt(["Convex", "Stripe", "Convex"])
|
|
assert p.count("Convex") == 1
|
|
assert p.index("Convex") < p.index("Stripe")
|
|
|
|
|
|
def test_le_vocabulaire_couvre_les_projets_de_ralph():
|
|
for terme in ("Convex", "Supabase", "Stripe", "n8n", "Airtable"):
|
|
assert terme in VOCABULAIRE
|
|
|
|
|
|
def test_config_expose_le_prompt():
|
|
assert CONFIG["initial_prompt"]
|
|
assert "Playwright" in CONFIG["initial_prompt"]
|