Plan détaillé pour réintégrer la logique de génération par couples
et contraintes de longueur du système legacy.
Analyse COT complète avec:
- Comparaison plan initial vs legacy code
- Identification erreurs de conception
- 2 options d'implémentation (Option A recommandée)
- Risques et mitigations
- Critères de succès
- Stratégie de rollback
Status: EN ATTENTE VALIDATION UTILISATEUR
Action requise: Analyser buildSmartHierarchy() output
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
12 KiB
Plan d'Implémentation : Réintégration InitialGeneration
Date : 2025-10-12 Objectif : Réintégrer la logique de génération par couples et contraintes de longueur du système legacy Auteur : Claude Code (avec validation utilisateur requise)
🧠 Analyse Chain of Thought
Problèmes Identifiés
Dans le système actuel (generateSimple() dans SelectiveUtils.js) :
- ✅ Génération élément par élément → lent (33 appels), coûteux
- ✅ Prompt générique pour tous types → pas de contraintes adaptées
- ✅ Pas de contraintes de longueur → articles de 400 mots au lieu de 150
- ✅ Pas de gestion des couples → Q sans R cohérente, Titre sans Texte lié
- ✅ MaxTokens insuffisants pour certains modèles
Systèmes legacy existants et fonctionnels :
- ✅
InitialGeneration.js: batch generation (chunks de 4) + détection de type + contraintes de longueur - ✅
buildSmartHierarchy(): associe automatiquement couples titre/texte et paires FAQ - ✅
parseFAQPairsResponse(): validation stricte de cohérence des paires
❌ Erreurs dans le Plan Initial
1. Détection de type trop complexe
Legacy (InitialGeneration.js:132-146) :
detectElementType(tag) {
if (tagLower.includes('titre') || tagLower.includes('h1') || tagLower.includes('h2')) {
return 'titre'; // ← STRING simple
}
}
Mon plan initial :
detectElementType(tag) {
return { type: 'titre_h2', maxWords: 12, maxTokens: 30 }; // ← OBJET complexe
}
❌ Problème : Sur-ingénierie. Le legacy est plus simple et fonctionne.
2. Chunking sur-complexifié
Legacy (InitialGeneration.js:52) :
const chunks = chunkArray(Object.entries(elementsToGenerate), 4); // Simple chunks de 4
Mon plan initial :
function groupIntoBatches(hierarchy) {
// Logique complexe : calcul tokens, groupement intelligent des FAQ, etc.
// ~60 lignes de code
}
❌ Problème : Réinvente la roue. Le chunking simple par 4 marche déjà.
3. Hiérarchie ignorée
Point critique découvert :
Le pipeline utilise DÉJÀ buildSmartHierarchy() qui retourne cette structure :
{
"H2_1": {
title: { instructions: "..." }, // ← Titre H2_1
text: { instructions: "..." }, // ← Texte P_1 associé
questions: [] // ← Vide si pas de FAQ
},
"q_1": {
title: null,
text: null,
questions: [ // ← q_1 et a_1 groupées ici
{ type: 'Faq', level: 'q', ... },
{ type: 'Faq', level: 'a', ... }
]
}
}
❌ Mon erreur majeure : Je traite H2_1, P_1, q_1, a_1 comme éléments séparés au lieu d'exploiter les couples déjà identifiés par buildSmartHierarchy().
✅ Architecture Correcte
Principe de base
Réutiliser la logique d'InitialGeneration.js qui :
- Prépare les éléments avec type détecté
- Groupe en chunks de 4
- Génère par batch avec contraintes de longueur
- Parse les réponses avec fallback
MAIS : Adapter pour respecter la structure hiérarchique créée par buildSmartHierarchy().
📋 Plan Révisé
Option A : Réutiliser InitialGenerationLayer (RECOMMANDÉ)
Avantages :
- ✅ Code déjà testé et fonctionnel
- ✅ Gestion fallback robuste
- ✅ Contraintes de longueur intégrées
- ✅ Chunking optimisé
Modifications nécessaires :
1. Dans PipelineExecutor.js (ligne 214-247)
Avant :
const result = await generateSimple(hierarchy, csvData, { llmProvider });
Après :
const { InitialGenerationLayer } = require('../generation/InitialGeneration');
const layer = new InitialGenerationLayer();
// Aplatir la hiérarchie pour InitialGeneration
const flatStructure = flattenHierarchy(hierarchy);
const result = await layer.apply(flatStructure, {
llmProvider,
temperature: 0.9,
csvData
});
2. Créer fonction flattenHierarchy() dans PipelineExecutor.js
function flattenHierarchy(hierarchy) {
const flat = {};
Object.entries(hierarchy).forEach(([sectionKey, section]) => {
// Ajouter titre si présent
if (section.title && section.title.instructions) {
const titleTag = sectionKey.includes('_') ? sectionKey : `${sectionKey}_title`;
flat[titleTag] = section.title.instructions;
}
// Ajouter texte si présent
if (section.text && section.text.instructions) {
const textTag = sectionKey.includes('_') ? `${sectionKey}_text` : sectionKey;
flat[textTag] = section.text.instructions;
}
// Ajouter questions FAQ
if (section.questions && section.questions.length > 0) {
section.questions.forEach((faq, index) => {
if (faq.originalElement && faq.originalElement.resolvedContent) {
const faqTag = faq.hierarchyPath || `faq_${index}`;
flat[faqTag] = faq.originalElement.resolvedContent;
}
});
}
});
return flat;
}
Impact : Minimal, réutilise code existant
Option B : Adapter generateSimple() pour respecter la hiérarchie
Avantages :
- ✅ Pas de changement dans PipelineExecutor
- ✅ Compatibilité maintenue
Inconvénients :
- ❌ Réécriture partielle de generateSimple()
- ❌ Plus de code à tester
Modifications dans SelectiveUtils.js
Ajouter détection de couples avant la boucle :
async function generateSimple(hierarchy, csvData, options = {}) {
// ... début identique ...
const batches = [];
// Grouper éléments par couples et type
for (const [sectionKey, section] of Object.entries(hierarchy)) {
const batch = [];
// Couple titre + texte
if (section.title && section.text) {
batch.push([`${sectionKey}_title`, section.title]);
batch.push([`${sectionKey}_text`, section.text]);
} else if (section.title) {
batch.push([`${sectionKey}_title`, section.title]);
} else if (section.text) {
batch.push([`${sectionKey}_text`, section.text]);
}
// Paires FAQ
if (section.questions && section.questions.length > 0) {
for (let i = 0; i < section.questions.length; i += 2) {
const question = section.questions[i];
const answer = section.questions[i + 1];
if (question && answer) {
batch.push([question.hierarchyPath, question]);
batch.push([answer.hierarchyPath, answer]);
}
}
}
if (batch.length > 0) {
batches.push(batch);
}
}
// Générer chaque batch avec prompt adapté
// ... suite similaire au plan initial mais avec couples respectés ...
}
🎯 Décision Requise
Questions Critiques
1. Quelle option choisir ?
- Option A : Réutiliser InitialGenerationLayer (moins de code, plus sûr)
- Option B : Adapter generateSimple() (plus de flexibilité, plus de risque)
2. Structure réelle de buildSmartHierarchy() ?
Pour valider le plan, j'ai besoin de voir un exemple concret de ce que retourne buildSmartHierarchy() actuellement.
Action : Ajouter ce log temporaire dans PipelineExecutor.js:233 :
const hierarchy = await buildSmartHierarchy(elementsArray);
logSh(`DEBUG HIERARCHY: ${JSON.stringify(hierarchy, null, 2)}`, 'DEBUG');
Puis relancer une génération et me partager les logs.
3. Nombre d'éléments attendus ?
- Si
buildSmartHierarchy()retourne 23 sections au lieu de 33 éléments, c'est normal (couples fusionnés) - Si on veut 33 éléments générés, il faut aplatir la hiérarchie (Option A)
📊 Comparaison Options
| Critère | Option A (Réutiliser) | Option B (Adapter) |
|---|---|---|
| Code à écrire | ~30 lignes | ~150 lignes |
| Risque | Faible | Moyen |
| Tests nécessaires | Minimes | Complets |
| Maintenance | Simple | Double système |
| Performance | Identique | Identique |
| Compatibilité | Changement PipelineExecutor | Transparent |
| Recommandation | ✅ OUI | ⚠️ Si besoin spécifique |
🚀 Étapes d'Implémentation (Option A - Recommandée)
Phase 1 : Validation de la structure (30 min)
- Ajouter logs debug pour comprendre
buildSmartHierarchy() - Analyser la sortie réelle
- Valider que les couples sont bien formés
Phase 2 : Fonction flattenHierarchy (45 min)
- Créer la fonction dans
PipelineExecutor.js - Tests unitaires avec fixtures
- Validation que tous les éléments sont extraits
Phase 3 : Intégration InitialGenerationLayer (60 min)
- Importer InitialGenerationLayer dans PipelineExecutor
- Remplacer appel à generateSimple()
- Adapter le retour pour compatibilité
Phase 4 : Augmentation maxTokens (15 min)
Mettre à jour LLMManager.js :
'claude-sonnet-4-5': { maxTokens: 8000 },
'gpt-4o-mini': { maxTokens: 6000 },
'gpt-5-mini': { maxTokens: 10000 },
// etc.
Phase 5 : Tests et validation (60 min)
- Test génération ligne 2 production
- Vérifier 33 éléments générés
- Vérifier longueurs respectées
- Vérifier cohérence FAQ
- Mesurer temps (~40-50s attendu)
Temps total : 3h30
📝 Modifications de Code
Fichiers impactés
-
lib/pipeline/PipelineExecutor.js(ligne 214-247)- Import InitialGenerationLayer
- Fonction flattenHierarchy()
- Remplacement generateSimple()
-
lib/LLMManager.js(ligne 18-67)- Augmentation maxTokens
-
lib/selective-enhancement/SelectiveUtils.js(optionnel)- Marquer generateSimple() comme DEPRECATED
- Ajouter commentaire pointant vers InitialGeneration
⚠️ Risques et Mitigations
Risque 1 : Structure hiérarchie différente de l'attendu
Impact : High Probabilité : Medium Mitigation : Logs debug + validation avant implémentation
Risque 2 : Parsing échoue sur certains éléments
Impact : Medium Probabilité : Low (code legacy testé) Mitigation : Fallback déjà présent dans InitialGenerationLayer
Risque 3 : Régression performance
Impact : Medium Probabilité : Very Low Mitigation : Tests avant/après avec métriques
Risque 4 : Incompatibilité avec pipeline actuel
Impact : High Probabilité : Low Mitigation : Tests complets sur environnement dev
✅ Critères de Succès
-
Fonctionnel :
- 33/33 éléments générés (pas de skip)
- Longueurs respectées (H2: 8-15 mots, P: 80-200 mots)
- Paires FAQ cohérentes (Q pertinente pour R)
- Aucune erreur FATAL
-
Performance :
- Temps < 60s (vs ~150s actuellement)
- Coût -30% minimum
-
Qualité :
- Contenu non générique
- Pas de troncature
- Style personnalité respecté
🔄 Rollback Strategy
En cas de problème :
- Phase 1-3 :
git revertsimple - Phase 4 : Restaurer anciennes valeurs maxTokens
- Phase 5 : Si échec tests, rollback complet
Fallback automatique : InitialGenerationLayer a déjà un fallback intégré par chunk.
📌 TODO Immédiat
- DÉCISION : Choisir Option A ou Option B
- ACTION : Ajouter logs debug buildSmartHierarchy()
- PARTAGE : Envoyer exemple output buildSmartHierarchy()
- Valider avec utilisateur avant implémentation
📚 Références Code Legacy
lib/generation/InitialGeneration.js(ligne 1-284)lib/ElementExtraction.js-buildSmartHierarchy()(ligne 276-313)lib/ElementExtraction.js-parseFAQPairsResponse()(ligne 402-451)lib/pipeline/PipelineExecutor.js-runGeneration()(ligne 214-247)
Status : ⏸️ EN ATTENTE VALIDATION UTILISATEUR
Avant de commencer l'implémentation, il faut :
- Décider de l'option (A recommandée)
- Analyser la structure réelle de buildSmartHierarchy()
- Valider que le plan correspond aux besoins