Firebase JS SDK LiveServerContent 接口详解:实时语音会话的增量内容更新协议 开发工具后端【免费下载链接】firebase-js-sdkFirebase Javascript SDK项目地址https://gitcode.com/gh_mirrors/fi/firebase-js-sdk点击查看免费下载导读LiveServerContent是 Firebase JS SDK 中 AI 模块firebase/ai为实时Live会话定义的服务器消息类型用于在 Gemini Live API 双向流式交互中承载模型输出的增量内容更新——包括模型生成的内容片段、轮次结束信号、被打断信号以及可选的语音输入/输出转写文本。本文将以 docs-devsite/ai.liveservercontent.md 为核心逐字段剖析该接口的语义并结合 packages/ai/src/types/responses.ts、packages/ai/src/methods/live-session.ts 等源码与测试用例讲清它的产生机制、消费方式与典型应用场景。读完本文你将能准确理解并处理 Live 会话中每一条serverContent消息正确实现语音打断、轮次判断与转写展示。LiveServerContent 在实时会话中的定位Live 会话由LiveGenerativeModel建立、LiveSession维护是 WebSocket 之上的全双工实时交互通道客户端持续发送文本、音频16kHz/16-bit PCM或视频帧服务端则持续回推模型响应。LiveServerContent就是服务端回推消息中最核心、出现频率最高的一类其类型定义明确写着An incremental content update from the model.模型的一次增量内容更新。从源码结构看LiveSession.receive()返回的异步生成器统一产出五种消息类型见 packages/ai/src/methods/live-session.ts#L333-L339async *receive(): AsyncGenerator | LiveServerContent | LiveServerToolCall | LiveServerToolCallCancellation | LiveServerGoingAwayNotice | LiveSessionResumptionUpdate 其中LiveServerContent携带模型说了什么、轮到谁、有没有被打断、说了哪些话的转写等会话状态信息是理解实时对话进程的主线索。接口签名与属性总览接口定义于 packages/ai/src/types/responses.ts#L580-L609标注为betaPublic PreviewAPIexport interface LiveServerContent { type: serverContent; modelTurn?: Content; turnComplete?: boolean; interrupted?: boolean; inputTranscription?: Transcription; outputTranscription?: Transcription; }各属性语义如下表与官方 API 文档一致属性类型说明typeserverContent消息类型判别常量用于区分toolCall、goingAwayNotice等其它消息modelTurnContent模型在本轮对话中生成的内容文本、内联音频等 Part 集合turnCompleteboolean是否已到模型回合结束未结束时为undefinedinterruptedboolean模型是否被客户端打断未被中断时为undefinedinputTranscriptionTranscription输入给模型的音频的语音转写outputTranscriptionTranscription模型输出音频的语音转写下面逐字段展开。判别字段type消息路由的稳定锚点type: serverContent;type是唯一必填字段且是字面量serverContent。它的作用体现在两处消费端路由SDK 内部如 live-session-helpers.ts 的接收循环以及开发者自己的receive()消费代码都需要先检查message.type serverContent再进入分支处理。线协议还原服务端原始消息本身并不带type字段SDK 在 live-session.ts#L348-L360 中检测到serverContent键后将其解包并补上type: serverContent再产出if (LiveResponseType.SERVER_CONTENT in message) { const serverContent ( message as { serverContent: OmitLiveServerContent, type } ).serverContent; if (serverContent?.modelTurn?.parts) { serverContent.modelTurn.parts serverContent.modelTurn.parts.map(assignPartType); } yield { type: serverContent, ...serverContent } as LiveServerContent; }值得注意的是SDK 在产出前会调用assignPartType为每个 Part 补齐type标签如text、inlineData这保证了后续处理modelTurn.parts时能安全地按类型分派。modelTurn模型本轮生成的内容载体modelTurn?: Content;modelTurn持有模型在当前对话轮次生成的内容类型为Content定义见 packages/ai/src/types/content.ts#L24-L27export interface Content { role: Role; parts: Part[]; }parts是联合类型数组可能包含TextPart、InlineDataPart、FunctionCallPart、FunctionResponsePart、FileDataPart等见 content.ts#L34-L41。在实时语音场景中modelTurn最常见的形态是音频块InlineDataPart其inlineData为mimeType: audio/pcm的 Base64 编码 PCM 数据文本片段TextPart当模型开启文字输出或语音与文字混合输出时出现。音频增量如何被播放AudioConversationRunner的实现印证SDK 的AudioConversationRunner语音会话运行器在 live-session-helpers.ts#L318-L335 中演示了标准消费方式const serverContent message as LiveServerContent; if (serverContent.interrupted) { this.interruptPlayback(); } const audioPart serverContent.modelTurn?.parts.find( part part?.type inlineData part.inlineData?.mimeType?.startsWith(audio/) ); if (audioPart audioPart.type inlineData) { const audioData Uint8Array.from( atob(audioPart.inlineData.data), c c.charCodeAt(0) ).buffer; this.enqueueAndPlay(audioData); }即从modelTurn.parts中筛选出mimeType以audio/开头的inlineData部分把 Base64 解码为ArrayBuffer后进入播放队列。队列以 24kHz 16-bit PCM 为输入通过 Web Audio API 的AudioBufferSourceNode无缝衔接调度见 live-session-helpers.ts#L147-L152 的注释与队列实现。对应的单元测试 packages/ai/src/methods/live-session-helpers.test.ts#L233-L254 直接构造了一条LiveServerContent消息来验证音频入队播放const serverMessage: LiveServerContent { type: serverContent, modelTurn: { role: model, parts: [ { type: inlineData, inlineData: { mimeType: audio/pcm, data: 1111222233334444 } } ] } };这印证了一条serverContent消息 一个或多个内容 Part 的增量多条消息拼接起来才构成完整的模型输出。turnComplete轮次结束判定turnComplete?: boolean;true模型本轮turn已完整结束客户端可以据此切换发言状态、展示对方已说完或开启新一轮输入undefined本轮尚未结束后续还会继续收到携带更多modelTurn内容的serverContent消息。由于增量更新的特性模型的一段完整回答会被拆成多条serverContent消息下发因此必须等待turnComplete true才能认定一段话说完。turnComplete与interrupted都是可选的布尔标志其未触发即为undefined的语义而非false是官方 API 文档明确强调的要点消费时建议使用真值判断if (msg.turnComplete)而非 true之外的严格比较。interrupted客户端抢占导致的打断信号interrupted?: boolean;当客户端在模型尚未说完时抢先发送了新消息文本、音频或视频输入模型会被打断服务端随后下发一条interrupted: true的serverContent消息。官方文档原话An interruption occurs when the client sends a message before the model finishes its turn.AudioConversationRunner对该信号的处理非常典型live-session-helpers.ts#L228-L243private interruptPlayback(): void { // 停止所有已调度的音频源 [...this.scheduledSources].forEach(source source.stop(0)); // 清空尚未播放的音频缓冲 this.playbackQueue.length 0; // 重置播放时钟从当前时刻重新开始 this.nextStartTime this.deps.audioContext.currentTime; }也就是说收到interrupted后 SDK 会立即停掉正在播放与排队等待的模型音频避免用户抢话后模型声音还在继续的体验问题。测试 live-session-helpers.test.ts#L286-L320 精确验证了这一行为先入队两个音频块再下发{ type: serverContent, interrupted: true }断言两个AudioBufferSourceNode均被stop调用。开发提示如果你自研 UI 层遇到interrupted true时应同步清除本地正在播放/正在显示的模型内容缓冲并立即允许用户继续输入。inputTranscription/outputTranscription双向语音转写inputTranscription?: Transcription; outputTranscription?: Transcription;两个字段分别承载输入给模型的音频与模型输出音频的文本转写类型均为Transcription定义见 packages/ai/src/types/responses.ts#L619-L624export interface Transcription { text?: string; }目前Transcription仅含一个可选的text字段即转写出的文本。如何开启转写LiveGenerationConfig转写不是默认开启的需要通过LiveGenerationConfig上的两个配置项启用定义见 packages/ai/src/types/requests.ts#L301-L317inputAudioTranscription?: AudioTranscriptionConfig开启后模型会在LiveServerContent.inputTranscription中回传你语音输入的转写outputAudioTranscription?: AudioTranscriptionConfig开启后模型会在LiveServerContent.outputTranscription中回传其语音输出的转写。官方文档特别提醒转写是跨消息分片的。例如你对模型说 How are you today?转写可能分三条消息下发为 How a、re yo、u today?模型的语音输出同理。因此做字幕/转写展示时必须在会话层面对连续多条消息的inputTranscription/outputTranscription做增量拼接而不是把每条消息当成完整句子。配置在协议层的搬运细节一个值得注意的实现细节inputAudioTranscription/outputAudioTranscription虽在公共 API 上属于LiveGenerationConfig但后端期望它们位于 WebSocket 首条setup消息的顶层。SDK 在 packages/ai/src/models/live-generative-model.ts#L87-L110 的connect()中专门做了拆解与搬运const { inputAudioTranscription, outputAudioTranscription, ...generationConfig } this.generationConfig; // ... const setupMessage: _LiveClientSetup { setup: { model: fullModelPath, generationConfig, tools: this.tools, systemInstruction: this.systemInstruction, inputAudioTranscription, outputAudioTranscription, sessionResumption } };同时类型层用_LiveGenerationConfig OmitLiveGenerationConfig, inputAudioTranscription | outputAudioTranscription强制保证这两个字段不会泄漏到generationConfig中见 packages/ai/src/types/live-responses.ts#L93-L101。对应测试 packages/ai/src/models/live-generative-model.test.ts#L170-L190 也验证了setup.inputAudioTranscription/setup.outputAudioTranscription会被正确下发。实战消费LiveServerContent的完整模式综合以上分析一个标准的serverContent消费循环可以这样写基于LiveSession.receive()的公开 API 形态const liveModel new LiveGenerativeModel({ model: gemini-live-2.5-flash }); const session await liveModel.connect(); let inputCaption ; let outputCaption ; for await (const message of session.receive()) { if (message.type ! serverContent) { // 其它类型toolCall / toolCallCancellation / goingAwayNotice / sessionResumptionUpdate continue; } const serverContent message as LiveServerContent; // 1) 模型被客户端打断清空本地正在播放/展示的模型内容 if (serverContent.interrupted) { stopLocalPlayback(); // 你的自定义实现 outputCaption ; continue; } // 2) 模型内容增量文本直接展示音频交给播放器 for (const part of serverContent.modelTurn?.parts ?? []) { if (part.type text) { appendToModelTranscript(part.text); } else if (part.type inlineData) { // mimeType 以 audio/ 开头时按音频处理 enqueueAudioForPlayback(part.inlineData.data); } } // 3) 转写增量注意跨消息拼接 if (serverContent.inputTranscription?.text) { inputCaption serverContent.inputTranscription.text; } if (serverContent.outputTranscription?.text) { outputCaption serverContent.outputTranscription.text; } // 4) 轮次结束刷新 UI 状态允许用户发言 if (serverContent.turnComplete) { onModelTurnComplete(); } }要点回顾先以type分流再做字段级处理interrupted优先处理并清空本地缓冲转写要拼接、modelTurn要按 Part 类型分派以turnComplete作为一轮对话的结束信号。使用前提与 API 状态说明LiveServerContent属于Public PreviewbetaAPI官方在 docs-devsite/ai.liveservercontent.md 中明确提示Do not use this API in a production environment不要在生产环境使用接口可能在后续版本中依据反馈调整。该接口随firebase/ai包提供源码位于 packages/ai/src/types/responses.ts#L580-L609与之配套的接口还有 LiveSession、LiveGenerativeModel、LiveGenerationConfig、Content 与 Transcription。相关单元测试live-session-helpers.test.ts 与 live-generative-model.test.ts覆盖了音频入队播放、打断清队、转写配置下发等关键路径可作为理解协议行为的参考实现。小结LiveServerContent是 Firebase JS SDK 实时语音对话的核心消息协议modelTurn承载模型内容增量turnComplete标记轮次边界interrupted驱动打断处理inputTranscription/outputTranscription提供可选的语音转写。掌握它的字段语义与增量特性就能在自研的实时对话应用中正确处理语音播放、字幕拼接与交互状态机。赞分享开发工具后端【免费下载链接】firebase-js-sdkFirebase Javascript SDK项目地址https://gitcode.com/gh_mirrors/fi/firebase-js-sdk点击查看免费下载相关推荐Firebase JS SDK 中 LanguageModelCreateCoreOptions 详解配置 Chrome 端侧语言模型会话的入口Firebase JS SDK 中 LanguageModelCreateCoreOptions 详解配置 Chrome 端侧语言模型会话的入口 在 Fire开发工具后端Firebase JS SDK AI 实时语音对话控制器 AudioConversationController 深入解析Firebase JS SDK AI 实时语音对话控制器 AudioConversationController 深入解析 Firebase JS SDK 在开发工具后端LanceDB JS SDK SessionLogout 接口详解OAuth 会话登出的返回值与幂等语义LanceDB JS SDK SessionLogout 接口详解OAuth 会话登出的返回值与幂等语义 导读 SessionLogout 是 LanceDB数据库向量数据库全文检索人工智能上一篇终极指南揭开Discord服务器隐藏频道的秘密 - ShowHiddenChannels完全解析下一篇中兴光猫工厂模式一键解锁zteOnu工具完整使用指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考