Modelo de lenguaje

Funciones web: LanguageModel

La API de Prompt permite que los desarrolladores ejecuten tareas de procesamiento de lenguaje natural directamente en el navegador con Gemini Nano. Este enfoque de IA integrada garantiza la privacidad del usuario, reduce los costos del servidor y habilita la funcionalidad sin conexión.

1. Cómo comenzar y requisitos de hardware

Actualmente, la API de Prompt está disponible en Chrome a partir de la versión 148 (computadoras de escritorio) para Windows, macOS, Linux y Chromebook Plus.

Requisitos previos de hardware

  • Almacenamiento: 22 GB de espacio libre (para el perfil y el modelo iniciales)
  • Memoria/CPU: 16 GB de RAM y más de 4 núcleos de CPU
  • GPU: 4 GB de VRAM o más (obligatorio para la entrada de audio)
  • Red: Solo se requiere para la descarga inicial del modelo.

Inicializa la API

Verifica la disponibilidad del modelo antes de activar una descarga:

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. Funciones principales de instrucciones

Los ejemplos de sesiones de esta sección omiten session.destroy() para mayor brevedad. Siempre llama a session.destroy() cuando ya no se necesite una sesión para liberar memoria del dispositivo (consulta la sección 5).

Salida básica y transmitida

Para respuestas cortas, usa prompt(). Para contenido más largo, usa promptStreaming() para proporcionar una IU más responsiva.

OBLIGATORIO: Nunca asignes el resultado del modelo a innerHTML. El resultado del modelo no es confiable y puede contener lenguaje de marcado insertado. Usa siempre textContent o un desinfectante.

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);

Entrada multimodal

La API de Prompt admite entradas de texto, audio y visuales (imágenes, lienzo y fotogramas de 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. Administración avanzada de sesiones

Las sesiones permiten que el modelo mantenga el contexto en varias interacciones.

Contexto y cuota

Cada sesión tiene un límite máximo de tokens. Puedes supervisar el uso a través de session.contextUsage y session.contextWindow. Si la ventana se desborda, se descartan los mensajes más antiguos (excepto la instrucción del sistema).

Clonación de sesiones

La clonación es eficiente para iniciar conversaciones paralelas que comparten el mismo contexto inicial (como una personalidad del "sistema") sin reinicializar.

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();

Cómo restablecer sesiones anteriores

Mientras se desarrolla una función nativa de "restablecimiento", puedes volver a crear una sesión ingresando el historial anterior en initialPrompts.

Nota: localStorage no está encriptado y es persistente. El historial de conversaciones almacenado puede incluir IIP del usuario. Ten en cuenta las implicaciones de privacidad antes de conservar el historial de 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. Resultado estructurado con esquema JSON

Para evitar que el modelo agregue "charlas" (p.ej., "Claro, aquí tienes tu JSON:"), usa un esquema JSON a través del campo responseConstraint. Esto garantiza que el resultado sea un JSON válido que se pueda analizar de inmediato.

Ejemplo: Clasificación de opiniones

// 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

Restricciones y prefijos

Puedes guiar aún más al modelo completando previamente la respuesta del asistente con prefix: true.

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

5. Prácticas recomendadas y seguridad

  • Limpieza de recursos: Siempre llama a session.destroy() cuando finalice una conversación para liberar memoria.
  • Seguridad de los resultados: El resultado del modelo no es confiable. Escribe siempre los resultados en textContent, no en innerHTML, para evitar la inyección de XSS desde el resultado del modelo malicioso.
  • Usa un limpiador como la API de Sanitizer nativa o DOMPurify si necesitas permitir HTML limitado.
  • Anulación de tareas: Usa AbortController para permitir que los usuarios detengan las generaciones de larga duración. Pasa el signal a prompt() o promptStreaming(), no a LanguageModel.create().
  • Seguridad: Usa políticas de permisos para controlar el acceso en los iframes: <iframe src="..." allow="language-model"></iframe>.
  • Diseño: Revisa la guía de People + AI para garantizar una implementación responsable de la IA.

Combinando los resultados estructurados con una administración de sesiones sólida, los desarrolladores pueden crear aplicaciones de IA complejas y con estado que se ejecutan por completo en el dispositivo del usuario.

Qué debes y no debes hacer

Para obtener la lista detallada completa de lo que se debe y no se debe hacer, consulta https://developer.chrome.com/docs/ai/built-in-ai-dos-donts.md.txt. A continuación, se muestra la esencia:

Prepara el modelo con un tiempo razonable

Se aplica a todas las APIs, por ejemplo, Summarizer, Translator y Writer.

Qué hacer: Inicializa la sesión en cuanto hayas establecido claramente la intención del usuario de usar la función potenciada por IA, por ejemplo, cuando un usuario navega a una plataforma de herramientas de IA relevante, coloca el cursor sobre un espacio de trabajo de IA o interactúa con la IU que rodea la función. La preparación previa de la sesión permite que el modelo se cargue en la memoria de forma silenciosa en segundo plano mientras el usuario configura su tarea, lo que elimina la latencia de inicio en frío evitable. Intenta adelantarte un paso iniciando la siguiente tarea de IA más probable en cuanto comiences a renderizar el resultado actual, por ejemplo, si la función está diseñada para un uso iterativo.

Qué no hacer: A menos que sea necesario, no esperes a que el usuario haga clic en "Generar" para inicializar la sesión. Esto genera un retraso de inicio en frío, ya que el modelo primero debe cargarse en la memoria y preparar su canalización de ejecución.

Establece instrucciones iniciales durante la creación

Se aplica a la API de Prompt.

Qué hacer: Proporciona instrucciones del sistema durante la inicialización de la sesión para mejorar la velocidad de la primera instrucción.

No hagas lo siguiente: No inicies con una sesión vacía y envíes instrucciones del sistema como parte de la primera llamada a prompt(). Esto aumenta la latencia porque obliga al modelo a procesar esas instrucciones en el último momento.

Clona sesiones para tareas repetitivas

Se aplica a la API de Prompt.

Para la API de Prompt, cada sesión hace un seguimiento del contexto de la conversación, teniendo en cuenta todas las interacciones anteriores. Debido a que una clonación hereda todo de su sesión superior, incluidas las instrucciones iniciales y todo el historial de interacciones hasta el momento de la clonación, estructura tu uso para heredar solo lo que necesitas.

Qué debes hacer:

  • Crea una sesión base: Para controlar tareas no relacionadas de manera eficiente, crea una sesión base que solo contenga las instrucciones del sistema y ningún contexto conversacional anterior.
  • Clona la base de referencia: Usa clone() en esa sesión base para las tareas nuevas y, así, ahorrar la sobrecarga de volver a analizar las instrucciones del sistema. Esto te permite crear conversaciones paralelas o restablecer una tarea a su estado inicial.

Qué no debes hacer:

  • No reutilices la misma sesión para tareas no relacionadas y evita clonar cualquier sesión que ya contenga un historial de interacciones innecesario. Ambos patrones pueden hacer que el contexto anterior no relacionado interfiera con tu tarea actual.
  • No llames a create() de forma repetida con instrucciones del sistema idénticas. En su lugar, usa el patrón de clonación para optimizar el rendimiento.

Destruye las sesiones no utilizadas

Se aplica a todas las APIs.

Qué hacer: Llama de forma explícita a destroy() en las sesiones que ya no necesites para liberar memoria cuando una función ya no esté en uso. Si usas un patrón de clonación, conserva la sesión base y destruye los clones que ya no necesites.

No hagas lo siguiente: Mantener activas varias sesiones grandes. Cada sesión consume memoria, lo que genera un uso innecesario de recursos y podría convertirse en un problema. El recolector de elementos no utilizados limpiará las sesiones de forma natural, pero llamar a destroy() libera memoria con mayor rapidez.

Renderiza respuestas de transmisión de forma segura y eficiente

Se aplica a todas las APIs con compatibilidad con transmisión (Prompt, Summarizer, Writer, Rewriter y Translator).

Qué hacer: Trata todos los resultados de LLM como contenido no confiable. Limpia el resultado combinado completo, no solo los fragmentos, ya que el código malicioso podría dividirse entre las actualizaciones. Antes de renderizar, usa la API de Sanitizer cuando sea compatible. Para evitar una disminución en el rendimiento, usa un analizador de Markdown de transmisión, como streaming-markdown.

Qué no hacer: No configures innerHTML directamente en cada actualización de fragmento. Esto es lento, en especial con formatos complejos, como el resaltado de sintaxis, y vulnerable a la inserción.

Optimiza la entrada para mejorar la velocidad

Se aplica a todas las APIs.

Qué hacer: Pasa al modelo solo lo que sea estrictamente necesario. Quita todo lo que sea irrelevante para la tarea en cuestión. Para conjuntos de datos grandes, proporciona una breve descripción general y una pequeña selección de elementos relevantes.

No hagas lo siguiente: No envíes texto sin procesar, metadatos innecesarios, etiquetas HTML ni listas grandes sin filtrar a las APIs. La latencia aumenta significativamente con el tamaño de la entrada, lo que puede hacer que la función potenciada por IA parezca rota en muchos dispositivos.

Usa resultados estructurados para obtener resultados predecibles

Se aplica a la API de Prompt.

Qué hacer: Cuando necesites que el modelo devuelva datos en un formato específico, usa la salida estructurada proporcionando un campo responseConstraint para proporcionar un esquema JSON. Esto garantiza que el resultado sea predecible y evita que necesites un procesamiento posterior complejo o un análisis manual.

No hagas lo siguiente: No confíes solo en las instrucciones en lenguaje natural (como "solo genera JSON"). Los modelos pueden incluir palabras de relleno conversacionales que interrumpan el analizador.

Desvincula la generación de las restricciones de longitud

Se aplica a: API de Prompt, ya que es la única API que admite esquemas de salida estructurados.

Qué hacer: Deja que el modelo genere su respuesta de forma natural y, luego, usa la lógica del cliente para truncar el texto y que se ajuste a tu IU.

No hagas lo siguiente: No apliques límites de caracteres estrictos, como maxLength: 125, con esquemas de salida estructurados. Cuando la respuesta de un modelo es más larga que el límite que estableciste, el modelo puede cambiar a tokens de alta densidad, como idiomas extranjeros o emojis, para comprimir el significado, lo que genera un resultado sin sentido.

Cómo mantener informado al usuario

Se aplica a todas las APIs.

Qué hacer: Según la complejidad y la duración prevista de la tarea, usa animaciones, indicadores visuales y de progreso para mantener informado al usuario. El enfoque óptimo depende de tu caso de uso y de la longitud esperada del resultado de la API. Estas son algunas ideas:

  • Transmisión de contenido largo: Para resúmenes o chats, la transmisión crea un efecto de máquina de escribir por token de forma predeterminada. Esto puede sentirse natural y proporcionar comentarios inmediatos.
  • Sin transmisión para tareas cortas (o tareas asíncronas largas): Para resultados cortos, por ejemplo, texto alternativo, la opción sin transmisión puede crear una IU más refinada. También proporciona tiempo para preparar de forma especulativa la siguiente tarea de IA mientras se renderiza la actual. Este enfoque también funciona para tareas asíncronas o en segundo plano más largas. Si el usuario no está bloqueado en el resultado para continuar su recorrido, no hay una necesidad urgente de producir el resultado tal como sucede. Indica que el proceso está en curso en la IU.
  • Transiciones visuales para las actualizaciones: Cuando traduzcas o reescribas texto, usa animaciones, por ejemplo, de transformación de palabras.

Incorrecto: Actualizar la IU sin indicadores visuales.

Alinearse con el modelo mental del usuario sobre el tiempo y el trabajo

Se aplica a todas las APIs.

Qué hacer: Considera un retraso artificial de uno o dos segundos si una respuesta es casi instantánea. Paradójicamente, los usuarios pueden encontrar resultados más confiables cuando perciben un proceso de generación que se alinea con la dificultad percibida de la tarea. Usa animaciones para indicar que se produjo un procesamiento con IA.

No hagas lo siguiente: No sorprendas a los usuarios con reemplazos instantáneos de la IU.

Permite que los usuarios naveguen rápidamente y deshagan las ediciones de la IA

Se aplica a todas las APIs.

Qué hacer: Equipa tu IU con un stepper o un historial de navegación que permita a los usuarios explorar diferentes resultados con confianza y deshacer rápidamente las ediciones de la IA. Esto garantiza que las diferentes versiones sigan estando disponibles.

No hagas lo siguiente: No reemplaces el borrador anterior del usuario ni un resultado de la IA que le haya gustado sin una forma de volver atrás, revertir o comparar versiones.

Empodera el control y las anulaciones de los usuarios

Se aplica a todas las APIs.

Qué hacer: Haz que el usuario sea el editor final de todo el contenido generado. Proporciona anulaciones intuitivas para que el usuario mantenga la propiedad total del resultado final. Es posible que las APIs produzcan resultados incorrectos.

No hagas lo siguiente: Forzar un resultado generado por IA como la única opción.

Almacena en caché los resultados de las tareas recurrentes

Se aplica a todas las APIs.

Qué hacer: Implementa una caché de resultados local (por ejemplo, con sessionStorage o IndexedDB) para entradas o consultas repetidas. Normaliza la entrada recortando los espacios en blanco y usando minúsculas para aumentar los aciertos de caché. En el caso de las entradas pesadas, por ejemplo, las imágenes, genera un hash para usarlo como clave de caché. Establece un tiempo de actividad (TTL) conservador para la caché (o entrega resultados almacenados en caché mientras los actualizas en segundo plano). Permite que el usuario active una inferencia nueva si el resultado no es satisfactorio.

Qué no hacer: No vuelvas a ejecutar la misma inferencia para una búsqueda repetida o una entrada de datos idéntica en la que no se desee variabilidad, por ejemplo, cuando un usuario navega de un lado a otro entre los resultados de la búsqueda. Esto optimiza la capacidad de respuesta y el uso eficiente de la computación local.

6. Estrategias de resguardo

Antes de usarlo, verifica si el objeto LanguageModel está disponible en el alcance global:

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

Si la API de Prompt no es compatible o las verificaciones de disponibilidad devuelven "no disponible", debes recurrir a una alternativa de forma elegante:

  • Resguardo de API remota: Redirige la solicitud de detección a un extremo de servidor o a una API de Cloud (como la API de Vertex AI Gemini).
  • Resguardo de la API local: Redirige la solicitud de detección a un extremo local, por ejemplo, con Transformers.js.