firebase-js-sdk 中 `LanguageModelExpected` 接口详解:为 @firebase/ai 端侧语言模型声明多模态能力

原创2026-10-14 17:43:421,724 阅读
文章标签:开发工具后端

firebase-js-sdk 中 LanguageModelExpected 接口详解:为 @firebase/ai 端侧语言模型声明多模态能力

本篇技术指南聚焦 @firebase/ai 包中的 LanguageModelExpected 接口——Firebase JS SDK 混合推理(hybrid inference)功能下,用于声明端侧(on-device)语言模型“预期输入/输出能力”的核心配置类型。读完本文,你将掌握该接口每个字段的含义与取值、SDK 内置默认值是如何填充的、如何将其写入 getGenerativeModel 的混合推理参数,以及它在 ChromeAdapterImpl 内部 availability() / create() 调用链中的作用位置,从而能正确配置端侧模型的多模态(文本/图像/音频)能力声明。

一、接口定义与文档定位

LanguageModelExpected 是 @firebase/ai 的公开类型(@public),其官方参考文档位于 LanguageModelExpected 接口文档。文档给出的接口描述与签名如下:

Options for the expected inputs for an on-device language model.(端侧语言模型预期输入的选项。)

export interface LanguageModelExpected

文档同时列出了它的两个属性:

Property Type 说明
languages string[] 可选。模型预期输入/输出涉及的语种列表
type LanguageModelMessageType 必填。模态类型,取值见下文

该接口的实际源码定义在 language-model.ts:

/**
 * Options for the expected inputs for an on-device language model.
 * @public
 */
export interface LanguageModelExpected {
  type: LanguageModelMessageType;
  languages?: string[];
}

它与 Chrome Prompt API 的完整 API 表面(Web IDL)保持对齐——文件头注释说明,language-model.ts 中定义的 LanguageModel 系列类型是“hybrid functionality(混合功能)所需的 Prompt API 子集”。

二、字段详解:type 与 languages

2.1 type: LanguageModelMessageType

type 是必填字段,其类型 LanguageModelMessageType 定义在 language-model.ts:

/**
 * Allowable types for on-device language model messages.
 * @public
 */
export type LanguageModelMessageType = 'text' | 'image' | 'audio';

即一个 LanguageModelExpected 对象只能描述三种模态之一:

  • 'text':文本,此时 languages 字段才有实际意义,用于声明文本所属语种(如 ['en']、['zh']);
  • 'image':图像输入/输出,声明图像模态能力时 languages 无意义,可省略;
  • 'audio':音频模态。

从源码结构看,LanguageModelMessageType 同时被用于 LanguageModelMessageContent.type(language-model.ts),也就是说消息内容的模态与能力声明的模态共用同一套枚举,保证“声明的能力”与“实际发送的消息”在类型层面一致。

2.2 languages?: string[]

languages 为可选字段,类型为字符串数组。从源码注释(language-model.ts)与 SDK 默认值(见第三节)可以确认,其用途是声明模型预期处理的文本语种,SDK 的默认声明即为 ['en'](英语)。该字段只挂在文本模态声明上才有配置价值:{ type: 'image' } 这类图像声明中不携带语种信息。

三、SDK 默认值:未声明时端侧模型“预期什么”

LanguageModelExpected 并不是一个孤立类型,它是创建选项 LanguageModelCreateCoreOptions 中 expectedInputs / expectedOutputs 数组的元素。其文档页 LanguageModelCreateCoreOptions 明确说明:

  • expectedInputs:Defaults to image input and English text input if not overriden.(未覆盖时默认为图像输入 + 英文文本输入)
  • expectedOutputs:Defaults to English text output if not overriden.(未覆盖时默认为英文文本输出)

这两个默认值在 chrome-adapter.ts 中被显式实现:

// Defaults to English text. This can be overriden by user config.
const defaultExpectedText: LanguageModelExpected = {
  type: 'text',
  languages: ['en']
};

export const defaultExpectedInputs: LanguageModelExpected[] = [
  defaultExpectedText,
  { type: 'image' }
];

export const defaultExpectedOutputs: LanguageModelExpected[] = [
  defaultExpectedText
];

即默认声明为:输入支持英文文本 + 图像,输出支持英文文本。值得注意的是,ChromeAdapterImpl 的构造函数对传入配置做了逐层兜底(chrome-adapter.ts):

  • 若用户完全没有传 onDeviceParams.createOptions,整个 createOptions 被替换为 { expectedInputs: defaultExpectedInputs, expectedOutputs: defaultExpectedOutputs };
  • 若传了 createOptions 但缺 expectedInputs 或 expectedOutputs,也会分别单独补上默认值。

这意味着开发者即使只配置了其中一项,另一项也不会是 undefined,而是回到上表所述的默认能力声明。

四、如何配置:HybridParams 到 LanguageModelExpected[] 的完整链路

4.1 类型链路

端侧推理的完整配置结构定义在 requests.ts:

/**
 * Encapsulates configuration for on-device inference.
 * @public
 */
export interface OnDeviceParams {
  createOptions?: LanguageModelCreateOptions;   // 含 expectedInputs / expectedOutputs
  promptOptions?: LanguageModelPromptOptions;
}

/**
 * Configures hybrid inference.
 * @public
 */
export interface HybridParams {
  /** Specifies on-device or in-cloud inference. Defaults to prefer on-device. */
  mode: InferenceMode;
  /** Optional. Specifies advanced params for on-device inference. */
  onDeviceParams?: OnDeviceParams;
  /** Optional. Specifies advanced params for in-cloud inference. */
  inCloudParams?: ModelParams;
}

其中 LanguageModelCreateOptions(language-model.ts)继承自 LanguageModelCreateCoreOptions,额外增加 signal 与 initialPrompts 字段。对应文档页见 HybridParams、OnDeviceParams、LanguageModelCreateOptions。

4.2 使用示例

在 getGenerativeModel 中指定混合推理模式后,mode、onDeviceParams、inCloudParams 就是全部合法键(@firebase/ai 的 api.ts 会校验这一点:当指定了 mode 时,传入其他 ModelParams 键会直接报错)。因此声明端侧能力时的典型写法为:

import { getAI, getGenerativeModel, InferenceMode } from 'firebase/ai';

const ai = getAI(app);
const model = getGenerativeModel(ai, {
  mode: InferenceMode.ONLY_ON_DEVICE,
  onDeviceParams: {
    createOptions: {
      // 声明端侧模型预期能力:英文文本 + 图像输入,英文文本输出
      expectedInputs: [
        { type: 'text', languages: ['en'] },
        { type: 'image' }
      ],
      expectedOutputs: [
        { type: 'text', languages: ['en'] }
      ]
    }
  },
  inCloudParams: { model: 'gemini-flash-latest' }
});

InferenceMode 的四个取值定义在 enums.ts:PREFER_ON_DEVICE、ONLY_ON_DEVICE、ONLY_IN_CLOUD、PREFER_IN_CLOUD,其语义分别是:优先端侧(失败回退云端)、仅端侧(不可用则抛错)、仅云端、优先云端(失败回退端侧)。

五、LanguageModelExpected 在推理流程中的生效位置

声明的能力配置并不是“写完即止”,它在 ChromeAdapterImpl 的三处关键路径中被实际消费(均在 chrome-adapter.ts):

  1. 可用性探测 isAvailable()(chrome-adapter.ts):SDK 调用 this.languageModelProvider?.availability(this.onDeviceParams.createOptions),把包含 expectedInputs / expectedOutputs 的完整 createOptions 透传给浏览器原生的 LanguageModel.availability()。端侧推理是否可用、是否需要下载模型,取决于这份能力声明。
  2. 模型下载 downloadIfAvailable() / download()(chrome-adapter.ts):当可用性为 DOWNLOADABLE 或 DOWNLOADING 时,SDK 会(在合并下载进度回调后)调用 LanguageModel.create(options) 触发下载;options 即携带 expectedInputs / expectedOutputs 的 createOptions。
  3. 会话创建 createSession()(chrome-adapter.ts):每次端侧推理都通过 languageModelProvider.create(this.onDeviceParams.createOptions) 新建会话——能力声明在每次 create() 时都会随会话一起提交给端侧运行时。

下载完成后可用性状态的变化,由 Availability 枚举刻画(language-model.ts):UNAVAILABLE → DOWNLOADABLE → DOWNLOADING → AVAILABLE。

用户侧的显式入口是 GenerativeModel.initializeDeviceModel():它调用 downloadIfAvailable(onDownloadProgress),并在 Availability.UNAVAILABLE 且模式为 ONLY_ON_DEVICE 时抛出 API_NOT_ENABLED 错误('Local LanguageModel API not available in this environment.')。其文档注释特别强调:该调用必须在用户与页面发生交互(如点击按钮、按键)之后发起,否则若需要下载会报错;若希望用更简单的进度回调而不是原生的 LanguageModelDownloadMonitor,直接给 initializeDeviceModel 传 onDownloadProgress 回调即可(monitor 字段只面向高级场景,见 LanguageModelCreateCoreOptions 文档)。

请求层面的路由逻辑则由 hybrid-helpers.ts 中的 callCloudOrDevice() 完成:根据 mode 与 chromeAdapter.isAvailable(request) 的结果决定走端侧还是云端;其中 ONLY_ON_DEVICE 模式下端侧不可用会抛出 UNSUPPORTED 错误,PREFER_IN_CLOUD 模式只在云端返回特定可回退错误(FETCH_ERROR、ERROR、API_NOT_ENABLED)时才降级到端侧。

六、实践注意事项与适用前提

  • 运行环境前提:整个端侧链路依赖浏览器全局暴露的 LanguageModel 对象(Chrome Prompt API)。chrome-adapter.ts 中的 chromeAdapterFactory() 只有在 window.LanguageModel 存在且指定了 mode 时才创建适配器;若浏览器不支持,端侧能力整体不可用(ONLY_ON_DEVICE 模式会报 API_NOT_ENABLED)。
  • 能力声明决定模型选择:从源码调用链看,availability() 与 create() 都以 createOptions(含 expectedInputs/expectedOutputs)为入参,因此修改 LanguageModelExpected 数组实质上是重新声明对端侧模型的能力需求。默认值(英文文本 + 图像输入)已经覆盖了 ChromeAdapterImpl.isOnDeviceRequest() 校验所支持的请求形态——该校验仅接受文本与 image/jpeg、image/png 两类内联图像(chrome-adapter.ts 与 L224-L257)。
  • languages 只服务文本模态:图像/音频声明无需也不应携带语种;声明文本能力时建议按实际输入语种填写,如 languages: ['en', 'zh'],避免依赖默认的 ['en']。
  • 默认值兜底机制:如第三节所述,ChromeAdapterImpl 构造函数保证 expectedInputs / expectedOutputs 永不为 undefined,只配置其中一项时另一项自动回落到默认值,不会造成“半配置”状态。
  • 不支持的端侧调用:ChromeAdapterImpl.countTokens() 目前直接抛错 'Count Tokens is not yet available for on-device model.'(chrome-adapter.ts),token 计数仅在云端可用。

七、小结

LanguageModelExpected 虽只有 type('text' | 'image' | 'audio',必填)与 languages(string[],可选)两个字段,但它处在 @firebase/ai 混合推理配置的枢纽位置:作为 LanguageModelCreateCoreOptions.expectedInputs / expectedOutputs 的元素,经 OnDeviceParams.createOptions 传入 getGenerativeModel,最终在 ChromeAdapterImpl 的可用性探测、模型下载与会话创建三处被原样提交给 Chrome Prompt API,直接决定端侧模型“能否服务当前请求”。理解其默认值(英文文本 + 图像输入、英文文本输出)、兜底逻辑与配置校验规则,是正确落地 Firebase AI 端侧推理的前提。

核心参考路径:LanguageModelExpected 源码定义、默认值与适配器实现、HybridParams 与 OnDeviceParams 定义、initializeDeviceModel 实现、请求路由逻辑。

登录后查看全文
firebase-js-sdk