"""E1.1 — Banc de reference commun. 400 items de classification de tickets. Trois niveaux de difficulte, verite terrain par construction : explicite : le mot-cle de la categorie est present implicite : la categorie se deduit de la situation, aucun mot-cle piege : un mot-cle d'une AUTRE categorie est present, la verite est ailleurs Ce decoupage est ce qui permet a la baseline sans IA d'etre une echelle de lecture : elle doit reussir l'explicite et echouer le reste. """ import random CATS = ["facturation", "technique", "commercial", "remerciement"] CRITERIA = { "facturation": "Paiement, facture, abonnement, prelevement, remboursement", "technique": "Bug, panne, erreur, quelque chose qui ne fonctionne pas", "commercial": "Devis, tarif, contrat, changement d'offre, avant-vente", "remerciement": "Message positif sans demande a traiter", } EXPLICITE = { "facturation": [ "Je conteste la facture {n} recue le {d}.", "Le prelevement de {m} euros du {d} est errone.", "Mon abonnement a ete facture deux fois ce mois-ci.", "Je demande le remboursement de la facture {n}.", "Le montant preleve ne correspond pas a mon abonnement.", ], "technique": [ "L'application plante des que j'ouvre le module de rapports.", "J'ai une erreur {n} au moment de valider le formulaire.", "Le bug de synchronisation signale le {d} est toujours present.", "La panne du service dure depuis {h} heures.", "L'export ne fonctionne plus depuis la mise a jour.", ], "commercial": [ "Pouvez-vous m'envoyer un devis pour {n} licences ?", "Quel est votre tarif pour une equipe de {n} personnes ?", "Je souhaite changer d'offre avant la fin du contrat.", "Nous voulons negocier le renouvellement du contrat.", "Quelles sont vos conditions tarifaires pour {n} postes ?", ], "remerciement": [ "Merci beaucoup pour votre aide sur le dossier.", "Bravo a l'equipe, tout est rentre dans l'ordre.", "Je vous remercie pour la rapidite de la reponse.", "Excellent travail, rien a signaler.", "Un grand merci, le probleme est resolu.", ], } IMPLICITE = { "facturation": [ "Ma banque m'a signale un mouvement de {m} euros que je ne reconnais pas.", "J'ai resilie en {mois} mais je vois encore des mouvements sur mon compte.", "On m'avait annonce {m} euros a la souscription, je constate autre chose.", "Le montant du {d} est parti deux fois de mon compte.", "Je n'ai jamais recu le document pour ma comptabilite du mois de {mois}.", ], "technique": [ "Depuis {h} heures, l'ecran reste blanc apres la connexion.", "Rien ne s'affiche quand je clique sur le menu de gauche.", "Le fichier que je telecharge fait zero octet a chaque tentative.", "Les chiffres affiches ne correspondent plus a ceux de la semaine derniere.", "Mes collegues voient les donnees, moi non, sur le meme compte.", ], "commercial": [ "Nous passons de {n} a {nn} personnes en janvier, comment ca se passe ?", "Avant de nous engager sur trois ans, nous voulons discuter des conditions.", "Un concurrent nous propose la meme chose pour moins cher.", "Nous evaluons plusieurs solutions avant de decider en {mois}.", "Notre engagement arrive a son terme, quelles sont les options ?", ], "remerciement": [ "Tout fonctionne parfaitement depuis votre intervention de {d}.", "Je voulais juste vous dire que la nouvelle version est tres reussie.", "Rien a demander, je passais simplement saluer le travail accompli.", "L'equipe a ete d'une efficacite remarquable, je tenais a le dire.", "Plus aucun souci de mon cote, c'etait juste pour vous le faire savoir.", ], } PIEGE = { # mot-cle present -> categorie leurre ; la verite est ailleurs "facturation": [ ("Aucun probleme technique a signaler, juste une question : pourquoi {m} euros ?", "technique"), ("Je ne cherche pas de devis, je veux comprendre la ligne a {m} euros.", "commercial"), ("Merci d'avoir repondu, mais le double prelevement est toujours la.", "remerciement"), ("Le bug est corrige, reste le montant de {m} euros preleve en trop.", "technique"), ("Pas besoin de tarif, je veux juste l'annulation de la facture {n}.", "commercial"), ], "technique": [ ("Le tarif me convient parfaitement, c'est l'application qui ne demarre plus.", "commercial"), ("Ma facture est juste, mais plus rien ne fonctionne depuis {h} heures.", "facturation"), ("Merci pour le geste commercial, malheureusement l'export reste casse.", "remerciement"), ("Aucune question de facturation : l'ecran reste bloque au chargement.", "facturation"), ("Je ne veux pas resilier, je veux juste que la synchronisation remarche.", "commercial"), ], "commercial": [ ("Aucun bug de votre cote, je veux juste un devis pour {n} postes.", "technique"), ("Ma derniere facture est correcte, ma question porte sur le renouvellement.", "facturation"), ("Merci pour le support, ma question porte sur le passage a l'offre superieure.", "remerciement"), ("Rien ne plante, je veux connaitre vos conditions pour {n} licences.", "technique"), ("Pas de remboursement a demander, seulement le tarif pour {nn} personnes.", "facturation"), ], "remerciement": [ ("Plus aucune erreur, plus aucune facture en double : merci a vous.", "technique"), ("Le devis est parfait et le probleme regle, rien d'autre a demander.", "commercial"), ("Aucun bug, aucune facture a contester, juste un grand merci.", "facturation"), ("Le remboursement est arrive, le service remarche, merci beaucoup.", "facturation"), ("Tarif clair, panne reglee : vraiment bravo a toute l'equipe.", "commercial"), ], } MOIS = ["janvier", "fevrier", "mars", "avril", "mai", "juin", "juillet", "aout", "septembre", "octobre", "novembre", "decembre"] def _fill(t, rng): return (t.replace("{n}", str(rng.randint(3, 400))) .replace("{nn}", str(rng.randint(50, 900))) .replace("{m}", str(rng.randint(12, 890))) .replace("{d}", f"{rng.randint(1,28):02d}/{rng.randint(1,12):02d}/2026") .replace("{h}", str(rng.randint(2, 72))) .replace("{mois}", rng.choice(MOIS))) def build(n_per_cell=None, seed=20260920): """400 items : 4 categories x 3 difficultes, equilibre.""" rng = random.Random(seed) items, i = [], 0 per = n_per_cell or {"explicite": 30, "implicite": 30, "piege": 40} for cat in CATS: for _ in range(per["explicite"]): k = rng.randrange(len(EXPLICITE[cat])) items.append({"id": f"ex{i}", "text": _fill(EXPLICITE[cat][k], rng), "truth": cat, "diff": "explicite", "leurre": None, "tpl": f"ex_{cat}_{k}"}); i += 1 for _ in range(per["implicite"]): k = rng.randrange(len(IMPLICITE[cat])) items.append({"id": f"im{i}", "text": _fill(IMPLICITE[cat][k], rng), "truth": cat, "diff": "implicite", "leurre": None, "tpl": f"im_{cat}_{k}"}); i += 1 for _ in range(per["piege"]): k = rng.randrange(len(PIEGE[cat])) tpl, leurre = PIEGE[cat][k] items.append({"id": f"pi{i}", "text": _fill(tpl, rng), "truth": cat, "diff": "piege", "leurre": leurre, "tpl": f"pi_{cat}_{k}"}); i += 1 rng.shuffle(items) return items if __name__ == "__main__": it = build() from collections import Counter print(f"{len(it)} items") print("par difficulte :", dict(Counter(x["diff"] for x in it))) print("par categorie :", dict(Counter(x["truth"] for x in it))) for d in ("explicite", "implicite", "piege"): ex = next(x for x in it if x["diff"] == d) print(f"\n[{d}] attendu={ex['truth']}" + (f" leurre={ex['leurre']}" if ex['leurre'] else "")) print(f" {ex['text']}")