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 ainda têm acesso a topK e temperature via LanguageModel.params(), mas cuidado: esses parâmetros estão depreciados e podem ser removidos. A recomendação atual da spec é samplingMode, um enum de presets que funciona tanto na web quanto em Extensions.
⚠️ Antes de tudo: topK e temperature estão depreciados
A spec do Prompt API depreciou o controle numérico direto de sampling. Vale entender o que isso significa antes de usar qualquer coisa desta página:
// ❌ Depreciado — ainda funciona em Extensions, mas será removido
const session = await LanguageModel.create({ temperature: 0.8, topK: 10 });
// ✅ Recomendado
const session = await LanguageModel.create({ samplingMode: 'creative' });
O que muda na prática, por contexto:
| Contexto | topK / temperature |
samplingMode |
|---|---|---|
| Web page | Aceitos mas silenciosamente ignorados. Loga warning de depreciação no console; session.topK e session.temperature ficam undefined |
✅ Disponível (via Origin Trial) |
| Extension | Funcionam, mas depreciados | ✅ Disponível |
Duas regras que valem para quem usa os parâmetros legados em Extensions:
- Se passar
samplingModejunto comtopKoutemperature,create()rejeita comTypeError. - Uma sessão criada com
topK/temperaturetemsession.samplingMode === null.
Se você já tem topK/temperature no seu código de extensão, migrar para samplingMode é o caminho — e funciona nas duas plataformas.
samplingMode — o controle de sampling recomendado
samplingMode substitui o ajuste numérico por presets que fazem sentido entre modelos diferentes. O enum tem 7 valores, do mais determinístico ao mais criativo:
| Valor | Comportamento | Use para |
|---|---|---|
"most-predictable" |
Máxima determinismo e reprodutibilidade | Testes, geração de código, extração de dados |
"predictable" |
Focado, variação mínima | Classificação, extração |
"slightly-predictable" |
Focado com um pouco mais de variação | Classificação com julgamento |
"balanced" |
Equilíbrio entre previsibilidade e criatividade (padrão) | Conversação em geral |
"slightly-creative" |
Criativo, mas mais contido que "creative" |
Copy com direção |
"creative" |
Variedade e criatividade sobre reprodutibilidade | Brainstorming, ideias |
"most-creative" |
Máxima diversidade | Brainstorming aberto |
// Funciona na web (com Origin Trial) e em Extensions
const session = await LanguageModel.create({
samplingMode: 'creative',
});
// O modo resolvido é exposto como atributo read-only
console.log(session.samplingMode); // "creative"
O modo configurado é exposto na sessão como atributo read-only, então dá pra confirmar o que foi aplicado.
Diferenças entre Extensions e Web
| Funcionalidade | Chrome Extensions | Web (Chrome 148+) |
|---|---|---|
| Disponível desde | Chrome 138 | Chrome 148 |
samplingMode |
✅ Disponível | ✅ Via Origin Trial de sampling parameters |
LanguageModel.params() |
✅ Disponível (depreciado) | ❌ Não disponível |
topK / temperature |
⚠️ Depreciado, ainda funcional | ❌ Ignorados silenciosamente |
| Namespace | window.LanguageModel (ou self.ai.languageModel legado) |
window.LanguageModel |
| Contexto de execução | Background, popup, content script | Apenas top-level window e iframes |
| Permissão necessária | Nenhuma permissão especial no manifest | Permission Policy (iframes) |
LanguageModel.params() (depreciado)
⚠️ Esta seção documenta uma API depreciada.
params(),topKetemperaturesó funcionam em Extensions e podem ser removidas em uma release futura. Para código novo, usesamplingMode. Mantenho a referência aqui porque boa parte das extensões publicadas ainda usa esses parâmetros.
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âmetro | Tipo | Descrição |
|---|---|---|
defaultTopK |
number |
Valor padrão de top-K (geralmente 3) |
maxTopK |
number |
Valor máximo permitido para top-K (geralmente 128) |
defaultTemperature |
number |
Temperatura padrão (geralmente 1.0) |
maxTemperature |
number |
Temperatura 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:
| Contexto | Funciona | Observação |
|---|---|---|
| Background (Service Worker) | ✅ | Principal contexto de execução |
| Popup | ✅ | Fechado quando popup é fechado |
| Content Script | ✅ | Roda no contexto da página |
| Side Panel | ✅ | Persistente enquanto aberto |
| Options page | ✅ | Página de configurações |
| DevTools panel | ✅ | Ferramentas 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 recomendo. Esses parâmetros estão depreciados: em web pages são aceitos mas silenciosamente ignorados (com warning no console), e em Extensions funcionam mas podem ser removidos. O caminho atual na web é o Origin Trial de sampling parameters, que expõe samplingMode — um enum de presets que também funciona em Extensions.
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: topK/temperature (depreciados) só têm efeito em Extensions, enquanto samplingMode funciona nas duas plataformas.