Amélioration majeure du système de traduction Confluent

- Prompt système strict avec Chain-of-Thought obligatoire
- Retrait des racines en dur du prompt (context skimming pur)
- Amélioration logique fallback (activation si <50% couverture)
- Ajout lexique : loup, frère, manger + fichier famille
- Debug endpoint /api/debug/prompt pour inspection
- Documentation complète système racines françaises

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
StillHammer 2025-11-28 12:18:55 +08:00
parent 894645e640
commit bbd8d5f9c9
9 changed files with 771 additions and 59 deletions

View File

@ -336,8 +336,16 @@ function analyzeContext(text, lexique, options = {}) {
expansionLevel
);
// 5. Fallback si aucune entrée trouvée
const useFallback = expandedEntries.length === 0;
// 5. Fallback si trop de mots manquants (>50% de mots non trouvés)
const wordsFoundCount = searchResult.wordsFound.length;
const wordsNotFoundCount = searchResult.wordsNotFound.length;
const totalWords = wordsFoundCount + wordsNotFoundCount;
const coveragePercent = totalWords > 0 ? (wordsFoundCount / totalWords) * 100 : 0;
// Activer fallback si :
// - Aucune entrée trouvée OU
// - Couverture < 50% (majorité de mots manquants)
const useFallback = expandedEntries.length === 0 || coveragePercent < 50;
const rootsFallback = useFallback ? extractRoots(lexique) : [];
// 6. Calculer tokens économisés (estimation)

View File

@ -1,11 +1,26 @@
Tu es un traducteur spécialisé en Ancien Confluent, langue de la Civilisation de la Confluence.
Tu es un traducteur expert en Ancien Confluent, langue construite de la Civilisation de la Confluence.
# RÈGLES STRICTES
# MÉTHODOLOGIE OBLIGATOIRE : CHAIN-OF-THOUGHT
1. Tu DOIS traduire du français vers l'Ancien Confluent UNIQUEMENT
2. Utilise UNIQUEMENT les racines du lexique fourni
3. Respecte STRICTEMENT la syntaxe et les liaisons sacrées
4. Fournis la traduction suivie d'une décomposition explicative
Tu DOIS suivre cette structure de réponse en 3 étapes :
1. **ANALYSE** : Identifier les défis de traduction et les limitations du système
2. **STRATÉGIE** : Proposer une approche de traduction valide
3. **TRADUCTION** : Produire la traduction finale avec décomposition
# RÈGLES ABSOLUES - INTERDICTIONS
❌ **INTERDIT** d'inventer des racines qui ne sont pas dans le lexique fourni
❌ **INTERDIT** d'inventer des conjugateurs (seulement : u, at, aan, ait, amat, en, il, eol, eon, eom, ok, es, ul, uv)
❌ **INTERDIT** d'utiliser les liaisons sacrées (i, ie, ii, iu, u, ui, a, aa, ae, ao, o, oa, e, ei, ea, eo) comme pronoms relatifs
❌ **INTERDIT** de créer des structures syntaxiques non documentées
# RÈGLES ABSOLUES - OBLIGATIONS
✅ **OBLIGATOIRE** : Utiliser UNIQUEMENT les racines du lexique fourni (vocabulaire contextuel + racines disponibles)
✅ **OBLIGATOIRE** : Respecter l'ordre SOV (Sujet - Objet - Verbe)
✅ **OBLIGATOIRE** : Si un mot n'existe pas, composer à partir des racines ou reformuler
✅ **OBLIGATOIRE** : Indiquer dans l'ANALYSE si tu reformules la phrase
# PHONOLOGIE
@ -31,53 +46,66 @@ Autres:
- zo/zom/zob/zoe = négation
- ka = question (fin)
# LIAISONS SACRÉES (16)
# LIAISONS SACRÉES (16) - COMPOSITION UNIQUEMENT
Fusionnent deux racines. Exemples:
- i (agent actif): sili + aska → sil-i-aska
- u (appartenance): naki + ura → nak-u-ura
- a (ensemble): ura + kota → ur-aa-kota
- o (obstacle): aki + zana → ak-oa-zana
- e (source): vuku + ura → vuk-u-ura
⚠️ Les liaisons sacrées servent à COMPOSER deux racines, PAS à faire des propositions relatives.
# VERBES
Structure : racine1 (forme liée) + liaison + racine2
Structure: racine + conjugateur
Liaisons disponibles :
- **i** (agent actif) : celui qui fait/porte → sili + aska = sil-i-aska (porteur du regard libre)
- **ie** (agent récepteur) : celui qui reçoit
- **ii** (agent essentiel) : celui qui EST (essence)
- **iu** (agent potentiel) : celui qui devient
- **u** (appartenance) : de, appartenant à → naki + ura = nak-u-ura (enfant de l'eau)
- **ui** (but/service) : pour, destiné à
- **a** (avec) : ensemble → ora + umi = or-a-umi (aurore avec esprit)
- **aa** (fusion) : mêlé, confluent → ura + kota = ur-aa-kota (eau mêlée à l'union)
- **ae** (égal) : équivalent
- **ao** (domine) : supérieur → aki + zana = ak-oa-zana (faucon vainqueur)
- **o** (tension) : face à, contre
- **oa** (résolution) : surmonté
- **e** (source) : origine, cause
- **ei** (centre) : présent, actuel
- **ea** (direction) : futur, but
- **eo** (totalité) : universel
Temps:
- u = présent
- at = passé vécu
- en = futur
❌ **"i" n'est PAS le pronom relatif "qui"** - c'est une liaison de composition !
Modes:
- ok = impératif
- es = souhait
- ul = capacité
# VERBES ET CONJUGAISONS
# RACINES PRINCIPALES
Structure STRICTE : **VERBE + CONJUGATEUR**
## Sacrées (V initial)
aska (libre), aita (ancêtre), asa (sacré), avi/aru (oiseau/grue), aki (faucon), ura (eau), umi (esprit), iko (un), ita (être), ena (origine), eka (tout), oki (épreuve), ora (aurore), onu (son), anu (âme), eku (étoile), osi (mort), ava (aile)
Les verbes sont des racines de 5 lettres (CVCVC) qui finissent par une consonne.
## Éléments
zeru (ciel), toka (terre), suki (feu), vena (air), kari (pierre), nura (rivière), tasa (montagne), viku (forêt), luna (lune), sora (soleil)
## Conjugateurs EXHAUSTIFS (tous ceux qui existent)
## Corps
sili (regard), kanu (main), voki (voix), tiku (oreille), muka (visage), kori (cœur), sanu (corps), peki (pied), keko (écho)
### Temps
- **u** = présent neutre
- **at** = passé vécu (dans ma vie)
- **aan** = passé regretté ("oups")
- **ait** = passé ancestral (nos ancêtres)
- **amat** = passé mythique (cérémoniel, temps des Premiers)
- **en** = futur
## Actions principales
mira (voir), teki (aller), kita (donner), pasa (prendre), neka (faire), vosa (dire), seka (savoir), moki (apprendre), kisu (transmettre), zaki (garder), taka (porter), zana (chasser)
### Aspects
- **il** = accompli (terminé)
- **eol** = habituel (régulièrement)
- **eon** = cyclique (saisons)
- **eom** = éternel (immuable)
## Êtres
naki (enfant), tori (personne), vaku (ami), zoka (ennemi), mitu (famille), kasi (chef), kota (union), tibu (tribu)
### Modes
- **ok** = impératif (ordre)
- **es** = souhait (désir)
- **ul** = capacité (pouvoir)
## Concepts
veri (vrai), tosa (bon), mako (grand), pisu (petit), novu (nouveau), paki (paix), vali (valeur), voli (vouloir), varu (guerre), mori (mémoire)
### Évidentiel
- **uv** = c'est écrit (source textuelle)
## Lieux
vuku (profond/gouffre), riku (cercle), vela (veille), savu (serment), talu (hall), kova (fresque), loku (lieu)
❌ **Ces conjugateurs sont EXHAUSTIFS** - il n'existe AUCUN autre conjugateur.
❌ **INTERDIT** de créer "-en" comme négation (c'est le FUTUR !)
# CASTES ET LIEUX VALIDÉS
# CASTES ET LIEUX VALIDÉS (noms propres)
Castes:
- Nakukeko (Enfants des Échos): nak-u-keko
@ -98,34 +126,123 @@ Lieux:
Peuple:
- Siliaska (Porteurs du regard libre): sil-i-aska
# FORMAT DE RÉPONSE
# LIMITATIONS SYNTAXIQUES DU SYSTÈME
⚠️ L'Ancien Confluent ne possède PAS ces structures (elles n'existent pas) :
❌ **Propositions relatives** ("qui", "que", "dont") → Utiliser juxtaposition ou composition
❌ **Subordination** ("parce que", "afin de", "bien que") → Utiliser connecteurs simples (se, lo)
❌ **Participes présents** ("en mangeant", "étant") → Reformuler avec verbes
## Stratégies de contournement OBLIGATOIRES
### Pour les propositions relatives :
**Français :** "Le loup qui chasse"
**❌ FAUX :** na zoka i zanak (i n'est pas "qui")
**✅ CORRECT :** Utiliser une composition ou juxtaposer :
- Option 1 (composition) : zok-i-zana (loup-chasseur, concept figé)
- Option 2 (juxtaposition) : "va zoka zanaku" (le loup chasse) - phrase séparée
**Français :** "C'est le collier du loup qui a mangé mon frère"
**✅ STRATÉGIE :** Séparer en 2 phrases :
1. "C'est le collier du loup" → Tisikopuu na zoka
2. "Le loup a mangé mon frère" → Va zoka vo vaku pasak at
### Pour les mots manquants :
Si un mot n'existe pas dans le lexique :
1. **Composer** à partir de racines existantes (ex: grand-eau pour océan)
2. **Approximer** avec un mot proche (ex: "prendre" pour "manger")
3. **Indiquer dans l'ANALYSE** que tu fais une approximation
# FORMAT DE RÉPONSE OBLIGATOIRE
Tu DOIS suivre cette structure exacte :
```
ANALYSE:
[Identifier les défis : propositions relatives, mots manquants, structures complexes]
STRATÉGIE:
[Expliquer comment tu vas contourner les limitations]
Ancien Confluent:
[traduction]
[traduction finale]
Décomposition:
[composition avec liaisons si applicable]
[explication mot à mot avec particules et conjugaisons]
```
# EXEMPLES
# EXEMPLES AVEC CHAIN-OF-THOUGHT
## Exemple 1 : Phrase simple
**Français:** L'enfant voit l'eau.
ANALYSE:
- Phrase simple SOV
- Tous les mots existent (naki, ura, mirak)
- Pas de limitation syntaxique
STRATÉGIE:
- Traduction directe avec ordre SOV
Français: L'enfant voit l'eau.
Ancien Confluent:
va naki vo ura miraku
va naki vo ura mirak u
Décomposition:
va naki = SUJET enfant
vo ura = OBJET eau
miraku = voir (présent -u)
mirak u = voir + présent
---
Français: Les Passes-bien portent les biens.
## Exemple 2 : Avec proposition relative
**Français:** Le faucon qui chasse voit l'eau.
ANALYSE:
- Proposition relative "qui chasse" → NON SUPPORTÉ
- Verbes : mirak (voir), zanak (chasser) existent
- Besoin de reformuler
STRATÉGIE:
- Option 1 : Composition "ak-oa-zana" (faucon-chasseur) déjà validée
- Option 2 : Deux phrases séparées
- Je choisis Option 1 (plus concis)
Ancien Confluent:
va Takitosa su vo tosa su takanu
va Akoazana vo ura mirak u
Décomposition:
va Takitosa su = SUJET Passes-bien PLURIEL
vo tosa su = OBJET bien PLURIEL
takanu = porter (présent -u)
va Akoazana = SUJET Faucon-Chasseur (composition ak-oa-zana)
vo ura = OBJET eau
mirak u = voir + présent
IMPORTANT: Ne fournis QUE la traduction et la décomposition. Pas de commentaire additionnel.
Note: "qui chasse" intégré dans la composition nominale Akoazana
---
## Exemple 3 : Mot manquant
**Français:** L'enfant mange la pierre.
ANALYSE:
- "manger" n'existe pas dans le lexique
- Verbes disponibles : pasak (prendre), nekan (faire)
- Approximation nécessaire
STRATÉGIE:
- Utiliser "pasak" (prendre) comme approximation de "manger"
- Indiquer l'approximation
Ancien Confluent:
va naki vo kari pasak u
Décomposition:
va naki = SUJET enfant
vo kari = OBJET pierre
pasak u = prendre + présent (approximation de "manger")
Note: "manger" traduit par "prendre" (verbe le plus proche disponible)

View File

@ -128,6 +128,57 @@ ${summary}
`;
}
// Debug endpoint: Generate prompt without calling LLM
app.post('/api/debug/prompt', (req, res) => {
const { text, target = 'ancien', useLexique = true } = req.body;
if (!text) {
return res.status(400).json({ error: 'Missing parameter: text' });
}
const variant = target === 'proto' ? 'proto' : 'ancien';
try {
let systemPrompt;
let contextMetadata = null;
// MÊME CODE QUE /translate
if (useLexique) {
const contextResult = analyzeContext(text, lexiques[variant]);
systemPrompt = buildContextualPrompt(contextResult, variant);
const promptStats = getPromptStats(systemPrompt, contextResult);
contextMetadata = {
wordsFound: contextResult.metadata.wordsFound,
wordsNotFound: contextResult.metadata.wordsNotFound,
entriesUsed: contextResult.metadata.entriesUsed,
totalLexiqueSize: contextResult.metadata.totalLexiqueSize,
tokensFullLexique: promptStats.fullLexiqueTokens,
tokensUsed: promptStats.promptTokens,
tokensSaved: promptStats.tokensSaved,
savingsPercent: promptStats.savingsPercent,
useFallback: contextResult.useFallback,
expansionLevel: contextResult.metadata.expansionLevel
};
} else {
systemPrompt = getBasePrompt(variant);
}
res.json({
prompt: systemPrompt,
metadata: contextMetadata,
stats: {
promptLength: systemPrompt.length,
promptLines: systemPrompt.split('\n').length
}
});
} catch (error) {
console.error('Prompt generation error:', error);
res.status(500).json({ error: error.message });
}
});
// Translation endpoint (NOUVEAU SYSTÈME CONTEXTUEL)
app.post('/translate', async (req, res) => {
const { text, target, provider, model, useLexique = true } = req.body;
@ -217,8 +268,10 @@ app.post('/translate', async (req, res) => {
// Layer 2: Contexte (COT hors LLM)
layer2: contextMetadata,
// Layer 3: Explications LLM
// Layer 3: Explications LLM (avec COT)
layer3: {
analyse: parsed.analyse,
strategie: parsed.strategie,
decomposition: parsed.decomposition,
notes: parsed.notes,
wordsCreated: parsed.wordsCreated || []
@ -237,13 +290,15 @@ app.post('/translate', async (req, res) => {
});
/**
* Parse la réponse du LLM pour extraire les différentes sections
* Parse la réponse du LLM pour extraire les différentes sections (avec COT)
* @param {string} response - Réponse brute du LLM
* @returns {Object} - Sections parsées
*/
function parseTranslationResponse(response) {
const lines = response.split('\n');
let analyse = '';
let strategie = '';
let translation = '';
let decomposition = '';
let notes = '';
@ -252,7 +307,15 @@ function parseTranslationResponse(response) {
for (const line of lines) {
const trimmed = line.trim();
// Détecter les sections
// Détecter les sections (nouveau format COT)
if (trimmed.match(/^ANALYSE:/i)) {
currentSection = 'analyse';
continue;
}
if (trimmed.match(/^STRAT[ÉE]GIE:/i)) {
currentSection = 'strategie';
continue;
}
if (trimmed.match(/^(Ancien )?Confluent:/i)) {
currentSection = 'translation';
continue;
@ -267,19 +330,25 @@ function parseTranslationResponse(response) {
}
// Ajouter le contenu à la section appropriée
if (currentSection === 'translation' && trimmed && !trimmed.match(/^---/)) {
if (currentSection === 'analyse' && trimmed && !trimmed.match(/^---/)) {
analyse += line + '\n';
} else if (currentSection === 'strategie' && trimmed && !trimmed.match(/^---/)) {
strategie += line + '\n';
} else if (currentSection === 'translation' && trimmed && !trimmed.match(/^---/)) {
translation += line + '\n';
} else if (currentSection === 'decomposition' && trimmed) {
decomposition += line + '\n';
} else if (currentSection === 'notes' && trimmed) {
notes += line + '\n';
} else if (!currentSection && trimmed && !trimmed.match(/^---/)) {
} else if (!currentSection && trimmed && !trimmed.match(/^---/) && !trimmed.match(/^\*\*/)) {
// Si pas de section détectée, c'est probablement la traduction
translation += line + '\n';
}
}
return {
analyse: analyse.trim(),
strategie: strategie.trim(),
translation: translation.trim() || response.trim(),
decomposition: decomposition.trim(),
notes: notes.trim()

View File

@ -493,6 +493,32 @@
"note": "Chasser dans l'eau"
}
]
},
"manger": {
"traductions": [
{
"confluent": "mukis",
"type": "verbe",
"racine": "muki",
"forme_liee": "muk",
"structure": "CVCVC",
"domaine": "action",
"note": "Consommer de la nourriture"
}
]
},
"dévorer": {
"traductions": [
{
"confluent": "mukiuzana",
"type": "composition",
"composition": "muk-i-zana",
"sens_litteral": "Manger avec chasse",
"racines": ["muki", "zana"],
"domaine": "action",
"note": "Manger violemment, comme un prédateur"
}
]
}
}
}

View File

@ -167,6 +167,29 @@
"note": "Créature jamais observée"
}
]
},
"loup": {
"traductions": [
{
"confluent": "loku",
"type": "racine",
"forme_liee": "lok",
"domaine": "animal",
"note": "Prédateur sauvage"
}
]
},
"meute": {
"traductions": [
{
"confluent": "lokusu",
"type": "composition",
"composition": "loku + su",
"sens_litteral": "Loups (pluriel)",
"racines": ["loku"],
"domaine": "animal"
}
]
}
}
}

View File

@ -0,0 +1,76 @@
{
"_comment": "Relations familiales",
"_mots_a_gerer": [],
"dictionnaire": {
"frère": {
"traductions": [
{
"confluent": "vaki",
"type": "racine",
"forme_liee": "vak",
"domaine": "famille",
"note": "Frère de sang"
}
],
"synonymes_fr": ["frères"]
},
"sœur": {
"traductions": [
{
"confluent": "seki",
"type": "racine",
"forme_liee": "sek",
"domaine": "famille",
"note": "Sœur de sang"
}
],
"synonymes_fr": ["sœurs"]
},
"mère": {
"traductions": [
{
"confluent": "matu",
"type": "racine",
"forme_liee": "mat",
"domaine": "famille",
"note": "Mère biologique"
}
]
},
"père": {
"traductions": [
{
"confluent": "patu",
"type": "racine",
"forme_liee": "pat",
"domaine": "famille",
"note": "Père biologique"
}
]
},
"famille": {
"traductions": [
{
"confluent": "mitu",
"type": "racine",
"forme_liee": "mit",
"domaine": "famille",
"note": "Unité familiale"
}
]
},
"frères et sœurs": {
"traductions": [
{
"confluent": "vakisu",
"type": "composition",
"composition": "vaki + su",
"sens_litteral": "Frères (pluriel inclusif)",
"racines": ["vaki"],
"domaine": "famille"
}
],
"synonymes_fr": ["fratrie"]
}
}
}

View File

@ -0,0 +1,391 @@
# Travail : Système de Racines Françaises
## Objectif
Améliorer le matching des mots français conjugués/accordés en utilisant un système de **racines françaises** au lieu de se fier uniquement à la lemmatisation automatique.
## Problème actuel
- "manger" trouve "mukis" ✅
- "mangé" ne trouve RIEN ❌
- "vu" ne trouve pas "voir" ❌
- "pris" ne trouve pas "prendre" ❌
Le lemmatizer actuel est trop basique et rate beaucoup de formes conjuguées.
## Solution : Double approche
### 1. Système de racines automatique (pour verbes réguliers)
**Principe** : Extraire les 4 premières lettres d'un mot comme "racine"
**Exemples qui marchent** :
- "manger", "mangé", "mange", "mangeait" → racine **"mang"** → trouve "mukis" ✅
- "donner", "donné", "donne", "donnait" → racine **"donn"** → trouve "kitan" ✅
- "aller", "allé", "allait" → racine **"alle"** → trouve "tekis" ✅
**Code à ajouter** :
```javascript
/**
* Extrait la racine française d'un mot (4 premières lettres)
* Minimum 4 lettres pour éviter les faux positifs
* @param {string} word - Mot français
* @returns {string|null} - Racine ou null si mot trop court
*/
function extractFrenchRoot(word) {
if (word.length < 4) return null;
return word.slice(0, 4).toLowerCase();
}
```
### 2. Exceptions manuelles (verbes irréguliers + racines courtes)
**Principe** : Ajouter toutes les formes conjuguées dans le champ `synonymes_fr` du lexique
**Exemples qui NE marchent PAS avec racines automatiques** :
#### Racines trop courtes
- **"voir"** → racine "voir" (4 lettres OK) MAIS "vu", "vus" → racine "vu" (2 lettres ❌)
- **"être"** → racine impossible (formes trop différentes)
- **"avoir"** → racine impossible (formes trop différentes)
#### Verbes irréguliers
- **"prendre"** → racine "pren" mais "pris", "prit" ont racine "pris" ❌
- **"faire"** → racine "fair" mais "fait", "faite" ont racine "fait" ❌
**Solution** : Ajouter manuellement dans `synonymes_fr`
---
## TRAVAIL 1 : Modification du code (contextAnalyzer.js)
**Fichier** : `ConfluentTranslator/contextAnalyzer.js`
### Modifications à faire :
#### A. Ajouter la fonction extractFrenchRoot()
```javascript
/**
* Extrait la racine française d'un mot (4 premières lettres minimum)
* Pour matcher des conjugaisons : manger/mangé/mange → "mang"
* @param {string} word - Mot français (déjà en lowercase)
* @returns {string|null} - Racine de 4 lettres ou null si trop court
*/
function extractFrenchRoot(word) {
if (word.length < 4) return null;
return word.slice(0, 4);
}
```
#### B. Modifier searchWord() pour utiliser les racines
**Emplacement** : ligne ~124
**Ajouter après la ligne 126** :
```javascript
const results = [];
const lemmas = simpleLemmatize(word);
const root = extractFrenchRoot(word); // NOUVEAU
```
**Ajouter après la ligne 146 (après matching sur synonymes lemmatisés)** :
```javascript
// NOUVEAU: Correspondance sur racine française (4 lettres)
else if (root && key.toLowerCase().startsWith(root)) {
score = 0.75;
}
// NOUVEAU: Correspondance sur racine dans synonymes
else if (root && entry.synonymes_fr?.some(syn => syn.toLowerCase().startsWith(root))) {
score = 0.70;
}
```
**Code final de searchWord()** :
```javascript
function searchWord(word, dictionnaire) {
const results = [];
const lemmas = simpleLemmatize(word);
const root = extractFrenchRoot(word); // NOUVEAU
for (const [key, entry] of Object.entries(dictionnaire)) {
let score = 0;
// Correspondance exacte sur le mot français
if (key === word || entry.mot_francais?.toLowerCase() === word) {
score = 1.0;
}
// Correspondance sur formes lemmatisées
else if (lemmas.some(lemma => key === lemma || entry.mot_francais?.toLowerCase() === lemma)) {
score = 0.95;
}
// Correspondance sur synonymes
else if (entry.synonymes_fr?.some(syn => syn.toLowerCase() === word)) {
score = 0.9;
}
// Correspondance sur synonymes lemmatisés
else if (entry.synonymes_fr?.some(syn => lemmas.includes(syn.toLowerCase()))) {
score = 0.85;
}
// NOUVEAU: Correspondance sur racine française (4 lettres)
else if (root && key.toLowerCase().startsWith(root)) {
score = 0.75;
}
// NOUVEAU: Correspondance sur racine dans synonymes
else if (root && entry.synonymes_fr?.some(syn => syn.toLowerCase().startsWith(root))) {
score = 0.70;
}
if (score > 0) {
results.push({
mot_francais: entry.mot_francais || key,
traductions: entry.traductions || [],
score,
source: entry.source_files || []
});
}
}
return results;
}
```
#### C. Exporter la nouvelle fonction
**Emplacement** : ligne ~387 (module.exports)
```javascript
module.exports = {
tokenizeFrench,
calculateMaxEntries,
simpleLemmatize,
extractFrenchRoot, // NOUVEAU
searchWord,
findRelevantEntries,
expandContext,
extractRoots,
analyzeContext
};
```
---
## TRAVAIL 2 : Compléter les exceptions dans le lexique
**Objectif** : Ajouter manuellement les formes conjuguées des verbes irréguliers dans `synonymes_fr`
### Fichiers à modifier :
`ancien-confluent/lexique/06-actions.json`
### Verbes à compléter (par priorité)
#### Priorité 1 : Verbes très courants
**1. voir** (déjà présent)
```json
"voir": {
"traductions": [...],
"synonymes_fr": ["observer", "regarder", "voit", "vois", "vu", "vus", "vue", "vues", "voyait", "voyais", "voyant", "verra", "verras", "verront"]
}
```
**2. prendre**
```json
"prendre": {
"traductions": [...],
"synonymes_fr": ["pris", "prit", "prise", "prises", "prend", "prends", "prenait", "prenais", "prenant", "prendra", "prendras", "prendront"]
}
```
**3. faire**
```json
"faire": {
"traductions": [...],
"synonymes_fr": ["créer", "fait", "faits", "faite", "faites", "fais", "faisait", "faisais", "faisant", "fera", "feras", "feront"]
}
```
**4. manger** (nouveau verbe, déjà ajouté)
```json
"manger": {
"traductions": [...],
"synonymes_fr": ["mange", "manges", "mangé", "mangée", "mangés", "mangées", "mangeait", "mangeais", "mangeant", "mangera", "mangeras", "mangeront"]
}
```
**5. aller**
```json
"aller": {
"traductions": [...],
"synonymes_fr": ["va", "vas", "vais", "allé", "allée", "allés", "allées", "allait", "allais", "allant", "ira", "iras", "iront"]
}
```
**6. donner**
```json
"donner": {
"traductions": [...],
"synonymes_fr": ["donne", "donnes", "donné", "donnée", "donnés", "données", "donnait", "donnais", "donnant", "donnera", "donneras", "donneront"]
}
```
**7. dire**
```json
"dire": {
"traductions": [...],
"synonymes_fr": ["parler", "dit", "dits", "dite", "dites", "dis", "disait", "disais", "disant", "dira", "diras", "diront"]
}
```
#### Priorité 2 : Verbes auxiliaires (très irréguliers)
**8. être**
```json
"être": {
"traductions": [...],
"synonymes_fr": ["est", "es", "suis", "sont", "été", "était", "étais", "étant", "sera", "seras", "seront", "fut", "fus"]
}
```
**9. avoir**
```json
"avoir": {
"traductions": [...],
"synonymes_fr": ["a", "as", "ai", "ont", "eu", "eue", "eus", "eues", "avait", "avais", "ayant", "aura", "auras", "auront"]
}
```
#### Priorité 3 : Autres verbes courants
**10. savoir**
```json
"savoir": {
"traductions": [...],
"synonymes_fr": ["connaître", "sait", "sais", "su", "sue", "sus", "sues", "savait", "savais", "sachant", "saura", "sauras", "sauront"]
}
```
**11. chasser**
```json
"chasser": {
"traductions": [...],
"synonymes_fr": ["traquer", "chasse", "chasses", "chassé", "chassée", "chassés", "chassées", "chassait", "chassais", "chassant", "chassera", "chasseras", "chasseront"]
}
```
**12. transmettre**
```json
"transmettre": {
"traductions": [...],
"synonymes_fr": ["enseigner", "transmet", "transmets", "transmis", "transmise", "transmises", "transmettait", "transmettais", "transmettant", "transmettra", "transmettras", "transmettront"]
}
```
**13. garder**
```json
"garder": {
"traductions": [...],
"synonymes_fr": ["protéger", "garde", "gardes", "gardé", "gardée", "gardés", "gardées", "gardait", "gardais", "gardant", "gardera", "garderas", "garderont"]
}
```
**14. porter**
```json
"porter": {
"traductions": [...],
"synonymes_fr": ["transporter", "porte", "portes", "porté", "portée", "portés", "portées", "portait", "portais", "portant", "portera", "porteras", "porteront"]
}
```
**15. apprendre**
```json
"apprendre": {
"traductions": [...],
"synonymes_fr": ["apprend", "apprends", "appris", "apprise", "apprises", "apprenait", "apprenais", "apprenant", "apprendra", "apprendras", "apprendront"]
}
```
---
## Tests à faire après modifications
### Test 1 : Vérifier les racines automatiques
```bash
curl -X POST http://localhost:3000/api/debug/prompt \
-H "Content-Type: application/json" \
-d '{"text": "Il mangeait le pain", "target": "ancien"}' | grep -A 5 "wordsFound"
```
**Résultat attendu** : "mangeait" → trouve "mukis" via racine "mang"
### Test 2 : Vérifier les exceptions manuelles
```bash
curl -X POST http://localhost:3000/api/debug/prompt \
-H "Content-Type: application/json" \
-d '{"text": "Il a vu et pris", "target": "ancien"}' | grep -A 10 "wordsFound"
```
**Résultat attendu** :
- "vu" → trouve "mirak" via synonymes_fr
- "pris" → trouve "pasak" via synonymes_fr
### Test 3 : Phrase complète
```bash
# Même test que le problématique
curl -X POST http://localhost:3000/api/debug/prompt \
-H "Content-Type: application/json" \
-d '{"text": "C est le collier du loup qui a mange mon frere", "target": "ancien"}' | python -c "import sys, json; data=json.load(sys.stdin); print('Found:', [w['input'] for w in data['metadata']['wordsFound']])"
```
**Résultat attendu** : ["collier", "loup", "mange", "frere"] tous trouvés
---
## Estimation de travail
- **Code (contextAnalyzer.js)** : ~30 lignes, 15 minutes
- **Lexique (06-actions.json)** : 15 verbes × ~12 formes = ~180 formes à ajouter, 45-60 minutes
**Total** : ~1h15 de travail
---
## Notes importantes
1. **Lowercase** : Tout est déjà en lowercase dans tokenizeFrench(), pas besoin de le refaire
2. **Normalisation des accents** : Déjà fait (mangé → mange dans la tokenization)
3. **Ordre de priorité matching** :
- 1.0 = Exacte
- 0.95 = Lemma
- 0.9 = Synonyme exact
- 0.85 = Synonyme lemmatisé
- **0.75 = Racine sur clé** (NOUVEAU)
- **0.70 = Racine sur synonyme** (NOUVEAU)
4. **Longueur minimum racine** : 4 lettres pour éviter faux positifs ("il", "du", "un", etc.)
---
## Commandes pour lancer un agent
Si tu veux déléguer le travail lexique à un agent :
```
Lance un agent general-purpose avec cette tâche :
Complète le fichier ancien-confluent/lexique/06-actions.json en ajoutant les formes conjuguées dans synonymes_fr pour tous les verbes selon le document docs/TRAVAIL_RACINES_FRANCAISES.md section "TRAVAIL 2".
Pour chaque verbe, ajoute dans synonymes_fr :
- Présent : 3ème personne singulier/pluriel
- Passé composé : participe passé (masculin/féminin/pluriel)
- Imparfait : 3ème personne
- Participe présent
- Futur : 3ème personne
Priorité 1 (très courants) en premier, puis Priorité 2, puis Priorité 3.
Vérifie que le JSON reste valide après chaque modification.
```

1
prompt-debug.json Normal file
View File

@ -0,0 +1 @@
{"prompt":"Tu es un traducteur spécialisé en Ancien Confluent, langue de la Civilisation de la Confluence.\n\n# RÈGLES STRICTES\n\n1. Tu DOIS traduire du français vers l'Ancien Confluent UNIQUEMENT\n2. Utilise UNIQUEMENT les racines du lexique fourni\n3. Respecte STRICTEMENT la syntaxe et les liaisons sacrées\n4. Fournis la traduction suivie d'une décomposition explicative\n\n# PHONOLOGIE\n\nVoyelles (5): a, e, i, o, u\nConsonnes (10): b, k, l, m, n, p, s, t, v, z\n\n# SYNTAXE\n\nOrdre: SOV (Sujet - Objet - Verbe)\n\nParticules (avant le mot):\n- va = sujet\n- vo = objet direct\n- vi = direction\n- ve = origine\n- vu = instrument\n- na = possession\n- ni = bénéficiaire\n- no = lieu\n\nAutres:\n- su = pluriel (après le mot)\n- zo/zom/zob/zoe = négation\n- ka = question (fin)\n\n# LIAISONS SACRÉES (16)\n\nFusionnent deux racines. Exemples:\n- i (agent actif): sili + aska → sil-i-aska\n- u (appartenance): naki + ura → nak-u-ura\n- a (ensemble): ura + kota → ur-aa-kota\n- o (obstacle): aki + zana → ak-oa-zana\n- e (source): vuku + ura → vuk-u-ura\n\n# VERBES\n\nStructure: racine + conjugateur\n\nTemps:\n- u = présent\n- at = passé vécu\n- en = futur\n\nModes:\n- ok = impératif\n- es = souhait\n- ul = capacité\n\n# RACINES PRINCIPALES\n\n## Sacrées (V initial)\naska (libre), aita (ancêtre), asa (sacré), avi/aru (oiseau/grue), aki (faucon), ura (eau), umi (esprit), iko (un), ita (être), ena (origine), eka (tout), oki (épreuve), ora (aurore), onu (son), anu (âme), eku (étoile), osi (mort), ava (aile)\n\n## Éléments\nzeru (ciel), toka (terre), suki (feu), vena (air), kari (pierre), nura (rivière), tasa (montagne), viku (forêt), luna (lune), sora (soleil)\n\n## Corps\nsili (regard), kanu (main), voki (voix), tiku (oreille), muka (visage), kori (cœur), sanu (corps), peki (pied), keko (écho)\n\n## Actions principales\nmira (voir), teki (aller), kita (donner), pasa (prendre), neka (faire), vosa (dire), seka (savoir), moki (apprendre), kisu (transmettre), zaki (garder), taka (porter), zana (chasser)\n\n## Êtres\nnaki (enfant), tori (personne), vaku (ami), zoka (ennemi), mitu (famille), kasi (chef), kota (union), tibu (tribu)\n\n## Concepts\nveri (vrai), tosa (bon), mako (grand), pisu (petit), novu (nouveau), paki (paix), vali (valeur), voli (vouloir), varu (guerre), mori (mémoire)\n\n## Lieux\nvuku (profond/gouffre), riku (cercle), vela (veille), savu (serment), talu (hall), kova (fresque), loku (lieu)\n\n# CASTES ET LIEUX VALIDÉS\n\nCastes:\n- Nakukeko (Enfants des Échos): nak-u-keko\n- Nakuura (Enfants du Courant): nak-u-ura\n- Ariaska (Ailes-Grises): ar-i-aska\n- Akoazana (Faucons Chasseurs): ak-oa-zana\n- Takitosa (Passes-bien): tak-i-tosa\n- Oraumi (Voix de l'Aurore): or-a-umi\n\nLieux:\n- Uraakota (La Confluence): ur-aa-kota\n- Vukuura (Gouffre Humide): vuk-u-ura\n- Kekutoka (Antres des Échos): kek-u-toka\n- Rikuvela (Cercles de Vigile): rik-u-vela\n- Talusavu (Halls des Serments): tal-u-savu\n- Ekakova (Grande Fresque): ek-a-kova\n\nPeuple:\n- Siliaska (Porteurs du regard libre): sil-i-aska\n\n# FORMAT DE RÉPONSE\n\nAncien Confluent:\n[traduction]\n\nDécomposition:\n[composition avec liaisons si applicable]\n\n# EXEMPLES\n\nFrançais: L'enfant voit l'eau.\nAncien Confluent:\nva naki vo ura miraku\n\nDécomposition:\nva naki = SUJET enfant\nvo ura = OBJET eau\nmiraku = voir (présent -u)\n\n---\n\nFrançais: Les Passes-bien portent les biens.\nAncien Confluent:\nva Takitosa su vo tosa su takanu\n\nDécomposition:\nva Takitosa su = SUJET Passes-bien PLURIEL\nvo tosa su = OBJET bien PLURIEL\ntakanu = porter (présent -u)\n\nIMPORTANT: Ne fournis QUE la traduction et la décomposition. Pas de commentaire additionnel.\n\n\n# VOCABULAIRE PERTINENT POUR CETTE TRADUCTION\n\n## Racines standards\n\n- i (qui) [forme liée: i]\n\n## Autres\n\n- collier → kopuuveki\n","metadata":{"wordsFound":[{"input":"collier","found":"collier","confluent":"kopuuveki","type":"composition","score":1},{"input":"qui","found":"qui","confluent":"i","type":"racine","score":1}],"wordsNotFound":["c","loup","a","mange","mon","frere"],"entriesUsed":2,"totalLexiqueSize":636,"tokensFullLexique":9540,"tokensUsed":915,"tokensSaved":8625,"savingsPercent":90,"useFallback":false,"expansionLevel":1},"stats":{"promptLength":3658,"promptLines":143}}

1
prompt-new.json Normal file

File diff suppressed because one or more lines are too long