Commit graph

10 commits

Author SHA1 Message Date
79ed5afdba fix(experiments): corrige les échecs de parsing JSON intermittents du moteur Ollama
Diagnostiqué et reproduit : sur un petit modèle (qwen2.5:0.5b) face à une
phrase longue (fr-concat-volumetrie, fr-recette-complete), le modèle part
en boucle de répétition dans le tableau `actions` et n'atteint jamais
l'accolade fermante avant la limite de tokens (response.done_reason ===
"length", jusqu'à ~130 000 caractères observés). La grammaire imposée par
`format` ne borne que la syntaxe token par token, pas la longueur du
tableau.

- options.repeat_penalty (1.3) décourage la boucle — réduit le dérapage
  d'un facteur ~18 sur le pire cas reproduit, sans l'éliminer à coup sûr.
- options.num_predict (2048) borne le dégât si ça dérape quand même.
- analyzeStep() réessaie jusqu'à 3 fois sur un parse invalide, avec une
  température légèrement relevée (0.3) à partir de la 2e tentative — à
  température 0 stricte, retenter à l'identique peut reproduire l'échec.

Vérifié : 3/3 runs réussissent sur le pire cas reproduit après correctif,
contre un échec systématique avant.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-22 00:12:33 +02:00
f5f30923d0 feat(experiments): ajoute un 4e moteur — même LLM via Ollama
Nouveau src/ollama-tech-step-poc.ts : même tâche/SYSTEM_PROMPT (exporté
depuis llm-tech-step-poc.ts et réutilisé tel quel) que le moteur
node-llama-cpp, mais via Ollama — une implémentation architecturalement
différente plutôt qu'une redite :

- Ollama tourne comme serveur HTTP local séparé (ollama serve), pas comme
  binding natif dans ce process — le paquet npm ollama n'a aucune
  dépendance native (rien à compiler à l'install, contrairement à
  node-llama-cpp).
- Modèle géré par Ollama lui-même (ollama.pull(), cache dans
  ~/.ollama/models), pas par ce projet — progression de pull journalisée
  palier par palier plutôt que silencieuse.
- Schéma JSON imposé via `format` (JSON Schema standard, `type:
  ["string","null"]` pour un champ nullable) — plus simple que le détour
  `oneOf` qu'exige la grammaire GBNF de node-llama-cpp.
- initialize() échoue avec un message explicite si le serveur Ollama n'est
  pas joignable, plutôt que l'erreur fetch brute.
- Caveat documenté en tête de fichier et rappelé avant le récapitulatif :
  la colonne RSS du harness ne mesure rien d'utile ici, l'inférence tourne
  dans le process ollama serve, pas dans ce script.

OllamaStepAnalyzer.dispose() décharge le modèle du serveur (keep_alive: 0,
best effort). Env vars OLLAMA_TECH_STEP_MODEL/OLLAMA_TECH_STEP_HOST,
scripts pnpm bench:ollama.

Vérifié en conditions réelles (Ollama tournait déjà dans l'environnement) :
pull + inférence structurée + parsing JSON fonctionnels, latence nettement
inférieure à node-llama-cpp sur les mêmes phrases (748-1260 ms vs 3-13 s),
delta RSS confirmé proche de zéro/bruit comme attendu.

README mis à jour (4 moteurs, section Ollama avec tableau comparatif
architectural, limites).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 23:14:03 +02:00
b8e599106f feat(experiments): ajoute une entrée de volumétrie par locale basée sur TEST_RECIPE
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 <noreply@anthropic.com>
2026-08-21 22:48:39 +02:00
9f274f9461 feat(experiments): ajoute une entrée de volumétrie par locale (FR/EN)
TEST_SENTENCES gagne 2 entrées dérivées (fr-concat-volumetrie,
en-concat-volumetrie) qui concatènent toutes les phrases de base d'une
même locale en un seul step géant, calculées depuis les phrases existantes
(jamais recopiées à la main) — pour isoler l'effet du seul volume de texte
sur la durée de traitement de chaque moteur, indépendamment de la
complexité déjà couverte par les 7 phrases existantes.

Vérifié via bench:nlp : la latence croît nettement avec le volume
(fr-concat ~2200ms vs 300-1100ms pour les phrases individuelles FR).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 22:15:45 +02:00
c73c62328d refactor(experiments): retire le script apps/api, ajoute NLP frais + pipeline hybride
Étape 1 — retire apps/api/src/scripts/bench-tech-step-classifier.ts
(DB-backed, taxonomie ~26 techniques non comparable terme à terme au LLM).

Étape 2 — reconstruit tout dans experiments/llm-tech-step-poc, entièrement
autonome (aucune dépendance Postgres/apps/api) :

- shared/kitchen-action.ts, shared/test-sentences.ts,
  shared/benchmark-harness.ts : types, 7 phrases de test et harness de
  mesure/affichage désormais partagés par les trois scripts (plus de
  recopie manuelle entre fichiers).
- nlp-tech-step-poc.ts : classifieur node-nlp FRAIS (NER + clauses +
  classification), entraîné directement sur la taxonomie à 7 catégories du
  LLM plutôt que réutiliser TechStepClassifierService — comparaison terme à
  terme, et surtout un score de confiance BRUT jamais masqué (contrairement
  au repli silencieux sur l'ancre NER de la version production), condition
  nécessaire au pipeline hybride. Corpus qui préfère les synonymes mono-mot
  ("revenir") aux phrases figées, pour ne pas se faire piéger par les
  pronoms clitiques français ("faites-les-revenir").
- hybrid-tech-step-poc.ts : NLP toujours en premier (chemin rapide), LLM en
  secours si la confiance NLP passe sous NLP_TRUST_THRESHOLD (0.6, tunable)
  ou qu'aucune action n'est trouvée — récapitulatif avec colonnes "moteur"
  et "confiance NLP" pour observer les bascules.
- llm-tech-step-poc.ts : inchangé fonctionnellement, migré vers les modules
  partagés.
- shared/module-entry.ts (isMainModule) : garde chaque script pour que
  l'import de ses classes (par hybrid-tech-step-poc.ts) ne déclenche pas
  aussi son propre benchmark comme effet de bord.

pnpm bench / bench:nlp / bench:hybrid. README réécrit en conséquence.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 21:13:20 +02:00
0582822a78 feat(api): ajoute le pendant node-nlp du benchmark tech-step
Nouveau script apps/api/src/scripts/bench-tech-step-classifier.ts, calqué
sur experiments/llm-tech-step-poc/src/llm-tech-step-poc.ts : mêmes 7
phrases de TEST_SENTENCES (recopiées à l'identique), même structure de
sortie (logs itératifs par répétition, tableau récapitulatif
latence/RSS/nombre de détections), pour que les deux pipelines soient
directement comparables phrase par phrase.

Réutilise techStepClassifier.warmUp() (déjà prévu pour absorber le coût de
l'entraînement + l'init paresseuse de node-nlp) et résout les techStepId en
key lisible pour l'affichage détaillé. Nécessite une base Postgres avec
TechStep seedée (matchTechStepSpans résout ses uid vers de vrais ids).

README du PoC LLM mis à jour : la section "Méthodologie de comparaison"
pointe vers ce script réel plutôt que le snippet REPL manuel qu'elle
suggérait avant.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 19:47:15 +02:00
6574d8e4a8 fix(experiments): ajoute un warm-up et des logs itératifs au benchmark LLM
- LocalLlmStepAnalyzer.warmUp() : force le coût caché du tout premier appel
  d'inférence (spin-up threads llama.cpp, cache KV, tokenizer) avant le
  benchmark, plutôt que de laisser la première phrase l'absorber — constaté
  sur des runs réels (Qwen/Llama) où fr-multi-action montait jusqu'à ~28s
  contre ~5s pour ses autres répétitions.
- initialize() et runBenchmark() journalisent maintenant chaque sous-étape
  (résolution du modèle, chargement des poids, contexte, grammaire, puis
  chaque répétition avec son résultat immédiat) au lieu de rester muets
  plusieurs minutes avant le récapitulatif final.
- RECOMMENDED_MODELS / README corrigés suite aux runs réels de l'utilisateur :
  Qwen2.5-1.5B s'est montré systématiquement plus rapide que Llama-3.2-1B
  sur les deux machines testées, contredisant l'hypothèse a priori du README
  ("moins de paramètres = plus rapide") — gardé comme résultat empirique
  plutôt que corrigé silencieusement.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 19:32:37 +02:00
f0ffd9644e docs(experiments): documente le --ignore-workspace nécessaire à l'install
pnpm install seul, lancé depuis experiments/llm-tech-step-poc, remonte au
monorepo (pnpm-workspace.yaml) et n'installe rien pour ce dossier hors
workspace — sans erreur visible. --ignore-workspace force pnpm à traiter
le dossier comme un package standalone.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 19:10:44 +02:00
0c1743c614 feat(experiments): ajoute 4 phrases de test hyper complexes au PoC LLM
Complète les 3 phrases initiales de TEST_SENTENCES avec 4 cas cherchant
volontairement le point de rupture (au lieu de juste confirmer le cas
courant) : actions simultanées plutôt que séquentielles ("pendant que..."),
action conditionnelle noyée dans des actions fermes, négation explicite
d'action ("sans jamais laisser bouillir"), fin de cuisson par état/test de
résultat plutôt que par durée, et un champ température qui désigne un seuil
de cuisson à cœur plutôt qu'un réglage de feu. README mis à jour (7 phrases,
4 FR + 3 EN).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 19:04:00 +02:00
4c3e00a08a feat(experiments): ajoute un PoC de détection d'actions culinaires par mini LLM local
Fichier TypeScript autonome (hors du workspace pnpm) qui compare le
pipeline node-nlp existant (tech-step-matcher.ts) à un mini LLM instruct
local via node-llama-cpp : sortie JSON strictement contrainte par schéma
(grammaire GBNF, createGrammarForJsonSchema), interfaces RecipeStepAnalysis/
KitchenAction, recommandation de modèle (Qwen2.5-1.5B-Instruct Q4_K_M par
défaut, Llama-3.2-1B-Instruct Q4_K_M en alternative), et un benchmark simple
(performance.now() + delta RSS) sur 3 phrases complexes FR/EN, dont le cas
piège sans verbe littéral déjà documenté dans tech-step-matcher.ts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 18:58:28 +02:00