Prompt API を使用した AI セッション管理のベスト プラクティス

公開日: 2025 年 1 月 27 日

Prompt API は、Chrome チームが検討している組み込み AI API の 1 つです。早期プレビュー プログラムに参加してアプリでローカルにテストできます。また、Chrome 拡張機能の Prompt API オリジン トライアルに登録して、Chrome 拡張機能で本番環境でテストすることもできます。Prompt API の主な機能の 1 つはセッションです。これにより、AI モデルと 1 つ以上の会話を継続できます。会話の内容が失われることはありません。このガイドでは、言語モデルを使用したセッション管理のベスト プラクティスについて説明します。

1 つ以上の並列セッションのセッション管理のユースケースには、1 人のユーザーが AI とやり取りする従来の chatbot や、1 人のサポート エージェントが複数の顧客を同時に対応し、AI を使用してさまざまな会話を追跡するカスタマー リレーションシップ管理システムなどがあります。

システム プロンプトを使用してセッションを初期化する

最初に理解しておくべきコンセプトは、システム プロンプトです。セッションの開始時にセッションの全体的なコンテキストを設定します。たとえば、システム プロンプトを使用して、モデルにどのように応答するかを指示できます。

// Make this work in web apps and in extensions.
const aiNamespace = self.ai || chrome.aiOriginTrial || chrome.ai;
const languageModel = await aiNamespace.languageModel.create({
  systemPrompt: 'You are a helpful assistant and you speak like a pirate.',
});
console.log(await languageModel.prompt('Tell me a joke.'));
// 'Avast ye, matey! What do you call a lazy pirate?\n\nA **sail-bum!**\n\nAhoy there, me hearties!  Want to hear another one? \n'

メイン セッションのクローンを作成する

1 つのセッションが終了したときに新しいセッションを開始するアプリや、異なるセッションで独立した会話を並行して行うアプリの場合は、メイン セッションのクローンを作成するというコンセプトを利用できます。クローンは、temperaturetopK などのセッション パラメータと、潜在的なセッション操作履歴を元から継承します。これは、システム プロンプトでメイン セッションを初期化した場合などに便利です。これにより、アプリでこの処理を行う必要は 1 回だけで、すべてのクローンはメイン セッションから継承されます。

// Make this work in web apps and in extensions.
const aiNamespace = self.ai || chrome.aiOriginTrial || chrome.ai;
const languageModel = await aiNamespace.languageModel.create({
  systemPrompt: 'You are a helpful assistant and you speak like a pirate.',
});

// The original session `languageModel` remains unchanged, and
// the two clones can be interacted with independently from each other.
const firstClonedLanguageModel = await languageModel.clone();
const secondClonedLanguageModel = await languageModel.clone();
// Interact with the sessions independently.
await firstClonedLanguageModel.prompt('Tell me a joke about parrots.');
await secondClonedLanguageModel.prompt('Tell me a joke about treasure troves.');
// Each session keeps its own context.
// The first session's context is jokes about parrots.
await firstClonedLanguageModel.prompt('Tell me another.');
// The second session's context is jokes about treasure troves.
await secondClonedLanguageModel.prompt('Tell me another.');

過去のセッションを復元する

3 つ目のコンセプトは、最初のプロンプトのコンセプトです。元の目的は、n ショット プロンプト、つまりn 個のサンプル プロンプトとレスポンスをセットにしてモデルをプリミングし、実際のプロンプトに対する回答の精度を高めることです。モデルとの進行中の会話を記録している場合は、ブラウザの再起動後など、セッションを復元するために初期プロンプトのコンセプトを「悪用」して、ユーザーが中断したところからモデルを続行できるようにできます。次のコード スニペットは、localStorage でセッション履歴を追跡することを前提として、このアプローチをどのように行うかを説明しています。

// Make this work in web apps and in extensions.
const aiNamespace = self.ai || chrome.aiOriginTrial || chrome.ai;

// Restore the session from localStorage, or initialize a new session.
// The UUID is hardcoded here, but would come from a
// session picker in your user interface.
const uuid = '7e62c0e0-6518-4658-bc38-e7a43217df87';

function getSessionData(uuid) {
  try {
    const storedSession = localStorage.getItem(uuid);
    return storedSession ? JSON.parse(storedSession) : false;
  } catch {
    return false;
  }
}

let sessionData = getSessionData(uuid);

// Initialize a new session.
if (!sessionData) {
  // Get the current default parameters so they can be restored as they were,
  // even if the default values change in the future.
  const { defaultTopK, defaultTemperature } =
    await aiNamespace.languageModel.capabilities();
  sessionData = {
    systemPrompt: '',
    initialPrompts: [],
    topK: defaultTopK,
    temperature: defaultTemperature,
  };
}

// Initialize the session with the (previously stored or new) session data.
const languageModel = await aiNamespace.languageModel.create(sessionData);

// Keep track of the ongoing conversion and store it in localStorage.
const prompt = 'Tell me a joke';
try {
  const stream = languageModel.promptStreaming(prompt);
  let result = '';
  // You can already work with each `chunk`, but then store
  // the final `result` in history.
  for await (const chunk of stream) {
    // In practice, you'd render the chunk.
    console.log(chunk);
    result = chunk;
  }

  sessionData.initialPrompts.push(
    { role: 'user', content: prompt },
    { role: 'assistant', content: result },
  );

  // To avoid growing localStorage infinitely, make sure to delete
  // no longer used sessions from time to time.
  localStorage.setItem(uuid, JSON.stringify(sessionData));
} catch (err) {
  console.error(err.name, err.message);
}

回答が役に立たない場合にユーザーがモデルを停止できるようにして、セッションの割り当てを維持する

各セッションにはコンテキスト ウィンドウがあり、セッションの関連フィールド maxTokenstokensLefttokensSoFar にアクセスすると表示できます。

const { maxTokens, tokensLeft, tokensSoFar } = languageModel;

このコンテキスト ウィンドウを超えると、セッションで最も古いメッセージが追跡されなくなります。このコンテキストは重要である可能性があるため、望ましくない場合があります。割り当てを維持するため、プロンプトを送信した後にユーザーが回答が役に立たないと判断した場合は、AbortController を使用して言語モデルが回答しないようにします。prompt() メソッドと promptStreaming() メソッドの両方では、signal フィールドを含むオプションの 2 番目のパラメータを使用できます。これにより、ユーザーはセッションの応答を停止できます。

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

try {
  const stream = languageModel.promptStreaming('Write me a poem!', {
    signal: controller.signal,
  });
  for await (const chunk of stream) {
    console.log(chunk);
  }
} catch (err) {
  // Ignore `AbortError` errors.
  if (err.name !== 'AbortError') {
    console.error(err.name, err.message);
  }
}

デモ

AI セッション管理の実例については、AI セッション管理デモをご覧ください。Prompt API を使用して複数の並列会話を作成し、タブを再読み込みしたり、ブラウザを再起動したりして、中断したところから続行できます。GitHub のソースコードをご覧ください。

まとめ

これらの手法とベスト プラクティスで AI セッションを慎重に管理することで、Prompt API の可能性を最大限に引き出し、より効率的でレスポンシブなユーザー中心のアプリケーションを実現できます。これらのアプローチを組み合わせることもできます。たとえば、復元された過去のセッションのクローンを作成して、「what if」シナリオを実行できるようにします。このガイドが、スキルを向上させる一助となれば幸いです。

謝辞

このガイドは、Sebastian BenzAndre BandarraFrançois BeaufortAlexandra Klepper が確認しました。