Mastra 的語音轉語音功能
簡介簡介 的直接連結
Mastra 的語音轉語音(STS)功能為跨多個 Provider 的即時互動提供標準化介面。 STS 透過監聽 Realtime 模型的事件,實現持續的雙向音訊通訊。與分開執行 TTS 和 STT 不同,STS 會保持連線開啟,持續處理雙向語音。
設定設定 的直接連結
apiKey:你的 OpenAI API 金鑰。如未提供,會改用OPENAI_API_KEY環境變數。model:用於即時語音互動的模型 ID(例如gpt-5.1-realtime)。speaker:語音合成的預設語音 ID。你可以指定語音輸出所使用的聲音。
const voice = new OpenAIRealtimeVoice({
apiKey: 'your-openai-api-key',
model: 'gpt-5.1-realtime',
speaker: 'alloy', // Default voice
})
// If using default settings the configuration can be simplified to:
const voice = new OpenAIRealtimeVoice()
使用 STS使用 STS 的直接連結
import { Agent } from '@mastra/core/agent'
import { OpenAIRealtimeVoice } from '@mastra/voice-openai-realtime'
import { playAudio, getMicrophoneStream } from '@mastra/node-audio'
const agent = new Agent({
id: 'agent',
name: 'OpenAI Realtime Agent',
instructions: `You are a helpful assistant with real-time voice capabilities.`,
model: 'openai/gpt-5.6-sol',
voice: new OpenAIRealtimeVoice(),
})
// Connect to the voice service
await agent.voice.connect()
// Listen for agent audio responses
agent.voice.on('speaker', ({ audio }) => {
playAudio(audio)
})
// Initiate the conversation
await agent.voice.speak('How can I help you today?')
// Send continuous audio from the microphone
const micStream = getMicrophoneStream()
await agent.voice.send(micStream)
如需 Agent 語音 Provider 的更全面概覽,請參閱 Mastra 的語音功能。
在即時工作階段中使用 Tool在即時工作階段中使用 Tool 的直接連結
即時語音 Provider 可以使用 Agent 上設定的 Tool。請將 Tool 加至 Agent 定義,然後連線並透過語音 Provider 傳送音訊:
import { Agent } from '@mastra/core/agent'
import { OpenAIRealtimeVoice } from '@mastra/voice-openai-realtime'
import { calculate, search } from '../tools'
export const agent = new Agent({
id: 'speech-to-speech-agent',
name: 'Speech-to-Speech Agent',
instructions: 'You are a helpful assistant with speech-to-speech capabilities.',
model: 'openai/gpt-5.6-sol',
tools: {
search,
calculate,
},
voice: new OpenAIRealtimeVoice(),
})
監聽即時事件監聽即時事件 的直接連結
即時語音 Provider 會發出事件,你可以利用這些事件更新 UI、播放助手音訊、記錄轉錄文字及處理錯誤:
agent.voice.on('speaking', ({ audio }) => {
playAudio(audio)
})
agent.voice.on('writing', ({ text, role }) => {
console.log(`${role}: ${text}`)
})
agent.voice.on('error', error => {
console.error('Voice error:', error)
})
事件名稱和資料內容因 Provider 而異。完整事件清單請參閱下方相應的 Provider 章節或 Provider 參考文件。
每個工作階段的語音實例每個工作階段的語音實例 的直接連結
靜態 voice 實例會由所有請求共用。這適用於單次文字轉語音,但即時及語音轉語音 Provider 會儲存工作階段狀態,例如 WebSocket 連線、Tool、指示及請求情境。如果一個 Agent 同時處理多個即時工作階段,共用實例可能會令某個工作階段覆寫另一個工作階段的狀態。
當每個即時工作階段都需要自己的語音實例時,請將 voice 設為解析器。Mastra 會在每次呼叫 getVoice() 時執行解析器,並為該請求情境傳回全新實例:
import { Agent } from '@mastra/core/agent'
import { RequestContext } from '@mastra/core/request-context'
import { OpenAIRealtimeVoice } from '@mastra/voice-openai-realtime'
export const agent = new Agent({
id: 'support-line',
name: 'Support Line',
instructions: ({ requestContext }) => `Help user ${requestContext.get('user')}.`,
model: 'openai/gpt-5.6-sol',
voice: ({ requestContext }) =>
new OpenAIRealtimeVoice({
apiKey: requestContext.get('apiKey'),
}),
})
const requestContext = new RequestContext()
requestContext.set('user', 'user-123')
requestContext.set('apiKey', process.env.OPENAI_API_KEY)
const voice = await agent.getVoice({ requestContext })
await voice.connect()
使用解析器時:
- 每次呼叫
getVoice()都會傳回新實例,因此並行工作階段不會共用狀態。 - Mastra 不會將 Tool 或指示加入解析器實例。請在解析器內或 Provider 上設定這些項目。
- 你需要自行管理所傳回實例的生命週期,因此請在工作階段結束時呼叫
disconnect()或close()。
agent.voice getter 沒有請求情境,因此當 voice 是解析器時會擲回錯誤。請改用 agent.getVoice({ requestContext })。
Google Gemini Live (Realtime)Google Gemini Live (Realtime) 的直接連結
import { Agent } from '@mastra/core/agent'
import { GeminiLiveVoice } from '@mastra/voice-google-gemini-live'
import { playAudio, getMicrophoneStream } from '@mastra/node-audio'
const agent = new Agent({
id: 'agent',
name: 'Gemini Live Agent',
instructions: 'You are a helpful assistant with real-time voice capabilities.',
// Model used for text generation; voice provider handles realtime audio
model: 'openai/gpt-5.6-sol',
voice: new GeminiLiveVoice({
apiKey: process.env.GOOGLE_API_KEY,
model: 'gemini-2.0-flash-exp',
speaker: 'Puck',
debug: true,
// Vertex AI option:
// vertexAI: true,
// project: 'your-gcp-project',
// location: 'us-central1',
// serviceAccountKeyFile: '/path/to/service-account.json',
}),
})
await agent.voice.connect()
agent.voice.on('speaker', ({ audio }) => {
playAudio(audio)
})
agent.voice.on('writing', ({ role, text }) => {
console.log(`${role}: ${text}`)
})
await agent.voice.speak('How can I help you today?')
const micStream = getMicrophoneStream()
await agent.voice.send(micStream)
注意:
- Live API 需要
GOOGLE_API_KEY。Vertex AI 需要項目、位置及服務帳戶憑證。 - 事件:
speaker(音訊串流)、writing(文字)、turnComplete、usage及error。
AWS Nova Sonic (Realtime)AWS Nova Sonic (Realtime) 的直接連結
import { Agent } from '@mastra/core/agent'
import { NovaSonicVoice } from '@mastra/voice-aws-nova-sonic'
import { playAudio, getMicrophoneStream } from '@mastra/node-audio'
const agent = new Agent({
id: 'agent',
name: 'Nova Sonic Agent',
instructions: 'You are a helpful assistant with real-time voice capabilities.',
// Model used for text generation; voice provider handles realtime audio
model: 'openai/gpt-5.6-sol',
voice: new NovaSonicVoice({
region: 'us-east-1',
speaker: 'matthew',
// Static credentials are optional. The default AWS credential provider
// chain is used when none are passed.
}),
})
await agent.voice.connect()
// Assistant audio is emitted as 16-bit PCM on the `speaking` event
agent.voice.on('speaking', ({ audioData }) => {
if (audioData) playAudio(audioData)
})
agent.voice.on('writing', ({ role, text }) => {
console.log(`${role}: ${text}`)
})
await agent.voice.speak('How can I help you today?')
const micStream = getMicrophoneStream()
await agent.voice.send(micStream)
注意:
- 可用區域:
us-east-1、us-west-2及ap-northeast-1。 - 透過標準 AWS 憑證 Provider 鏈進行驗證。傳入
credentials即可覆寫。 - 事件:
speaking(Int16Array 音訊)、writing(包含generationStage的文字)、toolCall、interrupt、turnComplete、usage、session及error。
Inworld RealtimeInworld Realtime 的直接連結
import { Agent } from '@mastra/core/agent'
import { InworldRealtimeVoice } from '@mastra/voice-inworld'
import { playAudio, getMicrophoneStream } from '@mastra/node-audio'
const agent = new Agent({
id: 'agent',
name: 'Inworld Realtime Agent',
instructions: 'You are a helpful assistant with real-time voice capabilities.',
// Model used for text generation; voice provider handles realtime audio
model: 'openai/gpt-5.6-sol',
voice: new InworldRealtimeVoice({
apiKey: process.env.INWORLD_API_KEY,
model: 'inworld/models/gemma-4-26b-a4b-it',
speaker: 'Sarah',
// Typed Inworld realtime knobs (semantic VAD, playback speed, etc.)
// session: {
// audio: {
// output: { speed: 1.1 },
// input: { turn_detection: { type: 'semantic_vad', eagerness: 'high' } },
// },
// },
}),
})
await agent.voice.connect()
agent.voice.on('speaker', stream => {
playAudio(stream)
})
agent.voice.on('writing', ({ role, text }) => {
console.log(`${role}: ${text}`)
})
await agent.voice.speak('How can I help you today?')
const micStream = getMicrophoneStream()
await agent.voice.send(micStream)
注意:
- 需要
INWORLD_API_KEY。Inworld API 金鑰已預先使用 Basic 編碼,請原樣貼上。 - WebSocket URL 會附加由用戶端產生的
?key=...&protocol=realtime。模型透過初始session.update設定,而不是在 URL 中設定。 - Inworld 的通訊協定採用 OpenAI Realtime GA 規格,因此事件名稱與
@mastra/voice-openai-realtime相符。 - 具類型的 Inworld 即時控制選項(MCP Tool 路由、語意 VAD 靈敏度、播放速度、轉錄模型、輸出模態等)透過
session建構函式欄位公開。另有未設定類型的providerData後備機制,系統亦會將它深層合併,以便向前兼容 Inworld 的新功能。 - 事件:
speaker(PCM 音訊串流)、speaking(每個 delta 的音訊 Buffer)、writing(文字)、conversation.item.added、conversation.item.done、function_call.arguments、tool-call-start、tool-call-result及error。