feat(adversarial): Enrichissement complet des prompts avec personnalité et tournures idiomatiques
Ajouts majeurs:
- DetectorStrategies: +2 nouvelles stratégies (CopyLeaks, Winston) - 5 au total
- Instructions adversariales 2x plus riches (8-12 règles au lieu de 4-5)
- Adaptation personnalité enrichie: vocabulairePref, connecteursPref, expressionsFavorites
- Instructions spécifiques par type d'élément (6 types: titres, intro, textes, FAQ, conclusion)
- Tournures idiomatiques françaises explicitement demandées
- Variation longueur phrases avec chiffres précis (5-10 vs 20-30 mots)
- Imperfections naturelles (répétitions, hésitations, reformulations)
Modifications:
- AdversarialCore.js: Prompts régénération et enhancement 3x plus détaillés
* generatePersonalityInstructions() - extraction vocabulaire/connecteurs/expressions
* generateElementSpecificInstructions() - conseils détaillés par type
* detectElementTypeFromTag() - parsing intelligent des tags
* getElementSpecificTip() - tips contextuels pour enhancement
- DetectorStrategies.js: Stratégies complètes avec techniques détaillées
* CopyLeaksStrategy - reformulation radicale, originalité absolue
* WinstonStrategy - variation humaine, imperfections authentiques
* Instructions getInstructions() et getEnhancementTips() enrichies pour toutes stratégies
Impact:
- Prompts 3-4x plus riches qu'avant
- Meilleur respect personnalité (vocabulaire, connecteurs, expressions)
- Tournures phrases plus intéressantes et authentiques
- Cohérence avec ancien système excellent (commit 590f6a9)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
2fc31c12aa
commit
ec2e2e7a83
244
ADVERSARIAL_IMPROVEMENTS.md
Normal file
244
ADVERSARIAL_IMPROVEMENTS.md
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
# 🎯 Améliorations du Système Adversarial
|
||||||
|
|
||||||
|
## Résumé Exécutif
|
||||||
|
|
||||||
|
Le système adversarial a été considérablement amélioré en intégrant les meilleures pratiques de l'ancien système (commit 590f6a9). Les prompts sont maintenant **beaucoup plus riches** et produiront des **tournures de phrases plus intéressantes** avec un **respect accru de la personnalité**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Améliorations Apportées
|
||||||
|
|
||||||
|
### 1. ✅ Enrichissement DetectorStrategies.js
|
||||||
|
|
||||||
|
**Avant** : 3 stratégies (general, gptZero, originality)
|
||||||
|
**Après** : 5 stratégies complètes
|
||||||
|
|
||||||
|
#### Nouvelles Stratégies Ajoutées
|
||||||
|
|
||||||
|
- **CopyLeaksStrategy** : Focus sur originalité absolue
|
||||||
|
- Reformulation radicale
|
||||||
|
- Personnalisation avec exemples spécifiques
|
||||||
|
- Transformation descriptions → récits/témoignages
|
||||||
|
|
||||||
|
- **WinstonStrategy** : Focus sur variation humaine
|
||||||
|
- Simulation variation d'humeur et d'énergie
|
||||||
|
- Imperfections authentiques (hésitations, corrections)
|
||||||
|
- Changements registres émotionnels
|
||||||
|
|
||||||
|
#### Instructions Enrichies
|
||||||
|
|
||||||
|
Chaque stratégie contient maintenant :
|
||||||
|
- Instructions de base (4-5 règles)
|
||||||
|
- Instructions intensives (3-4 règles supplémentaires)
|
||||||
|
- Conseils d'amélioration spécifiques
|
||||||
|
- Métriques d'analyse de contenu
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. ✅ Enrichissement Prompts de Régénération
|
||||||
|
|
||||||
|
**Fichier** : `lib/adversarial-generation/AdversarialCore.js`
|
||||||
|
|
||||||
|
#### Ajouts Majeurs
|
||||||
|
|
||||||
|
1. **Adaptations Personnalité Enrichies**
|
||||||
|
```javascript
|
||||||
|
ADAPTATION PERSONNALITÉ MARC:
|
||||||
|
- Respecte le style technique et pragmatique de Marc de façon authentique et marquée
|
||||||
|
- Intègre naturellement ce vocabulaire: solide, efficace, pratique, durable, fiable
|
||||||
|
- Utilise ces connecteurs variés: du coup, en gros, concrètement, en pratique
|
||||||
|
- Longueur phrases: moyennes (12-18 mots) mais avec variation anti-détection
|
||||||
|
- Expressions typiques: ça tient la route, c'est du costaud, on ne rigole pas
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Instructions Spécifiques par Type d'Élément**
|
||||||
|
- **Titres** : Évite formules marketing lisses, préfère authentique et direct
|
||||||
|
- **Intro** : Commence par angle inattendu (anecdote, constat, question)
|
||||||
|
- **Textes** : Mélange infos factuelles et observations personnelles
|
||||||
|
- **FAQ Questions** : Formulations vraiment utilisées par clients
|
||||||
|
- **FAQ Réponses** : Ajoute nuances "ça dépend" et précisions contextuelles
|
||||||
|
- **Conclusion** : Personnalise avec avis subjectif
|
||||||
|
|
||||||
|
3. **Consignes Générales Améliorées**
|
||||||
|
- Expressions françaises familières et tournures idiomatiques
|
||||||
|
- Variation longueurs phrases (5-10 mots vs 20-30 mots)
|
||||||
|
- Imperfections naturelles (répétitions légères, hésitations, reformulations)
|
||||||
|
- Détection automatique type d'élément
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. ✅ Enrichissement Prompts d'Enhancement
|
||||||
|
|
||||||
|
**Même fichier** : `lib/adversarial-generation/AdversarialCore.js`
|
||||||
|
|
||||||
|
#### Ajouts Majeurs
|
||||||
|
|
||||||
|
1. **Techniques Générales Explicites**
|
||||||
|
- Remplace mots typiques IA par synonymes plus naturels
|
||||||
|
- Varie longueurs phrases et structures syntaxiques
|
||||||
|
- Utilise expressions idiomatiques françaises
|
||||||
|
- Ajoute nuances humaines : "peut-être", "généralement", "souvent"
|
||||||
|
|
||||||
|
2. **Tips Spécifiques par Élément**
|
||||||
|
Chaque élément reçoit un conseil personnalisé :
|
||||||
|
- `TIP: Évite formules marketing, préfère authentique et percutant`
|
||||||
|
- `TIP: Ajoute observation personnelle ou aparté léger`
|
||||||
|
- `TIP: Ajoute nuance "ça dépend" ou précision contextuelle`
|
||||||
|
|
||||||
|
3. **Affichage TYPE + PROBLÈME**
|
||||||
|
```
|
||||||
|
[1] TAG: Titre_H2_3 | TYPE: titre_h2
|
||||||
|
CONTENU: "..."
|
||||||
|
PROBLÈME DÉTECTÉ: low_punctuation_complexity(5%), formal_tone(2_mots)
|
||||||
|
TIP: Varie structure (question/affirmation/fragment)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Résultats Attendus
|
||||||
|
|
||||||
|
### Avant (Prompt Simple)
|
||||||
|
```
|
||||||
|
MISSION: Réécris ces contenus pour éviter détection par gptZero.
|
||||||
|
|
||||||
|
TECHNIQUE ANTI-GPTZERO:
|
||||||
|
- Instructions basiques...
|
||||||
|
|
||||||
|
CONSIGNES:
|
||||||
|
- Style: Marc (technique et pragmatique)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Après (Prompt Enrichi)
|
||||||
|
```
|
||||||
|
MISSION: Réécris ces contenus pour éviter détection par gptZero.
|
||||||
|
|
||||||
|
TECHNIQUE ANTI-GPTZERO:
|
||||||
|
- Surprends avec tournures inattendues et constructions atypiques
|
||||||
|
- Varie drastiquement la complexité syntaxique entre phrases
|
||||||
|
- Intercale observations personnelles ou détours narratifs
|
||||||
|
- Brise la logique linéaire avec des parenthèses, incises, apartés
|
||||||
|
... (8 instructions au total)
|
||||||
|
|
||||||
|
CONSIGNES GÉNÉRALES:
|
||||||
|
- Utilise expressions françaises familières et tournures idiomatiques authentiques
|
||||||
|
- Varie longueurs phrases : mélange phrases courtes (5-10 mots) ET longues (20-30 mots)
|
||||||
|
- Ajoute imperfections naturelles : répétitions légères, hésitations, reformulations
|
||||||
|
|
||||||
|
ADAPTATION PERSONNALITÉ MARC:
|
||||||
|
- Respecte le style technique et pragmatique de Marc de façon authentique et marquée
|
||||||
|
- Intègre naturellement ce vocabulaire: solide, efficace, pratique, durable, fiable
|
||||||
|
- Utilise ces connecteurs variés: du coup, en gros, concrètement, en pratique
|
||||||
|
- Longueur phrases: moyennes (12-18 mots) mais avec variation anti-détection
|
||||||
|
- Expressions typiques: ça tient la route, c'est du costaud, on ne rigole pas
|
||||||
|
|
||||||
|
INSTRUCTIONS SPÉCIFIQUES PAR TYPE:
|
||||||
|
• TITRES: Évite formules marketing lisses, préfère authentique et direct
|
||||||
|
Varie structure : question, affirmation, fragment percutant
|
||||||
|
• INTRO: Commence par angle inattendu : anecdote, constat, question rhétorique
|
||||||
|
• TEXTES: Mélange informations factuelles et observations personnelles
|
||||||
|
Intègre apartés : "(j'ai testé, c'est bluffant)", questions rhétoriques
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Comparaison Détaillée
|
||||||
|
|
||||||
|
| Aspect | Avant | Après | Impact |
|
||||||
|
|--------|-------|-------|--------|
|
||||||
|
| **Stratégies détecteurs** | 3 | 5 | +67% couverture |
|
||||||
|
| **Instructions adversariales** | 4-5 | 8-12 | +100% richesse |
|
||||||
|
| **Adaptation personnalité** | Nom + Style | Nom + Style + Vocabulaire + Connecteurs + Expressions | +300% contexte |
|
||||||
|
| **Instructions spécifiques** | ❌ Absentes | ✅ 6 types d'éléments | Personnalisation maximale |
|
||||||
|
| **Tournures idiomatiques** | ❌ Non mentionnées | ✅ Explicitement demandées | Authenticité française |
|
||||||
|
| **Variation longueur phrases** | ❌ Vague | ✅ Chiffres précis (5-10 vs 20-30 mots) | Guidage clair |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Utilisation
|
||||||
|
|
||||||
|
Les améliorations sont **automatiquement actives** dans tout le système adversarial :
|
||||||
|
|
||||||
|
1. **Pipeline standard** : `lib/Main.js` → appelle `AdversarialCore.applyAdversarialLayer()`
|
||||||
|
2. **API** : `/api/adversarial/enhance` utilise les nouveaux prompts
|
||||||
|
3. **Interfaces web** : Toutes les interfaces bénéficient des améliorations
|
||||||
|
|
||||||
|
### Test Manuel
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Tester les nouveaux prompts
|
||||||
|
node test-adversarial-prompts.js
|
||||||
|
|
||||||
|
# Exécuter workflow complet avec adversarial enrichi
|
||||||
|
node -e "const main = require('./lib/Main'); main.handleFullWorkflow({ rowNumber: 2, source: 'production' });"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎓 Techniques Adversariales Avancées
|
||||||
|
|
||||||
|
### GPTZero
|
||||||
|
- **Objectif** : Imprévisibilité maximale
|
||||||
|
- **Techniques** : Tournures atypiques, ruptures narratives, registres mélangés
|
||||||
|
- **Effectiveness** : 90%
|
||||||
|
|
||||||
|
### Originality
|
||||||
|
- **Objectif** : Créativité sémantique
|
||||||
|
- **Techniques** : Métaphores inattendues, angles multiples, néologismes justifiés
|
||||||
|
- **Effectiveness** : 85%
|
||||||
|
|
||||||
|
### CopyLeaks
|
||||||
|
- **Objectif** : Originalité absolue
|
||||||
|
- **Techniques** : Reformulation radicale, analogies créatives, récits personnalisés
|
||||||
|
- **Effectiveness** : 85%
|
||||||
|
|
||||||
|
### Winston
|
||||||
|
- **Objectif** : Variation humaine
|
||||||
|
- **Techniques** : Imperfections authentiques, changements d'humeur, hésitations
|
||||||
|
- **Effectiveness** : 80%
|
||||||
|
|
||||||
|
### General
|
||||||
|
- **Objectif** : Équilibre naturel
|
||||||
|
- **Techniques** : Expressions idiomatiques, variation douce, synonymes évidents
|
||||||
|
- **Effectiveness** : 75%
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Notes de Développement
|
||||||
|
|
||||||
|
### Fonctions Ajoutées
|
||||||
|
|
||||||
|
1. **`generatePersonalityInstructions(personality, intensity)`**
|
||||||
|
- Extrait vocabulairePref, connecteursPref, longueurPhrases, expressionsFavorites
|
||||||
|
- Adapte selon intensité (marqué si ≥1.0)
|
||||||
|
|
||||||
|
2. **`generateElementSpecificInstructions(chunk)`**
|
||||||
|
- Détecte types d'éléments uniques dans le chunk
|
||||||
|
- Génère instructions ciblées par type
|
||||||
|
|
||||||
|
3. **`detectElementTypeFromTag(tag)`**
|
||||||
|
- Parse le tag pour identifier le type (titre_h1, intro, texte, etc.)
|
||||||
|
|
||||||
|
4. **`getElementSpecificTip(elementType)`**
|
||||||
|
- Retourne conseil rapide adapté au type d'élément
|
||||||
|
|
||||||
|
### Compatibilité
|
||||||
|
|
||||||
|
✅ **100% rétrocompatible**
|
||||||
|
- Fonctionne avec anciennes configs (pas de breaking change)
|
||||||
|
- Si personnalité manque vocabulairePref/connecteursPref → ignore gracieusement
|
||||||
|
- Anciens workflows continuent de fonctionner normalement
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Conclusion
|
||||||
|
|
||||||
|
Les prompts adversariaux sont maintenant **3-4x plus riches** qu'avant et intègrent :
|
||||||
|
|
||||||
|
✅ 5 stratégies détecteurs (au lieu de 3)
|
||||||
|
✅ Instructions adversariales 2x plus détaillées
|
||||||
|
✅ Adaptation personnalité enrichie (vocabulaire, connecteurs, expressions)
|
||||||
|
✅ Instructions spécifiques par type d'élément
|
||||||
|
✅ Tournures idiomatiques françaises explicites
|
||||||
|
✅ Variation longueur phrases avec chiffres précis
|
||||||
|
|
||||||
|
**Résultat attendu** : Contenus avec **tournures plus intéressantes**, **meilleur respect de la personnalité**, et **authenticité maximale** ! 🚀
|
||||||
@ -237,6 +237,7 @@ async function applyHybridMethod(existingContent, config, strategy) {
|
|||||||
*/
|
*/
|
||||||
function createRegenerationPrompt(chunk, config, strategy) {
|
function createRegenerationPrompt(chunk, config, strategy) {
|
||||||
const { detectorTarget, intensity, csvData } = config;
|
const { detectorTarget, intensity, csvData } = config;
|
||||||
|
const personality = csvData?.personality;
|
||||||
|
|
||||||
let prompt = `MISSION: Réécris ces contenus pour éviter détection par ${detectorTarget}.
|
let prompt = `MISSION: Réécris ces contenus pour éviter détection par ${detectorTarget}.
|
||||||
|
|
||||||
@ -245,16 +246,24 @@ ${strategy.getInstructions(intensity).join('\n')}
|
|||||||
|
|
||||||
CONTENUS À RÉÉCRIRE:
|
CONTENUS À RÉÉCRIRE:
|
||||||
|
|
||||||
${chunk.map(([tag, content], i) => `[${i + 1}] TAG: ${tag}
|
${chunk.map(([tag, content], i) => {
|
||||||
ORIGINAL: "${content}"`).join('\n\n')}
|
const elementType = detectElementTypeFromTag(tag);
|
||||||
|
return `[${i + 1}] TAG: ${tag} | TYPE: ${elementType}
|
||||||
|
ORIGINAL: "${content}"`;
|
||||||
|
}).join('\n\n')}
|
||||||
|
|
||||||
CONSIGNES:
|
CONSIGNES GÉNÉRALES:
|
||||||
- GARDE exactement le même message et informations factuelles
|
- GARDE exactement le même message et informations factuelles
|
||||||
- CHANGE structure, vocabulaire, style pour éviter détection ${detectorTarget}
|
- CHANGE structure, vocabulaire, style pour éviter détection ${detectorTarget}
|
||||||
|
- Utilise expressions françaises familières et tournures idiomatiques authentiques
|
||||||
|
- Varie longueurs phrases : mélange phrases courtes (5-10 mots) ET longues (20-30 mots)
|
||||||
|
- Ajoute imperfections naturelles : répétitions légères, hésitations, reformulations
|
||||||
- Intensité adversariale: ${intensity.toFixed(2)}
|
- Intensité adversariale: ${intensity.toFixed(2)}
|
||||||
${csvData?.personality ? `- Style: ${csvData.personality.nom} (${csvData.personality.style})` : ''}
|
${generatePersonalityInstructions(personality, intensity)}
|
||||||
|
${generateElementSpecificInstructions(chunk)}
|
||||||
|
|
||||||
IMPORTANT: Réponse DIRECTE par les contenus réécrits, pas d'explication.
|
IMPORTANT: Ces contraintes doivent sembler naturelles, pas forcées.
|
||||||
|
Réponse DIRECTE par les contenus réécrits, pas d'explication.
|
||||||
|
|
||||||
FORMAT:
|
FORMAT:
|
||||||
[1] Contenu réécrit anti-${detectorTarget}
|
[1] Contenu réécrit anti-${detectorTarget}
|
||||||
@ -264,27 +273,137 @@ etc...`;
|
|||||||
return prompt;
|
return prompt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Générer instructions personnalité enrichies (inspiré ancien système)
|
||||||
|
*/
|
||||||
|
function generatePersonalityInstructions(personality, intensity) {
|
||||||
|
if (!personality) return '';
|
||||||
|
|
||||||
|
let instructions = `\nADAPTATION PERSONNALITÉ ${personality.nom.toUpperCase()}:
|
||||||
|
- Respecte le style ${personality.style} de ${personality.nom} de façon authentique${intensity >= 1.0 ? ' et marquée' : ''}`;
|
||||||
|
|
||||||
|
// Vocabulaire préféré
|
||||||
|
if (personality.vocabulairePref) {
|
||||||
|
const vocabArray = Array.isArray(personality.vocabulairePref)
|
||||||
|
? personality.vocabulairePref
|
||||||
|
: personality.vocabulairePref.split(',').map(v => v.trim());
|
||||||
|
instructions += `\n- Intègre naturellement ce vocabulaire: ${vocabArray.slice(0, 5).join(', ')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connecteurs préférés
|
||||||
|
if (personality.connecteursPref) {
|
||||||
|
const connArray = Array.isArray(personality.connecteursPref)
|
||||||
|
? personality.connecteursPref
|
||||||
|
: personality.connecteursPref.split(',').map(c => c.trim());
|
||||||
|
instructions += `\n- Utilise ces connecteurs variés: ${connArray.slice(0, 4).join(', ')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Longueur phrases selon personnalité
|
||||||
|
if (personality.longueurPhrases) {
|
||||||
|
instructions += `\n- Longueur phrases: ${personality.longueurPhrases} mais avec variation anti-détection`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expressions favorites
|
||||||
|
if (personality.expressionsFavorites) {
|
||||||
|
const exprArray = Array.isArray(personality.expressionsFavorites)
|
||||||
|
? personality.expressionsFavorites
|
||||||
|
: personality.expressionsFavorites.split(',').map(e => e.trim());
|
||||||
|
instructions += `\n- Expressions typiques: ${exprArray.slice(0, 3).join(', ')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return instructions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Générer instructions spécifiques par type d'élément (inspiré ancien système)
|
||||||
|
*/
|
||||||
|
function generateElementSpecificInstructions(chunk) {
|
||||||
|
const elementTypes = new Set(chunk.map(([tag]) => detectElementTypeFromTag(tag)));
|
||||||
|
|
||||||
|
if (elementTypes.size === 0) return '';
|
||||||
|
|
||||||
|
let instructions = '\n\nINSTRUCTIONS SPÉCIFIQUES PAR TYPE:';
|
||||||
|
|
||||||
|
if (elementTypes.has('titre_h1') || elementTypes.has('titre_h2')) {
|
||||||
|
instructions += `\n• TITRES: Évite formules marketing lisses, préfère authentique et direct`;
|
||||||
|
instructions += `\n Varie structure : question, affirmation, fragment percutant`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elementTypes.has('intro')) {
|
||||||
|
instructions += `\n• INTRO: Commence par angle inattendu : anecdote, constat, question rhétorique`;
|
||||||
|
instructions += `\n Évite intro-types, crée surprise puis retour naturel au sujet`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elementTypes.has('texte')) {
|
||||||
|
instructions += `\n• TEXTES: Mélange informations factuelles et observations personnelles`;
|
||||||
|
instructions += `\n Intègre apartés : "(j'ai testé, c'est bluffant)", questions rhétoriques`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elementTypes.has('faq_question')) {
|
||||||
|
instructions += `\n• QUESTIONS FAQ: Formulations vraiment utilisées par clients, pas académiques`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elementTypes.has('faq_reponse')) {
|
||||||
|
instructions += `\n• RÉPONSES FAQ: Ajoute nuances, "ça dépend", précisions contextuelles comme humain`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elementTypes.has('conclusion')) {
|
||||||
|
instructions += `\n• CONCLUSION: Personnalise avec avis subjectif ou ouverture inattendue`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return instructions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Détecter type d'élément depuis le tag
|
||||||
|
*/
|
||||||
|
function detectElementTypeFromTag(tag) {
|
||||||
|
const tagLower = tag.toLowerCase();
|
||||||
|
|
||||||
|
if (tagLower.includes('titre_h1') || tagLower === 'titre_h1') return 'titre_h1';
|
||||||
|
if (tagLower.includes('titre_h2') || tagLower.includes('h2')) return 'titre_h2';
|
||||||
|
if (tagLower.includes('intro')) return 'intro';
|
||||||
|
if (tagLower.includes('conclusion')) return 'conclusion';
|
||||||
|
if (tagLower.includes('faq_question') || tagLower.includes('question')) return 'faq_question';
|
||||||
|
if (tagLower.includes('faq_reponse') || tagLower.includes('reponse')) return 'faq_reponse';
|
||||||
|
|
||||||
|
return 'texte';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Créer prompt d'enhancement adversarial
|
* Créer prompt d'enhancement adversarial
|
||||||
*/
|
*/
|
||||||
function createEnhancementPrompt(elementsToEnhance, config, strategy) {
|
function createEnhancementPrompt(elementsToEnhance, config, strategy) {
|
||||||
const { detectorTarget, intensity } = config;
|
const { detectorTarget, intensity, csvData } = config;
|
||||||
|
const personality = csvData?.personality;
|
||||||
|
|
||||||
let prompt = `MISSION: Améliore subtilement ces contenus pour réduire détection ${detectorTarget}.
|
let prompt = `MISSION: Améliore subtilement ces contenus pour réduire détection ${detectorTarget}.
|
||||||
|
|
||||||
AMÉLIORATIONS CIBLÉES:
|
AMÉLIORATIONS CIBLÉES ANTI-${detectorTarget.toUpperCase()}:
|
||||||
${strategy.getEnhancementTips(intensity).join('\n')}
|
${strategy.getEnhancementTips(intensity).join('\n')}
|
||||||
|
|
||||||
|
TECHNIQUES GÉNÉRALES:
|
||||||
|
- Remplace mots typiques IA par synonymes plus naturels et moins évidents
|
||||||
|
- Varie longueurs phrases et structures syntaxiques
|
||||||
|
- Utilise expressions idiomatiques françaises et tournures familières
|
||||||
|
- Ajoute nuances humaines : "peut-être", "généralement", "souvent"
|
||||||
|
- Intègre connecteurs variés et naturels selon contexte
|
||||||
|
${generatePersonalityInstructions(personality, intensity)}
|
||||||
|
|
||||||
ÉLÉMENTS À AMÉLIORER:
|
ÉLÉMENTS À AMÉLIORER:
|
||||||
|
|
||||||
${elementsToEnhance.map((element, i) => `[${i + 1}] TAG: ${element.tag}
|
${elementsToEnhance.map((element, i) => {
|
||||||
|
const elementType = detectElementTypeFromTag(element.tag);
|
||||||
|
return `[${i + 1}] TAG: ${element.tag} | TYPE: ${elementType}
|
||||||
CONTENU: "${element.content}"
|
CONTENU: "${element.content}"
|
||||||
PROBLÈME: ${element.detectionRisk}`).join('\n\n')}
|
PROBLÈME DÉTECTÉ: ${element.detectionRisk}
|
||||||
|
${getElementSpecificTip(elementType)}`;
|
||||||
|
}).join('\n\n')}
|
||||||
|
|
||||||
CONSIGNES:
|
CONSIGNES:
|
||||||
- Modifications LÉGÈRES et naturelles
|
- Modifications LÉGÈRES mais EFFICACES pour anti-détection
|
||||||
- GARDE le fond du message intact
|
- GARDE le fond du message intact (informations factuelles identiques)
|
||||||
- Focus sur réduction détection ${detectorTarget}
|
- Focus sur réduction détection ${detectorTarget} avec naturalité
|
||||||
- Intensité: ${intensity.toFixed(2)}
|
- Intensité: ${intensity.toFixed(2)}
|
||||||
|
|
||||||
FORMAT DE RÉPONSE OBLIGATOIRE (UN PAR LIGNE):
|
FORMAT DE RÉPONSE OBLIGATOIRE (UN PAR LIGNE):
|
||||||
@ -297,11 +416,29 @@ IMPORTANT:
|
|||||||
- Réponds UNIQUEMENT avec les contenus améliorés
|
- Réponds UNIQUEMENT avec les contenus améliorés
|
||||||
- GARDE le numéro [N] devant chaque contenu
|
- GARDE le numéro [N] devant chaque contenu
|
||||||
- PAS d'explications, PAS de commentaires
|
- PAS d'explications, PAS de commentaires
|
||||||
- RESPECTE STRICTEMENT le format [N] Contenu`;
|
- RESPECTE STRICTEMENT le format [N] Contenu
|
||||||
|
- Ces améliorations doivent sembler naturelles, pas forcées`;
|
||||||
|
|
||||||
return prompt;
|
return prompt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtenir conseil spécifique pour type d'élément (enhancement)
|
||||||
|
*/
|
||||||
|
function getElementSpecificTip(elementType) {
|
||||||
|
const tips = {
|
||||||
|
'titre_h1': 'TIP: Évite formules marketing, préfère authentique et percutant',
|
||||||
|
'titre_h2': 'TIP: Varie structure (question/affirmation/fragment)',
|
||||||
|
'intro': 'TIP: Commence par angle inattendu si possible',
|
||||||
|
'texte': 'TIP: Ajoute observation personnelle ou aparté léger',
|
||||||
|
'faq_question': 'TIP: Formulation vraie client, pas académique',
|
||||||
|
'faq_reponse': 'TIP: Ajoute nuance "ça dépend" ou précision contextuelle',
|
||||||
|
'conclusion': 'TIP: Personnalise avec avis subjectif subtil'
|
||||||
|
};
|
||||||
|
|
||||||
|
return tips[elementType] || 'TIP: Rends plus naturel et humain';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parser réponse régénération
|
* Parser réponse régénération
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -381,6 +381,221 @@ class OriginalityStrategy extends BaseDetectorStrategy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STRATÉGIE ANTI-COPYLEAKS
|
||||||
|
* Focus: Originalité absolue et reformulation créative
|
||||||
|
*/
|
||||||
|
class CopyLeaksStrategy extends BaseDetectorStrategy {
|
||||||
|
constructor() {
|
||||||
|
super('CopyLeaks');
|
||||||
|
this.effectiveness = 0.85;
|
||||||
|
this.targetMetrics = ['originality_score', 'paraphrasing_quality', 'uniqueness'];
|
||||||
|
|
||||||
|
this.techniques = {
|
||||||
|
radicalReformulation: {
|
||||||
|
name: 'Reformulation radicale',
|
||||||
|
rules: [
|
||||||
|
'Reformule idées communes avec angles totalement originaux',
|
||||||
|
'Évite phrases-types et formulations standard du secteur',
|
||||||
|
'Transforme descriptions directes en récits ou témoignages',
|
||||||
|
'Réinvente la façon de présenter informations basiques'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
personalizedExamples: {
|
||||||
|
name: 'Exemples personnalisés',
|
||||||
|
rules: [
|
||||||
|
'Personnalise chaque assertion avec exemples spécifiques',
|
||||||
|
'Utilise analogies et métaphores plutôt que descriptions directes',
|
||||||
|
'Fragmente informations techniques en observations pratiques',
|
||||||
|
'Contextualise chaque donnée factuelle avec du vécu'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
generateInstructions(elementType, personality, csvData) {
|
||||||
|
const instructions = [];
|
||||||
|
|
||||||
|
instructions.push(`ANTI-COPYLEAKS - ORIGINALITÉ MAXIMALE:`);
|
||||||
|
|
||||||
|
// Reformulation radicale
|
||||||
|
instructions.push(`\nREFORMULATION RADICALE:`);
|
||||||
|
this.techniques.radicalReformulation.rules.forEach(rule => {
|
||||||
|
instructions.push(`• ${rule}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Exemples personnalisés
|
||||||
|
instructions.push(`\nPERSONNALISATION:`);
|
||||||
|
this.techniques.personalizedExamples.rules.forEach(rule => {
|
||||||
|
instructions.push(`• ${rule}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
return instructions.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
getInstructions(intensity = 1.0) {
|
||||||
|
const baseRules = [
|
||||||
|
'Reformule idées communes avec angles totalement originaux',
|
||||||
|
'Évite phrases-types et formulations standard du secteur',
|
||||||
|
'Personnalise chaque assertion avec exemples spécifiques',
|
||||||
|
'Réinvente la façon de présenter informations basiques'
|
||||||
|
];
|
||||||
|
|
||||||
|
const intensiveRules = [
|
||||||
|
'Utilise analogies et métaphores plutôt que descriptions directes',
|
||||||
|
'Fragmente informations techniques en observations pratiques',
|
||||||
|
'Transforme données factuelles en récits ou témoignages'
|
||||||
|
];
|
||||||
|
|
||||||
|
return intensity >= 1.0 ? [...baseRules, ...intensiveRules] : baseRules;
|
||||||
|
}
|
||||||
|
|
||||||
|
getEnhancementTips(intensity = 1.0) {
|
||||||
|
return [
|
||||||
|
'Trouve angles d\'approche inédits pour infos classiques',
|
||||||
|
'Remplace descriptions techniques par analogies concrètes',
|
||||||
|
'Contextualise avec exemples spécifiques et originaux',
|
||||||
|
...(intensity > 0.8 ? [
|
||||||
|
'Transforme assertions en mini-récits authentiques',
|
||||||
|
'Crée métaphores personnalisées au contexte'
|
||||||
|
] : [])
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
analyzeContent(content) {
|
||||||
|
const baseMetrics = super.analyzeContent(content);
|
||||||
|
const words = content.split(/\s+/);
|
||||||
|
|
||||||
|
// Détection formulations standard
|
||||||
|
const standardPhrases = [
|
||||||
|
'il est important de', 'permet de', 'grâce à', 'en effet',
|
||||||
|
'par ailleurs', 'de plus', 'notamment', 'ainsi'
|
||||||
|
];
|
||||||
|
|
||||||
|
const standardCount = standardPhrases.reduce((count, phrase) => {
|
||||||
|
return count + (content.toLowerCase().match(new RegExp(phrase, 'g')) || []).length;
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
const standardDensity = (standardCount / words.length) * 100;
|
||||||
|
const originalityScore = Math.max(0, 100 - (standardDensity * 20));
|
||||||
|
|
||||||
|
return {
|
||||||
|
...baseMetrics,
|
||||||
|
standardPhrasesCount: standardCount,
|
||||||
|
standardDensity: Math.round(standardDensity * 100) / 100,
|
||||||
|
originalityScore: Math.round(originalityScore),
|
||||||
|
copyLeaksRiskLevel: originalityScore > 70 ? 'low' : originalityScore > 40 ? 'medium' : 'high'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STRATÉGIE ANTI-WINSTON
|
||||||
|
* Focus: Variation humaine et imperfections authentiques
|
||||||
|
*/
|
||||||
|
class WinstonStrategy extends BaseDetectorStrategy {
|
||||||
|
constructor() {
|
||||||
|
super('Winston');
|
||||||
|
this.effectiveness = 0.8;
|
||||||
|
this.targetMetrics = ['human_variation', 'stylistic_inconsistency', 'emotional_range'];
|
||||||
|
|
||||||
|
this.techniques = {
|
||||||
|
stylisticVariation: {
|
||||||
|
name: 'Variation stylistique',
|
||||||
|
rules: [
|
||||||
|
'Évite cohérence stylistique trop parfaite entre paragraphes',
|
||||||
|
'Simule variation naturelle d\'humeur et d\'énergie rédactionnelle',
|
||||||
|
'Varie niveau de détail : parfois précis, parfois elliptique',
|
||||||
|
'Alterne registres émotionnels : enthousiaste → neutre → critique'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
humanImperfections: {
|
||||||
|
name: 'Imperfections humaines',
|
||||||
|
rules: [
|
||||||
|
'Intègre "erreurs" humaines : répétitions, corrections, précisions',
|
||||||
|
'Inclus hésitations et nuances : "peut-être", "généralement", "souvent"',
|
||||||
|
'Personnalise avec opinions subjectives et préférences',
|
||||||
|
'Ajoute auto-corrections : "enfin, plus précisément..."'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
generateInstructions(elementType, personality, csvData) {
|
||||||
|
const instructions = [];
|
||||||
|
|
||||||
|
instructions.push(`ANTI-WINSTON - VARIATION HUMAINE MAXIMALE:`);
|
||||||
|
|
||||||
|
// Variation stylistique
|
||||||
|
instructions.push(`\nVARIATION STYLISTIQUE:`);
|
||||||
|
this.techniques.stylisticVariation.rules.forEach(rule => {
|
||||||
|
instructions.push(`• ${rule}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Imperfections humaines
|
||||||
|
instructions.push(`\nIMPERFECTIONS AUTHENTIQUES:`);
|
||||||
|
this.techniques.humanImperfections.rules.forEach(rule => {
|
||||||
|
instructions.push(`• ${rule}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
return instructions.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
getInstructions(intensity = 1.0) {
|
||||||
|
const baseRules = [
|
||||||
|
'Évite cohérence stylistique trop parfaite entre paragraphes',
|
||||||
|
'Simule variation naturelle d\'humeur et d\'énergie rédactionnelle',
|
||||||
|
'Intègre "erreurs" humaines : répétitions, corrections, précisions',
|
||||||
|
'Varie niveau de détail : parfois précis, parfois elliptique'
|
||||||
|
];
|
||||||
|
|
||||||
|
const intensiveRules = [
|
||||||
|
'Alterne registres émotionnels : enthousiaste → neutre → critique',
|
||||||
|
'Inclus hésitations et nuances : "peut-être", "généralement", "souvent"',
|
||||||
|
'Personnalise avec opinions subjectives et préférences',
|
||||||
|
'Ajoute auto-corrections et reformulations spontanées'
|
||||||
|
];
|
||||||
|
|
||||||
|
return intensity >= 1.0 ? [...baseRules, ...intensiveRules] : baseRules;
|
||||||
|
}
|
||||||
|
|
||||||
|
getEnhancementTips(intensity = 1.0) {
|
||||||
|
return [
|
||||||
|
'Ajoute hésitations naturelles et nuances',
|
||||||
|
'Varie ton et énergie légèrement dans le texte',
|
||||||
|
'Inclus répétitions légères ou reformulations',
|
||||||
|
...(intensity > 0.8 ? [
|
||||||
|
'Personnalise avec opinions subjectives',
|
||||||
|
'Simule changements d\'humeur subtils'
|
||||||
|
] : [])
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
analyzeContent(content) {
|
||||||
|
const baseMetrics = super.analyzeContent(content);
|
||||||
|
|
||||||
|
// Détection variation humaine
|
||||||
|
const humanMarkers = [
|
||||||
|
'peut-être', 'probablement', 'généralement', 'souvent',
|
||||||
|
'parfois', 'vraiment', 'plutôt', 'assez'
|
||||||
|
];
|
||||||
|
|
||||||
|
const humanMarkerCount = humanMarkers.reduce((count, marker) => {
|
||||||
|
return count + (content.toLowerCase().match(new RegExp(`\\b${marker}\\b`, 'g')) || []).length;
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
const sentences = content.split(/[.!?]+/).filter(s => s.trim().length > 5);
|
||||||
|
const humanVariationScore = Math.min(100, (humanMarkerCount / sentences.length) * 100);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...baseMetrics,
|
||||||
|
humanMarkerCount,
|
||||||
|
humanVariationScore: Math.round(humanVariationScore),
|
||||||
|
winstonRiskLevel: humanVariationScore > 30 ? 'low' : humanVariationScore > 15 ? 'medium' : 'high'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* STRATÉGIE GÉNÉRALE
|
* STRATÉGIE GÉNÉRALE
|
||||||
* Équilibre entre toutes les techniques
|
* Équilibre entre toutes les techniques
|
||||||
@ -487,7 +702,9 @@ class DetectorStrategyFactory {
|
|||||||
static strategies = {
|
static strategies = {
|
||||||
'general': GeneralStrategy,
|
'general': GeneralStrategy,
|
||||||
'gptZero': GPTZeroStrategy,
|
'gptZero': GPTZeroStrategy,
|
||||||
'originality': OriginalityStrategy
|
'originality': OriginalityStrategy,
|
||||||
|
'copyLeaks': CopyLeaksStrategy,
|
||||||
|
'winston': WinstonStrategy
|
||||||
};
|
};
|
||||||
|
|
||||||
static createStrategy(detectorName) {
|
static createStrategy(detectorName) {
|
||||||
@ -568,6 +785,8 @@ module.exports = {
|
|||||||
DetectorStrategyFactory,
|
DetectorStrategyFactory,
|
||||||
GPTZeroStrategy,
|
GPTZeroStrategy,
|
||||||
OriginalityStrategy,
|
OriginalityStrategy,
|
||||||
|
CopyLeaksStrategy,
|
||||||
|
WinstonStrategy,
|
||||||
GeneralStrategy,
|
GeneralStrategy,
|
||||||
selectOptimalStrategy,
|
selectOptimalStrategy,
|
||||||
BaseDetectorStrategy
|
BaseDetectorStrategy
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user