Prompt API 的实验性 Polyfill

发布时间:2026 年 5 月 14 日

借助 Chrome 中的 Prompt API,您可以在 window.LanguageModel 上使用高级浏览器 API 与 LLM 进行交互。不过,此功能仍处于有限支持状态,实现过程也比较复杂。

浏览器 支持的操作系统 不支持的操作系统 位置
Chrome Windows、macOS、Linux、ChromeOS (Chromebook Plus) Android、iOS ✅ 支持
Edge Windows、macOS Android、iOS ✅ 支持
Safari 📋 职位已确定
Firefox 📋 职位已确定

与此同时,抢先试用计划中的开发者也表达了对 Prompt API 的热衷。在可预见的未来,该 API 的可用性将带来兼容性挑战。

解决方案

因此,我们发布了一个实验性的符合规范Prompt API Polyfill(请参阅 GitHub 上的源代码),该 Polyfill 可在可配置的云端后端提供程序以及 Transformers.js 形式的本地后端提供程序之上准确实现 Prompt API。

使用 Polyfill

如需使用 Polyfill,请执行以下操作:

  1. 从 npm 下载 polyfill

    npm install prompt-api-polyfill
    
  2. 选择您要使用云后端提供方还是本地后端提供方:

    • 云后端提供方:用户数据会发送到云端进行远程处理,但您不必等待本地模型可用。您需要根据云提供商的价格信息承担产生的任何费用。
    • 本地后端提供方:用户数据会保留在浏览器中并在本地进行处理,但您需要下载模型,与真实的 Prompt API 不同,该模型无法在不同来源之间共享。本地处理不涉及任何费用。

云后端

选择任意云后端,并获取后端提供商的 API 密钥(以及任何其他凭据)。

获得 API 密钥后,在配置文件 .env.json 中输入详细信息。如果您未指定 modelName,polyfill 将使用每个后端的默认模型;如果您指定了 modelName,则可以选择每个后端支持的模型之一。

{
  "apiKey": "y0ur-Api-k3Y",
  "modelName": "model-name"
}

本地后端

如果您决定使用基于 Transformers.js 的本地后端提供方,则只需要一个虚拟 API 密钥。不过,您可以配置 Transformers.js 应使用哪些设备。选择 "webgpu" 可获得最佳性能,选择 "wasm" 可获得最佳兼容性。您可以选择更改默认设置。从 Hugging Face 的兼容模型目录中选择其他模型。对于某些模型,您可以使用 dtype 参数选择不同的量化。

{
  "apiKey": "dummy",
  "device": "webgpu",
  "dtype": "q4f16",
  "modelName": "onnx-community/gemma-3-1b-it-ONNX-GQA"
};

配置填充

有了配置文件后,您现在可以在应用中开始使用 Polyfill。

  1. 导入配置文件并将其分配给一个名称恰当的全局变量,其中 $BACKEND 是您选择的后端:window.$BACKEND_CONFIG
  2. 使用动态导入,以便仅在底层浏览器不支持时才加载填充程序。
  3. 调用 Prompt API 函数
import config from './.env.json' with { type: 'json' };

// Set $BACKEND_CONFIG to select a backend
window.$BACKEND_CONFIG = config;

if (!('LanguageModel' in window)) {
  await import('prompt-api-polyfill');
}

const session = await LanguageModel.create({
  expectedInputs: [{type: 'text', languages: ['en']}],
  expectedOutputs: [{type: 'text', languages: ['en']}],
});
await session.prompt('Tell me a joke!');

该填充程序支持结构化输出(Transformers.js 后端除外),可处理多模态输入(OpenAI 后端除外,该后端不支持同时处理音频和图片,只能分别处理),并且已针对 LanguageModel完整 Web 平台测试套件进行过测试。

如需了解更多背景信息和详细的使用信息以及源代码,请参阅 GitHub 代码库中的 README 文件

与浏览器提示 API 的区别

如果填充由云模型提供支持,则在客户端运行的某些优势不再适用。也就是说,您无法再保证敏感数据在本地处理,不过后端提供商的隐私权政策仍然适用。用户离线时,您的应用也无法再使用 AI。如需了解您是处于在线状态还是离线状态,您可以监听相应的事件。

window.addEventListener("offline", (e) => {
  console.log("offline");
});

window.addEventListener("online", (e) => {
  console.log("online");
});

如果 AI 推理针对云端模型运行,则无需下载本地模型。该填充区会伪造 downloadprogress 事件,因此对于您的应用而言,它会显示为内置模型已下载完毕,这意味着将有两个事件,一个的 loaded 值为 0,另一个的 loaded 值为 1,这符合规范的要求。

与设备端推理不同,基于云的推理在从所选的后端提供商调用 API 时可能会产生费用。查看价格信息,例如 Gemini API 的价格信息。如果您知道每个 token 的费用,可以使用 Prompt API 的 contextUsage 信息来计算费用。

const COST_PER_TOKEN = 123;
const COST_LIMIT = 456;

let costSoFar = 0;

const session = await LanguageModel.create(options);

/…/

if (costSoFar < COST_LIMIT) {
  await session.prompt('Tell me a joke.');
  costSoFar = session.contextUsage * COST_PER_TOKEN;
} else {
  // Show premium AI plan promo.
}

如果您直接从移动应用或 Web 应用调用云 API(例如,允许访问生成式 AI 模型的 API),则 API 密钥很容易遭到未经授权的客户端滥用。为了帮助保护这些 API,如果您使用 Firebase AI Logic 混合 SDK,则应使用 Firebase App Check 来验证所有传入的 API 调用是否都来自您的实际应用。对于 Google 等某些云提供方,您还可以强制执行严格的源检查,以确保只有允许的网站可以使用该 API。

例如,后端提供商的限制(而非提示 API 的限制)适用于会话的 contextWindow。对于 contextWindow,这些限制通常比设备端高得多,您可以在云端处理更多数据,因此虽然您应该了解这种差异,但在实践中,您可能不会遇到相关问题。

创建您自己的后端

如需添加您自己的后端提供程序,请按以下步骤操作:

扩展基础后端类

backends/ 目录中创建一个新文件,例如 backends/custom-backend.js。您需要扩展 PolyfillBackend 类并实现满足预期接口的核心方法。

import PolyfillBackend from './base.js';
import { DEFAULT_MODELS } from './defaults.js';

export default class CustomBackend extends PolyfillBackend {
  constructor(config) {
    // config typically comes from a window global (e.g., window.CUSTOM_CONFIG)
    super(config.modelName || DEFAULT_MODELS.custom.modelName);
  }

  // Check if the backend is configured (e.g., API key is present), if given
  // combinations of modelName and options are supported, or, for local model,
  // if the model is available.
  static availability(options) {
    return window.CUSTOM_CONFIG?.apiKey ? 'available' : 'unavailable';
  }

  // Initialize the underlying SDK or API client. With local models, use
  // monitorTarget to report model download progress to the polyfill.
  createSession(options, sessionParams, monitorTarget) {
    // Return the initialized session or client instance
  }

  // Non-streaming prompt execution
  async generateContent(contents) {
    // contents: Array of { role: 'user'|'model', parts: [{ text: string }] }
    // Return: { text: string, usage: number }
  }

  // Streaming prompt execution
  async generateContentStream(contents) {
    // Return: AsyncIterable yielding chunks
  }

  // Token counting for quota/usage tracking
  async countTokens(contents) {
    // Return: total token count (number)
  }
}

注册后端

polyfill 使用基于全局配置的“优先匹配”策略。您需要在 prompt-api-polyfill.js 文件中注册后端,方法是将其添加到静态 #backends 数组:

// prompt-api-polyfill.js
static #backends = [
  // ... existing backends
  {
    config: 'CUSTOM_CONFIG', // The global object to look for on `window`
    path: './backends/custom-backend.js',
  },
];

设置默认模型

backends/defaults.js 中定义后备模型身份。当用户初始化会话但未指定特定 modelName 时,系统会使用此值。

// backends/defaults.js
export const DEFAULT_MODELS = {
  // ...
  custom: 'custom-model-pro-v1',
};

启用本地开发和测试

该项目使用发现脚本 (scripts/list-backends.js) 来生成测试矩阵。如需在测试运行程序中添加新的后端,请在根目录中创建一个 .env-[name].json 文件(例如 .env-custom.json):

{
  "apiKey": "your-api-key-here",
  "modelName": "custom-model-pro-v1"
}

通过 Web 平台测试 (WPT) 进行验证

最后一步是确保合规性。由于 polyfill 是由规范驱动的,因此任何新的后端都应通过官方(或暂定)Web 平台测试:

npm run test:wpt

此验证步骤可确保您的后端能够按照 Prompt API 规范的要求,准确处理 AbortSignal、系统提示和历史记录格式设置等事宜。

总结

借助 Polyfill,您可以在所有平台和设备上使用 Prompt API。通过针对 Prompt API 的明确定义的 API 进行编码,您可以更独立于云提供商,并尽可能贴近平台。

在支持 Prompt API 的设备上,甚至不会加载该填充区,因此您无需让用户下载他们不会执行的代码。如果您有反馈或遇到 bug,请在 GitHub 上提交问题。希望您享受撰写提示的过程!