firebase-js-sdk 中 `LanguageModelExpected` 接口详解:为 @firebase/ai 端侧语言模型声明多模态能力
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):
- 可用性探测
isAvailable()(chrome-adapter.ts):SDK 调用this.languageModelProvider?.availability(this.onDeviceParams.createOptions),把包含expectedInputs/expectedOutputs的完整createOptions透传给浏览器原生的LanguageModel.availability()。端侧推理是否可用、是否需要下载模型,取决于这份能力声明。 - 模型下载
downloadIfAvailable()/download()(chrome-adapter.ts):当可用性为DOWNLOADABLE或DOWNLOADING时,SDK 会(在合并下载进度回调后)调用LanguageModel.create(options)触发下载;options即携带expectedInputs/expectedOutputs的createOptions。 - 会话创建
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 实现、请求路由逻辑。