La maggior parte della copertura sull'AI integrata di Chrome si concentra sulla Prompt API e su Gemini Nano — il modello general-purpose che consente di scrivere prompt liberi direttamente nel browser. Meno attenzione riceve il secondo modello incluso in Chrome: Gemma 197M, un modello esperto ultra-efficiente annunciato al Google I/O 2026 che alimenta in modo trasparente una suite di API specifiche per compiti. I due modelli servono scopi fondamentalmente diversi, operano su budget di download separati ed espongono interfacce JavaScript del tutto differenti. Capire quando usare l'uno o l'altro è la differenza tra costruire una funzionalità AI flessibile e costruirne una che scala su ogni dispositivo senza costi server (Google Chrome for Developers, 2026).

Questo articolo è un'analisi tecnica approfondita di Gemma 197M: cosa rende la sua architettura abbastanza efficiente da girare in un browser, quali API abilita e come usarle tutte con pattern di livello produttivo. Ogni esempio di codice funziona con le API Chrome stabili a partire da Chrome 148, con controlli di disponibilità e gestione degli errori inclusi.

Due Modelli, Due Ruoli

Lo stack AI on-device di Chrome non è un singolo modello che fa tutto. Separa l'inferenza general-purpose dall'inferenza su compiti specifici, con una buona ragione: un modello ottimizzato per tradurre due frasi non ha bisogno di contenere un modello generale del mondo nei propri pesi. Distribuire uno specialista più piccolo evita il costo in memoria e latenza di instradare ogni compito attraverso l'intero Gemini Nano.

Nota sull'attribuzione del modello

La documentazione pubblica di Google al Google I/O 2026 posiziona Gemma 197M come il modello che alimenta le task API. Vale la pena notare che le API Language Detector e Translator precedono l'annuncio di Gemma 197M e storicamente giravano su modelli linguistici dedicati più piccoli, scaricati come language pack separati. Se queste due API siano state silenziosamente migrate a Gemma 197M o continuino a utilizzare modelli separati non è confermato nella documentazione pubblica attuale di Google. La Summarizer API è esplicitamente associata a Gemma 197M. Per Language Detector e Translator, considera l'attribuzione del modello come il framing pubblico corrente, non un dettaglio di implementazione verificato.

General Purpose
Gemini Nano
Prompt API · Chrome 148 stable
  • Prompt liberi con istruzioni di sistema
  • Input multimodale: testo, immagine, audio
  • Output JSON strutturato via responseConstraint
  • Generazione di token in streaming
  • Stato di sessione multi-turno
  • Lingue di output: en, es, ja
Task Specialist
Gemma 197M
Task APIs · Chrome 138+ stable
  • Summarizer: tldr, key-points, teaser, headline
  • Language Detector: rilevamento lingua con ranking per confidenza
  • Translator: traduzione di coppie di lingue on-device

Architettura: Perché 197M Parametri Attivi Sono Sufficienti

L'efficienza di Gemma 197M deriva da due innovazioni architetturali che hanno origine nella famiglia di modelli Gemma 3n. Insieme permettono a Chrome di eseguire un modello con molti meno parametri attivi di quanto il conteggio grezzo dei pesi lascerebbe supporre.

01
MatFormer — Matryoshka Transformer
L'architettura MatFormer (arXiv:2310.07707) nidifica sotto-modelli più piccoli e completamente funzionali all'interno di uno più grande — come le matrioske. Durante il training, più blocchi FFN (feed-forward network) nidificati di dimensioni diverse vengono ottimizzati simultaneamente all'interno dello stesso transformer. Questo produce uno spettro di modelli autonomi da un singolo ciclo di addestramento, ciascuno accurato ed eseguibile indipendentemente. Un browser può quindi caricare solo il sotto-modello più piccolo la cui qualità soddisfa il requisito del compito, senza scaricare o eseguire il modello completo.
02
Per-Layer Embedding (PLE) caching
PLE separa i parametri di embedding associati a ogni layer del transformer dai pesi principali. I pesi principali vengono caricati nell'acceleratore (GPU o NPU); i dati PLE vengono generati al di fuori della memoria operativa del modello, memorizzati nella cache su storage veloce e trasferiti layer per layer durante l'inferenza. Ciò significa che l'impronta sul GPU corrisponde a un modello molto più piccolo di quanto implichi il conteggio totale dei parametri. La variante E2B di Gemma 3n (5B parametri totali) gira con l'impronta di memoria di un modello da 2B grazie a questa tecnica (Google Developers Blog, 2025).
03
Spazio di output limitato al compito
Le task API operano su spazi di output ristretti e ben definiti — «in che lingua è questo?» o «accorcia questo testo» — che non richiedono una conoscenza generale del mondo. Un modello più piccolo con fine-tuning specializzato supera un generalista grande su questi compiti. Il budget di 197M parametri attivi è calibrato specificamente al limite di complessità dei compiti di riassunto, traduzione e assistenza alla scrittura in un contesto browser.
Distinzione chiave

Il valore 197M si riferisce ai parametri attivi durante l'inferenza — i pesi effettivamente caricati ed eseguiti sull'acceleratore per un dato compito. Il conteggio totale dei parametri del modello, inclusi gli embedding PLE residenti su CPU, è più alto. Questa distinzione conta quando si ragiona su latenza e memoria: ciò che colpisce la GPU è 197M; ciò che risiede su disco e in memoria CPU è di più.

Le Tre Task API Stabili

A partire da Chrome 138, tre API browser specifiche per compiti sono stabili. Funzionano senza flag, token di origin trial o alcuna configurazione lato server.

Summarizer
Stabile
Da Chrome 138 · tldr, key-points, teaser, headline · output in testo normale o markdown
Language Detector
Stabile
Da Chrome 138 · Restituisce array di {detectedLanguage, confidence} · solo desktop
Translator
Stabile
Da Chrome 138 · Controllo disponibilità per coppia di lingue · solo desktop
Proofreader
Early Preview
Solo Early Preview Program · correzioni grammaticali e stilistiche

Summarizer API

Il Summarizer è l'utilizzo di punta di Gemma 197M. Accetta un testo lungo e restituisce un riassunto in uno dei quattro tipi — tldr, key-points, teaser, headline — in testo normale o markdown, a tre impostazioni di lunghezza. L'API espone inputQuota e measureInputUsage() per controllare il budget di token prima dell'invio — fondamentale per i documenti lunghi che potrebbero superare la finestra di contesto.

Summarizer API — pattern di produzione
async function summarize(text, {
  type   = 'key-points',
  format = 'plain-text',
  length = 'medium',
  onProgress,
} = {}) {
  if (!('Summarizer' in self)) throw new Error('Summarizer API not supported');

  const availability = await Summarizer.availability();
  if (availability === 'unavailable') throw new Error('Summarizer not available on this device');

  const summarizer = await Summarizer.create({
    type, format, length,
    outputLanguage: 'en',   // required: 'en' | 'es' | 'ja'
    monitor(m) {
      m.addEventListener('downloadprogress', (e) => {
        const pct = e.total ? Math.round((e.loaded / e.total) * 100) : 0;
        onProgress?.(pct);
      });
    },
  });

  // Check token budget — guard required: not exposed in all builds
  if (typeof summarizer.measureInputUsage === 'function') {
    try {
      const usage = await summarizer.measureInputUsage(text);
      if (usage > summarizer.inputQuota) {
        summarizer.destroy();
        throw new Error(`Input too long: ${usage} tokens, quota is ${summarizer.inputQuota}`);
      }
    } catch (e) {
      if (e.message?.includes('too long')) throw e;
      // TypeError: not implemented in this build — skip quota check
    }
  }

  let result = '';
  const stream = summarizer.summarizeStreaming(text);
  for await (const chunk of stream) {
    // defensive: older builds yield cumulative text; newer builds yield deltas
    if (chunk.startsWith(result)) result = chunk;
    else                          result += chunk;
  }

  summarizer.destroy();
  return result;
}

// Usage
const summary = await summarize(longArticleText, {
  type:   'key-points',
  format: 'markdown',
  length: 'short',
  onProgress: (pct) => console.log(`Model: ${pct}%`),
});

La semantica dei chunk di summarizeStreaming() — e di writeStreaming() e rewriteStreaming() — differisce tra le build di Chrome. Le build più vecchie producono testo cumulativo (ogni chunk contiene tutto il testo prodotto finora); le build più recenti producono delta incrementali. Il pattern difensivo sopra copre entrambi i casi: se il nuovo chunk inizia con il buffer accumulato è cumulativo e lo sostituisce; altrimenti è un delta e viene concatenato. Senza questa guardia, le build cumulative producono output raddoppiato e corrotto quando accumulato con +=.

↳ Demo live — Summarizer API

Language Detector API

Il Language Detector è utile ovunque sia necessario instradare i contenuti generati dagli utenti per lingua — prima della traduzione, prima della selezione del modello, o per presentare l'UI nella lingua rilevata. Restituisce un array di candidati ordinati per confidenza decrescente, coprendo dalla lingua più probabile ai casi limite. Il modello gira interamente on-device; nessun testo viene inviato a un server.

Language Detector API
async function detectLanguage(text) {
  if (!('LanguageDetector' in self)) return null;

  const availability = await LanguageDetector.availability();
  if (availability === 'unavailable') return null;

  const detector = await LanguageDetector.create();
  const results = await detector.detect(text);
  detector.destroy();

  // [ { detectedLanguage: 'it', confidence: 0.97 },
  //   { detectedLanguage: 'la', confidence: 0.02 }, ... ]
  return {
    primary:     results[0]?.detectedLanguage ?? 'en',
    confidence:  results[0]?.confidence ?? 0,
    all:         results,
  };
}

// Instrada un ticket di supporto al team giusto per lingua
async function routeTicket(ticketBody) {
  const { primary, confidence } = (await detectLanguage(ticketBody)) ?? {};
  if (confidence > 0.85) {
    return ROUTING_MAP[primary] ?? 'default-queue';
  }
  return 'default-queue'; // fallback bassa confidenza
}

Nota: le API Language Detector e Translator funzionano solo su desktop (Windows, macOS, Linux, ChromeOS). Non sono disponibili nelle versioni Android o iOS di Chrome a partire da Chrome 148 (Google Chrome for Developers, 2026).

↳ Demo live — Language Detector API

Translator API

La Translator API traduce testo tra coppie di lingue on-device. Ogni coppia di lingue richiede il proprio download del modello, quindi è necessario verificare la disponibilità per coppia prima di tentare la traduzione. Il metodo Translator.availability() accetta sourceLanguage e targetLanguage e restituisce lo stato di disponibilità per quella specifica combinazione.

Translator API — con disponibilità per coppia
async function translate(text, { from, to }) {
  if (!('Translator' in self)) throw new Error('Translator API not supported');

  // Check pair-specific availability before creating the instance
  const availability = await Translator.availability({
    sourceLanguage: from,
    targetLanguage: to,
  });
  if (availability === 'unavailable') {
    throw new Error(`Translation pair ${from}→${to} not available on this device`);
  }

  const translator = await Translator.create({
    sourceLanguage: from,
    targetLanguage: to,
    monitor(m) {
      m.addEventListener('downloadprogress', (e) => {
        console.log(`Language pair: ${Math.round(e.loaded / e.total * 100)}%`);
      });
    },
  });

  const result = await translator.translate(text);
  translator.destroy();
  return result;
}

// Traduce una recensione utente in inglese per l'elaborazione downstream
const english = await translate('Produit excellent, livraison rapide', {
  from: 'fr',
  to:   'en',
});
↳ Demo live — Translator API

Pattern Avanzato: Concatenare le API

Il vero vantaggio di avere tutte e tre le API nello stesso contesto JavaScript è la componibilità. È possibile concatenare Language Detector → Translator → Summarizer per elaborare documenti multilingua interamente lato client — nessun server, nessuna chiave API, nessun dato che lascia il dispositivo. Questo pattern è particolarmente rilevante per le applicazioni enterprise che gestiscono contenuti sensibili o regolamentati.

Catena: rileva lingua → traduci → riassumi
async function summarizeAnyLanguage(text, {
  summaryType   = 'key-points',
  summaryLength = 'short',
  targetLang    = 'en',
} = {}) {

  // Step 1: Detect source language
  const detection = await detectLanguage(text);
  const sourceLang = detection?.primary ?? targetLang;

  // Step 2: Translate only if needed
  let processText = text;
  if (sourceLang !== targetLang && detection?.confidence > 0.80) {
    try {
      processText = await translate(text, { from: sourceLang, to: targetLang });
    } catch {
      // Pair not available — summarize in original language
    }
  }

  // Step 3: Summarize
  return summarize(processText, { type: summaryType, length: summaryLength });
}

// Elabora un contratto in francese estraendo i punti chiave in inglese
const keyPoints = await summarizeAnyLanguage(frenchContractText, {
  summaryType:   'key-points',
  summaryLength: 'medium',
  targetLang:    'en',
});
↳ Demo live — Catena completa: Rileva → Traduci → Riassumi

Gemma 197M vs Gemini Nano: Scegliere lo Strumento Giusto

Entrambi i modelli sono on-device, entrambi sono privi di costi di token e richiedono entrambi gli stessi ~22 GB di spazio su disco disponibile nel volume del profilo Chrome. Il punto di decisione è la complessità del compito e la flessibilità richiesta.

Dimensione Gemini Nano — Prompt API Gemma 197M — Task APIs
Flessibilità Prompt personalizzabili, istruzioni di sistema, sessioni multi-turno Tipi di compito predefiniti con parametri di configurazione
Modalità di input Testo, immagine, audio Solo testo
Formato di output Stringa libera o JSON strutturato via responseConstraint Specifico del compito (riassunto, testo tradotto, contenuto generato)
Vincolo lingua output Solo en, es, ja (da specificare) Determinato dal compito (Translator produce la lingua target)
Profilo di latenza Più alto — inferenza generativa completa per prompt Più basso — compito più ristretto = meno percorsi di calcolo effettivi
Quota di token Finestra di contesto per sessione, gestita manualmente inputQuota + measureInputUsage() prima della chiamata
Ideale per Estrazione di entità, classificazione, Q&A su contenuti di pagina, dati strutturati da testo non strutturato, descrizione di immagini Riassunto, traduzione, instradamento per lingua, assistenza alla scrittura, regolazione del tono

Checklist di Produzione

01
Chiama sempre availability() prima
Ogni API espone .availability() che restituisce 'available', 'downloadable', 'downloading' o 'unavailable'. Alla prima esecuzione, aspettati 'downloadable' — Chrome avvierà il download del modello quando viene chiamato .create(). Non saltare mai questo controllo; su hardware non supportato (meno di ~4 GB di VRAM o GPU integrate vecchie) l'API restituisce 'unavailable' e .create() genererà un'eccezione.
02
Gestisci lo stato downloadable nell'UI
La prima chiamata a .create() su un nuovo dispositivo attiva un download del modello di ~2 GB. Usa il callback monitor(m) per ascoltare gli eventi downloadprogress e mostrare una barra di avanzamento all'utente. Senza feedback, l'attesa di 30–120 secondi appare come un blocco. Le chiamate successive sullo stesso dispositivo sono istantanee — il modello è in cache.
03
Controlla la quota di token per input lunghi
Per la Summarizer API, chiama await summarizer.measureInputUsage(text) e confronta con summarizer.inputQuota prima di inviare. Superare la quota genera un'eccezione a metà stream. Per i documenti lunghi, considera di suddividere ai confini dei paragrafi e riassumere a blocchi, poi riassumere i riassunti.
04
Chiama sempre destroy() al termine
Ogni sessione — Summarizer, Translator, LanguageDetector — trattiene risorse GPU. Chiama .destroy() in un blocco finally per rilasciarle immediatamente invece di aspettare la garbage collection. Non farlo in una pipeline multi-step accumula pressione sulle risorse e degrada le prestazioni delle chiamate successive.
05
Imposta outputLanguage nella Summarizer API
La Summarizer API richiede che outputLanguage: 'en' (o 'es' / 'ja') venga impostato esplicitamente sia nel controllo availability() che nella chiamata create(). Senza di esso, Chrome registra un avviso runtime e la qualità dell'output degrada silenziosamente. La Translator API è esente — la sua lingua di output è determinata da targetLanguage. La Language Detector API non ha il concetto di lingua di output.
06
Implementa il graceful degradation
Tutte le task API sono solo per Chrome e solo per desktop (per Language Detector, Translator). I browser mobili, Firefox, Safari e Edge non restituiscono nulla dai controlli di feature detection. Progetta la funzionalità come un miglioramento, non un requisito: esegui il percorso AI in un try/catch e torna alla baseline non-AI. L'utente su un browser non supportato dovrebbe trovare un prodotto funzionante, non uno rotto.
Requisiti di piattaforma (tutte le task API)

Chrome 138+ su Windows 10/11, macOS 13+ (Ventura e versioni successive), Linux o ChromeOS su dispositivi Chromebook Plus. Sono necessari almeno 22 GB di spazio libero su disco sul volume contenente il profilo Chrome per l'archiviazione del modello. Il download al primo utilizzo è di circa 2 GB e viene eseguito in background; tutte le chiamate successive utilizzano il modello in cache e sono disponibili offline (Google Chrome for Developers, 2026).

Riferimenti
  1. Google Chrome for Developers. (2026). 15 updates from Google I/O 2026: Powering the agentic web with new capabilities, tools, and features in Chrome. developer.chrome.com/blog/chrome-at-io26
  2. Google Chrome for Developers. (2026). Summarize with built-in AI — Summarizer API. developer.chrome.com/docs/ai/summarizer-api
  3. Google Chrome for Developers. (2026). Language detection with built-in AI. developer.chrome.com/docs/ai/language-detection
  4. Google Chrome for Developers. (2026). Translation with built-in AI — Translator API. developer.chrome.com/docs/ai/translator-api
  5. Google Chrome for Developers. (2026). Built-in AI APIs. developer.chrome.com/docs/ai/built-in-apis
  6. Google Developers Blog. (2025). Announcing Gemma 3n preview: powerful, efficient, mobile-first AI. developers.googleblog.com — introducing-gemma-3n
  7. Google Developers Blog. (2025). Introducing Gemma 3n: The developer guide — Per-Layer Embedding and MatFormer architecture. developers.googleblog.com — introducing-gemma-3n-developer-guide
  8. MatFormer: Nested Transformer for Elastic Inference. arXiv:2310.07707. arxiv.org/abs/2310.07707
  9. Google Chrome for Developers. (2025). Enhancing Gemini Nano: delivering higher quality summaries with LoRA. developer.chrome.com/blog/improved-summaries-gemini-nano
M
Michele Mader
Technical Leader · AI Systems & Data Engineering

Guido la direzione tecnica di prodotti dati basati su AI per clienti enterprise — definendo architetture, scegliendo lo stack tecnologico e gestendo la delivery dal roadmap alla produzione.

Connettiti su LinkedIn