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.
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.
- 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
- 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.
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 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.
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 +=.
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.
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).
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.
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', });
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.
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', });
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
.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..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.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..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.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.try/catch e torna alla baseline non-AI. L'utente su un browser non supportato dovrebbe trovare un prodotto funzionante, non uno rotto.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).
- 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
- Google Chrome for Developers. (2026). Summarize with built-in AI — Summarizer API. developer.chrome.com/docs/ai/summarizer-api
- Google Chrome for Developers. (2026). Language detection with built-in AI. developer.chrome.com/docs/ai/language-detection
- Google Chrome for Developers. (2026). Translation with built-in AI — Translator API. developer.chrome.com/docs/ai/translator-api
- Google Chrome for Developers. (2026). Built-in AI APIs. developer.chrome.com/docs/ai/built-in-apis
- Google Developers Blog. (2025). Announcing Gemma 3n preview: powerful, efficient, mobile-first AI. developers.googleblog.com — introducing-gemma-3n
- Google Developers Blog. (2025). Introducing Gemma 3n: The developer guide — Per-Layer Embedding and MatFormer architecture. developers.googleblog.com — introducing-gemma-3n-developer-guide
- MatFormer: Nested Transformer for Elastic Inference. arXiv:2310.07707. arxiv.org/abs/2310.07707
- Google Chrome for Developers. (2025). Enhancing Gemini Nano: delivering higher quality summaries with LoRA. developer.chrome.com/blog/improved-summaries-gemini-nano