Chrome 擴充功能中的提示 API

發布日期:2024 年 11 月 11 日

擴充功能的提示 API 現已開放源試用,因此您可以建構 Chrome 擴充功能,在瀏覽器中使用 Gemini Nano 這項最高效的語言模型。

搭配 Chrome 擴充功能使用提示 API 的用途相當多元。例如:

  • 即時日曆活動:開發 Chrome 擴充功能,自動從網頁中擷取活動詳細資料,讓使用者只需幾個步驟就能建立日曆項目。
  • 順暢的聯絡人擷取功能。建立可從網站擷取聯絡資訊的擴充功能,方便使用者與商家聯絡,或在聯絡人清單中新增詳細資料。
  • 動態內容篩選功能:建立 Chrome 擴充功能,分析新聞文章,並根據使用者定義的主題自動模糊處理或隱藏內容。

以上只是幾個可能的應用情境,我們很期待看到你創造的內容。

可用性

  • 加入 Prompt API 來源試用,在 Chrome 131 到 136 之間的版本中執行,即可使用此 API 建立擴充功能。如果您是 origin trials 的新手,請注意,這是一項開放給所有開發人員參加的限時計畫,可讓您搶先體驗實驗平台功能。開發人員可以進行測試、收集使用者意見回饋,並針對日後推出的版本進行調整。
    • 雖然可能會有使用限制,但您可以整合這些功能,進行實時測試並收集使用者意見回饋。目的是為了讓這個 API 日後的版本更廣泛地提供服務。
  • 加入搶先預覽計畫,搶先一睹全新內建 AI API,並參與我們的郵寄清單討論。

參與來源試用

如要在 Chrome 擴充功能中使用提示 API,請按照以下摘錄內容,在 manifest.json 檔案中新增 "aiLanguageModelOriginTrial" 權限,以及擴充功能可能需要的其他權限。

如要為擴充功能申請來源測試,請使用網址 chrome-extension://YOUR_EXTENSION_ID 做為網站來源。例如:chrome-extension://ljjhjaakmncibonnjpaoglbhcjeolhkk

申請 Chrome Origin 試用版

擴充功能 ID 會以動態方式建立,但一旦指派 ID,您可以將 key 屬性新增至資訊清單,強制 ID 保持穩定。

註冊原始試用方案後,您會收到產生的符記,您需要將該符記做為陣列傳遞,做為資訊清單中 trial_tokens 欄位的值。請參考程式碼片段示例。

{
  "permissions": ["aiLanguageModelOriginTrial"],
  "trial_tokens": ["GENERATED_TOKEN"],
}

為 localhost 新增支援

如要在來源試用期間存取 localhost 上的提示 API,您必須將 Chrome 更新至最新版本。接下來,請按照下列步驟進行:

  1. 在 Windows、Mac 或 Linux 等平台上開啟 Chrome。
  2. 前往chrome://flags/#optimization-guide-on-device-model
  3. 選取「Enabled BypassPerfRequirement」
    • 這會略過效能檢查,而這項檢查可能會導致您無法將 Gemini Nano 下載到裝置上。
  4. 按一下「重新啟動」或重新啟動 Chrome。

使用 Prompt API

取得使用 Prompt API 的權限後,即可建構擴充功能。chrome.aiOriginTrial.languageModel 命名空間提供兩個新的擴充函式:

  • capabilities() 以查看模型的功能和可用性。
  • create() 開始語言模型工作階段。

模型下載

Prompt API 會使用 Chrome 中的 Gemini Nano 模型。雖然 API 已內建於 Chrome,但擴充功能第一次使用 API 時,系統會另外下載模型。

如要判斷模型是否已準備好供使用,請呼叫非同步 chrome.aiOriginTrial.languageModel.capabilities() 函式。這個方法會傳回 AILanguageModelCapabilities 物件,其中包含 available 欄位,可採用三個可能的值:

  • 'no':目前的瀏覽器支援提示 API,但目前無法使用。這可能是因為磁碟空間不足,無法下載模型。
  • 'readily':目前的瀏覽器支援 Prompt API,可立即使用。
  • 'after-download':目前的瀏覽器支援提示 API,但需要先下載模型。

如要觸發模型下載作業並建立語言模型工作階段,請呼叫非同步 chrome.aiOriginTrial.languageModel.create() 函式。如果對 capabilities() 的回應是 'after-download',建議您監聽下載進度。這樣一來,如果下載作業需要花費一些時間,您就能通知使用者。

const session = await chrome.aiOriginTrial.languageModel.create({
  monitor(m) {
    m.addEventListener("downloadprogress", (e) => {
      console.log(`Downloaded ${e.loaded} of ${e.total} bytes.`);
    });
  },
});

模型功能

capabilities() 函式也會告知您語言模型的功能。除了 available 之外,產生的 AILanguageModelCapabilities 物件也包含下列欄位:

  • defaultTopK:預設的前 K 個值 (預設值:3)。
  • maxTopK最高 K 值 (8)。
  • defaultTemperature:預設溫度 (1.0)。溫度必須介於 0.02.0 之間。
await chrome.aiOriginTrial.languageModel.capabilities();
// {available: 'readily', defaultTopK: 3, maxTopK: 8, defaultTemperature: 1}

建立工作階段

確認 Prompt API 可執行後,請使用 create() 函式建立工作階段,然後使用 prompt()promptStreaming() 函式向模型提示。

工作階段選項

您可以使用選用的選項物件,透過 topKtemperature 自訂每個工作階段。這些參數的預設值會從 chrome.aiOriginTrial.languageModel.capabilities() 傳回。

const capabilities = await chrome.aiOriginTrial.languageModel.capabilities();
// Initializing a new session must either specify both `topK` and
// `temperature` or neither of them.
const slightlyHighTemperatureSession = await chrome.aiOriginTrial.languageModel.create({
  temperature: Math.max(capabilities.defaultTemperature * 1.2, 2.0),
  topK: capabilities.defaultTopK,
});

create() 函式的選用選項物件也會接收 signal 欄位,讓您傳遞 AbortSignal 來銷毀工作階段。

const controller = new AbortController();
stopButton.onclick = () => controller.abort();

const session = await chrome.aiOriginTrial.languageModel.create({
  signal: controller.signal,
})
系統提示

您可以透過系統提示,為語言模型提供一些情境。

const session = await chrome.aiOriginTrial.languageModel.create({
  systemPrompt: 'You are a helpful and friendly assistant.',
});
await session.prompt('What is the capital of Italy?');
// 'The capital of Italy is Rome.'

初始提示

透過初始提示,您可以為語言模型提供先前互動的相關資訊,例如讓使用者在瀏覽器重新啟動後,繼續執行已儲存的工作階段。

const session = await chrome.aiOriginTrial.languageModel.create({
  initialPrompts: [
    { role: 'system', content: 'You are a helpful and friendly assistant.' },
    { role: 'user', content: 'What is the capital of Italy?' },
    { role: 'assistant', content: 'The capital of Italy is Rome.'},
    { role: 'user', content: 'What language is spoken there?' },
    { role: 'assistant', content: 'The official language of Italy is Italian. [...]' }
  ]
});

工作階段資訊

特定語言模型工作階段可處理的符記數量有上限。您可以使用工作階段物件上的下列屬性,檢查用量和達到該上限的進度:

console.log(`${session.tokensSoFar}/${session.maxTokens}
(${session.tokensLeft} left)`);

工作階段持續性

每個工作階段都會追蹤對話情境。系統會將先前的互動納入考量,以便在會話的上下文視窗已滿之前,為日後的互動進行評估。

const session = await chrome.aiOriginTrial.languageModel.create({
  systemPrompt: 'You are a friendly, helpful assistant specialized in clothing choices.'
});

const result1 = await session.prompt(
  'What should I wear today? It is sunny and I am unsure between a t-shirt and a polo.'
);
console.log(result1);

const result2 = await session.prompt(
  'That sounds great, but oh no, it is actually going to rain! New advice?'
);
console.log(result2);

複製工作階段

為保留資源,您可以使用 clone() 函式複製現有工作階段。對話內容會重設,但初始提示或系統提示會保持不變。clone() 函式會使用含有 signal 欄位的選用選項物件,讓您傳遞 AbortSignal 來銷毀複製的工作階段。

const controller = new AbortController();
stopButton.onclick = () => controller.abort();

const clonedSession = await session.clone({
  signal: controller.signal,
});

提示模型

您可以使用 prompt()promptStreaming() 函式提示模型。

非串流輸出內容

如果您希望取得簡短的結果,可以使用 prompt() 函式,該函式會在回應可用時傳回回應。

// Start by checking if it's possible to create a session based on the
// availability of the model, and the characteristics of the device.
const {available, defaultTemperature, defaultTopK, maxTopK } =
  await chrome.aiOriginTrial.languageModel.capabilities();

if (available !== 'no') {
  const session = await chrome.aiOriginTrial.languageModel.create();

  // Prompt the model and wait for the whole result to come back.
  const result = await session.prompt('Write me a poem!');
  console.log(result);
}

串流輸出

如果您希望顯示較長的回應,請使用 promptStreaming() 函式,這樣您就能在模型傳回結果時顯示部分結果。

const {available, defaultTemperature, defaultTopK, maxTopK } =
  await chrome.aiOriginTrial.languageModel.capabilities();

if (available !== 'no') {
  const session = await chrome.aiOriginTrial.languageModel.create();

  // Prompt the model and stream the result:
  const stream = session.promptStreaming('Write me an extra-long poem!');
  for await (const chunk of stream) {
    console.log(chunk);
  }
}

promptStreaming() 會傳回 ReadableStream,其區塊會依序彼此建構。例如:"Hello,""Hello world,""Hello world I am,""Hello world I am an AI."。這不是預期的行為。我們打算與平台上的其他串流 API 保持一致,在該 API 中,區塊是單一長串流的連續片段。這表示輸出內容會是 "Hello"" world"" I am"" an AI" 等序列。

目前,如要達成預期行為,您可以實作下列內容。這適用於標準和非標準行為。

let result = '';
let previousChunk = '';

for await (const chunk of stream) {
  const newChunk = chunk.startsWith(previousChunk)
      ? chunk.slice(previousChunk.length) : chunk;
  console.log(newChunk);
  result += newChunk;
  previousChunk = chunk;
}
console.log(result);

停止執行提示

prompt()promptStreaming() 都會接受選用第二個參數,其中包含 signal 欄位,可讓您停止執行提示。

const controller = new AbortController();
stopButton.onclick = () => controller.abort();

const result = await session.prompt(
  'Write me a poem!',
  { signal: controller.signal }
);

終止工作階段

如果您不再需要工作階段,請呼叫 destroy() 釋出資源。工作階段遭到銷毀後,就無法再使用,且任何進行中的執行作業都會中止。如果您想經常提示模型,建議您保留工作階段,因為建立工作階段可能需要一些時間。

await session.prompt(
  'You are a friendly, helpful assistant specialized in clothing choices.'
);

session.destroy();

// The promise is rejected with an error explaining that
// the session is destroyed.
await session.prompt(
  'What should I wear today? It is sunny and I am unsure
  between a t-shirt and a polo.'
);

示範

如要測試 Chrome 擴充功能中的 Prompt API,請安裝示範擴充功能。您可以在 GitHub 上找到擴充功能原始碼

Prompt API 的示範介面

參與並提供意見回饋

立即加入來源試用計畫,並分享意見回饋,即可開始在 Chrome 擴充功能中測試 Prompt API。您的意見回饋會直接影響我們建構及實作此 API 後續版本,以及所有內建 AI API 的方式。