news 2026/9/15 19:50:28

Mastra 集成 Mistral Voxtral 语音能力:@mastra/voice-mistral 的 TTS 与 STT 完整实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Mastra 集成 Mistral Voxtral 语音能力:@mastra/voice-mistral 的 TTS 与 STT 完整实战指南

Mastra 集成 Mistral Voxtral 语音能力:@mastra/voice-mistral 的 TTS 与 STT 完整实战指南

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

@mastra/voice-mistral是 Mastra 生态中基于 Mistral Voxtral 音频模型的语音 Provider,为 AI 应用提供文本转语音(TTS)与语音转文本(STT)能力。本文将带你掌握该包的安装、配置、MistralVoiceCompositeVoice的组合使用、speak()/listen()/getSpeakers()三大核心 API 的参数细节,并结合仓库源码剖析其底层实现与默认行为,使你能够直接在自己的 Mastra 应用中落地多模态语音交互。

包概览:一个 Provider,覆盖双向语音

@mastra/voice-mistral(源码位于 voice/mistral/src/index.ts)是对 Mistral Voxtral 系列音频模型的封装。它同时提供两条能力链路:

  • Text-to-Speech(TTS):通过speak()将文本(或文本流)合成为语音,支持一次性返回完整音频的缓冲模式,以及边合成边返回的流式模式,并支持 mp3、wav、pcm、flac、opus 五种输出格式与基于参考音频的一次性音色克隆;
  • Speech-to-Text(STT):通过listen()对音频流进行批量转写,支持说话人分离(diarization)、上下文偏置(context biasing)与时间戳粒度控制。

根据 voice/mistral/CHANGELOG.md 中的 0.1.0 版本记录,该 Provider 于该版本正式引入,其底层依赖为 Mistral 官方 Node SDK(voice/mistral/package.json 中声明@mistralai/mistralai^2.4.1),要求 Node.js 版本不低于 22.13.0。

安装

在项目中使用 pnpm、npm 或 yarn 安装即可:

npm install @mastra/voice-mistral

安装后,@mastra/voice-mistral对外默认导出MistralVoice类;它与核心包中@mastra/core/voice导出的CompositeVoiceMastraVoice抽象基类配合使用,构成 Mastra 语音体系的标准用法。

配置:API Key 与模型选型

使用前必须配置 Mistral API 凭据。MistralVoice的构造逻辑(见 voice/mistral/src/index.ts 的构造函数)遵循以下优先级:

  1. 构造参数中显式传入的speechModel.apiKey/listeningModel.apiKey
  2. 环境变量MISTRAL_API_KEY(源码中通过process.env.MISTRAL_API_KEY读取);
  3. 若两者皆无,构造函数会直接抛错,提示设置MISTRAL_API_KEY或在参数中传入apiKey

构造参数支持以下配置:

参数类型默认值说明
speechModel{ name?, apiKey? }{ name: 'voxtral-mini-tts-2603' }负责 TTS 的模型与独立 API Key
listeningModel{ name?, apiKey? }{ name: 'voxtral-mini-latest' }负责 STT 的模型与独立 API Key
speakerstring'en_paul_neutral'默认发音人 ID

注意:speechModellisteningModel的 API Key 是独立解析的,可以分别传入不同密钥(例如语音与转写走不同账号),各自缺失时会抛出针对性的错误信息。模型名也可以覆盖为其他 Voxtral 系列模型,例如voxtral-mini-tts-2603之外的 TTS 模型(源码类型MistralSpeechModel允许任意字符串扩展)。

最小初始化示例:

import { MistralVoice } from '@mastra/voice-mistral'; // 依赖环境变量 MISTRAL_API_KEY const voice = new MistralVoice(); // 显式指定模型与发音人 const voice = new MistralVoice({ speechModel: { name: 'voxtral-mini-tts-2603', apiKey: process.env.MISTRAL_SPEECH_KEY }, listeningModel: { name: 'voxtral-mini-latest', apiKey: process.env.MISTRAL_LISTEN_KEY }, speaker: 'en_paul_neutral', });

与 CompositeVoice 组合:单向能力也可成对使用

官方 README 推荐的用法是将输入(STT)与输出(TTS)组合到CompositeVoice中,这样上层语音 Agent 无需关心具体 Provider 的分工:

import { CompositeVoice } from '@mastra/core/voice'; import { MistralVoice } from '@mastra/voice-mistral'; const voice = new CompositeVoice({ input: new MistralVoice(), // Voxtral 负责 STT output: new MistralVoice(), // Voxtral 负责 TTS });

从 packages/_internals/voice/src/voice/composite-voice.ts 的实现可以看到CompositeVoice的路由机制:speak()委托给output(内部名为speakProvider),listen()委托给input(内部名为listenProvider),getSpeakers()走输出 Provider,getListener()走输入 Provider;当某一路 Provider 未配置时,会抛出带错误码的MastraError(如VOICE_COMPOSITE_NO_SPEAK_PROVIDER)。因此你完全可以只配置单向能力,例如仅把input设为MistralVoice做转写、把output留给其他 TTS Provider——CompositeVoice支持异构拼接。

文本转语音:speak() 全参数详解

speak()接受字符串或 Node.js 可读流作为输入(若传入流,源码会先将其完整读取为文本),并返回一个NodeJS.ReadableStream音频流。空文本输入会直接抛出Input text is empty错误。

参数说明

参数类型默认值说明
speakerstring构造时的speaker指定发音人 ID,覆盖构造默认值
responseFormat'pcm' \| 'wav' \| 'mp3' \| 'flac' \| 'opus'由服务端决定(测试默认写出 mp3)输出音频编码格式
refAudiostring参考音频数据,用于一次性音色克隆
model字符串voxtral-mini-tts-2603覆盖 TTS 模型
streambooleanfalse是否启用流式合成
其他任意键any透传给 Mistral SDK 的扩展参数

缓冲模式(默认)

未开启stream时,源码调用speechClient.audio.speech.complete({ stream: false }),将返回的 base64 音频数据解码为 Buffer,再通过PassThrough以流的形式返回。因此无论缓冲还是流式,调用方拿到的都是统一的ReadableStream接口:

const audioStream = await voice.speak('Hello from Mistral.'); const chunks: Buffer[] = []; for await (const chunk of audioStream) { chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)); } // chunks 即为完整音频二进制,可写入文件或直接播放

流式模式

设置stream: true后,底层会请求 Mistral 的流式接口,源码在 voice/mistral/src/index.ts 的speakStreaming()中遍历事件流,遇到speech.audio.delta事件即把其中的 base64 音频块解码后写入PassThrough,实现“边合成边输出”,适合低延迟交互场景(如语音 Agent 的逐句播报):

const stream = await voice.speak('Hello', { stream: true, responseFormat: 'pcm' });

流式场景下建议配合pcm等低延迟格式使用,这也是 voice/mistral/CHANGELOG.md 中给出的示例组合。

发音人查询与音色克隆

在调用speak()前,通常先通过getSpeakers()拉取 Mistral 预置发音人列表(源码调用audio.voices.list({ type: 'preset', limit: 100 })),返回数组元素包含voiceIdnamelanguagesgender字段:

const speakers = await voice.getSpeakers(); console.log(speakers[0].voiceId, speakers[0].name, speakers[0].languages); // 使用查到的发音人合成 const audio = await voice.speak('Hello with a preset voice.', { speaker: speakers[0]!.voiceId, });

若需要定制音色,可传入refAudio参考音频,实现一次性(one-off)音色克隆,无需预先注册声音档案。

语音转文本:listen() 全参数详解

listen()接收一个音频流,源码会先将其完整读入 Buffer,再以audio.{filetype ?? 'mp3'}的文件形式调用audio.transcriptions.complete(),返回转写后的文本字符串(Promise<string>)。

参数说明

参数类型默认值说明
languagestring转写语言代码,例如'en'
diarizeboolean是否开启说话人分离,区分不同发言者
contextBiasstring[]上下文偏置词表,提升专有名词/领域词汇识别率
timestampGranularities('segment' \| 'word')[]时间戳粒度:按片段或按单词
filetypestring'mp3'音频文件扩展名(决定 MIME 识别)
其他任意键any透传给 Mistral SDK 的扩展参数
// 先用 TTS 生成测试音频,再转写回来 const audioStream = await voice.speak('This is a transcription test.'); const text = await voice.listen(audioStream, { language: 'en' }); console.log(text);

getListener()用于向框架报告该 Provider 是否具备听写能力,Mistral 实现固定返回{ enabled: true },表明可作为语音输入的接收端。

源码级的支撑细节

理解以下三点,能帮助你更准确地使用与排查问题:

  1. 抽象基类契约MistralVoice继承自 packages/_internals/voice/src/voice/voice.ts 中的抽象类MastraVoice,后者定义了speak/listen/getSpeakers/getListener/updateConfig等统一接口,并持有speechModellisteningModelspeaker配置字段。所有 Mastra 语音 Provider 都遵循这一契约,因此可以在CompositeVoice中任意互换。
  2. 观测安全:基类的serializeForSpan()在生成追踪 Span 时会剥离apiKey,只保留模型名与 speaker 等非敏感信息,避免密钥随遥测数据泄露(见 packages/core/src/voice/voice-serialize-for-span.test.ts 的对应测试)。
  3. 依赖与运行环境:voice/mistral/package.json 声明engines.node >= 22.13.0,peerDependency 为zod ^3.25.0 || ^4.0.0,集成时需确保环境满足要求。

如何验证集成是否可用

仓库为MistralVoice提供了完整的集成测试(voice/mistral/src/index.test.ts),可作为自测脚本的参考骨架。测试覆盖:初始化默认参数、getSpeakers()返回非空发音人列表、speak()的默认合成/指定 speaker/文本流输入/responseFormat: 'wav'/stream: true五种路径、空文本抛错、listen()基础转写与language选项、getListener()返回{ enabled: true },以及未配置 API Key 时的抛错行为。你可以在本地运行:

# 在 voice/mistral 目录下 pnpm test

运行前需确保环境变量MISTRAL_API_KEY已设置(测试中的new MistralVoice()依赖它)。测试通过后会生成test-outputs/mistral-speech.mp3音频文件,可直接播放验证合成效果。

小结

@mastra/voice-mistral用最少的配置把 Mistral Voxtral 的双向语音能力接入 Mastra:new MistralVoice()即获得 TTS 与 STT,配合CompositeVoice可与其他语音 Provider 灵活拼装;speak()的流式模式与五种输出格式适合实时场景,refAudio支持音色克隆;listen()diarizecontextBiastimestampGranularities则覆盖了会议转写、多说话人分析等进阶需求。结合 voice/mistral/src/index.ts 源码与 voice/mistral/src/index.test.ts 测试,你可以快速完成从配置、合成、转写到验证的完整闭环。更多版本变更记录可查阅 voice/mistral/CHANGELOG.md。

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

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 19:49:47

RomM 前端 v2 组件体系指南:三层组件模型、约定与工程实践

RomM 前端 v2 组件体系指南&#xff1a;三层组件模型、约定与工程实践 【免费下载链接】romm A beautiful, powerful, self-hosted ROM manager and player. 项目地址: https://gitcode.com/GitHub_Trending/rom/romm 导读 RomM 是一个自托管的 ROM 管理器与游戏播放器…

作者头像 李华
网站建设 2026/9/15 19:49:42

微信小程序五子棋开发:从棋盘渲染到对局状态管理

简介&#xff1a;微信小程序双人五子棋项目实例&#xff0c;适合具备基础前端知识、想进阶小程序游戏开发的初学者与移动端爱好者。资源为完整可运行工程&#xff0c;解压后导入微信开发者工具即可直接体验双人对局。压缩包共10个文件&#xff0c;包含4个json配置文件&#xff…

作者头像 李华
网站建设 2026/9/15 19:47:46

湖南关键词优化排名推广避坑指南:新手建站不踩雷

湖南关键词优化排名推广避坑指南:新手建站不踩雷 不会代码想做网站?别急着找外包。很多湖南的中小企业老板或创业者,卡在第一步:想做个官网或商城,但不懂技术,怕被坑。这篇避坑指南,不讲虚的,只讲湖南本地做关键词优化排名推广时,新手最容易交智商税的地方。 一、 明确目标:别被“全站收录”忽悠…

作者头像 李华
网站建设 2026/9/15 19:45:31

用分数阶傅里叶变换(FRFT)实现chirp信号检测与参数估计

在雷达目标检测、水声通信、甚至是生物医学信号分析里&#xff0c;我经常碰到一类“频率随时间线性变化”的信号。这类信号叫chirp&#xff0c;也叫线性调频信号。直观说&#xff0c;它的瞬时频率是一条直线&#xff0c;要么往上扫、要么往下扫。问题在于&#xff0c;常规FFT一…

作者头像 李华