Azure.AI.VoiceLive (.NET)
Azure AI를 사용하여 양방향 음성 도우미를 구축하기 위한 실시간 음성 AI SDK입니다.
설치
dotnet add package Azure.AI.VoiceLive
dotnet add package Azure.Identity
dotnet add package NAudio
현재 버전: 안정화 v1.0.0, 미리보기 v1.1.0-beta.1
환경 변수
AZURE_VOICELIVE_ENDPOINT=https://<resource>.services.ai.azure.com/
AZURE_VOICELIVE_MODEL=gpt-4o-realtime-preview
AZURE_VOICELIVE_VOICE=en-US-AvaNeural
AZURE_VOICELIVE_API_KEY=<your-api-key>
AZURE_TOKEN_CREDENTIALS=prod
인증
Microsoft Entra 토큰 자격 증명
using Azure.Identity;
using Azure.AI.VoiceLive;
Uri endpoint = new Uri("https://your-resource.cognitiveservices.azure.com");
var credential = new DefaultAzureCredential(
DefaultAzureCredential.DefaultEnvironmentVariableName
);
VoiceLiveClient client = new VoiceLiveClient(endpoint, credential);
필수 역할: Cognitive Services User (Azure Portal → 액세스 제어에서 할당)
API 키
Uri endpoint = new Uri("https://your-resource.cognitiveservices.azure.com");
AzureKeyCredential credential = new AzureKeyCredential("your-api-key");
VoiceLiveClient client = new VoiceLiveClient(endpoint, credential);
클라이언트 계층 구조
VoiceLiveClient
└── VoiceLiveSession (WebSocket 연결)
├── ConfigureSessionAsync()
├── GetUpdatesAsync() → SessionUpdate 이벤트
├── AddItemAsync() → UserMessageItem, FunctionCallOutputItem
├── SendAudioAsync()
└── StartResponseAsync()
핵심 워크플로우
1. 세션 시작 및 구성
using Azure.Identity;
using Azure.AI.VoiceLive;
var endpoint = new Uri(Environment.GetEnvironmentVariable("AZURE_VOICELIVE_ENDPOINT"));
var client = new VoiceLiveClient(endpoint, new DefaultAzureCredential());
var model = "gpt-4o-mini-realtime-preview";
using VoiceLiveSession session = await client.StartSessionAsync(model);
VoiceLiveSessionOptions sessionOptions = new()
{
Model = model,
Instructions = "당신은 도움이 되는 AI 비서입니다. 자연스럽게 응답하세요.",
Voice = new AzureStandardVoice("en-US-AvaNeural"),
TurnDetection = new AzureSemanticVadTurnDetection()
{
Threshold = 0.5f,
PrefixPadding = TimeSpan.FromMilliseconds(300),
SilenceDuration = TimeSpan.FromMilliseconds(500)
},
InputAudioFormat = InputAudioFormat.Pcm16,
OutputAudioFormat = OutputAudioFormat.Pcm16
};
sessionOptions.Modalities.Clear();
sessionOptions.Modalities.Add(InteractionModality.Text);
sessionOptions.Modalities.Add(InteractionModality.Audio);
await session.ConfigureSessionAsync(sessionOptions);
2. 이벤트 처리
await foreach (SessionUpdate serverEvent in session.GetUpdatesAsync())
{
switch (serverEvent)
{
case SessionUpdateResponseAudioDelta audioDelta:
byte[] audioData = audioDelta.Delta.ToArray();
break;
case SessionUpdateResponseTextDelta textDelta:
Console.Write(textDelta.Delta);
break;
case SessionUpdateResponseFunctionCallArgumentsDone functionCall:
break;
case SessionUpdateError error:
Console.WriteLine($"오류: {error.Error.Message}");
break;
case SessionUpdateResponseDone:
Console.WriteLine("\n--- 응답 완료 ---");
break;
}
}
3. 사용자 메시지 보내기
await session.AddItemAsync(new UserMessageItem("안녕하세요, 도와주실 수 있나요?"));
await session.StartResponseAsync();
4. 함수 호출
var weatherFunction = new VoiceLiveFunctionDefinition("get_current_weather")
{
Description = "주어진 위치의 현재 날씨를 가져옵니다",
Parameters = BinaryData.FromString("""
{
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "도시와 주 또는 국가"
}
},
"required": ["location"]
}
""")
};
sessionOptions.Tools.Add(weatherFunction);
if (serverEvent is SessionUpdateResponseFunctionCallArgumentsDone functionCall)
{
if (functionCall.Name == "get_current_weather")
{
var parameters = JsonSerializer.Deserialize<Dictionary<string, string>>(functionCall.Arguments);
string location = parameters?["location"] ?? "";
string weatherInfo = $"{location}의 날씨는 맑음, 75°F입니다.";
await session.AddItemAsync(new FunctionCallOutputItem(functionCall.CallId, weatherInfo));
await session.StartResponseAsync();
}
}
음성 옵션
| 음성 유형 | 클래스 | 예시 |
|---|
| Azure 표준 | AzureStandardVoice | "en-US-AvaNeural" |
| Azure HD | AzureStandardVoice | "en-US-Ava:DragonHDLatestNeural" |
| Azure 사용자 지정 | AzureCustomVoice | 엔드포인트 ID를 사용한 사용자 지정 음성 |
지원 모델
| 모델 | 설명 |
|---|
gpt-4o-realtime-preview | 실시간 오디오 지원 GPT-4o |
gpt-4o-mini-realtime-preview | 경량, 빠른 상호작용 |
phi4-mm-realtime | 비용 효율적인 멀티모달 |
주요 유형 참조
| 유형 | 목적 |
|---|
VoiceLiveClient | 세션 생성을 위한 메인 클라이언트 |
VoiceLiveSession | 활성 WebSocket 세션 |
VoiceLiveSessionOptions | 세션 구성 |
AzureStandardVoice | 표준 Azure 음성 공급자 |
AzureSemanticVadTurnDetection | 음성 활동 감지 |
VoiceLiveFunctionDefinition | 함수 도구 정의 |
UserMessageItem | 사용자 텍스트 메시지 |
FunctionCallOutputItem | 함수 호출 응답 |
SessionUpdateResponseAudioDelta | 오디오 청크 이벤트 |
SessionUpdateResponseTextDelta | 텍스트 청크 이벤트 |
모범 사례
- 항상 두 가지 모달리티 설정 — 음성 도우미에는
Text와 Audio 포함
AzureSemanticVadTurnDetection 사용 — 자연스러운 대화 흐름 제공
- 적절한 침묵 시간 구성 — 일반적으로 500ms로 조기 종료 방지
using 문 사용 — 적절한 세션 해제 보장
- 모든 이벤트 유형 처리 — 오류, 오디오, 텍스트, 함수 호출 확인
- DefaultAzureCredential 사용 — API 키를 하드코딩하지 마세요
오류 처리
if (serverEvent is SessionUpdateError error)
{
if (error.Error.Message.Contains("Cancellation failed: no active response"))
{
}
else
{
Console.WriteLine($"오류: {error.Error.Message}");
}
}
오디오 구성
- 입력 형식:
InputAudioFormat.Pcm16 (16비트 PCM)
- 출력 형식:
OutputAudioFormat.Pcm16
- 샘플 레이트: 24kHz 권장
- 채널: 모노
관련 SDK
| SDK | 목적 | 설치 |
|---|
Azure.AI.VoiceLive | 실시간 음성 (이 SDK) | dotnet add package Azure.AI.VoiceLive |
Microsoft.CognitiveServices.Speech | 음성-텍스트, 텍스트-음성 | dotnet add package Microsoft.CognitiveServices.Speech |
NAudio | 오디오 캡처/재생 | dotnet add package NAudio |
참조 링크