Chrome 扩展程序中的 Prompt API

发布时间:2024 年 11 月 11 日

适用于扩展程序的 Prompt API 现已推出源代码试用版,您可以构建在浏览器中使用我们最高效的语言模型 Gemini Nano 的 Chrome 扩展程序。

Prompt API 在 Chrome 扩展程序中有很多用例。下面是一些示例:

  • 即时日历活动。开发一个 Chrome 扩展程序,用于自动从网页中提取活动详情,以便用户只需几个步骤即可创建日历条目。
  • 顺畅的联系人提取。构建一个可从网站中提取联系信息的扩展程序,让用户更轻松地与商家联系或向其联系人列表中添加详细信息。
  • 动态内容过滤。创建一个 Chrome 扩展程序,用于分析新闻报道,并根据用户定义的主题自动模糊处理或隐藏内容。

以上只是一些可能的用途,我们期待看到您的创作成果。

可用性

  • 加入 Prompt API 源试用(在 Chrome 131 到 136 中运行),以便使用此 API 创建扩展程序。如果您刚开始接触源代码试用,请注意,这些试用计划面向所有开发者开放,可让您抢先体验实验性平台功能。开发者可以进行测试、收集用户反馈,并进行迭代,为日后发布做好准备。
    • 虽然可能存在使用限制,但您可以集成这些功能以进行现场测试和收集用户反馈。我们的目标是,在我们努力扩大此 API 的适用范围时,为其未来的迭代提供参考。
  • 加入抢先体验计划,抢先了解新的内置 AI API,并参与我们的邮寄名单讨论。

参与源试用

如需在 Chrome 扩展程序中使用 Prompt API,请按照以下摘录将 "aiLanguageModelOriginTrial" 权限添加到 manifest.json 文件中,以及添加扩展程序可能需要的任何其他权限。

如需为您的扩展程序注册源站试用,请使用网址 chrome-extension://YOUR_EXTENSION_ID 作为网站源站。例如 chrome-extension://ljjhjaakmncibonnjpaoglbhcjeolhkk

注册试用 Chrome Origin

扩展程序 ID 是动态创建的。分配 ID 后,您可以通过向清单添加 key 属性,强制使 ID 保持稳定。

注册原始试用版后,您会收到一个生成的令牌,您需要将其作为数组传入清单中的 trial_tokens 字段的值。

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

添加了对 localhost 的支持

如需在源代码试用期间在 localhost 上访问 Prompt API,您必须将 Chrome 更新到最新版本。然后,请按下列步骤操作:

  1. 在以下任一平台上打开 Chrome:Windows、Mac 或 Linux。
  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':当前浏览器支持 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() 函数还会告知您语言模型的功能。除了 available 之外,生成的 AILanguageModelCapabilities 对象还具有以下字段:

await chrome.aiOriginTrial.languageModel.capabilities();
// {available: 'readily', defaultTopK: 3, maxTopK: 8, defaultTemperature: 1}

创建会话

确保 Prompt API 可以运行后,您可以使用 create() 函数创建会话,然后使用 prompt()promptStreaming() 函数向模型提问。

会话选项

您可以使用可选的 options 对象,通过 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() 函数的可选 options 对象还接受 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."。这不是预期行为。我们打算与平台上的其他流式传输 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 的未来版本的方式。