L'API Prompt permet aux développeurs d'exécuter des tâches de traitement du langage naturel directement dans le navigateur à l'aide de Gemini Nano. Cette approche d'IA intégrée garantit la confidentialité des utilisateurs, réduit les coûts des serveurs et permet d'utiliser les fonctionnalités hors connexion.
1. Premiers pas et configuration matérielle requise
L'API Prompt est actuellement disponible dans Chrome à partir de la version 148 (ordinateur) pour Windows, macOS, Linux et Chromebook Plus.
Prérequis matériels
- Espace de stockage : 22 Go d'espace libre (pour le profil et le modèle initiaux).
- Mémoire/CPU : 16 Go de RAM et au moins 4 cœurs de CPU.
- GPU : 4 Go de VRAM ou plus (requis pour l'entrée audio).
- Réseau : requis uniquement pour le téléchargement initial du modèle.
Initialiser l'API
Vérifiez la disponibilité du modèle avant de déclencher un téléchargement :
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. Fonctionnalités de base du prompting
Les exemples de session de cette section omettent session.destroy() par souci de concision. Appelez toujours session.destroy() lorsqu'une session n'est plus nécessaire pour libérer de la mémoire sur l'appareil (voir la section 5).
Sortie de base et sortie en flux continu
Pour les réponses courtes, utilisez prompt(). Pour les contenus plus longs, utilisez promptStreaming() pour fournir une UI plus responsive.
OBLIGATOIRE : N'attribuez jamais la sortie du modèle à innerHTML. La sortie du modèle n'est pas fiable et peut contenir du balisage injecté. Utilisez toujours textContent ou un assainisseur.
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);
Entrée multimodale
L'API Prompt accepte les entrées textuelles, audio et visuelles (images, canevas, images vidéo).
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. Gestion avancée des sessions
Les sessions permettent au modèle de conserver le contexte sur plusieurs interactions.
Contexte et quota
Chaque session est limitée à un nombre maximal de jetons. Vous pouvez surveiller l'utilisation via session.contextUsage et session.contextWindow. Si la fenêtre déborde, les messages les plus anciens (à l'exception de l'invite système) sont supprimés.
Sessions de clonage
Le clonage est efficace pour démarrer des conversations parallèles qui partagent le même contexte initial (comme une personnalité "système") sans réinitialisation.
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();
Restaurer des sessions précédentes
Une fonctionnalité de restauration native est en cours de développement. En attendant, vous pouvez recréer une session en fournissant l'historique précédent à initialPrompts.
Remarque : localStorage n'est pas chiffré et est persistant. L'historique des conversations stocké peut inclure des informations permettant d'identifier personnellement l'utilisateur. Tenez compte des implications en termes de confidentialité avant de conserver l'historique des discussions.
// || '[]' 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. Résultat structuré avec un schéma JSON
Pour empêcher le modèle d'ajouter du "bavardage" (par exemple, "Bien sûr, voici votre JSON :"), utilisez un schéma JSON via le champ responseConstraint. Cela garantit que la sortie est un JSON valide qui peut être analysé immédiatement.
Exemple : Classification des sentiments
// 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
Contraintes et préfixes
Vous pouvez guider davantage le modèle en préremplissant la réponse de l'assistant à l'aide de prefix: true.
const character = await session.prompt([
{ role: 'user', content: 'Create a character sheet' },
{ role: 'assistant', content: '```json\n', prefix: true },
]);
5. Bonnes pratiques et sécurité
- Nettoyage des ressources : appelez toujours
session.destroy()lorsqu'une conversation est terminée pour libérer de la mémoire. - Sécurité des sorties : la sortie du modèle n'est pas fiable. Écrivez toujours les résultats dans
textContent, et non dansinnerHTML, pour éviter les injections XSS à partir de sorties de modèle malveillantes. - Utilisez un outil de nettoyage comme l'API Sanitizer native ou DOMPurify si vous devez autoriser un code HTML limité.
- Abandonner des tâches : utilisez
AbortControllerpour permettre aux utilisateurs d'arrêter les générations de longue durée. Transmettezsignalàprompt()oupromptStreaming(), et non àLanguageModel.create(). - Sécurité : utilisez des règles d'autorisation pour contrôler l'accès dans les iFrames :
<iframe src="..." allow="language-model"></iframe>. - Conception : consultez le guide People + AI pour vous assurer que l'IA est implémentée de manière responsable.
En combinant des sorties structurées avec une gestion de session robuste, les développeurs peuvent créer des applications d'IA complexes et avec état qui s'exécutent entièrement sur l'appareil de l'utilisateur.
Choses à faire et à éviter
Pour obtenir la liste complète des bonnes et mauvaises pratiques, consultez https://developer.chrome.com/docs/ai/built-in-ai-dos-donts.md.txt. Voici l'essentiel :
Préparer le modèle à un moment raisonnable
S'applique à : toutes les API, par exemple Summarizer, Translator et Writer.
À faire : Initialisez la session dès que vous avez clairement établi l'intention de l'utilisateur d'utiliser la fonctionnalité d'IA, par exemple lorsqu'un utilisateur accède à une surface d'outils d'IA pertinente, pointe sur un espace de travail d'IA ou interagit avec l'UI entourant la fonctionnalité. Le préchauffage de la session permet au modèle de se charger en mémoire en arrière-plan pendant que l'utilisateur configure sa tâche, ce qui élimine la latence de démarrage à froid évitable. Essayez d'avoir une longueur d'avance en démarrant la tâche d'IA suivante la plus probable dès que vous commencez à afficher le résultat actuel, par exemple si la fonctionnalité est conçue pour une utilisation itérative.
À éviter : Sauf si nécessaire, n'attendez pas que l'utilisateur clique sur "Générer" pour initialiser la session. Cela entraîne un délai de démarrage à froid, car le modèle doit d'abord se charger en mémoire et préparer son pipeline d'exécution.
Définir des requêtes initiales lors de la création
S'applique à l'API Prompt.
À faire : Fournissez des instructions système lors de l'initialisation de la session pour améliorer la vitesse de la première requête.
À ne pas faire : commencer par une session vide et envoyer des instructions système dans le premier appel prompt(). Cela augmente la latence, car le modèle est obligé de traiter ces instructions au dernier moment.
Cloner des sessions pour les tâches répétitives
S'applique à l'API Prompt.
Pour l'API Prompt, chaque session suit le contexte de la conversation, en tenant compte de toutes les interactions précédentes. Étant donné qu'un clone hérite de tout ce qui provient de sa session parente, y compris les requêtes initiales et l'historique des interactions jusqu'au moment du clonage, structurez votre utilisation pour n'hériter que de ce dont vous avez besoin.
À faire :
- Créer une session de base : pour gérer efficacement les tâches non liées, créez une session de base qui ne contient que vos instructions système et aucun contexte de conversation précédent.
- Cloner la référence : utilisez
clone()sur cette session de base pour les nouvelles tâches afin d'éviter de réanalyser les instructions système. Cela vous permet de créer des conversations parallèles ou de réinitialiser une tâche à son état de référence.
À éviter :
- Ne réutilisez pas la même session pour des tâches sans rapport et évitez de cloner une session qui contient déjà un historique d'interactions inutile. Ces deux modèles peuvent entraîner l'interférence d'un contexte précédent non lié avec votre tâche actuelle.
- N'appelez pas
create()de manière répétée avec des instructions système identiques. Utilisez plutôt le modèle de clonage pour optimiser les performances.
Détruire les sessions inutilisées
S'applique à : toutes les API.
À faire : appelez explicitement destroy() sur les sessions dont vous n'avez plus besoin pour libérer de la mémoire lorsqu'une fonctionnalité n'est plus utilisée. Si vous utilisez un modèle de clonage, conservez la session de base et détruisez les clones dont vous n'avez plus besoin.
À ne pas faire : garder plusieurs sessions volumineuses actives. Chaque session consomme de la mémoire, ce qui crée une utilisation inutile des ressources et peut devenir un problème. Les sessions sont naturellement nettoyées par le récupérateur de mémoire, mais l'appel de destroy() libère de la mémoire plus rapidement.
Afficher les réponses en streaming de manière sûre et efficace
S'applique à : toutes les API compatibles avec le streaming (Prompt, Summarizer, Writer, Rewriter et Translator).
À faire : Traitez toutes les sorties de LLM comme du contenu non fiable. Nettoyez l'intégralité de la sortie combinée, et pas seulement des fragments, car du code malveillant peut être réparti sur plusieurs mises à jour. Avant d'effectuer l'affichage, utilisez l'API Sanitizer si elle est compatible. Pour éviter une baisse des performances, utilisez un analyseur Markdown en streaming tel que streaming-markdown.
À ne pas faire : définir directement innerHTML à chaque mise à jour de fragment. Cette opération est lente, en particulier avec une mise en forme complexe comme la coloration syntaxique, et vulnérable aux injections.
Optimiser la saisie pour plus de rapidité
S'applique à : toutes les API.
À faire : ne transmettez au modèle que ce qui est strictement nécessaire. Supprimez tout ce qui n'est pas pertinent pour la tâche à accomplir. Pour les ensembles de données volumineux, fournissez un bref aperçu et une petite sélection d'éléments pertinents.
À ne pas faire : envoyer du texte brut non traité, des métadonnées inutiles, des balises HTML ou de longues listes non filtrées aux API. La latence augmente considérablement avec la taille de l'entrée, ce qui peut donner l'impression que la fonctionnalité d'IA ne fonctionne pas sur de nombreux appareils.
Utiliser une sortie structurée pour obtenir des résultats prévisibles
S'applique à l'API Prompt.
À faire : Lorsque vous avez besoin que le modèle renvoie des données dans un format spécifique, utilisez la sortie structurée en fournissant un champ responseConstraint pour fournir un schéma JSON. Cela garantit que la sortie est prévisible et vous évite d'avoir à effectuer un post-traitement complexe ou une analyse manuelle.
À éviter : vous fier uniquement aux instructions en langage naturel (comme "ne renvoyer que du JSON"). Les modèles peuvent inclure des éléments de remplissage conversationnels qui interrompent votre analyseur.
Dissocier la génération des contraintes de longueur
S'applique à : l'API Prompt, car il s'agit de la seule API compatible avec les schémas de sortie structurés.
À faire : laissez le modèle générer sa réponse naturellement, puis utilisez la logique côté client pour tronquer le texte afin qu'il s'adapte à votre UI.
À éviter : appliquer des nombres maximaux de caractères stricts comme maxLength: 125 à l'aide de schémas de sortie structurés. Lorsque la réponse d'un modèle est plus longue que la limite que vous avez définie, le modèle peut passer à des jetons à haute densité, comme des langues étrangères ou des emoji, pour compresser la signification, ce qui entraîne une sortie absurde.
L'information est clé
S'applique à : toutes les API.
À faire : En fonction de la complexité et de la durée prévue de la tâche, utilisez des animations, des repères visuels et des indicateurs de progression pour tenir l'utilisateur informé. L'approche optimale dépend de votre cas d'utilisation et de la longueur attendue de la sortie de l'API. Voici quelques idées :
- Streaming pour les contenus longs : pour les résumés ou les discussions, le streaming crée par défaut un effet de machine à écrire par jeton. Cela peut sembler naturel et fournir un feedback immédiat.
- Sans streaming pour les tâches courtes (ou les tâches asynchrones longues) : pour les sorties courtes, par exemple le texte alternatif, l'absence de streaming peut créer une UI plus soignée. Cela permet également de préparer de manière spéculative la tâche d'IA suivante pendant l'affichage de la tâche actuelle. Cette approche fonctionne également pour les tâches asynchrones ou en arrière-plan plus longues. Si l'utilisateur n'est pas bloqué dans son parcours en attendant la sortie, il n'est pas urgent de la produire immédiatement. Indiquez que le processus est en cours dans l'UI.
- Transitions visuelles pour les mises à jour : lorsque vous traduisez ou réécrivez du texte, utilisez des animations, par exemple, la transformation de mots.
À éviter : mettre à jour l'UI sans repères visuels.
S'aligner sur le modèle mental de l'utilisateur concernant le temps et le travail
S'applique à : toutes les API.
À faire : envisagez un délai artificiel d'une ou deux secondes si une réponse est presque instantanée. Paradoxalement, les utilisateurs peuvent trouver les résultats plus fiables lorsqu'ils perçoivent un processus de génération qui correspond à la difficulté perçue de la tâche. Utilisez des animations pour signaler qu'un processus d'IA a eu lieu.
À ne pas faire : surprendre les utilisateurs en remplaçant instantanément l'interface utilisateur.
Permettre aux utilisateurs de naviguer rapidement et d'annuler les modifications de l'IA
S'applique à : toutes les API.
À faire : Équipez votre UI d'un stepper ou d'un historique de navigation qui permet aux utilisateurs d'explorer différents résultats en toute confiance, et de rapidement annuler les modifications de l'IA. Cela permet de s'assurer que les différentes versions sont toujours facilement disponibles.
À ne pas faire : Écraser le brouillon précédent de l'utilisateur ou un résultat de l'IA qu'il aurait pu aimer sans lui permettre de revenir en arrière, d'annuler ou de comparer les versions.
Donner le contrôle aux utilisateurs et leur permettre de remplacer les paramètres
S'applique à : toutes les API.
À faire : faites en sorte que l'utilisateur soit l'éditeur final de tout le contenu généré. Fournissez des options de remplacement intuitives pour que l'utilisateur garde le contrôle total du résultat final. Les API peuvent produire des résultats incorrects.
À éviter : imposer un résultat généré par l'IA comme seule option.
Mettre en cache les résultats des tâches récurrentes
S'applique à : toutes les API.
À faire : implémentez un cache de résultats local (par exemple, à l'aide de sessionStorage ou IndexedDB) pour les entrées ou les requêtes répétées. Normalisez l'entrée en supprimant les espaces et en convertissant les caractères en minuscules pour augmenter les succès de cache. Pour les entrées lourdes, par exemple les images, générez un hachage à utiliser comme clé de cache. Définissez une valeur TTL (Time To Live) prudente pour votre cache (ou diffusez les résultats mis en cache tout en les mettant à jour en arrière-plan). Permettez à l'utilisateur de déclencher une nouvelle inférence si le résultat n'est pas satisfaisant.
À éviter : Réexécuter la même inférence pour une requête de recherche répétée ou une entrée de données identique lorsque la variabilité n'est pas souhaitable, par exemple lorsqu'un utilisateur navigue entre les résultats de recherche. Cela optimise la réactivité et l'utilisation efficace du calcul local.
6. Stratégies de remplacement
Avant de l'utiliser, vérifiez si l'objet LanguageModel est disponible dans le champ d'application global :
if ('LanguageModel' in self) {
// The Prompt API is supported.
} else {
// Execute fallback strategy
}
Si l'API Prompt n'est pas compatible ou si les vérifications de disponibilité renvoient "indisponible", vous devez effectuer un remplacement progressif :
- Solution de remplacement par API distante : redirigez la requête de détection vers un point de terminaison de serveur ou une API cloud (comme l'API Gemini Vertex AI).
- Solution de secours avec API locale : redirigez la requête de détection vers un point de terminaison local, par exemple à l'aide de Transformers.js.