Publicado el 1 de octubre de 2025
Antes de que se pueda usar cualquiera de las APIs de IA integrada, se deben descargar de la red el modelo subyacente y las personalizaciones (como los ajustes), se deben extraer los datos comprimidos y, por último, se deben cargar en la memoria. En esta guía, se documentan algunas de las prácticas recomendadas para mejorar la experiencia del usuario mientras espera la descarga.
Supervisa y comparte el progreso de la descarga
Todas las APIs de IA integradas tienen la función create()
para iniciar una sesión. La función create()
tiene una opción monitor
para que puedas acceder al progreso de la descarga y compartirlo con el usuario.
Si bien las APIs de IA integradas se crearon para la IA del cliente, en la que los datos se procesan en el navegador y en el dispositivo del usuario, algunas aplicaciones pueden permitir que los datos se procesen en un servidor. La forma en que te diriges al usuario durante el progreso de la descarga del modelo depende de esa pregunta: ¿El procesamiento de datos debe ejecutarse solo de forma local o no? Si es verdadero, tu aplicación es solo del cliente. De lo contrario, tu aplicación podría usar una implementación híbrida.
Solo del cliente
En algunos casos, se requiere el procesamiento de datos del cliente. Por ejemplo, una aplicación de atención médica que permite a los pacientes hacer preguntas sobre su información personal probablemente querrá que esa información permanezca privada en el dispositivo del usuario. El usuario debe esperar hasta que se descarguen y estén listos el modelo y todas las personalizaciones antes de poder usar cualquier función de procesamiento de datos.
En este caso, si el modelo aún no está disponible, debes mostrarle al usuario información sobre el progreso de la descarga.
<style>
progress[hidden] ~ label {
display: none;
}
</style>
<button type="button">Create LanguageModel session</button>
<progress hidden id="progress" value="0"></progress>
<label for="progress">Model download progress</label>
Ahora, para que esto funcione, se requiere un poco de JavaScript. Primero, el código restablece la interfaz de progreso al estado inicial (progreso oculto y en cero), verifica si la API es compatible y, luego, comprueba la disponibilidad de la API:
- La API es
'unavailable'
: Tu aplicación no se puede usar del lado del cliente en este dispositivo. Alertar al usuario que la función no está disponible - La API es
'available'
: La API se puede usar de inmediato, no es necesario mostrar la IU de progreso. - La API es
'downloadable'
o'downloading'
: La API se puede usar una vez que se completa la descarga. Muestra un indicador de progreso y actualízalo cada vez que se active el eventodownloadprogress
. Después de la descarga, muestra el estado indeterminado para indicarle al usuario que el navegador está extrayendo el modelo y cargándolo en la memoria.
const createButton = document.querySelector('.create');
const promptButton = document.querySelector('.prompt');
const progress = document.querySelector('progress');
const output = document.querySelector('output');
let sessionCreationTriggered = false;
let session = null;
const createSession = async (options = {}) => {
if (sessionCreationTriggered) {
return;
}
progress.hidden = true;
progress.value = 0;
try {
if (!('LanguageModel' in self)) {
throw new Error('LanguageModel is not supported.');
}
const availability = await LanguageModel.availability();
if (availability === 'unavailable') {
throw new Error('LanguageModel is not available.');
}
let modelNewlyDownloaded = false;
if (availability !== 'available') {
modelNewlyDownloaded = true;
progress.hidden = false;
}
console.log(`LanguageModel is ${availability}.`);
sessionCreationTriggered = true;
const llmSession = await LanguageModel.create({
monitor(m) {
m.addEventListener('downloadprogress', (e) => {
progress.value = e.loaded;
if (modelNewlyDownloaded && e.loaded === 1) {
// The model was newly downloaded and needs to be extracted
// and loaded into memory, so show the undetermined state.
progress.removeAttribute('value');
}
});
},
...options,
});
sessionCreationTriggered = false;
return llmSession;
} catch (error) {
throw error;
} finally {
progress.hidden = true;
progress.value = 0;
}
};
createButton.addEventListener('click', async () => {
try {
localSession = await createSession({
expectedInputs: [{ type: 'text', languages: ['en'] }],
expectedOutputs: [{ type: 'text', languages: ['en'] }],
});
promptButton.disabled = false;
} catch (error) {
output.textContent = error.message;
}
});
promptButton.addEventListener('click', async () => {
output.innerHTML = '';
try {
const stream = localSession.promptStreaming('Write me a poem');
for await (const chunk of stream) {
output.append(chunk);
}
} catch (err) {
output.textContent = err.message;
}
});
Si el usuario ingresa a la app mientras el modelo se descarga activamente en el navegador, la interfaz de progreso indica en qué punto del proceso de descarga se encuentra el navegador según los datos que aún faltan.
Echa un vistazo a la demostración que muestra este flujo en acción. Si la API de IA integrada (en este ejemplo, la API de Prompt) no está disponible, no se puede usar la app. Si aún se debe descargar el modelo de IA integrado, se le mostrará al usuario un indicador de progreso. Puedes ver el código fuente en GitHub.
Implementación híbrida
Si prefieres usar la IA del cliente, pero puedes enviar datos a la nube de forma temporal, puedes configurar una implementación híbrida. Esto significa que los usuarios pueden experimentar las funciones de inmediato mientras se descarga el modelo local en paralelo. Una vez que se descarga el modelo, cambia de forma dinámica a la sesión local.
Puedes usar cualquier implementación del servidor para el híbrido, pero probablemente sea mejor usar la misma familia de modelos en la nube y de forma local para garantizar que obtengas una calidad de resultados comparable. En Comienza a usar la API de Gemini y las apps web, se destacan los diferentes enfoques de la API de Gemini.
La demostración muestra este flujo en acción. Si la API de IA integrada no está disponible, la demostración recurre a la API de Gemini en la nube. Si aún se debe descargar el modelo integrado, se le muestra al usuario un indicador de progreso y la app usa la API de Gemini en la nube hasta que se descarga el modelo. Consulta el código fuente completo en GitHub.
Conclusión
¿En qué categoría se encuentra tu app? ¿Necesitas un procesamiento 100% del cliente o puedes usar un enfoque híbrido? Después de responder esta pregunta, el siguiente paso es implementar la estrategia de descarga de modelos que mejor se adapte a tus necesidades.
Asegúrate de que tus usuarios siempre sepan cuándo y si pueden usar tu app del lado del cliente mostrándoles el progreso de descarga del modelo, como se describe en esta guía.
Recuerda que este no es solo un desafío único: si el navegador borra el modelo debido a la presión de almacenamiento o cuando hay disponible una nueva versión del modelo, el navegador debe volver a descargarlo. Ya sea que sigas el enfoque híbrido o del cliente, puedes tener la certeza de que crearás la mejor experiencia posible para tus usuarios y dejarás que el navegador se encargue del resto.