深入解读 @mastra/voice-deepgram:Mastra 语音集成包的完整使用指南与版本演进
2026/9/15 20:06:02 网站建设 项目流程

深入解读 @mastra/voice-deepgram:Mastra 语音集成包的完整使用指南与版本演进

【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra

本篇文章以 voice/deepgram/CHANGELOG.md 为骨架,结合@mastra/voice-deepgram包的 README、核心实现 与测试用例,系统讲解如何在 Mastra 框架中接入 Deepgram 的文本转语音(TTS)与语音转文本(STT)能力。读完本文,你将掌握DeepgramVoice的完整配置方式、说话人分离(speaker diarization)的实战用法、包内模型与音色清单,以及从版本变更记录中梳理出的架构演进、运行环境要求与安全修复要点。

一、包概览:一个类同时提供 TTS 与 STT

@mastra/voice-deepgram是 Mastra 官方维护的 Deepgram 语音集成包,当前仓库内版本为0.13.1(见 package.json)。它的定位非常明确:通过一个DeepgramVoice类同时提供两种能力:

  • 文本转语音(TTS):基于 Deepgram 的aura系列模型合成语音;
  • 语音转文本(STT):基于 Deepgram 的nova/whisper等系列模型做流式或预录制音频转录。

安装方式与任意 npm 包一致:

npm install @mastra/voice-deepgram

安装后,包会在node_modules中提供 ESM(dist/index.js)与 CJS(dist/index.cjs)双格式产物,TypeScript 声明文件为dist/index.d.ts。根据 package.json 的声明,该包要求zod@^3.25.0 || ^4.0.0作为 peer dependency,这一约束源于 changelog 中 0.11.0 版本“Bump zod peerdep to 3.25.0 to support both v3/v4”的调整——即同时兼容 zod v3 与 v4,方便与不同版本的 Mastra 项目共存。

二、快速上手:创建语音实例并完成一次“说话—听话”闭环

2.1 实例化与 API Key 处理

import { DeepgramVoice } from '@mastra/voice-deepgram'; const voice = new DeepgramVoice({ speechModel: { name: 'aura', // TTS 模型家族 apiKey: 'your-api-key', // 可选,缺省时读取 DEEPGRAM_API_KEY 环境变量 }, listeningModel: { name: 'nova', // STT 模型家族 apiKey: 'your-api-key', // 可选,缺省时读取 DEEPGRAM_API_KEY 环境变量 }, speaker: 'asteria-en', // 默认音色 ID,见 src/voices.ts });

从源码看,构造函数 的关键逻辑包括:

  • speechModellisteningModel未显式传apiKey时,会自动回退到process.env.DEEPGRAM_API_KEY
  • 如果三个来源(环境变量、speechModel.apiKeylisteningModel.apiKey)都没有 key,会直接抛出At least one of DEEPGRAM_API_KEY, speechModel.apiKey, or listeningModel.apiKey must be set错误;
  • speech 与 listening 各自维护独立的 Deepgram 客户端(createClient),允许为 TTS 和 STT 使用不同的 API Key;
  • 默认音色为asteria-en,默认 TTS 模型为aura,默认 STT 模型为nova

2.2 完整使用示例

// 1. 列出所有可用音色 const voices = await voice.getSpeakers(); // => [{ voiceId: 'asteria-en' }, { voiceId: 'luna-en' }, ...] // 2. 文本合成语音(默认音色) const audioStream = await voice.speak('Hello from Mastra!', { speaker: 'hera-en', // 按需覆盖音色 }); // 3. 语音转文本,并开启说话人分离 const result = await voice.listen(audioStream, { diarize: true, diarize_speaker_count: 2, }); console.log(result.transcript);

这段示例即 README 中的标准用法,它展示了本包“双模型 + 可覆盖音色 + 可选说话人分离”的完整工作流。

三、TTS 能力详解:speak 方法

3.1 方法签名与返回值

speak接受一个字符串(或可读流)作为输入,返回一个 Node.jsReadableStream(具体为PassThrough):

async speak( input: string | NodeJS.ReadableStream, options?: { speaker?: string; // 覆盖默认音色 [key: string]: any; // 其余参数透传给 Deepgram API }, ): Promise<NodeJS.ReadableStream>

3.2 底层行为(源码级)

从 index.ts 可以看到三个值得注意的实现细节:

  1. 输入归一化:若传入的是流,内部会先聚合成 Buffer 再转为 UTF-8 文本;空文本或纯空白文本会抛出Input text is empty错误;
  2. 模型名拼接:最终请求模型名由baseModel + '-' + speakerId拼接而成,例如默认aura+ 音色asteria-en会生成aura-asteria-en;若 speakerId 本身已带模型前缀则直接复用;
  3. Web Stream 转 Node Stream:Deepgram SDK 返回的是 Web Stream,包内通过getReader()逐块读取并写入PassThrough,同时做了完善的错误销毁(nodeStream.destroy(error))处理,避免流异常泄漏。

其余options(除speaker外)会原样透传给speakClient.request,因此你可以直接传入 Deepgram TTS 支持的参数(如encodingcontainersample_rate等)。

3.3 可用模型与音色清单

音色列表定义在 src/voices.ts,共 12 个英语音色:

音色 ID说明
asteria-en / luna-en / stella-enAura 家族基础音色
athena-en / hera-en / orion-en不同音质与语调选择
arcas-en / perseus-en / angus-en男声/中性音色选择
orpheus-en / helios-en / zeus-en更多合成音色

可用模型(DeepgramModel)为:aura(TTS)、whisperbaseenhancednovanova-2nova-3(STT),见 src/voices.ts。测试用例中即使用了aura(TTS)与whisper(STT)的组合(见 index.test.ts)。

四、STT 能力详解:listen 方法与说话人分离

4.1 方法签名与返回值

async listen( audioStream: NodeJS.ReadableStream, options?: { diarize?: boolean; // 是否开启说话人分离 [key: string]: any; // 其余参数透传给 Deepgram 转录 API }, ): Promise<any>

返回对象的结构随diarize是否开启而变化(源码注释见 index.ts):

字段说明是否依赖 diarize
transcript完整转录文本
words单词数组,含时间戳与置信度
rawDeepgram API 完整原始响应
speakerSegments{ word, speaker, start, end }数组,区分说话人

4.2 说话人分离(Diarization)是核心新特性

changelog 在0.12.0 版本(对应 PR #10206)明确记录:“Add speaker diarization support for STT”,并在0.12.0-beta.1中以feat(voice-deepgram)前缀标记。这是该包近几个版本中最具业务价值的能力更新。

从实现看,listen会把diarizediarize_speaker_count从透传参数中单独提取,前者作为布尔开关传给transcribeFile,后者(如果传了)用于提示 Deepgram 预设说话人数。开启后,包会遍历返回的alt.words,为每个词附加speaker编号并组装speakerSegments(见 index.ts)。

典型应用场景:会议纪要自动区分发言者、客服通话质检中定位坐席与客户的对话轮次、访谈内容的角色标注等。配合diarize_speaker_count可以进一步提高分离精度:

const result = await voice.listen(audioStream, { diarize: true, diarize_speaker_count: 2, // 明确告诉模型只有两个说话人 }); for (const seg of result.speakerSegments) { console.log(`[说话人 ${seg.speaker}] ${seg.word} (${seg.start}ms-${seg.end}ms)`); }

4.3 预录制音频转录

listen基于listeningClient.listen.prerecorded.transcribeFile实现,属于预录制(pre-recorded)转录路径:先把整个输入流聚合成 Buffer,再一次性提交给 Deepgram。测试中通过createReadStream读取__fixtures__/voice-test.m4a并显式传入filetype: 'm4a'完成转录(见 index.test.ts),说明处理m4a等非默认格式时需在 options 中补充filetype

五、从 Changelog 看包的架构演进

5.1 命名继承:从 @mastra/speech-deepgram 迁移而来

0.1.0 版本(2024 年)即记录:deprecate @mastra/speech-deepgram for @mastra/voice-deepgram,原包所有功能迁移到新命名下,导入路径统一更新为@mastra/voice-deepgram。这次更名是 Mastra 将“语音”能力统一收敛到MastraVoice抽象体系的一部分。

5.2 0.12.1:语音原语下沉到 @internal/voice

0.12.1 是一个重要的架构里程碑,changelog 记录:“Moved shared voice primitives and route metadata into the new@internal/voicepackage so voice providers no longer depend on@mastra/coreand server voice routes share the same route definitions”,同时说明@mastra/core/voice仍会继续 re-export 这些 API 以保持向后兼容。

这一点在源码中得到印证:DeepgramVoice类继承自@internal/voice包导出的MastraVoice基类(见 index.ts),而不再直接依赖@mastra/core。仓库中的packages/_internals/voice/src/voice/voice.tspackages/_internals/voice/src/routes/index.ts等文件即承载了共享语音原语与路由定义。带来的收益包括:

  • 解除核心包耦合:各语音 provider 不再被迫绑定@mastra/core的具体版本;
  • 路由统一:服务端语音相关路由(如/api/voice/...)在 provider 之间共享同一套定义;
  • 兼容性保障:通过@mastra/core/voice的 re-export,老代码无需改动即可继续使用。

5.3 0.12.0:运行环境要求收紧

0.12.0 版本同时带来两个重要的环境变更:

  • Node.js 最低版本提升至 22.13.0(PR #9706)。当前 package.json 中engines.node字段即">=22.13.0",使用低于该版本的 Node 运行时会收到引擎不兼容警告;
  • 移除基于 OpenTelemetry 的旧 tracing 代码(PR #9237),并同步将 peer dependency 对齐到@mastra/core@1.0.0的版本号体系。

5.4 0.12.0:随包发布内嵌文档

0.12.0 还引入了“embedded documentation”机制:Mastra 各包发布到 npm 时会携带dist/docs/目录,包含SKILL.md(包的用途与能力说明)、SOURCE_MAP.json(导出符号到类型/实现文件的机器可读索引)以及按功能域组织的 Topic 目录。这套机制让编码 Agent 与 AI 助手可以直接从node_modules读取文档来理解并调用本包。package.json 中的prepack脚本(tsx ../../scripts/generate-package-docs.ts)正是该文档生成流程的入口。

5.5 0.12.2:供应链安全修复

0.12.2 是一次安全补丁发布,changelog 记录其为 2026-06-17 “easy-day-js” 供应链事件的 remediation:发布干净版本并将latestdist-tag 前移,取代声明了恶意easy-day-js依赖的受影响版本。对于使用者而言,这意味着务必升级到 0.12.2 及以上版本,并留意安装日志中的依赖来源。

5.6 0.13.1:包体瘦身与文档更新

0.13.1 包含两项 Patch 变更:

  • 从发布到 npm 的产物中移除CHANGELOG.md,减小包体积(PR #22737);
  • 更新 README 以保证信息准确、与当前 API 一致(PR #22858)。

5.7 其他值得留意的变更

  • 0.10.2@deepgram/sdk^3.11.2升级到^3.13.0,当前 package.json 即锁定该依赖;
  • 0.10.7:修复 TypeScript 声明文件导入以保证 ESM 兼容;
  • 0.1.3:调整 CJS 打包,确保产物文件正确拆分;
  • 0.1.1:新增 CommonJS 支持;
  • 0.1.13:包启用 Elastic-2.0 许可(注:当前仓库该包 package.json 中license字段为 Apache-2.0,以实际安装版本为准)。

六、测试与验证:如何确认包行为符合预期

包内自带 Vitest 集成测试(index.test.ts),可运行:

cd voice/deepgram pnpm test

测试覆盖了以下关键行为:

  • getSpeakers能返回asteria-enstella-enluna-en等内置音色;
  • speak能生成非空音频文件(deepgram-speech-test.mp3),且支持覆盖 speaker 参数;
  • 空文本 / 纯空白文本 / 非法音色都会正确抛出错误;
  • listen能转录voice-test.m4afixture,非法音频会被拒绝。

这些用例直接印证了本文章前面描述的 API 契约与错误处理逻辑,可作为你自行验证时的参考基线(注意:真实转录需要有效的 Deepgram API Key)。

七、最佳实践与注意事项

  1. API Key 优先走环境变量DEEPGRAM_API_KEY一次配置,speech 与 listening 自动共享;需要拆分权限时再分别传入speechModel.apiKeylisteningModel.apiKey
  2. 多说话人场景务必开启 diarize:区分对话轮次是语音 Agent 走向真实业务的常用能力,diarize_speaker_count在说话人数已知时能显著提升稳定性;
  3. 注意运行环境:Node.js 需 ≥ 22.13.0,且需要zod ^3.25.0 || ^4.0.0peer dependency;
  4. 及时升级:0.12.2 包含供应链安全修复,低于该版本的安装应视为存在风险;
  5. 格式处理:转录m4a等格式时记得传filetype参数,见 index.test.ts;
  6. 流错误处理speak返回的流在底层已做错误销毁兜底,消费端仍建议监听error事件以避免未捕获异常。

八、结语

@mastra/voice-deepgram是一个麻雀虽小、五脏俱全的语音集成包:一个类完成 TTS/STT 双能力、支持说话人分离、模型与音色可自由组合,并在最近的版本中完成了与@internal/voice的解耦、Node 版本收紧与供应链安全修复。无论是构建带语音对话的 Agent、会议纪要应用还是客服质检系统,本文梳理的配置参数、API 契约与版本演进都能帮助你快速上手并规避踩坑点。

【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询