From b8e599106fd3dbf120a5a58637bd85dba41543fa Mon Sep 17 00:00:00 2001 From: Nicolas Date: Fri, 21 Aug 2026 22:48:39 +0200 Subject: [PATCH] =?UTF-8?q?feat(experiments):=20ajoute=20une=20entr=C3=A9e?= =?UTF-8?q?=20de=20volum=C3=A9trie=20par=20locale=20bas=C3=A9e=20sur=20TES?= =?UTF-8?q?T=5FRECIPE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TEST_SENTENCES gagne 2 entrées supplémentaires (fr-recette-complete, en-recette-complete) qui concatènent les 7 étapes de TEST_RECIPE ("Tarte aux pommes rustique") en un seul step par locale — même principe que fr-concat-volumetrie/en-concat-volumetrie, mais sur du texte de recette réel plutôt qu'une concaténation de phrases-pièges synthétiques. TEST_RECIPE (déjà ajoutée localement) déplacée avant TEST_SENTENCES (nécessaire pour être référencée dans sa construction) et reformatée à la convention du fichier (clés non citées, virgules finales) ; contenu inchangé. Retire le stub dummyRecipeFr/dummyRecipeEn de benchmark-harness.ts : le harness générique n'a besoin d'aucun cas particulier, TEST_SENTENCES suffit. Co-Authored-By: Claude Sonnet 5 --- .../src/shared/test-sentences.ts | 162 ++++++++++++++++-- 1 file changed, 149 insertions(+), 13 deletions(-) diff --git a/experiments/llm-tech-step-poc/src/shared/test-sentences.ts b/experiments/llm-tech-step-poc/src/shared/test-sentences.ts index 62f0292..9f52cce 100644 --- a/experiments/llm-tech-step-poc/src/shared/test-sentences.ts +++ b/experiments/llm-tech-step-poc/src/shared/test-sentences.ts @@ -1,12 +1,12 @@ /** - * Les 9 phrases de test partagées par les trois moteurs de ce PoC (7 phrases - * de complexité variable + 2 concaténations pour tester l'effet du volume, - * voir {@link TEST_SENTENCES}) — un seul jeu de phrases, importé par - * `llm-tech-step-poc.ts`, `nlp-tech-step-poc.ts` et `hybrid-tech-step-poc.ts`, - * pour que leurs runs soient directement comparables phrase par phrase sans - * risque de désynchronisation (un défaut de la toute première version de ce - * PoC, où le pendant `node-nlp` vivait dans `apps/api` et recopiait ces - * phrases à la main). + * Les 11 phrases de test partagées par les trois moteurs de ce PoC (7 + * phrases de complexité variable + 2 concaténations synthétiques + 2 + * concaténations d'une vraie recette, voir {@link TEST_SENTENCES}) — un seul + * jeu de phrases, importé par `llm-tech-step-poc.ts`, `nlp-tech-step-poc.ts` + * et `hybrid-tech-step-poc.ts`, pour que leurs runs soient directement + * comparables phrase par phrase sans risque de désynchronisation (un défaut + * de la toute première version de ce PoC, où le pendant `node-nlp` vivait + * dans `apps/api` et recopiait ces phrases à la main). */ /** Une phrase de test, avec sa langue et ce qui la rend "complexe" (documentation, non exploité par le code). */ @@ -66,6 +66,13 @@ export interface BenchmarkSentence { * normale de ce jeu. * 9. EN, la concaténation des 3 phrases EN ci-dessus (2, 5, 7) en un seul * step — même principe côté EN. + * 10. FR, les 7 étapes de {@link TEST_RECIPE} ("Tarte aux pommes rustique") + * concaténées en un seul step — même principe volumétrique que les + * items 8/9, mais sur du texte de recette RÉEL (rédigé normalement, + * sans les tournures adversariales des phrases 1-7) plutôt qu'une + * concaténation de phrases-pièges synthétiques. + * 11. EN, les 7 étapes de {@link TEST_RECIPE} ("Rustic Apple Tart") + * concaténées en un seul step — même principe que l'item 10, côté EN. */ const BASE_SENTENCES: readonly BenchmarkSentence[] = [ { @@ -112,6 +119,111 @@ const BASE_SENTENCES: readonly BenchmarkSentence[] = [ }, ]; +/** + * Une vraie recette (titre, ingrédients, 7 étapes rédigées normalement en + * FR/EN) — matière première d'une volumétrie plus RÉALISTE que la + * concaténation de phrases-pièges synthétiques ci-dessus (items 8/9) : du + * texte de recette tel qu'un utilisateur l'écrirait vraiment, sans + * tournures adversariales délibérées. Seuls `steps[].text.fr`/`.en` sont + * utilisés par ce fichier ({@link concatenateRecipeByLocale}) — le reste + * (`ingredients`, `servings`, temps de préparation...) est conservé tel + * quel pour une éventuelle recette de test plus complète plus tard, pas + * exploité aujourd'hui. + */ +export const TEST_RECIPE = { + recipe_id: "apple_tart_001", + title: { + fr: "Tarte aux pommes rustique", + en: "Rustic Apple Tart", + }, + servings: 6, + prep_time_minutes: 20, + cook_time_minutes: 35, + ingredients: [ + { + id: "ing_1", + name: { fr: "pâte brisée", en: "shortcrust pastry" }, + quantity: 1, + unit: "piece", + }, + { + id: "ing_2", + name: { fr: "pommes Golden", en: "Golden Delicious apples" }, + quantity: 4, + unit: "pieces", + }, + { + id: "ing_3", + name: { fr: "beurre", en: "butter" }, + quantity: 30, + unit: "g", + }, + { + id: "ing_4", + name: { fr: "sucre vanillé", en: "vanilla sugar" }, + quantity: 1, + unit: "packet", + }, + { + id: "ing_5", + name: { fr: "compote de pommes", en: "applesauce" }, + quantity: 150, + unit: "g", + }, + ], + steps: [ + { + step_number: 1, + text: { + fr: "Préchauffez votre four à 180°C pendant 10 minutes.", + en: "Preheat your oven to 180°C (350°F) for 10 minutes.", + }, + }, + { + step_number: 2, + text: { + fr: "Épluchez et évidez les pommes, puis coupez-les en fines lamelles régulières sur votre planche à découper.", + en: "Peel and core the apples, then slice them into thin, even slices on your cutting board.", + }, + }, + { + step_number: 3, + text: { + fr: "Déroulez la pâte brisée dans un moule à tarte et piquez le fond avec une fourchette.", + en: "Unroll the shortcrust pastry into a tart pan and prick the bottom with a fork.", + }, + }, + { + step_number: 4, + text: { + fr: "Étalez la compote de pommes de manière égale sur le fond de pâte avec une spatule.", + en: "Spread the applesauce evenly over the pastry base using a spatula.", + }, + }, + { + step_number: 5, + text: { + fr: "Disposez les lamelles de pommes en rosette par-dessus la compote, puis parsemez de noisettes de beurre et de sucre vanillé.", + en: "Arrange the apple slices in a rosette pattern on top of the sauce, then dot with small knobs of butter and sprinkle with vanilla sugar.", + }, + }, + { + step_number: 6, + text: { + fr: "Enfournez à 180°C et laissez cuire pendant 35 minutes jusqu'à ce que les bordures soient bien dorées.", + en: "Bake at 180°C (350°F) for 35 minutes until the edges are golden brown.", + }, + }, + { + step_number: 7, + text: { + fr: "Sortez la tarte du four et laissez-la reposer au frais pendant 15 minutes avant de démouler et de servir.", + en: "Remove the tart from the oven and let it rest at room temperature for 15 minutes before unmolding and serving.", + }, + }, + ], +}; + /** * Concatène les textes de {@link BASE_SENTENCES} d'une locale donnée, * séparés par un espace, dans leur ordre d'apparition — calculé plutôt que @@ -125,16 +237,28 @@ function concatenateByLocale(locale: BenchmarkSentence["locale"]): string { .join(" "); } +/** + * Concatène les 7 étapes de {@link TEST_RECIPE} pour une locale donnée, + * dans leur ordre (`step_number`), séparées par un espace — même principe + * que {@link concatenateByLocale} mais sur la recette réelle plutôt que sur + * les phrases de test synthétiques. + */ +function concatenateRecipeByLocale(locale: BenchmarkSentence["locale"]): string { + return TEST_RECIPE.steps.map((step) => step.text[locale]).join(" "); +} + const FR_SENTENCE_COUNT = BASE_SENTENCES.filter((sentence) => sentence.locale === "fr").length; const EN_SENTENCE_COUNT = BASE_SENTENCES.filter((sentence) => sentence.locale === "en").length; /** * {@link BASE_SENTENCES} (7 phrases, complexité variable à taille à peu - * près constante) plus deux entrées dérivées par locale (items 8 et 9 du - * doc-comment ci-dessus) qui concatènent toutes les phrases de cette locale - * en un seul step — pour isoler l'effet du VOLUME de texte sur la durée de - * traitement de chaque moteur, indépendamment de la complexité sémantique - * déjà couverte par les 7 premières. + * près constante) plus quatre entrées dérivées par locale (items 8-11 du + * doc-comment ci-dessus) qui concatènent, respectivement, toutes les + * phrases de test d'une locale et toutes les étapes de {@link TEST_RECIPE} + * de cette même locale en un seul step chacune — pour isoler l'effet du + * VOLUME de texte sur la durée de traitement de chaque moteur, + * indépendamment de la complexité sémantique déjà couverte par les 7 + * premières, sur du texte synthétique ET sur du texte de recette réel. */ export const TEST_SENTENCES: readonly BenchmarkSentence[] = [ ...BASE_SENTENCES, @@ -150,4 +274,16 @@ export const TEST_SENTENCES: readonly BenchmarkSentence[] = [ text: concatenateByLocale("en"), note: `Concaténation des ${EN_SENTENCE_COUNT} étapes EN ci-dessus en un seul step — même test de volumétrie côté EN.`, }, + { + id: "fr-recette-complete", + locale: "fr", + text: concatenateRecipeByLocale("fr"), + note: `Les ${TEST_RECIPE.steps.length} étapes de "${TEST_RECIPE.title.fr}" concaténées en un seul step — même test de volumétrie que ci-dessus, mais sur du texte de recette réel plutôt qu'une concaténation de phrases-pièges synthétiques.`, + }, + { + id: "en-recette-complete", + locale: "en", + text: concatenateRecipeByLocale("en"), + note: `Les ${TEST_RECIPE.steps.length} étapes de "${TEST_RECIPE.title.en}" concaténées en un seul step — même principe côté EN.`, + }, ];