Prompt API em Chrome Extensions — Guia para Desenvolvedores

A Prompt API tá disponível em Chrome Extensions desde o Chrome 138 — antes mesmo do lançamento pra web (Chrome 148). Extensions têm acesso a funcionalidades exclusivas como controle de topK e temperature via LanguageModel.params(), o que permite ajuste fino da geração de texto.

Diferenças entre Extensions e Web

FuncionalidadeChrome ExtensionsWeb (Chrome 148+)
Disponível desdeChrome 138Chrome 148
LanguageModel.params()✅ Disponível❌ Não disponível*
topK / temperature✅ Configurável❌ Não configurável*
Namespacewindow.LanguageModel (ou self.ai.languageModel legado)window.LanguageModel
Contexto de execuçãoBackground, popup, content scriptApenas top-level window e iframes
Permissão necessáriaNenhuma permissão especial no manifestPermission Policy (iframes)

* Parâmetros de sampling estão disponíveis na web apenas via Origin Trial separado.

LanguageModel.params()

O método params() retorna informações sobre os parâmetros de sampling do modelo:

// Disponível APENAS em Chrome Extensions
const params = await LanguageModel.params();

console.log(params);
// {
//   defaultTopK: 3,
//   maxTopK: 128,
//   defaultTemperature: 1,
//   maxTemperature: 2
// }
ParâmetroTipoDescrição
defaultTopKnumberValor padrão de top-K (geralmente 3)
maxTopKnumberValor máximo permitido para top-K (geralmente 128)
defaultTemperaturenumberTemperatura padrão (geralmente 1.0)
maxTemperaturenumberTemperatura máxima permitida (geralmente 2.0)

O que são topK e temperature

  • top-K: Controla quantos tokens candidatos são considerados a cada passo da geração. Valores menores = mais determinístico. Valores maiores = mais diverso.
  • temperature: Controla a aleatoriedade da distribuição de probabilidade. Valores menores = mais previsível. Valores maiores = mais criativo.

Criando sessão com parâmetros personalizados

Em Extensions, você pode ajustar os parâmetros de sampling ao criar uma sessão:

// Obter parâmetros do modelo
const params = await LanguageModel.params();

// Sessão com temperatura mais alta (mais criativa)
const sessaoCreativa = await LanguageModel.create({
  temperature: Math.min(params.defaultTemperature * 1.5, params.maxTemperature),
  topK: params.maxTopK,
  initialPrompts: [
    { role: 'system', content: 'You are a creative writing assistant.' }
  ]
});

// Sessão com temperatura baixa (mais determinística)
const sessaoPrecisa = await LanguageModel.create({
  temperature: 0.1,
  topK: 3,
  initialPrompts: [
    { role: 'system', content: 'You are a data extraction tool. Be precise.' }
  ]
});

Regra: Ao especificar parâmetros, você deve definir ambos (topK E temperature) ou nenhum. Não é possível definir apenas um.

Configuração do manifest.json

A Prompt API em Extensions não requer permissão especial no manifest. O acesso é automático:

{
  "manifest_version": 3,
  "name": "Minha Extensão com IA",
  "version": "1.0.0",
  "description": "Extensão que usa a Prompt API para análise de texto",

  "background": {
    "service_worker": "background.js"
  },

  "action": {
    "default_popup": "popup.html",
    "default_icon": "icon.png"
  },

  "permissions": [
    "activeTab"
  ]
}

Nota sobre permissão legada

Se sua extensão usava a permissão experimental anterior "aiLanguageModelOriginTrial", remova-a:

{
  "permissions": [
    "aiLanguageModelOriginTrial"
  ]
}

Essa permissão está expirada e não é mais necessária.

Exemplos de extensões

Extensão 1: Extrator de contatos

Extrai informações de contato de páginas web automaticamente:

background.js

chrome.action.onClicked.addListener(async (tab) => {
  // Injeta content script para capturar texto da página
  const [result] = await chrome.scripting.executeScript({
    target: { tabId: tab.id },
    func: () => document.body.innerText
  });

  const textoPagina = result.result;

  // Criar sessão com alta precisão
  const params = await LanguageModel.params();
  const session = await LanguageModel.create({
    temperature: 0.1,
    topK: params.defaultTopK,
    initialPrompts: [
      {
        role: 'system',
        content: 'Extract contact information from web pages. Return structured JSON.'
      }
    ]
  });

  const schema = {
    type: 'object',
    properties: {
      contacts: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            name: { type: 'string' },
            email: { type: 'string' },
            phone: { type: 'string' },
            company: { type: 'string' }
          }
        }
      }
    }
  };

  const resultado = await session.prompt(
    `Extract all contact information from this page:\n\n${textoPagina.substring(0, 3000)}`,
    { responseConstraint: schema }
  );

  const contatos = JSON.parse(resultado);

  // Enviar resultado para o popup
  chrome.storage.local.set({ lastContacts: contatos });
  session.destroy();
});

Extensão 2: Criador de eventos de calendário

Detecta datas e horários em páginas e sugere eventos:

content-script.js

async function extrairEventos() {
  const textoSelecionado = window.getSelection().toString();

  if (!textoSelecionado) return;

  const session = await LanguageModel.create({
    temperature: 0.2,
    topK: 5,
    initialPrompts: [
      {
        role: 'system',
        content: 'Extract calendar events from text. Include date, time, title, and location when available.'
      }
    ]
  });

  const schema = {
    type: 'array',
    items: {
      type: 'object',
      properties: {
        title: { type: 'string' },
        date: { type: 'string' },
        time: { type: 'string' },
        location: { type: 'string' }
      },
      required: ['title', 'date']
    }
  };

  const resultado = await session.prompt(
    `Extract events from: "${textoSelecionado}"`,
    { responseConstraint: schema }
  );

  const eventos = JSON.parse(resultado);
  session.destroy();

  // Mostrar UI com os eventos encontrados
  mostrarEventosDetectados(eventos);
}

// Ativar com menu de contexto ou atalho
document.addEventListener('mouseup', () => {
  if (window.getSelection().toString().length > 20) {
    extrairEventos();
  }
});

Extensão 3: Resumidor de artigos

popup.js

document.getElementById('btn-resumir').addEventListener('click', async () => {
  const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });

  const [result] = await chrome.scripting.executeScript({
    target: { tabId: tab.id },
    func: () => {
      // Extrair texto principal do artigo
      const article = document.querySelector('article') || document.body;
      return article.innerText.substring(0, 5000);
    }
  });

  const textoArtigo = result.result;
  const outputEl = document.getElementById('resumo');
  outputEl.textContent = 'Gerando resumo...';

  const params = await LanguageModel.params();
  const session = await LanguageModel.create({
    temperature: 0.5,
    topK: params.defaultTopK,
    initialPrompts: [
      {
        role: 'system',
        content: 'Summarize articles in 3-5 bullet points. Be concise and capture key insights.'
      }
    ]
  });

  const stream = session.promptStreaming(
    `Summarize this article:\n\n${textoArtigo}`
  );

  outputEl.textContent = '';
  for await (const chunk of stream) {
    outputEl.textContent += chunk;
  }

  session.destroy();
});

Extensão 4: Classificador de spam em tempo real

background.js (service worker)

// Classificar conteúdo conforme o usuário navega
chrome.webNavigation.onCompleted.addListener(async (details) => {
  if (details.frameId !== 0) return; // Apenas frame principal

  const [result] = await chrome.scripting.executeScript({
    target: { tabId: details.tabId },
    func: () => document.title + ' ' + (document.querySelector('meta[name="description"]')?.content || '')
  });

  const conteudo = result.result;

  const session = await LanguageModel.create({
    temperature: 0.1,
    topK: 3
  });

  const schema = {
    type: 'object',
    properties: {
      isSpam: { type: 'boolean' },
      confidence: { type: 'number' },
      reason: { type: 'string' }
    },
    required: ['isSpam', 'confidence']
  };

  try {
    const resultado = await session.prompt(
      `Is this webpage spam or potentially dangerous? Title and description: "${conteudo}"`,
      { responseConstraint: schema }
    );

    const analise = JSON.parse(resultado);

    if (analise.isSpam && analise.confidence > 0.8) {
      // Mostrar aviso ao usuário
      chrome.action.setBadgeText({ text: '⚠️', tabId: details.tabId });
      chrome.action.setBadgeBackgroundColor({ color: '#FF0000', tabId: details.tabId });
    }
  } finally {
    session.destroy();
  }
});

Contextos de execução em Extensions

A Prompt API funciona nos seguintes contextos de uma extensão:

ContextoFuncionaObservação
Background (Service Worker)Principal contexto de execução
PopupFechado quando popup é fechado
Content ScriptRoda no contexto da página
Side PanelPersistente enquanto aberto
Options pagePágina de configurações
DevTools panelFerramentas de desenvolvimento

Boas práticas para Extensions

1. Gerenciar ciclo de vida da sessão

Em service workers, a sessão pode ser perdida quando o worker é desativado. Recrie quando necessário:

let session = null;

async function getSession() {
  if (!session) {
    session = await LanguageModel.create({
      temperature: 0.3,
      topK: 10,
      initialPrompts: [
        { role: 'system', content: 'You are a helpful browser assistant.' }
      ]
    });
  }
  return session;
}

// Limpar quando não necessário
chrome.runtime.onSuspend.addListener(() => {
  if (session) {
    session.destroy();
    session = null;
  }
});

2. Usar topK baixo para classificação

// Mais determinístico = melhor para classificação
const sessaoClassificacao = await LanguageModel.create({
  temperature: 0.1,
  topK: 3
});

3. Usar temperature alta para criatividade

// Mais diverso = melhor para geração criativa
const params = await LanguageModel.params();
const sessaoCreativa = await LanguageModel.create({
  temperature: Math.min(1.8, params.maxTemperature),
  topK: params.maxTopK
});

4. Respeitar limites de content scripts

Content scripts rodam no contexto da página. Não envie texto sensível do DOM diretamente — filtre primeiro.


Perguntas frequentes

Preciso declarar alguma permissão especial no manifest para usar a Prompt API?

Não. A Prompt API é automaticamente disponível em Chrome Extensions sem permissões adicionais no manifest.json.

A Prompt API funciona no service worker da extensão?

Sim. O service worker (background script) tem acesso total à Prompt API, incluindo params(), topK e temperature.

Posso usar topK e temperature na versão web da API?

Não diretamente. Na web, esses parâmetros estão disponíveis apenas via um Origin Trial separado para “sampling parameters”. Em Extensions, são nativamente suportados desde o Chrome 138.

A sessão persiste quando o service worker é desativado?

Não. Quando o Chrome suspende o service worker por inatividade, a sessão é perdida. Você precisa recriar a sessão quando o worker é reativado. Considere salvar o contexto da conversa em chrome.storage.session.

Qual a diferença de performance entre Extensions e Web?

Não há diferença de performance de inferência. Ambos usam o mesmo Gemini Nano. A diferença é funcional: Extensions têm controle sobre parâmetros de sampling.


Referências