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
| Funcionalidade | Chrome Extensions | Web (Chrome 148+) |
|---|---|---|
| Disponível desde | Chrome 138 | Chrome 148 |
LanguageModel.params() | ✅ Disponível | ❌ Não disponível* |
topK / temperature | ✅ Configurável | ❌ Não configurável* |
| 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) |
* 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â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 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.