发布时间:2025 年 10 月 1 日
在使用任何内置 AI API 之前,必须从网络下载底层模型和任何自定义项(例如微调),提取压缩数据,最后将其加载到内存中。本指南记录了一些最佳实践,可帮助您在用户等待下载时改善用户体验。
监控和分享下载进度
每个内置 AI API 都有一个 create()
函数来启动会话。create()
函数具有 monitor
选项,因此您可以访问下载进度并将其分享给用户。
虽然内置 AI API 是为客户端 AI 而构建的,可在浏览器和用户设备上处理数据,但有些应用允许在服务器上处理数据。您在模型下载进度中如何称呼用户取决于以下问题:数据处理是否必须仅在本地运行?如果值为 true,则表示您的应用仅为客户端应用。 如果不是,您的应用可以使用混合实现。
仅限客户端
在某些情况下,需要进行客户端数据处理。例如,如果某医疗保健应用允许患者询问有关其个人信息的问题,那么该应用可能希望这些信息在用户设备上保持私密状态。用户必须等到模型和所有自定义设置下载完毕并准备就绪后,才能使用任何数据处理功能。
在这种情况下,如果模型尚不可用,您应向用户显示下载进度信息。
<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>
现在,为了让此功能正常运行,我们需要编写一些 JavaScript 代码。该代码首先将进度界面重置为初始状态(进度隐藏且为零),检查是否完全支持该 API,然后检查该 API 的可用性:
- API 为
'unavailable'
:您的应用无法在此设备上以客户端方式使用。提醒用户相应功能不可用。 - API 为
'available'
:该 API 可立即使用,无需显示进度界面。 - API 为
'downloadable'
或'downloading'
:下载完成后即可使用 API。显示进度指示器,并在每次触发downloadprogress
事件时更新该指示器。下载完成后,显示不确定状态,向用户表明浏览器正在提取模型并将其加载到内存中。
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;
}
});
如果用户在模型正积极下载到浏览器时进入应用,进度界面会根据仍缺失的数据指示浏览器在下载过程中的位置。
不妨观看演示,了解此流程的实际应用。如果内置 AI API(在本例中为 Prompt API)不可用,则无法使用该应用。如果仍需下载内置 AI 模型,系统会向用户显示进度指示器。您可以在 GitHub 上查看源代码。
混合实现
如果您偏好使用客户端 AI,但可以暂时将数据发送到云端,则可以设置混合实现。这意味着,用户可以立即体验相关功能,同时并行下载本地模型。下载模型后,动态切换到本地会话。
您可以针对混合使用任何服务器端实现,但最好在云端和本地都坚持使用相同的模型系列,以确保获得可比较的结果质量。 Gemini API 和 Web 应用使用入门重点介绍了 Gemini API 的各种方法。
演示展示了此流程的实际效果。如果内置 AI API 不可用,演示会回退到云端中的 Gemini API。如果仍需下载内置模型,系统会向用户显示进度指示器,并且应用会在下载完成之前使用云端 Gemini API。查看 GitHub 上的完整源代码。
总结
您的应用属于哪个类别?您是否需要 100% 的客户端处理,还是可以使用混合方法?回答完此问题后,下一步是实现最适合您的模型下载策略。
请务必确保用户始终知道他们何时以及是否可以使用应用客户端,方法是按照本指南中的说明向他们显示模型下载进度。
请注意,这不仅仅是一次性挑战:如果浏览器因存储压力而清除模型,或者当有新模型版本可用时,浏览器需要再次下载模型。无论您采用客户端方法还是混合方法,都可以确保为用户打造尽可能出色的体验,并让浏览器处理其余事宜。