Modello linguistico

Funzionalità web: LanguageModel

L'API Prompt consente agli sviluppatori di eseguire attività di elaborazione del linguaggio naturale direttamente nel browser utilizzando Gemini Nano. Questo approccio di AI integrata garantisce la privacy dell'utente, riduce i costi dei server e consente la funzionalità offline.

1. Inizia e requisiti hardware

L'API Prompt è attualmente disponibile in Chrome a partire dalla versione 148 (computer) per Windows, macOS, Linux e Chromebook Plus.

Prerequisiti hardware

  • Spazio di archiviazione: 22 GB di spazio libero (per il profilo e il modello iniziali).
  • Memoria/CPU: 16 GB di RAM e almeno 4 core della CPU.
  • GPU: almeno 4 GB di VRAM (obbligatorio per l'input audio).
  • Rete: necessaria solo per il download iniziale del modello.

Inizializzazione dell'API

Controlla la disponibilità del modello prima di attivare un download:

const availability = await LanguageModel.availability();

// Do not call create() when unavailable — the model cannot run on this device.
if (availability !== 'unavailable') {
    const session = await LanguageModel.create({
        monitor(m) {
            // Inform the user while the model downloads so the UI doesn't appear frozen.
            m.addEventListener('downloadprogress', (e) => {
                console.log(`Downloaded ${e.loaded * 100}%`);
            });
        },
    });
}

2. Funzionalità di prompting principali

Per brevità, gli esempi di sessione in questa sezione omettono session.destroy(). Chiama sempre session.destroy() quando una sessione non è più necessaria per liberare memoria del dispositivo (vedi la Sezione 5).

Output di base e in streaming

Per risposte brevi, utilizza prompt(). Per contenuti più lunghi, utilizza promptStreaming() per fornire una UI più reattiva.

OBBLIGATORIO: non assegnare mai l'output del modello a innerHTML. L'output del modello non è attendibile e può contenere markup inserito. Utilizza sempre textContent o un igienizzante.

const session = await LanguageModel.create();

// prompt() accumulates the full response before resolving — use for short, one-shot output.
const result = await session.prompt('Write a haiku about coding.');
// textContent, not innerHTML — model output is untrusted and must not be parsed as markup.
outputEl.textContent = result;

// promptStreaming() yields independent chunks that must be concatenated;
// use for longer content so each chunk can be rendered progressively.
const stream = session.promptStreaming('Write a long story about a robot.');
let completeResult = '';
for await (const chunk of stream) {
    completeResult += chunk;
    outputEl.append(chunk);
}
console.log('Full story:', completeResult);

Input multimodale

L'API Prompt supporta input di testo, audio e visivi (immagini, canvas, frame video).

const session = await LanguageModel.create({
    // Declaring expected input types lets the browser optimize model loading.
    expectedInputs: [{ type: 'text' }, { type: 'image' }],
    expectedOutputs: [{ type: 'text' }],
});

const response = await session.prompt([
    {
        role: 'user',
        content: [
            { type: 'text', value: 'What is in this image?' },
            { type: 'image', value: document.querySelector('canvas') },
        ],
    },
]);

3. Gestione avanzata delle sessioni

Le sessioni consentono al modello di mantenere il contesto in più interazioni.

Contesto e quota

Ogni sessione ha un limite massimo di token. Puoi monitorare l'utilizzo tramite session.contextUsage e session.contextWindow. Se la finestra si riempie, i messaggi meno recenti (ad eccezione del prompt di sistema) vengono eliminati.

Clonazione delle sessioni

La clonazione è utile per avviare conversazioni parallele che condividono lo stesso contesto iniziale (come una personalità "di sistema") senza dover eseguire nuovamente l'inizializzazione.

const mainSession = await LanguageModel.create({
    initialPrompts: [{ role: 'system', content: 'You speak like a pirate.' }],
});

const branchA = await mainSession.clone();
const branchB = await mainSession.clone();
// Destroy the base after cloning — the clones own their own context from here.
mainSession.destroy();

Ripristino delle sessioni precedenti

Mentre è in fase di sviluppo una funzionalità di "ripristino" nativa, puoi ricreare una sessione inserendo la cronologia precedente in initialPrompts.

Nota: localStorage non è criptato ed è persistente. La cronologia delle conversazioni archiviata potrebbe includere PII degli utenti. Considera le implicazioni per la privacy prima di salvare la cronologia chat.

// || '[]' ensures JSON.parse never receives null when the key doesn't exist yet.
const history = JSON.parse(localStorage.getItem('chat_history') || '[]');
const session = await LanguageModel.create({
    initialPrompts: history, // Array of {role, content} objects
});

4. Output strutturato con schema JSON

Per evitare che il modello aggiunga "chiacchiere" (ad es. "Certo, ecco il tuo JSON:"), utilizza uno schema JSON tramite il campo responseConstraint. In questo modo, l'output è un JSON valido che può essere analizzato immediatamente.

Esempio: classificazione del sentiment

// Pass the schema as a plain object — do not JSON.stringify() it first.
const schema = {
    type: 'object',
    properties: {
        rating: { type: 'number', minimum: 1, maximum: 5 },
        is_positive: { type: 'boolean' },
    },
    required: ['rating', 'is_positive'],
};

const result = await session.prompt(
    "Rate the following feedback: 'The food was great!'",
    { responseConstraint: schema },
);

const data = JSON.parse(result);
console.log(data.rating); // 5

Vincoli e prefissi

Puoi guidare ulteriormente il modello precompilando la risposta dell'assistente utilizzando prefix: true.

const character = await session.prompt([
    { role: 'user', content: 'Create a character sheet' },
    { role: 'assistant', content: '```json\n', prefix: true },
]);

5. Best practice e sicurezza

  • Pulizia delle risorse: chiama sempre session.destroy() al termine di una conversazione per liberare memoria.
  • Sicurezza dell'output: l'output del modello non è attendibile. Scrivi sempre i risultati in textContent, non in innerHTML, per evitare l'inserimento di XSS dall'output del modello dannoso.
  • Se devi consentire un codice HTML limitato, utilizza un sanitizer come l'API Sanitizer nativa o DOMPurify.
  • Interruzione delle attività: utilizza AbortController per consentire agli utenti di interrompere le generazioni di lunga durata. Passa signal a prompt() o promptStreaming(), non a LanguageModel.create().
  • Sicurezza: utilizza i criteri di autorizzazione per controllare l'accesso negli iframe: <iframe src="..." allow="language-model"></iframe>.
  • Progettazione: consulta la People + AI Guidebook per garantire un'implementazione responsabile dell'AI.

Combinando gli output strutturati con una gestione efficace delle sessioni, gli sviluppatori possono creare applicazioni di AI complesse e stateful che vengono eseguite interamente sul dispositivo dell'utente.

Cose da fare e cose da evitare

Per l'elenco completo e dettagliato delle cose da fare e da evitare, visita la pagina https://developer.chrome.com/docs/ai/built-in-ai-dos-donts.md.txt. Ecco un riepilogo:

Preparare il modello in un momento ragionevole

Si applica a: tutte le API, ad esempio Summarizer, Translator e Writer.

Cosa fare: inizializza la sessione non appena hai stabilito chiaramente l'intenzione dell'utente di utilizzare la funzionalità di AI, ad esempio quando un utente accede a una superficie di strumenti AI pertinente, passa il mouse sopra un'area di lavoro AI o interagisce con l'UI circostante della funzionalità. Il pre-riscaldamento della sessione consente di caricare il modello in memoria in background mentre l'utente configura l'attività, eliminando la latenza di avvio a freddo evitabile. Cerca di essere un passo avanti avviando l'attività AI successiva più probabile non appena inizi il rendering del risultato corrente, ad esempio se la funzionalità è progettata per un utilizzo iterativo.

Da evitare: a meno che non sia necessario, non attendere che l'utente faccia clic su "Genera" per inizializzare la sessione. Questo porta a un ritardo di avvio a freddo, perché il modello deve prima essere caricato in memoria e preparare la pipeline di esecuzione.

Imposta i prompt iniziali durante la creazione

Si applica a: API Prompt.

Cosa fare: fornisci le istruzioni di sistema durante l'inizializzazione della sessione per migliorare la velocità del primo prompt.

Da evitare: iniziare con una sessione vuota e inviare le istruzioni di sistema come parte della prima chiamata prompt(). Ciò aumenta la latenza perché costringe il modello a elaborare le istruzioni all'ultimo momento.

Clona le sessioni per le attività ripetitive

Si applica a: API Prompt.

Per l'API Prompt, ogni sessione monitora il contesto della conversazione, tenendo conto di tutte le interazioni precedenti. Poiché un clone eredita tutto dalla sessione principale, inclusi i prompt iniziali e tutta la cronologia delle interazioni fino al momento della clonazione, struttura l'utilizzo in modo da ereditare solo ciò di cui hai bisogno.

Cosa fare:

  • Crea una sessione di base: per gestire in modo efficiente attività non correlate, crea una sessione di base che contenga solo le istruzioni di sistema e nessun contesto di conversazione precedente.
  • Clona la base di riferimento: utilizza clone() su quella sessione di base per le nuove attività per risparmiare l'overhead della nuova analisi delle istruzioni di sistema. In questo modo puoi creare conversazioni parallele o reimpostare un'attività alla sua base di riferimento.

Azione sconsigliata:

  • Non riutilizzare la stessa sessione per attività non correlate ed evita di clonare una sessione che contiene già una cronologia delle interazioni non necessaria. Entrambi i pattern possono far sì che il contesto precedente non correlato interferisca con l'attività corrente.
  • Non chiamare ripetutamente create() con istruzioni di sistema identiche. Utilizza invece il pattern di clonazione per ottimizzare le prestazioni.

Elimina le sessioni inutilizzate

Si applica a: tutte le API.

Cosa fare: chiama esplicitamente destroy() per le sessioni che non ti servono più per liberare memoria quando una funzionalità non è più in uso. Se utilizzi un pattern di clonazione, mantieni la sessione di base e distruggi i cloni che non ti servono più.

Da evitare: mantenere attive più sessioni di grandi dimensioni. Ogni sessione consuma memoria, il che crea un utilizzo non necessario delle risorse e potrebbe diventare un problema. Le sessioni verranno ripulite naturalmente dal garbage collector, ma la chiamata a destroy() libera la memoria più rapidamente.

Esegui il rendering delle risposte in streaming in modo sicuro ed efficiente

Si applica a: tutte le API con supporto per lo streaming (Prompt, Summarizer, Writer, Rewriter e Translator).

Cosa fare: tratta tutti gli output degli LLM come contenuti non attendibili. Sanifica l'output combinato completo, non solo i blocchi, perché il codice dannoso potrebbe essere suddiviso tra gli aggiornamenti. Prima del rendering, utilizza l'API Sanitizer, se supportata. Per evitare un calo delle prestazioni, utilizza un parser Markdown di streaming come streaming-markdown.

Da evitare: impostare direttamente innerHTML a ogni aggiornamento dei blocchi. Questo processo è lento, soprattutto con formattazioni complesse come l'evidenziazione della sintassi, ed è vulnerabile agli attacchi di injection.

Ottimizza l'input per la velocità

Si applica a: tutte le API.

Cosa fare: passa al modello solo ciò che è strettamente necessario. Elimina tutto ciò che non è pertinente all'attività in questione. Per i set di dati di grandi dimensioni, fornisci una breve panoramica e una piccola selezione di elementi pertinenti.

Cosa non fare: non inviare alle API testo non elaborato, metadati non necessari, tag HTML o elenchi di grandi dimensioni non filtrati. La latenza aumenta in modo significativo con le dimensioni dell'input, il che può far sembrare la funzionalità di AI non funzionante su molti dispositivi.

Utilizza l'output strutturato per risultati prevedibili

Si applica a: API Prompt.

Cosa fare: quando hai bisogno che il modello restituisca i dati in un formato specifico, utilizza l'output strutturato fornendo un campo responseConstraint per fornire uno schema JSON. In questo modo, l'output è prevedibile e non è necessario eseguire una post-elaborazione complessa o un'analisi manuale.

Da evitare: affidarsi solo alle istruzioni in linguaggio naturale (come "output solo JSON"). I modelli potrebbero includere elementi di riempimento della conversazione che interrompono l'analizzatore.

Disaccoppia la generazione dai vincoli di lunghezza

Si applica a: API Prompt, in quanto è l'unica API che supporta gli schema di output strutturati.

Cosa fare: lascia che il modello generi la risposta in modo naturale, quindi utilizza la logica lato client per troncare il testo in modo che si adatti alla UI.

Da evitare: applicare limiti di caratteri rigidi come maxLength: 125 utilizzando schemi di output strutturati. Quando la risposta di un modello è più lunga del limite impostato, il modello potrebbe passare a token ad alta densità, come lingue straniere o emoji, per comprimere il significato, con un output privo di senso.

Tieni informato l'utente

Si applica a: tutte le API.

Cosa fare: a seconda della complessità e della durata prevista dell'attività, utilizza animazioni, segnali visivi e indicatori di avanzamento per tenere l'utente informato. L'approccio ottimale dipende dal caso d'uso e dalla lunghezza prevista dell'output dell'API. Ecco alcune idee:

  • Streaming per contenuti lunghi: per riassunti o chat, lo streaming crea un effetto macchina da scrivere per token per impostazione predefinita. Questo può sembrare naturale e fornire un feedback immediato.
  • Non in streaming per attività brevi (o attività asincrone lunghe): per output brevi, ad esempio testo alternativo, la modalità non in streaming può creare una UI più rifinita. Inoltre, offre il tempo necessario per preparare in modo speculativo l'attività AI successiva mentre viene eseguito il rendering di quella corrente. Questo approccio funziona anche per attività asincrone o in background più lunghe. Se l'utente non è bloccato sull'output per continuare il suo percorso, non è urgente produrre l'output in tempo reale. Segnala che il processo è in corso nell'UI.
  • Transizioni visive per gli aggiornamenti: quando traduci o riscrivi il testo, utilizza animazioni, ad esempio il morphing delle parole.

Da evitare: aggiornare la UI senza segnali visivi.

Allineati al modello mentale di tempo e lavoro dell'utente

Si applica a: tutte le API.

Cosa fare: valuta la possibilità di inserire un ritardo artificiale di uno o due secondi se una risposta è quasi istantanea. Paradossalmente, gli utenti potrebbero ritenere i risultati più affidabili quando percepiscono un processo di generazione in linea con la difficoltà percepita dell'attività. Utilizza le animazioni per segnalare che è stato eseguito un processo di AI.

Da evitare: sorprendere gli utenti con sostituzioni istantanee della UI.

Consenti agli utenti di navigare rapidamente e annullare le modifiche apportate dall'AI

Si applica a: tutte le API.

Cosa fare: dota la tua UI di un selettore o di una cronologia di navigazione che consenta agli utenti di esplorare diversi risultati con sicurezza e di annullare rapidamente le modifiche apportate dall'AI. In questo modo, le diverse versioni sono ancora facilmente disponibili.

Cosa non fare: sovrascrivere la bozza precedente dell'utente o un risultato dell'AI che potrebbe essere piaciuto senza un modo per tornare indietro, ripristinare o confrontare le versioni.

Offri agli utenti la possibilità di controllare e ignorare le impostazioni

Si applica a: tutte le API.

Cosa fare: l'utente deve essere l'editor finale di tutti i contenuti generati. Fornisci override intuitivi in modo che l'utente mantenga la piena proprietà dell'output finale. Le API potrebbero produrre risultati errati.

Da evitare: forzare un risultato generato dall'AI come unica opzione.

Memorizza nella cache i risultati per le attività ricorrenti

Si applica a: tutte le API.

Cosa fare: implementa una cache dei risultati locale (ad esempio, utilizzando sessionStorage o IndexedDB) per input o query ripetuti. Normalizza l'input eliminando gli spazi vuoti e convertendo in minuscolo per aumentare i successi della cache. Per input pesanti, ad esempio immagini, genera un hash da utilizzare come chiave cache. Imposta una durata (TTL) conservativa per la cache (o pubblica i risultati memorizzati nella cache mentre li aggiorni in background). Consenti all'utente di attivare una nuova inferenza se il risultato non è soddisfacente.

Da evitare: eseguire nuovamente la stessa inferenza per una query di ricerca ripetuta o un input di dati identico in cui la variabilità non è auspicabile, ad esempio quando un utente naviga avanti e indietro tra i risultati di ricerca. In questo modo, si ottimizzano la reattività e l'utilizzo efficiente del computing locale.

6. Strategie di riserva

Prima dell'uso, controlla se l'oggetto LanguageModel è disponibile nell'ambito globale:

if ('LanguageModel' in self) {
  // The Prompt API is supported.
} else {
  // Execute fallback strategy
}

Se l'API Prompt non è supportata o i controlli di disponibilità restituiscono "non disponibile", devi eseguire il fallback in modo controllato:

  • Fallback dell'API remota: reindirizza la richiesta di rilevamento a un endpoint del server o a un'API cloud (come l'API Vertex AI Gemini).
  • Fallback dell'API locale: reindirizza la richiesta di rilevamento a un endpoint locale, ad esempio utilizzando Transformers.js.