ФронтендData и ИИJavaScriptHTML / CSS

Как сделать AI-расширение Chrome, которое пересказывает открытую страницу

Создаём Manifest V3 расширение, читаем текст активной вкладки, вызываем встроенный Summarizer API при доступности и используем безопасный локальный запасной вариант.

Кодик

Автор

7 мин чтения

Расширение может прочитать активную вкладку по клику и попросить встроенный Summarizer API сократить текст, не отправляя страницу на случайный внешний сервер. API доступен не во всех версиях и конфигурациях Chrome, поэтому рабочий проект обязан проверять availability. Если встроенная модель недоступна, расширение покажет простой локальный пересказ из первых содержательных предложений.

AI-функция выглядит эффектно только в счастливом сценарии. На практике есть четыре состояния: API отсутствует, модель доступна сразу, её можно скачать или она недоступна на устройстве. Кроме того, расширение не должно читать все вкладки постоянно. Мы используем activeTab, поэтому доступ появляется после явного клика пользователя по иконке.

1Получаем доступ

activeTab разрешает работу с текущей страницей после действия пользователя.

2Извлекаем текст

executeScript читает заголовок и ограниченный body.innerText внутри вкладки.

3Суммируем

Summarizer используется только после availability, иначе включается локальный fallback.

Как popup общается с активной вкладкой

manifest.json объявляет popup, разрешения activeTab и scripting. По нажатию кнопки popup получает активную вкладку и инъецирует короткую функцию. Она выполняется в контексте страницы, но возвращает только title и первые 12 тысяч символов innerText. Затем summarize проверяет наличие глобального Summarizer и вызывает availability.

ЭтапЧто происходитПризнак результата
КликПользователь открывает popup на нужной вкладкеactiveTab выдан для страницы
Извлечениеscripting читает title и ограниченный текстПолучена строка без HTML
Проверкаavailability определяет состояние моделиВыбран AI или fallback
ОтветPopup показывает резюме или понятную ошибкуСтраница остаётся неизменной

У проекта есть один главный маршрут: получить входные данные, проверить их, выполнить действие и показать результат. Если каждый этап можно проверить отдельно, ошибка перестаёт быть загадкой.

Путь текста из вкладки в popup
От входных данных до видимого результата. Доступ появляется после явного клика пользователя

Доступ к странице должен начинаться с действия пользователя. Не запрашивайте широкое разрешение на все сайты, если достаточно activeTab. Чем меньше доступ, тем проще объяснить поведение расширения и безопаснее установка.

Собираем Manifest V3 и пересказ

Создайте каталог с manifest.json, popup.html и popup.js из исходников. Откройте chrome://extensions, включите режим разработчика и выберите «Загрузить распакованное расширение». Откройте обычную статью, нажмите иконку расширения и кнопку пересказа. Встроенные AI API Chrome могут требовать поддерживаемую версию, совместимое устройство и загруженную модель. Код ниже не предполагает, что они есть у каждого пользователя.

async function getPageText() {
  const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
  if (!tab?.id) throw new Error("Активная вкладка не найдена");

  const [{ result }] = await chrome.scripting.executeScript({
    target: { tabId: tab.id },
    func: () => ({
      title: document.title,
      text: document.body.innerText.replace(/\s+/g, " ").slice(0, 12_000),
    }),
  });
  return result;
}

function extractiveFallback(text) {
  return text.split(/(?<=[.!?])\s+/).filter((part) => part.length > 40).slice(0, 3).join(" ");
}

async function summarize(text) {
  if (!("Summarizer" in globalThis)) return extractiveFallback(text);
  const availability = await Summarizer.availability();
  if (availability === "unavailable") return extractiveFallback(text);

  const session = await Summarizer.create({
    type: "key-points",
    format: "markdown",
    length: "short",
  });
  try {
    return await session.summarize(text);
  } finally {
    session.destroy();
  }
}
Что должно произойти после запуска
  • На обычной статье popup получает заголовок и текст только после клика.
  • При доступном Summarizer результат создаёт встроенная модель Chrome.
  • При отсутствии API выводятся первые содержательные предложения без сетевого запроса.
  • На служебной вкладке расширение показывает понятную ошибку доступа, а не пустой экран.

Fallback не изображает искусственный интеллект и не обещает одинаковое качество. Он даёт полезный минимальный результат и делает ограничение прозрачным. Пользователь всегда понимает, что расширение не отправляло страницу наружу.

Широкий доступ и минимальные permissions
Что отличает устойчивый проект от случайного успеха. Функция должна запрашивать ровно те права, которые использует

Проверяем доступность встроенной модели

Popup является короткоживущей страницей расширения. activeTab выдаёт временный доступ к вкладке после жеста пользователя. scripting.executeScript выполняет сериализуемую функцию в изолированном мире и возвращает данные. Мы не передаём DOM-узлы, только строки. Summarizer API использует встроенную модель, если среда соответствует требованиям.

ЧастьОтветственностьЧто проверить
Manifest V3Описывает popup и минимальные permissionsНет доступа ко всем сайтам
activeTabДаёт временный доступ после кликаРаботает только с выбранной вкладкой
scriptingИзвлекает ограниченный текст страницыНе возвращает HTML и секретные формы
SummarizerСоздаёт краткий пересказ локальной модельюavailability проверен заранее
FallbackДаёт минимальный результат без AIПользователь видит ограничение

document.body.innerText может содержать меню, рекламу и комментарии. Для качества сначала попробуйте article.innerText, затем main.innerText и только потом body. Ограничивайте объём, чтобы не перегружать контекст. Не читайте поля ввода, буфер обмена, историю и другие вкладки без отдельной необходимости.

Не называйте fallback «AI-пересказом». Первые предложения не понимают смысл текста. Покажите в интерфейсе, какой режим сработал: встроенная модель или простой локальный вариант.

Тестируем пустую страницу, запрет и длинный текст

Проверьте расширение на короткой заметке, длинной статье, странице без article и вкладке chrome://extensions. Для каждого случая статус должен быть явным. Добавьте сначала извлечение article или main, а затем body. Покажите счётчик символов, переданных в summarize. После этого создайте переключатель длины short/medium и передавайте его в Summarizer.create.

Проверка своими руками
  1. Загрузите unpacked extension и перескажите собственную локальную страницу.
  2. Проверьте страницу с main, article и только body.
  3. Откройте chrome://extensions и получите понятную ошибку доступа.
  4. Искусственно отключите ветку Summarizer и проверьте fallback.
  5. Добавьте индикатор режима «встроенная модель» или «локальный fallback».
  6. Ограничьте вход и убедитесь, что popup остаётся отзывчивым.
Готово, если выполняются все пункты
  • Расширение читает только активную вкладку после клика.
  • Availability проверяется до create.
  • Fallback работает без сетевого ключа.
  • Запрещённая вкладка даёт понятное сообщение.

Устойчивое AI-расширение начинается с честной проверки возможностей. Оно полезно и на совместимом устройстве, и без модели, а пользователь видит, какой путь дал результат.

Четыре проверки AI-расширения
Четыре проверки перед следующим шагом. Отсутствие модели является обычным сценарием

Улучшаем расширение без лишних разрешений

Следующий шаг: добавить выделение текста. contextMenus может запускать пересказ только выбранного фрагмента, что уменьшает объём и улучшает релевантность. Затем сохраните настройки длины через chrome.storage, но не содержимое страниц. Для публикации подготовьте иконки, описание permissions и политику приватности.

Как изучить тему в Кодике

В Кодике сначала закрепите DOM, события и массивы строк. Затем сделайте обычное расширение с popup без AI. После этого добавьте проверку возможности и два маршрута результата. Так новый API оказывается одной заменяемой функцией, а не центром всего проекта.

ШагЧто изучить в КодикеМини-проверка
1DOM и innerTextВыбрать article, main или body
2События и async/awaitЗапустить действие по кнопке и показать статус
3Manifest V3Объяснить activeTab и scripting
4Feature detectionРазделить Summarizer и fallback
5Ошибки и UXОбработать служебную вкладку и пустой текст

Не пытайтесь запомнить весь API. В тренажёре Кодика сначала воспроизведите чистую логику без библиотеки, затем восстановите подключение и обработку ошибок. Финальный тест: объяснить проект по памяти и добавить одну свою функцию.

Запрошен доступ ко всем сайтам

Для действия по клику обычно достаточно activeTab и scripting.

Summarizer вызывается без availability

API или модель могут отсутствовать. Всегда проверяйте состояние и готовьте запасной путь.

API-ключ спрятан в popup.js

Код расширения доступен пользователю. Секретный ключ должен находиться только на доверенном сервере.

Весь body отправляется без ограничения

Сначала выбирайте содержательную область и ограничивайте объём входного текста.

Сверьтесь с первичным источником. Команды, версии и ограничения примера проверяйте по официальной документации Chrome: Extensions and AI. Если интерфейс изменился, первичная документация важнее старого скриншота.

Что получится в итоге

Готовый результат: Как сделать AI-расширение Chrome, которое пересказывает открытую страницу
Popup читает содержательную часть активной вкладки, показывает режим и возвращает короткое резюме через встроенную модель или локальный fallback.

Короткие ответы
Зачем activeTab, если есть host_permissions?

activeTab даёт узкий временный доступ после действия пользователя и не требует постоянного чтения всех сайтов.

Почему нужно проверять availability?

Наличие объекта API не гарантирует, что модель уже доступна или поддерживается на устройстве.

Можно ли положить внешний AI API key в расширение?

Нет. Пользователь может извлечь его из кода. Для секрета нужен доверенный сервер.

Как понять, что проект действительно работает?

Проверьте основной сценарий, неверный ввод, повторный запуск и один граничный случай. Затем объясните путь данных своими словами.

Можно ли начать с готового кода из статьи?

Да. Добейтесь результата, измените одно правило и соберите ключевой файл заново без копирования.

Сначала соберите безопасное расширение, затем добавляйте AI

DOM, события и async/await закрепите в курсе JavaScript. Основу Manifest V3 разберите по статье про расширение Chrome.

Для сетевого запасного варианта повторите Fetch API, а обработку отсутствующих элементов сравните с материалом про null в JavaScrip