본문으로 건너뛰기

Mastra의 음성 대 음성 기능

소개
소개에 대한 직접 링크

Mastra의 STS(Speech-to-Speech)는 여러 공급자 간의 실시간 상호 작용을 위한 표준화된 인터페이스를 제공합니다. STS는 실시간 Model의 이벤트를 청취하여 지속적인 양방향 오디오 통신을 가능하게 합니다. 별도의 TTS 및 STT 작업과 달리 STS는 양방향으로 지속적으로 음성을 처리하는 개방형 연결을 유지합니다.

구성
구성에 대한 직접 링크

  • apiKey: OpenAI API 키입니다. 로 다시 떨어진다OPENAI_API_KEY environment variable.
  • model: 실시간 음성 상호작용에 사용할 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의 음성 제공자에 대한 광범위한 개요는 다음을 참조하세요.Voice in Mastra.

실시간 세션에서 Tool 사용
실시간 세션에서 Tool 사용에 대한 직접 링크

실시간 음성 제공자는 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(),
})

실시간 이벤트 듣기
실시간 이벤트 듣기에 대한 직접 링크

실시간 음성 제공자는 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)
})

이벤트 이름과 페이로드는 공급자에 따라 다릅니다. 전체 이벤트 목록을 보려면 아래 공급자 섹션이나 공급자 참조를 확인하세요.

세션별 ​​음성 인스턴스
세션별 ​​음성 인스턴스에 대한 직접 링크

정적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나 지침을 추가하지 않습니다. 확인자 내부 또는 공급자에서 구성합니다.
  • 반환된 인스턴스 수명 주기를 소유하고 있으므로 다음을 호출하세요.disconnect() or close() when the session ends.

그만큼agent.voice getter에는 요청 컨텍스트가 없으므로 voice is a resolver. Use agent.getVoice({ requestContext }) instead.

Google Gemini 라이브(실시간)
Google Gemini 라이브(실시간)에 대한 직접 링크

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)

메모:

  • 라이브 API에는 다음이 필요합니다.GOOGLE_API_KEY. Vertex AI에는 프로젝트/위치와 서비스 계정 자격 증명이 필요합니다.
  • 이벤트:speaker (audio stream), writing (text), turnComplete, usage, and error.

AWS Nova Sonic(실시간)
AWS Nova Sonic(실시간)에 대한 직접 링크

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, and ap-northeast-1.
  • 표준 AWS 자격 증명 공급자 체인을 통해 인증합니다. 통과하다credentials to override.
  • 이벤트:speaking (Int16Array audio), writing (text with generationStage), toolCall, interrupt, turnComplete, usage, session, and error.

인월드 실시간
인월드 실시간에 대한 직접 링크

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은 클라이언트가 생성한 URL을 추가합니다.?key=...&protocol=realtime. The model is configured via the initial session.update, not in the URL.
  • Inworld의 유선 프로토콜은 OpenAI Realtime GA 사양이므로 이벤트 이름이 일치합니다.@mastra/voice-openai-realtime.
  • 입력된 Inworld 실시간 노브(MCP Tool 라우팅, 의미론적 VAD 열망, 재생 속도, 전사 Model, 출력 양식 등)는 다음을 통해 노출됩니다.session constructor field. An untyped providerData 이스케이프 해치도 새로운 Inworld 기능과의 향후 호환성을 위해 심층 병합됩니다.
  • 이벤트:speaker (PCM audio stream), speaking (audio Buffer per delta), writing (text), conversation.item.added, conversation.item.done, function_call.arguments, tool-call-start, tool-call-result, and error.