Scribe

Traduzione

Come funziona scribe translate: hashing per l'obsolescenza, Gemini, convalida dell'output, reportistica sui costi e strumenti di revisione.

View as Markdown

Scribe traduce il sorgente inglese in tutte le altre lingue tramite un LLM (Gemini) e archivia i risultati in SQLite. Non occorre mai modificare i file localizzati. Basta modificare l'inglese, lanciare di nuovo scribe translate e committare lo store.

Cosa viene tradotto

Per ogni documento, al traduttore vengono inviati esattamente due elementi:

  1. I campi del frontmatter contrassegnati con field.translatable(), compresi quelli nidificati in array e oggetti.
  2. Il corpo in MDX.

Tutto il resto (field.structural(), relazioni, campi integrati) viene copiato dal documento in inglese durante il caricamento. Con slugStrategy: "localized" il traduttore genera anche uno slug URL per ciascuna lingua (in formato kebab-case ASCII, traslitterato per gli alfabeti non latini).

Una lingua non ancora tradotta non blocca l'esecuzione. La funzione resolve() fornisce la traduzione più vicina disponibile attraverso la catena di fallback delle lingue (ad esempio, pt-BR ripiega su pt e poi sulla lingua predefinita), permettendo così di introdurre nuove lingue gradualmente.

Monitoraggio dell'obsolescenza

Ogni traduzione memorizzata registra un hash SHA-256 del contenuto traducibile in inglese da cui è stata generata. Il comando scribe translate ritraduce una pagina solo quando:

  • non esiste alcuna traduzione per quella specifica lingua (mancante), oppure
  • il contenuto traducibile in inglese ha subito modifiche nel frattempo (obsoleto).

Modificare un campo strutturale o una voce di _redirects.json non rende le traduzioni obsolete, poiché tali campi non vengono tradotti.

Convalida dell'output

Una traduzione viene salvata definitivamente solo se supera due controlli:

  1. Il corpo in MDX restituito deve essere elaborato correttamente (dopo aver normalizzato eventuali artefatti di escape e la formattazione degli attributi JSX che il modello a volte sbaglia).
  2. Il frontmatter restituito deve superare nuovamente la convalida rispetto all'intero schema Zod.

Gli elementi che non superano la convalida vengono riprovati automaticamente una volta al termine dell'esecuzione, fornendo al modello gli errori riscontrati in modo che possa correggerli (le esecuzioni in batch effettuano il nuovo tentativo come processo batch aggiuntivo, mantenendo la stessa tariffa). Qualsiasi elemento che fallisca di nuovo viene elencato nel riepilogo finale con il relativo nuovo errore e il comando termina con un codice di uscita diverso da zero. Output del modello difettosi non arrivano mai nello store, garantendo che non raggiungano mai la produzione.

Esecuzione

export GEMINI_API_KEY=...        # letto anche da .env / .env.local

scribe status                     # copertura per tipo e lingua
scribe translate                  # selettore interattivo in un TTY
scribe translate --locale fr de   # lingue specifiche
scribe translate --preset active  # un gruppo localePresets dalla configurazione
scribe translate --type blog      # un solo tipo di contenuto (separati da virgola: --type blog,glossary)
scribe translate --slug my-post   # un solo documento
scribe translate --dry-run        # mostra l'elenco dei lavori + stima token/costi, non scrive nulla
scribe translate --force          # ritraduce anche se gli hash corrispondono
scribe translate --strategy missing-only   # ignora gli obsoleti, riempie solo i vuoti
scribe translate --batch          # forza la modalità batch (predefinita)
scribe translate --direct         # chiamate API per pagina, risultati immediati
scribe translate --resume         # riprende i job batch in sospeso, non invia nulla di nuovo
scribe translate --concurrency 5  # richieste parallele (solo modalità direct)
scribe translate --model gemini-3.1-pro

Eseguito in un terminale, scribe translate mostra un'interfaccia di avanzamento in tempo reale con lo stato dei lavori in batch, i risultati dei singoli elementi, il conteggio parziale dei token e un costo stimato in dollari USA. I token di elaborazione sono inclusi nell'utilizzo riportato, quindi la stima corrisponde a quanto fatturato da Google. Aggiungendo il flag --no-progress (oppure eseguendolo in modalità non interattiva, ad esempio in CI) si ottiene un semplice log riga per riga.

Il comando --dry-run stampa l'elenco delle attività senza scrivere nulla, riportando una stima dei token e del costo in dollari per singolo elemento e in totale, calcolata in base al prompt effettivo e alle dimensioni del payload in inglese. Utilizzando --batch, la stima applica lo sconto previsto per i lotti, offrendo un'anteprima del costo effettivo dell'operazione.

Infine, esegui il commit di .scribe/store.sqlite.

Modalità batch e ripristino

Per impostazione predefinita, l'intero elenco delle attività passa attraverso la Gemini Batch API, che opera con un costo dei token dimezzato rispetto alle chiamate dirette. Scribe pianifica in anticipo ogni richiesta (un job per modello, frammentato per elenchi di lavoro molto ampi), invia tutti i job simultaneamente, quindi li interroga insieme e memorizza i risultati di ciascuno non appena viene completato. I job in batch solitamente terminano nel giro di pochi minuti, ma Google ne garantisce il completamento solo entro 24 ore. Di conseguenza, il comando preferisce attendere anziché trasmettere i risultati pagina per pagina.

Ogni job viene registrato nello store SQLite prima dell'inizio del polling, assieme a uno snapshot del sorgente in inglese da cui è stato inviato ciascun elemento. Questo rende le esecuzioni sicure da interrompere:

  • Uscendo durante il polling (Ctrl+C) non si perde nulla.
  • scribe translate --resume controlla i job in sospeso, assimila quelli conclusi e non invia nulla di nuovo.
  • Anche eseguendo scribe translate normalmente si riprendono prima i job in sospeso, e gli elementi già in fase di elaborazione non vengono mai inviati due volte.
  • Modificare una pagina in inglese mentre il relativo batch è in esecuzione non è un problema: il risultato viene salvato rispetto allo snapshot da cui è stato tradotto, venendo poi rilevato come obsoleto all'esecuzione successiva.

Preferisci risultati immediati, pagina per pagina, a prezzo intero? Usa --direct, che ripristina le chiamate API per pagina con il parallelismo di --concurrency. In un terminale, il selettore interattivo offre la medesima scelta. Gli errori API temporanei (429, 5xx, interruzioni di rete) vengono riprovati automaticamente con un backoff esponenziale in entrambe le modalità.

Guidare il traduttore

Il prompt integrato è studiato per la transcreazione, non per la traduzione letterale. Il modello scrive come un copywriter madrelingua alle prese con l'edizione localizzata: ricrea modi di dire e giochi di parole anziché riproporli alla lettera, e applica le convenzioni tipografiche native (virgolette, apostrofi, spaziature della punteggiatura). context, rules e prompt personalizzati si aggiungono a questa impostazione di base.

Impostazioni predefinite a livello di progetto e sovrascritture per tipo di contenuto:

export default defineConfig({
  translate: {
    context: "MyBrand is a B2B SaaS. Never translate the brand name MyBrand.",
    rules: ["Keep numbers and statistics accurate."],
  },
  types: [
    defineContentType({
      id: "blog",
      // ...
      translate: {
        rules: [
          "Preserve all MDX/JSX component tags, props, and URLs exactly.",
          "Translate link anchor text; never change href paths.",
        ],
      },
    }),
  ],
});
OpzioneAmbitoDescrizione
contextprogetto + tipoContesto del brand o del dominio anteposto a ogni richiesta (i contesti del progetto e del tipo vengono concatenati).
rulesprogetto + tipoRegole extra aggiunte a quelle predefinite.
promptprogetto o tipoIstruzioni di localizzazione supplementari, anteposte prima della direttiva della lingua di destinazione (il nome e il codice della lingua vengono sempre aggiunti).
defaultModel / modelprogetto / tipoID del modello Gemini. Valore predefinito: gemini-3.1-pro (sovrascrivibile anche tramite la variabile d'ambiente PROSE_GEMINI_MODEL o --model).

Le regole integrate (sempre applicate) prevedono di non tradurre i nomi dei brand a meno che non abbiano una variante locale nota nel mercato di destinazione, di restituire corpi MDX con interruzioni di riga reali (senza sequenze di escape \n) e di correggere le virgolette degli attributi JSX quando i valori contengono doppi apici.

Revisione delle traduzioni

scribe history blog my-post fr    # cronologia degli snapshot EN per una pagina
scribe studio                     # interfaccia web di sola lettura su :3600

Ogni traduzione è collegata a uno snapshot del sorgente inglese da cui è stata generata (conservato nello stesso file SQLite), per permettere di verificare in qualsiasi momento quando, a partire da cosa e con quale modello è stata tradotta una pagina. Il comando scribe history stampa quella cronologia. Lo studio mostra la copertura per lingua, l'attuale elenco dei lavori mancanti o obsoleti e i dettagli per ogni singolo documento con lo snapshot affiancato alla traduzione archiviata.

Preset delle lingue

Per rilasci progressivi, assegna un nome ai gruppi di lingue nella configurazione e utilizzali come target tramite --preset:

localePresets: {
  active: ["fr", "es", "ja"],
  ultraLight: ["fr"],
}
scribe translate --preset ultraLight
Traduzione · Scribe