Passer au contenu principal

Fonctionnement de la synchronisation

La commande sync est l'opération principale de rosetta. Voici ce qui se produit lorsque vous exécutez npx i18n-rosetta sync.

Aperçu du pipeline

Étape par étape

1. Résolution de la configuration

Rosetta charge i18n-rosetta.config.json (ou détecte automatiquement les paramètres). Il résout :

  • Les paramètres régionaux (locales) source et cibles
  • Le graphe des paires (quelles combinaisons source→cible traiter)
  • Les paramètres de méthode, de modèle et de qualité pour chaque paire

Avant d'analyser les fichiers, rosetta affiche un en-tête de démarrage :

i18n-rosetta v3.3.2

[INFO] Detected format: json (auto)
[INFO] Detected framework: Hugo
  • Bannière de version : Affiche la version installée pour le débogage et les rapports de bogues.
  • Détection du format : Indique le format de fichier et s'il a été détecté automatiquement (auto) ou configuré explicitement (config). Prend en charge json, toml et yaml.
  • Détection du framework : Lorsque contentDir est défini, identifie le framework (Hugo) pour confirmer que la synchronisation du contenu est active.

2. Analyse de la source

Le fichier de paramètres régionaux source est chargé et mis à plat sous forme de carte clé→valeur :

// Input (nested)
{ "hero": { "title": "Welcome", "subtitle": "Build" } }

// Flattened
{ "hero.title": "Welcome", "hero.subtitle": "Build" }

3. Détection des modifications

Rosetta lit .i18n-rosetta.lock, qui stocke les hachages SHA-256 des valeurs sources précédemment traduites. Pour chaque clé, il vérifie :

ConditionAction
Clé manquante dans la cibleTraduire
Le hachage source a changé depuis la dernière synchronisationRetraduire (obsolète)
La valeur cible commence par [EN]Retraduire (marqueur de repli hérité)
Hachage source inchangé, la clé existeIgnorer

C'est pourquoi rosetta ne traduit que ce qui a changé — il ne retraduit pas l'intégralité de votre fichier à chaque synchronisation.

4. Traitement par lots (Batching)

Les clés sont regroupées par lots (par défaut : 80 clés/lot pour les LLM, 128 pour Google Translate). Le traitement par lots réduit les allers-retours avec l'API tout en conservant des invites (prompts) gérables.

Pendant la traduction, rosetta affiche une barre de progression intégrée qui se met à jour après l'achèvement de chaque lot :

[INFO] fr.json — 2,847 missing
████████████████░░░░░░░░░░░░░░░░ 1,440/2,847 keys

La barre s'affiche en utilisant le retour chariot \r pour des mises à jour sur place — sans défilement. Elle est masquée dans les modes --quiet et --json.

4b. Mémoire de traduction

Avant le traitement par lots, rosetta vérifie le cache de la mémoire de traduction (.rosetta/tm.json). Les clés dont le texte source + les paramètres régionaux + la méthode correspondent à une traduction précédente sont servies instantanément depuis le cache — aucun appel d'API n'est nécessaire.

[TM] 142 key(s) served from cache
Translating 3 key(s) to French (llm)... [OK]

La mémoire de traduction (TM) est le principal mécanisme de réduction des coûts. Relancer la synchronisation après la modification d'une seule clé ne traduit que cette clé, et non l'intégralité du fichier. Consultez la section Mémoire de traduction pour plus de détails.

Pour contourner le cache lors d'une exécution unique : i18n-rosetta sync --no-tm

5. Traduction

Chaque lot est envoyé à la méthode de traduction configurée :

  • llm : Invite structurée vers OpenRouter avec des instructions sur le registre et des directives de genre
  • llm-coached : Identique, mais avec l'injection de règles de grammaire, d'un dictionnaire et de notes de style
  • google-translate : Requête par lots vers l'API Google Cloud Translation v2
  • api : Requête HTTP POST vers un point de terminaison distant

Le message système (registre, directives de genre, règles) est identique pour tous les lots d'un paramètre régional donné, ce qui permet la mise en cache des invites (prompt caching) — les fournisseurs tels qu'Anthropic et Google mettent en cache les messages systèmes répétés, réduisant ainsi les coûts liés aux jetons (tokens).

6. Contrôle de qualité (Quality Gate)

Chaque traduction est validée avant d'être écrite sur le disque. Cinq vérifications sont effectuées :

VérificationCe qu'elle détecteExemple
Vide/blancLe modèle n'a rien renvoyé""
Écho de la sourceLe modèle a renvoyé l'entrée en anglais"Welcome" pour le japonais
Boucle d'hallucinationTrigrammes répétés"Qo' Qo' Qo' Qo'"
Inflation de la longueurLa sortie est plus de 4 fois plus longue que la sourceSource de 10 caractères → Sortie de 50 caractères
Conformité du scriptScript incorrect pour les paramètres régionauxTexte latin pour des paramètres régionaux arabes

Les échecs sont consignés avec un préfixe [GATE]. Aucun repli silencieux n'est effectué.

Consultez la section Contrôle de qualité pour plus de détails.

6b. Vérification de la terminologie

Pour les paires encadrées (coached) disposant d'un dictionnaire, rosetta vérifie si le LLM a effectivement utilisé la terminologie requise après la traduction. Les violations sont consignées sous forme d'avertissements [TERM] :

[TERM] en→fr: 2 term violation(s)
• "dashboard" → expected "tableau de bord" but got "panneau"

Il s'agit d'avertissements et non d'erreurs bloquantes — la traduction est tout de même écrite.

7. Cascade de tentatives (Retry Cascade)

En cas d'échec de l'analyse JSON ou d'erreurs au niveau du lot, rosetta effectue de nouvelles tentatives avec des lots de plus en plus petits :

Full batch (80 keys) → Failed
└→ Half batch (40 keys) → 1 failure
└→ Individual keys (1 each) → Isolates the problem key

Le budget de tentatives est plafonné par maxRetries (par défaut : 3) afin d'éviter des dépenses incontrôlées en jetons.

8. Écriture et verrouillage

Les traductions validées sont écrites dans le fichier de paramètres régionaux cible, en préservant la structure d'imbrication d'origine. Le fichier de verrouillage est mis à jour avec les nouveaux hachages SHA-256.

9. Vérification

Une fois toutes les paires traitées, rosetta relit les fichiers de paramètres régionaux écrits sur le disque et exécute une passe de vérification (sauf si --no-verify est défini). Cela permet de détecter l'écart entre le rapport de réussite de la synchronisation et les clés qui sont en réalité incorrectes :

  • Parité des clés — toutes les clés sources sont présentes dans chaque cible
  • Marqueurs de repli [EN] — marqueurs hérités des exécutions précédentes
  • Traductions vides — valeurs blanches qui sont passées au travers
  • Conformité du script — paramètres régionaux non latins avec des traductions uniquement en ASCII
  • Préservation des espaces réservés — les espaces réservés ICU correspondent à la source
  • Problèmes d'encodage — marqueurs BOM, caractères invisibles

Ceci est également disponible en tant que commande autonome i18n-rosetta verify pour les portes de contrôle CI (CI gates).

Traduction de contenu (Phase 2)

Pour les projets Docusaurus et Hugo, sync exécute une deuxième phase après la traduction des clés JSON. Cette phase traduit les fichiers Markdown et MDX (documentation, articles de blog, tutoriels) en utilisant les mêmes méthodes et le même contrôle de qualité.

Comment cela fonctionne

  1. Rosetta découvre tous les fichiers de contenu source (.md, .mdx) en parcourant le répertoire content/docs
  2. Pour chaque paire fichier × paramètre régional, il vérifie un fichier de verrouillage de contenu distinct (.i18n-rosetta-content.lock) pour détecter les modifications de hachage SHA-256
  3. Les fichiers modifiés ou manquants sont rassemblés dans un pool d'éléments de travail plat
  4. Le pool est traité avec une concurrence parallèle (par défaut : 12 appels d'API simultanés)
Phase 2: content (79 translations to process, 341 skipped, concurrency: 48)

[1/79] (1%) docs/concepts/security.md → ja [RE-TRANSLATE] (~3328s left)
[2/79] (3%) docs/concepts/security.md → th [RE-TRANSLATE] (~1821s left)
...
[79/79] (100%) blog/v3-2-quality.md → de [OK]

[OK] Created 79 content file(s), 341 unchanged

Parallélisme

La Phase 1 (clés JSON) et la Phase 2 (contenu) s'exécutent désormais en parallèle :

  • Phase 1 : Toutes les traductions de paramètres régionaux se déclenchent simultanément (par défaut : 50 paramètres régionaux simultanés). Au sein de chaque paramètre régional, les lots d'API s'exécutent également en parallèle (4 lots simultanés). Une synchronisation de 12 paramètres régionaux avec 120 clés se termine en ~1 minute au lieu de ~15 minutes.
  • Phase 2 : Toutes les combinaisons fichier × paramètre régional sont traduites sous forme de pool plat (par défaut : 12 appels d'API simultanés). Différents fichiers et différents paramètres régionaux sont traduits simultanément.

Contrôlez le parallélisme avec --json-concurrency, --content-concurrency ou --concurrency (définit les deux) :

# Faster JSON sync (more parallel locale translations)
npx i18n-rosetta sync --json-concurrency 30

# Faster content sync (more parallel API calls)
npx i18n-rosetta sync --content-concurrency 20

# Slower (gentler on rate limits)
npx i18n-rosetta sync --concurrency 4

Protection du contenu

Pendant la traduction, rosetta protège le contenu non traduisible :

  • Les blocs de code (délimités et indentés) sont remplacés par des espaces réservés
  • Les champs Frontmatter qui ne figurent pas dans la liste translatableFields sont préservés tels quels
  • Les liens, les chemins d'images et les balises HTML sont protégés
  • Les codes courts (shortcodes) et les variables d'interpolation (par exemple, {count}, {{.Params.title}}) sont protégés

Après la traduction, tous les espaces réservés sont restaurés et validés. S'il en manque ou s'ils sont corrompus, la traduction est rejetée et une nouvelle tentative est effectuée.

Succès partiel

L'échec d'un lot ne bloque pas le reste. Si 9 lots sur 10 réussissent, ces 9 lots sont écrits. Le lot ayant échoué est consigné, et vous pouvez relancer sync pour réessayer.

Exécution à blanc (Dry Run)

Prévisualisez ce qui changerait sans écrire de fichiers :

npx i18n-rosetta sync --dry-run

Forcer la retraduction

Forcez la retraduction de clés spécifiques même si elles sont inchangées :

npx i18n-rosetta sync --force-keys "hero.title,nav.about"

Estimation des coûts

Avant la traduction, rosetta génère un rapport de coûts de pré-synchronisation indiquant les coûts estimés par paire. Cela s'exécute automatiquement lors de chaque sync — vous le voyez avant que tout appel d'API ne soit effectué.

╔══════════════════════════════════════════════════════════╗
║ Cost Estimate ║
╠════════════╦═══════╦════════════╦════════════════════════╣
║ Pair ║ Keys ║ Est. Cost ║ Method ║
╠════════════╬═══════╬════════════╬════════════════════════╣
║ en → fr ║ 142 ║ $0.07 ║ google-translate ║
║ en → ja ║ 38 ║ — ║ llm (model-dependent) ║
║ en → crk ║ 38 ║ — ║ llm-coached ║
╚════════════╩═══════╩════════════╩════════════════════════╝

Ce qui est estimé

Chaque méthode de traduction fournit sa propre estimation de coût :

MéthodeBase de coûtPrécision
google-translateTarif publié par Google (20 $/million de caractères)Précise
llmVarie selon le modèle OpenRouterDépend du modèle — consultez la tarification d'OpenRouter
llm-coachedIdentique à llm plus les jetons de contexte d'encadrementDépend du modèle
apiDéterminé par le serveurInconnue — impossible à estimer sans interroger le point de terminaison

Lorsqu'une méthode ne peut pas déterminer le coût (méthodes LLM, API distantes), rosetta indique plutôt que de deviner. Utilisez --dry pour voir les estimations de coûts sans effectuer de traduction réelle.


Voir aussi