Chrome 拡張機能の Prompt API

公開日: 2024 年 11 月 11 日

拡張機能向けの Prompt API がオリジン トライアルで利用可能になりました。これにより、ブラウザで Google の最も効率的な言語モデルである Gemini Nano を使用する Chrome 拡張機能を構築できるようになりました。

Chrome 拡張機能で Prompt API を使用するユースケースは多数あります。次に例を示します。

  • 即時カレンダーの予定。ウェブページからイベントの詳細を自動的に抽出する Chrome 拡張機能を開発して、ユーザーが数ステップでカレンダー エントリを作成できるようにします。
  • シームレスな連絡先の抽出。ウェブサイトから連絡先情報を抽出する拡張機能を作成して、ユーザーがビジネスに連絡したり、連絡先リストに詳細情報を追加したりしやすくします。
  • 動的コンテンツ フィルタリング。ニュース記事を分析し、ユーザー定義のトピックに基づいてコンテンツを自動的にぼかしたり非表示にしたりできる Chrome 拡張機能を作成します。

これらはほんの一例ですが、皆様がどのようなものを作成されるか楽しみにしております。

対象

  • Chrome 131 ~ 136 で実施されている Prompt API オリジン トライアルに参加して、この API を使用して拡張機能を作成できます。オリジン トライアルは、すべてのデベロッパーが参加できる期間限定のプログラムで、試験運用版のプラットフォーム機能に早期アクセスできます。デベロッパーは、テスト、ユーザー フィードバックの収集、反復処理を行い、今後のリリースに向けて準備できます。
    • 使用制限がある場合もありますが、これらの機能を統合してライブテストを行い、ユーザー フィードバックを収集できます。今後、この API の提供範囲を拡大していく予定です。
  • 早期プレビュー プログラムに参加して、新しい組み込み AI API をいち早くお試しください。また、メーリング リストでのディスカッションにもご参加いただけます。

オリジン トライアルに参加する

Chrome 拡張機能で Prompt API を使用するには、次の抜粋に従って、拡張機能に必要な他の権限とともに "aiLanguageModelOriginTrial" 権限を manifest.json ファイルに追加します。

オリジン トライアルに拡張機能を登録するには、ウェブ オリジンとして URL chrome-extension://YOUR_EXTENSION_ID を使用します。例: chrome-extension://ljjhjaakmncibonnjpaoglbhcjeolhkk

Chrome オリジン トライアルの登録

拡張機能 ID は動的に作成されます。割り当てが完了したら、マニフェストに key プロパティを追加して、ID を強制的に安定させることができます。

最初のトライアルに登録すると、生成されたトークンが届きます。このトークンは、マニフェストの trial_tokens フィールドの値として配列で渡す必要があります。

{
  "manifest_version": 3,
  "name": "YOUR_EXTENSION_NAME",
  "permissions": ["aiLanguageModelOriginTrial"],
  "trial_tokens": ["GENERATED_TOKEN"],
}

localhost のサポートを追加

オリジン トライアル中に localhost で Prompt 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 名前空間で使用できる新しい拡張関数は 2 つあります。

  • capabilities(): モデルの機能と利用可能かどうかを確認します。
  • create(): 言語モデル セッションを開始します。

モデルのダウンロード

Prompt API は、Chrome で Gemini Nano モデルを使用します。API は Chrome に組み込まれていますが、拡張機能が API を初めて使用するときにモデルが個別にダウンロードされます。

モデルの使用準備ができているかどうかを確認するには、非同期 chrome.aiOriginTrial.languageModel.capabilities() 関数を呼び出します。available フィールドを持つ AILanguageModelCapabilities オブジェクトを返します。このフィールドには、次の 3 つの値を指定できます。

  • 'no': 現在のブラウザは Prompt API をサポートしていますが、現時点では使用できません。モデルをダウンロードするための空きディスク容量が不足しているなど、さまざまな理由が考えられます。
  • 'readily': 現在のブラウザは Prompt API をサポートしており、すぐに使用できます。
  • 'after-download': 現在のブラウザは Prompt 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() 関数は、言語モデルの機能も通知します。結果の AILanguageModelCapabilities オブジェクトには、available のほかに次のフィールドもあります。

  • 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. 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."。これは想定された動作ではありません。チャンクは 1 つの長いストリームの連続した部分であるため、プラットフォーム上の他のストリーミング 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 フィールドを含む 2 番目のパラメータ(省略可)を指定できます。これにより、プロンプトの実行を停止できます。

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 の構築と実装に直接影響します。