Prompt API позволяет разработчикам выполнять задачи по обработке естественного языка прямо в браузере с помощью Gemini Nano. Такой подход обеспечивает конфиденциальность пользователей, снижает затраты на серверы и позволяет использовать функции офлайн.
1. Начало работы и требования к оборудованию
Prompt API сейчас доступен в Chrome версии 148 (для компьютеров) на устройствах с Windows, macOS, Linux и Chromebook Plus.
Требования к оборудованию
- Хранилище: 22 ГБ свободного места (для начального профиля и модели).
- Память и ЦП. 16 ГБ ОЗУ и не менее четырех ядер ЦП.
- Графический процессор: не менее 4 ГБ видеопамяти (требуется для аудиовхода).
- Сеть. Требуется только для первоначального скачивания модели.
Инициализация API
Проверьте доступность модели, прежде чем запускать скачивание:
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. Основные возможности запросов
В примерах сеансов в этом разделе для краткости опущен параметр session.destroy(). Всегда вызывайте session.destroy(), когда сеанс больше не нужен, чтобы освободить память устройства (см. раздел 5).
Базовый и потоковый вывод
Для коротких ответов используйте prompt(). Для более длинного контента используйте promptStreaming(), чтобы сделать интерфейс более отзывчивым.
ОБЯЗАТЕЛЬНО. Никогда не присваивайте результат работы модели переменной innerHTML. Результаты работы модели не заслуживают доверия и могут содержать внедренную разметку. Всегда используйте textContent или дезинфицирующее средство.
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);
Мультимодальный ввод
Prompt API поддерживает текстовые, аудио- и визуальные входные данные (изображения, холст, кадры видео).
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. Расширенное управление сеансами
Сеансы позволяют модели сохранять контекст в нескольких взаимодействиях.
Контекст и квота
Для каждого сеанса установлено ограничение на количество токенов. Отслеживать использование можно с помощью session.contextUsage и session.contextWindow. Если окно переполнено, самые старые сообщения (кроме системного запроса) удаляются.
Клонирование сеансов
Клонирование позволяет эффективно начинать параллельные чаты с одним и тем же начальным контекстом (например, личностью системы) без повторной инициализации.
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();
Восстановление прошлых сеансов
Пока мы разрабатываем встроенную функцию восстановления, вы можете воссоздать сеанс, загрузив в initialPrompts историю предыдущего.
Примечание. localStorage – это незашифрованный постоянный файл cookie. Сохраненная история чата может содержать информацию, позволяющую идентифицировать личность пользователя. Прежде чем сохранять историю чата, подумайте о конфиденциальности.
// || '[]' 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. Структурированный вывод со схемой JSON
Чтобы модель не добавляла лишний текст (например, "Конечно, вот ваш JSON:"), используйте схему JSON в поле responseConstraint. Это гарантирует, что выходные данные будут в формате JSON, который можно сразу обработать.
Пример: классификация тональности
// 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
Ограничения и префиксы
Вы можете дополнительно направлять модель, предварительно заполнив ответ помощника с помощью prefix: true.
const character = await session.prompt([
{ role: 'user', content: 'Create a character sheet' },
{ role: 'assistant', content: '```json\n', prefix: true },
]);
5. Рекомендации и безопасность
- Очистка ресурсов. Всегда вызывайте
session.destroy(), когда разговор завершен, чтобы освободить память. - Безопасность выходных данных. Выходные данные модели не считаются надежными. Всегда записывайте результаты в
textContent, а не вinnerHTML, чтобы предотвратить межсайтовый скриптинг (XSS) из-за вредоносных выходных данных модели. - Если вам нужно разрешить ограниченный HTML, используйте дезинфектор, например встроенный Sanitizer API или DOMPurify.
- Прерывание задач. Используйте
AbortController, чтобы пользователи могли останавливать длительные генерации. Передайтеsignalвprompt()илиpromptStreaming(), а не вLanguageModel.create(). - Безопасность. Используйте правила разрешений, чтобы управлять доступом в окнах iframe:
<iframe src="..." allow="language-model"></iframe>. - Проектирование. Ознакомьтесь с руководством People + AI Guidebook, чтобы обеспечить ответственное внедрение ИИ.
Объединяя структурированные выходные данные с надежным управлением сеансами, разработчики могут создавать сложные ИИ-приложения с сохранением состояния, которые работают полностью на устройстве пользователя.
Рекомендации
Полный список рекомендаций и запретов можно найти на странице https://developer.chrome.com/docs/ai/built-in-ai-dos-donts.md.txt. Вот краткое изложение:
Подготовьте модель в разумные сроки
Применимо ко всем API, например Summarizer, Translator и Writer.
Рекомендуется. Инициализируйте сеанс, как только пользователь явно выразит намерение использовать ИИ-функцию, например перейдет в раздел с ИИ-инструментами, наведет указатель на рабочую область ИИ или начнет взаимодействовать с интерфейсом функции. Предварительный прогрев сеанса позволяет модели загружаться в память в фоновом режиме, пока пользователь настраивает свою задачу, устраняя задержку холодного запуска. Постарайтесь быть на шаг впереди, запуская следующую наиболее вероятную ИИ-задачу, как только начнете рендеринг текущего результата, например, если функция предназначена для итеративного использования.
Не рекомендуется. Не ждите, пока пользователь нажмет кнопку "Сгенерировать", чтобы инициализировать сеанс, если в этом нет необходимости. Это приводит к задержке холодного запуска, поскольку модель должна сначала загрузиться в память и подготовить конвейер выполнения.
Как задать начальные запросы при создании приложения
Применимо к Prompt API.
Рекомендуется. Предоставляйте системные инструкции во время инициализации сеанса, чтобы ускорить обработку первого запроса.
Не рекомендуется. Начинать с пустого сеанса и отправлять системные инструкции в рамках первого вызова prompt(). Это увеличивает задержку, поскольку заставляет модель обрабатывать эти инструкции в последний момент.
Клонирование сеансов для повторяющихся задач
Применимо к Prompt API.
В Prompt API каждый сеанс отслеживает контекст разговора, учитывая все предыдущие взаимодействия. Поскольку клон наследует все от родительского сеанса, включая исходные запросы и всю историю взаимодействия до момента клонирования, структурируйте использование так, чтобы наследовать только то, что вам нужно.
Что рекомендуется делать
- Создайте базовый сеанс. Чтобы эффективно обрабатывать несвязанные задачи, создайте базовый сеанс, который содержит только системные инструкции и не содержит предыдущего контекста разговора.
- Клонируйте базовый сеанс. Используйте
clone()в базовом сеансе для новых задач, чтобы не тратить ресурсы на повторный анализ системных инструкций. Это позволяет вести параллельные чаты или сбрасывать задачу до исходного состояния.
Чего не следует делать
- Не используйте один и тот же сеанс для несвязанных задач и не клонируйте сеансы, которые уже содержат ненужную историю взаимодействия. Оба шаблона могут привести к тому, что нерелевантный предыдущий контекст будет мешать текущей задаче.
- Не вызывайте
create()повторно с теми же системными инструкциями. Чтобы оптимизировать производительность, используйте шаблон клонирования.
Удаление неиспользуемых сеансов
Применяется ко всем API.
Рекомендуется. Явно вызывайте destroy() для сеансов, которые больше не нужны, чтобы освободить память, когда функция больше не используется. Если вы используете шаблон клонирования, сохраните базовый сеанс и удалите клоны, которые вам больше не нужны.
Не рекомендуется оставлять активными несколько больших сеансов. Каждый сеанс потребляет память, что приводит к ненужному использованию ресурсов и может стать проблемой. Сеансы будут автоматически удалены сборщиком мусора, но вызов destroy() позволяет быстрее освободить память.
Безопасная и эффективная обработка потоковых ответов
Применимо ко всем API с поддержкой потоковой передачи (Prompt, Summarizer, Writer, Rewriter и Translator).
Рекомендуется. Относитесь ко всем выходным данным LLM как к ненадежному контенту. Проверяйте весь объединенный вывод, а не только его фрагменты, поскольку вредоносный код может быть разделен между обновлениями. Перед отрисовкой используйте Sanitizer API, если он поддерживается. Чтобы избежать снижения производительности, используйте потоковый синтаксический анализатор Markdown, например streaming-markdown.
Неправильно. Напрямую задавать innerHTML при каждом обновлении фрагмента. Это медленно, особенно при сложном форматировании, таком как подсветка синтаксиса, и уязвимо для инъекций.
Оптимизировать ввод для скорости
Применяется ко всем API.
Рекомендуется. Передавайте модели только то, что строго необходимо. Уберите все, что не имеет отношения к текущей задаче. Для больших наборов данных предоставьте краткий обзор и небольшую подборку релевантных элементов.
Не рекомендуется. Отправлять в API необработанный текст, ненужные метаданные, HTML-теги или большие неотфильтрованные списки. Задержка значительно увеличивается с размером входных данных, из-за чего может показаться, что ИИ-функция не работает на многих устройствах.
Используйте структурированные выходные данные для получения предсказуемых результатов
Применимо к Prompt API.
Рекомендуется. Если вам нужно, чтобы модель возвращала данные в определенном формате, используйте структурированный вывод, указав поле responseConstraint для предоставления схемы JSON. Это гарантирует, что выходные данные будут предсказуемыми, и избавит вас от необходимости сложной постобработки или ручного синтаксического анализа.
Не полагайтесь только на инструкции на естественном языке (например, "выводи только JSON"). Модели могут включать разговорные заполнители, которые нарушают работу синтаксического анализатора.
Отключить ограничения по длине
Применимо к Prompt API, так как это единственный API, поддерживающий схемы структурированных выходных данных.
Рекомендуется. Позвольте модели сгенерировать ответ естественным образом, а затем используйте клиентскую логику, чтобы усечь текст в соответствии с вашим интерфейсом.
Не делайте так: не задавайте строгие ограничения на количество символов, например maxLength: 125, с помощью схем структурированных выходных данных. Если ответ модели длиннее заданного ограничения, она может переключиться на токены высокой плотности, например иностранные языки или эмодзи, чтобы сжать смысл, что приведет к бессмысленному выводу.
Информируйте пользователя
Применяется ко всем API.
Рекомендуется. В зависимости от сложности и ожидаемой продолжительности задачи используйте анимацию, визуальные подсказки и индикаторы выполнения, чтобы информировать пользователя. Оптимальный подход зависит от вашего варианта использования и ожидаемой длины выходных данных API. Вот несколько идей:
- Потоковая передача длинного контента. Для сводок и чатов потоковая передача по умолчанию создает эффект пишущей машинки для каждого токена. Это может показаться естественным и обеспечить немедленную обратную связь.
- Без потоковой передачи для коротких задач (или длинных асинхронных задач). Для коротких выходных данных, например альтернативного текста, отсутствие потоковой передачи может сделать интерфейс более удобным. Это также дает время на подготовку следующей ИИ-задачи, пока выполняется текущая. Этот подход также работает для более длительных асинхронных или фоновых задач. Если пользователю не нужно сразу же получить результат, чтобы продолжить работу, то нет необходимости генерировать его в реальном времени. Покажите в интерфейсе, что процесс продолжается.
- Визуальные переходы для обновлений. При переводе или переписывании текста используйте анимацию, например морфинг слов.
Не рекомендуется. Обновлять интерфейс без визуальных подсказок.
Соответствие ментальной модели времени и работы пользователя
Применяется ко всем API.
Рекомендуется. Если ответ генерируется почти мгновенно, добавьте искусственную задержку в одну или две секунды. Парадоксально, но пользователи могут считать результаты более надежными, когда они видят процесс генерации, который соответствует их восприятию сложности задачи. Используйте анимацию, чтобы показать, что произошла ИИ-обработка.
Не рекомендуется. Неожиданно заменять интерфейс.
Разрешить пользователям быстро перемещаться и отменять изменения, внесенные ИИ
Применяется ко всем API.
Рекомендуется. Добавьте в интерфейс пошаговый процесс или историю навигации, чтобы пользователи могли уверенно изучать разные результаты и быстро отменять изменения, внесенные ИИ. Это гарантирует, что разные версии по-прежнему будут легко доступны.
Не рекомендуется. Перезаписывать предыдущий черновик пользователя или результат работы ИИ, который мог ему понравиться, не давая возможности вернуться к предыдущей версии, отменить изменения или сравнить версии.
Предоставьте пользователям возможность управлять настройками и переопределять их
Применяется ко всем API.
Рекомендуется. Сделайте пользователя окончательным редактором всего сгенерированного контента. Предоставьте пользователю возможность легко переопределять настройки, чтобы он мог полностью контролировать конечный результат. API могут выдавать неверные результаты.
Не рекомендуется. Предлагать только один результат, созданный ИИ.
Кеширование результатов повторяющихся задач
Применяется ко всем API.
Рекомендуется. Реализуйте локальный кеш результатов (например, с помощью sessionStorage или IndexedDB) для повторяющихся входных данных или запросов. Нормализуйте входные данные, удалив пробелы и преобразовав символы в нижний регистр, чтобы увеличить количество совпадений в кеше. Для больших входных данных, например изображений, сгенерируйте хеш, который будет использоваться в качестве ключа кеша. Установите для кеша консервативное время жизни (TTL) или показывайте кешированные результаты, обновляя их в фоновом режиме. Предоставьте пользователю возможность запустить новый вывод, если результат его не устраивает.
Не рекомендуется. Повторно запускать инференс для одного и того же поискового запроса или идентичных входных данных, когда вариативность нежелательна, например когда пользователь переходит между результатами поиска. Это позволяет оптимизировать скорость отклика и эффективно использовать локальные вычислительные ресурсы.
6. Резервные стратегии
Перед использованием проверьте, доступен ли объект LanguageModel в глобальной области видимости:
if ('LanguageModel' in self) {
// The Prompt API is supported.
} else {
// Execute fallback strategy
}
Если Prompt API не поддерживается или проверка доступности возвращает значение unavailable, необходимо корректно вернуться к предыдущему состоянию:
- Резервный удаленный API. Перенаправьте запрос на обнаружение в конечную точку сервера или облачный API, например Vertex AI Gemini API.
- Резервный локальный API. Перенаправьте запрос на обнаружение на локальную конечную точку, например с помощью Transformers.js.