ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Mastra 集成 Google Gemini Live API 语音能力全解析:从实时音频事件到工具调用与会话恢复

2026/9/15 17:46:47 拓冰建站 浏览量
Mastra 集成 Google Gemini Live API 语音能力全解析:从实时音频事件到工具调用与会话恢复 Mastra 集成 Google Gemini Live API 语音能力全解析从实时音频事件到工具调用与会话恢复【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra本篇技术指南围绕 Mastra 仓库中的mastra/voice-google-gemini-live语音集成包展开其版本历史与变更记录见 voice/google-gemini-live-api/CHANGELOG.md。该包将 Google Gemini Live API 的多模态实时语音能力接入 Mastra 框架提供双向音频流、实时转写、打断检测、工具调用与会话恢复等能力。读完本文你将掌握该包的安装配置、事件模型、sendContext()历史注入、工具调用机制、Vertex AI 认证方式以及从变更记录中可提炼的稳定性演进脉络并能直接在项目里落地一个可复制的实时语音 Agent。包概览mastra/voice-google-gemini-live在 Mastra 中的定位mastra/voice-google-gemini-live是 Mastra 官方发布的语音Voice集成包包名与入口位于 voice/google-gemini-live-api/package.json其核心导出类为GeminiLiveVoice见 src/index.ts。它继承自internal/voice提供的MastraVoice基类因此天然兼容 Mastra 统一的VoiceConfig配置范式与事件约定。从源码注释与 README见 README.md可以确认该包的核心能力清单双向音频流麦克风输入、模型语音输出内置 VAD语音活动检测与打断barge-in处理工具调用function calling会话管理与恢复session resumption实时转写STT输入与输出双侧同时支持 Gemini APIAPI Key 认证与 Vertex AIOAuth/服务账号认证支持原生音频native-audio模型。运行环境要求 Node.js 22.13.0该门槛在 0.11.0 版本被设定。依赖上使用google/genai、google-auth-library、ws与mastra/schema-compat。快速上手安装、连接与订阅事件安装npm install mastra/voice-google-gemini-live基础用法参照 README.md 与 src/index.ts 中的示例一个最小可运行的会话如下import { GeminiLiveVoice } from mastra/voice-google-gemini-live; const voice new GeminiLiveVoice({ apiKey: process.env.GOOGLE_API_KEY, model: gemini-2.0-flash-live-001, speaker: Puck, }); // 连接 Live API await voice.connect(); // 订阅音频响应Int16Array 分片 voice.on(speaking, ({ audioData }) { playAudio(audioData); }); // 或订阅每个响应对应的拼接音频流便于管道播放 voice.on(speaker, audioStream { audioStream.pipe(playbackDevice); }); // 订阅转写role 区分说话人 voice.on(writing, ({ text, role }) { // role: user → 调用者的语音转写 // role: assistant → 模型语音回复的转写 console.log(${role}: ${text}); }); // 订阅文本转语音 await voice.speak(Hello from Mastra!); // 订阅麦克风流 const microphoneStream getMicrophoneStream(); await voice.send(microphoneStream); // 结束会话 voice.disconnect();配置形态兼容旧式与新式两种写法源码中的normalizeConfig()src/index.ts处理了两种配置形态的归一化旧式直传legacy把apiKey、model、speaker、instructions直接平铺在构造参数里MastraVoiceConfig范式推荐使用speechModelspeakerrealtimeConfig含model、apiKey与内部options。// 推荐写法 const voice new GeminiLiveVoice({ speechModel: { name: gemini-2.0-flash-live-001, apiKey: your-api-key }, speaker: Puck, realtimeConfig: { model: gemini-2.0-flash-live-001, apiKey: your-api-key, options: { instructions: You are a helpful assistant, debug: true, }, }, });需要特别注意的是speaker是VoiceConfig根级字段与realtimeConfig平级源码中对此做了显式传播处理src/index.ts确保new GeminiLiveVoice({ speaker: Puck, realtimeConfig: { ... } })的写法能够生效。0.12.0 的变更记录中专门修复过「speaker选项只在扁平配置形态下生效」的问题如今两种形态都已支持。事件模型写作、思考与打断的统一契约Gemini Live 包的实时事件定义在GeminiLiveEventMap见 src/types.ts。0.12.0 版本PR #17434是本包事件体系的一次重要演进它把原生音频模型的行为信号统一到了 Mastra 的跨 Provider 实时事件契约上与 OpenAI、xAI、Inworld、AWS Nova Sonic 等语音包保持一致。转写事件writingsetup 帧中无条件启用input_audio_transcription与output_audio_transcription见 src/index.ts使服务端持续返回双侧转写用户侧转写以writing事件、role: user发出数据源为serverContent.inputTranscription.text模型侧转写以writing事件、role: assistant发出数据源为serverContent.outputTranscription.text。voice.on(writing, ({ text, role }) { // role: user → 调用者的语音转写 // role: assistant → 模型语音回复的转写 });思考事件thinking原生音频native-audio模型有一个容易踩坑的语义差异在这些模型上serverContent.modelTurn.parts.text携带的是模型的内部推理chain-of-thought而不是语音回复——语音回复走独立的outputTranscription通道。为避免把推理文本误渲染成助手回复包引入了 Gemini 专属的thinking事件src/types.ts实现见 src/index.tsvoice.on(thinking, ({ text }) { // Gemini 原生音频模型上的内部推理文本 });非原生音频模型没有outputTranscription通道此时modelTurn.parts.text就是语音回复继续以writingrole: assistant发出thinking不会触发。源码用model.includes(native-audio)子串判断是否为原生音频模型isNativeAudioModel()src/index.ts该判断对未来遵循相同命名约定的新变体保持向前兼容。打断事件interrupt与活动处理setup 帧中设置了realtime_input_config.activity_handling START_OF_ACTIVITY_INTERRUPTSsrc/index.ts服务端在用户开口打断时会取消正在进行的模型响应并在serverContent.interrupted true中标记。包随之清理所有进行中的 speaker 流避免被取消的音频导致播放挂起清空累积的半截助手文本发出interrupt事件{ type: user, timestamp }与mastra/voice-aws-nova-sonic的形状一致。voice.on(interrupt, ({ type, timestamp }) { // 丢弃排队的 TTS 音频——用户已经插话 });音频事件speaking/speaker模型输出的音频分片以 base64 形式经audioStreamManager解码为 Int16Array 后按响应 ID 聚合到独立的PassThrough流通过speaker事件暴露便于.pipe()播放并受并发流数量上限 10、30 秒超时等约束管理见 src/managers/AudioStreamManager.ts同时以speaking事件逐片发出{ audio, audioData, sampleRate }以兼容旧用法sampleRate为输出采样率 24kHz。会话与用量事件session事件在连接生命周期内发出connecting / connected / disconnected / disconnecting / error / updated状态并在断连时附带code与reason字段0.14.0 起。此外还有toolCall、vad、usage输入/输出/总 token 数及模态、sessionHandle、sessionExpiring、turnComplete等事件可供消费。会话历史注入sendContext()实现文本与语音的无缝衔接sendContext()是 0.14.0 引入的重要新能力PR #18286。它允许在冷连接时把一个全新的语音会话「播种」上之前的对话历史且不会触发模型立即回答——模型会保持静默直到用户真正开口。使用方式await voice.connect(); // 重放之前对话的若干轮次可从 Mastra Memory 或任何外部存储读取 await voice.sendContext([ { role: user, content: What is the weather? }, { role: assistant, content: It is 72°F in San Francisco. }, ]); // 模型保持静默直到用户真正说话 await voice.send(micStream);底层实现源码 src/index.ts 将 turns 映射为单个 Gemini Liveclient_content帧role: assistant被转换为协议层的model角色turnComplete默认false可通过options.turnComplete覆盖从而静默加载上下文随后将轮次同步写入本地 ContextManager 历史。关键的协议前提history_configsendContext()能够开箱即用依赖于 0.14.0 的配套修复PR #18368在gemini-3.1-flash-live-preview及后续 3.x 模型上setup 帧必须包含history_config: { initial_history_in_client_content: true }否则服务端会以 WebSocket 1007 关闭连接。该包现在默认在 setup 帧带上此配置src/index.ts并通过GeminiSessionConfig.initialHistoryInClientContent提供显式退出开关默认true。这一机制让「同一线程的文本聊天与语音对话无缝衔接」成为现实——先在文本界面聊再切到语音时模型已具备完整上下文。工具调用Function Calling的完整演进工具调用是 Gemini Live 语音 Agent 的关键能力CHANGELOG 记录了该能力从损坏到健壮的完整演进过程。0.12.0从「静默忽略」到「正确执行」0.12.0修复 #17018 / #17019集中修复了四个工具相关问题工具注册失败对使用 discriminated unions、literal、nullable 类型的工具Gemini 注册时报1007 Unknown name错误。修复方式是sanitizeToolParameters对参数 schema 做 OpenAPI 3.0 兼容重写oneOf→anyOf、const→enum、可空anyOf折叠为typenullable: true。在 Mastra 侧这一职责由mastra/schema-compat的GoogleSchemaCompatLayer承担convertZodSchemaToJsonSchema()见 src/index.ts工具调用被静默忽略即使 setup 时注册了工具模型也不会发回 tool_call 帧。根因是 tools 的载荷形状不对——Gemini Live 期望单个tools条目其function_declarations数组承载全部工具而旧实现用每个工具一个条目、camelCase 键名的形状setup 能通过校验但运行时不出调用帧。源码sendInitialConfig()与updateSessionConfig()现在共用buildToolDeclarations()src/index.ts保证两种路径形状一致工具返回值的形状限制response是 Gemini Live 的 struct 字段而非 repeated 字段数组或原始类型的返回值会导致会话以1007 Unknown name response关闭。源码用isPlainObject()判断src/index.ts非纯对象一律包装为{ result }保证response恒为 struct——Date、Map、Set、Error及类实例均不会因裸传而丢失数据speaker 根级配置生效VoiceConfig根级的speaker现在会被正确读取。0.14.9调用去重与未注册工具的兜底回复0.14.9 又解决了两个实战中才会暴露的问题按 provider call id 去重PR #22985同一个 function call 可能同时通过serverContent.modelTurn.parts[].functionCall和顶层toolCall消息两种通道到达。包用processedToolCallIds集合容量上限 512见 src/index.ts按 call id 去重同一调用只执行一次、只发出一个toolResponse避免工具被运行两次。无 provider id 的调用使用新 UUID 且不会被抑制每次connect()时清空去重集合防止跨连接残留未注册工具名不再导致「静默死机」PR #23131当模型调用了一个未注册的工具时Gemini 会阻塞当前 turn直到该 batch 中每个functionCallid 都被回答。旧实现直接返回不回复导致模型永远不再说话挂断前的静默。现在包会先为该 id 发送一个带error字段的functionResponsesrc/index.ts同时发出tool_not_found错误事件模型得以继续对话。0.11.0工具执行签名统一0.11.0 随框架统一了工具执行签名原先根据执行上下文Agent / Workflow / MCP / 无上下文有 3 种调用形态现在统一为tool.execute(data, context)两参形式上下文信息agent、mcp、workflow等通过第二个参数按需解构Gemini Live 的工具执行路径同步迁移到该签名。注册工具的完整示例import { createTool } from mastra/core; import { z } from zod; const weatherTool createTool({ id: getWeather, description: Get the current weather for a location, inputSchema: z.object({ location: z.string().describe(The city and state, e.g. San Francisco, CA), }), execute: async inputData { // 调用天气 API ... return { message: 当前 ${inputData.location} 的温度是 72°F }; }, }); voice.addTools({ getWeather: weatherTool });addTools()src/index.ts把工具注册进运行时 registrylistTools()可查看当前工具集。Zod schema 会经GoogleSchemaCompatLayer转换为 Gemini 期望的 OpenAPI 3.0 Schema Object 子集。工具调用事件本身通过toolCall事件对外暴露{ name, args, id }便于上层自行编排执行逻辑。会话管理连接、恢复与时长监控连接与恢复resumeSession()connect()src/index.ts完成 WebSocket 建连、发送 setup 帧、等待服务端setupComplete30 秒超时等流程。连接端点取决于认证方式Gemini APIwss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1alpha.GenerativeService.BidiGenerateContent请求头携带x-goog-api-keyVertex AIwss://{location}-aiplatform.googleapis.com/ws/google.cloud.aiplatform.v1beta1.LlmBidiService/BidiGenerateContent请求头携带Authorization: Bearer token。会话恢复在 0.14.0 得到端到端修复PR #18190此前resumeSession()总是超时。现在新会话在 setup 帧中请求服务端下发的session_resumptiontoken服务端通过sessionResumptionUpdate.newHandle下发句柄并缓存、对外发出sessionHandle事件恢复时在 setup 帧的session_resumption.handle中携带正确句柄即可重连。resumeSession(handle, context?)还支持顺带恢复上下文历史src/index.ts。// 保存句柄例如持久化到存储 voice.on(sessionHandle, ({ handle, expiresAt }) { await store.save(handle, expiresAt); }); // 网络中断后恢复 await voice.resumeSession(savedHandle);默认模型与模型生命周期默认模型经历了多次变迁这是 CHANGELOG 中值得关注的一个运营性变化早期默认gemini-2.0-flash-exp0.12.0 起改为gemini-3.1-flash-live-previewGoogle 当前 Live API quickstart 模型因为gemini-2.0-flash-exp已于 2025-12-09 下线——未显式指定model的应用在旧默认下线后会连不上升级后恢复连接0.11.3 将一批模型加入GeminiVoiceModel类型并标注废弃新增GA/预览gemini-live-2.5-flash-native-audioGAgemini-live-2.5-flash-preview-native-audio-09-2025gemini-2.5-flash-native-audio-preview-12-2025gemini-2.5-flash-native-audio-preview-09-2025已废弃deprecatedgemini-2.0-flash-exp2025-12-09 下线gemini-2.0-flash-exp-image-generation2025-11-14 下线gemini-2.0-flash-live-0012025-12-09 下线gemini-live-2.5-flash-preview-native-audio改用-09-2025后缀版本gemini-2.5-flash-exp-native-audio-thinking-dialog2025-10-20 下线gemini-live-2.5-flash-preview2025-12-09 下线完整的模型联合类型定义在 src/types.ts。会话时长与上下文管理GeminiSessionConfigsrc/types.ts提供会话级配置配置项类型说明enableResumptionboolean启用会话恢复新会话请求服务端 tokeninitialHistoryInClientContentboolean允许通过client_content帧播种初始历史3.x 模型上sendContext()必需默认truemaxDurationstring最大会话时长如24h、2h、30mparseDuration()支持 h/m/s 单位contextCompressionboolean开启上下文压缩ContextManager 阈值压缩默认falsevad{ enabled, sensitivity, silenceDurationMs }VAD 开关、灵敏度默认 0.5、静音判定毫秒数默认 1000interrupts{ enabled, allowUserInterruption }打断开关与是否允许用户打断updateSessionConfig()src/index.ts支持会话进行中动态更新 speaker、instructions、tools、VAD、interrupts 与上下文压缩10 秒内等待服务端确认模型与认证类配置不允许热更新会给出告警日志。音频管线与配置细节音频默认参数定义在 src/managers/AudioStreamManager.ts输入采样率 16kHz输出采样率 24kHz编码pcm16单声道每块最大 32KBGemini 限制缓冲上限 50MB、最长音频 5 分钟并发 speaker 流上限 10、流超时 30 秒。输入音频支持NodeJS.ReadableStream逐 chunk 处理并发送realtime_input或Int16Array经validateAndConvertAudioInput校验后 base64 发送见send()src/index.ts。audioConfig可部分覆盖默认值。0.14.0 还修复了实时音频流被立即拒绝的问题音频帧改用当前 API 格式替换了会导致连接在首帧即被关闭的过期载荷形状。0.14.6 则修复了会话就绪等待在结束后未释放超时资源的问题避免定时器泄漏。认证与部署Gemini API 与 Vertex AIAPI Key 认证Gemini APIconst voice new GeminiLiveVoice({ apiKey: process.env.GOOGLE_API_KEY, model: gemini-3.1-flash-live-preview, });未提供apiKey且未开启vertexAI时构造器会抛出api_key_missing错误src/index.ts。Vertex AI 认证OAuth / 服务账号开启vertexAI: true时必须提供project否则抛出project_id_missing。认证由AuthManagersrc/managers/AuthManager.ts基于google-auth-library的GoogleAuth实现支持三种凭证来源ADCApplication Default Credentials不提供任何凭证文件时自动使用服务账号 Key 文件serviceAccountKeyFile指定 JSON 路径服务账号模拟serviceAccountEmail指定要模拟的账号。const voice new GeminiLiveVoice({ realtimeConfig: { model: gemini-3.1-flash-live-preview, options: { vertexAI: true, project: your-gcp-project, location: us-central1, // 默认 us-central1 serviceAccountKeyFile: /path/to/service-account.json, }, }, });访问令牌缓存 50 分钟Google token 通常 1 小时有效取安全余量过期自动刷新disconnect()时清空缓存。tokenExpirationTime可自定义缓存时长。稳定性与安全层面的演进要点CHANGELOG 还记录了若干值得关注的工程决策WebSocket 依赖升级0.14.3ws升级到 ^8.21.0修复了未初始化内存泄露GHSA-58qx-3vcg-4xpx与内存耗尽型 DoSGHSA-96hv-2xvq-fx4p两个安全公告供应链安全响应0.12.4针对 2026-06-17 的 easy-day-js 供应链事件发布补丁版本将latestdist-tag 前移替换声明了恶意依赖的受损版本包体积优化0.14.8从发布的 npm 文件清单中移除CHANGELOG.md减小包体积嵌入式文档0.11.0发布包在dist/docs/下内置SKILL.md、SOURCE_MAP.json与按功能组织的主题文档便于编码 Agent 直接读取node_modules理解框架架构解耦0.12.0共享语音原语与路由元数据迁移到internal/voice语音 Provider 不再直接依赖mastra/coremastra/core/voice仍保留 re-export 以向后兼容错误码体系GeminiLiveErrorCode枚举src/types.ts覆盖连接、认证、WebSocket、音频、转写、工具、会话等 17 类错误错误统一以{ message, code, details }事件形状对外发出。版本演进速览版本主题关键内容0.10.7初版将 Google Gemini Live API 集成进 Mastra 框架0.11.0框架对齐统一工具执行签名、Node 22.13.0、嵌入式文档、Vertex AI WebSocket 修复0.11.3模型管理新增 4 个模型、废弃 6 个模型并标注deprecated0.12.0原生音频信号默认启用双侧转写与打断检测thinking/interrupt事件工具注册与执行修复默认模型切换internal/voice解耦0.12.4供应链安全easy-day-js 事件补丁0.14.0会话能力新增sendContext()修复resumeSession()超时history_config支持 3.x 模型音频帧格式修复session事件带code/reason0.14.3安全ws升级至 ^8.21.00.14.6资源释放会话就绪等待释放超时资源google-auth-library升级0.14.8包体积npm 包移除 CHANGELOG、README 更新0.14.9工具健壮性按 provider call id 去重未注册工具返回 functionResponse 兜底结语mastra/voice-google-gemini-live的变更记录与源码共同勾勒出一个「实时语音集成包」从可用走向健壮的完整路径事件模型统一到跨 Provider 契约writing/thinking/interrupt、sendContext()打通文本与语音的上下文衔接、工具调用在去重与兜底层面达到生产可用、会话恢复端到端打通同时持续跟进模型生命周期与安全公告。对于要在 Mastra 中构建实时语音 Agent 的开发者建议优先使用gemini-3.1-flash-live-preview默认模型或原生音频系列模型开启sendContext()复用既有对话历史并订阅interrupt事件实现打断感知的播放队列——这些正是该包经过多轮迭代沉淀下来的最佳实践。【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考