Voice Live API 提供自備模型 (BYOM) 功能,可讓您將自訂模型整合到語音互動工作流程中。 BYOM 適用於下列案例:
-
微調模型:使用你的自訂 Azure OpenAI 或 Azure Foundry 模型
-
任何未由 Voice Live 預先部署的 Foundry 模型:請使用 Foundry 模型目錄 中的模型,如 Anthropic Claude、Grok、 Fireworks 自訂權重,或模型 路由器 部署
-
佈建輸送量:使用您的 PTU (佈建輸送量單位) 部署來取得一致的效能
-
內容安全: 使用您的 LLM 應用定制的內容安全配置
這很重要
你可以將部署在 Azure Foundry 資源中的任何模型與 Voice Live API 整合。 若要使用來自其他 Foundry 資源的模型部署,請參見 資源覆寫。
驗證設定
使用 Voice Live API 的 Microsoft Entra ID 認證時,在 byom-azure-openai-chat-completion 或 byom-foundry-anthropic-messages 模式下,你需要為 Foundry 資源設定適當的權限。 由於權杖會在長時間工作階段中過期,因此 Foundry 資源的系統指派受控識別,需要能存取這些 BYOM 模式的模型部署。
請執行以下 Azure CLI 指令來設定必要的權限:
export subscription_id=<your-subscription-id>
export resource_group=<your-resource-group>
export foundry_resource=<your-foundry-resource>
# Enable system-assigned managed identity for the foundry resource
az cognitiveservices account identity assign --name ${foundry_resource} --resource-group ${resource_group} --subscription ${subscription_id}
# Get the system-assigned managed identity object ID
identity_principal_id=$(az cognitiveservices account show --name ${foundry_resource} --resource-group ${resource_group} --subscription ${subscription_id} --query "identity.principalId" -o tsv)
# Assign the Foundry User role to the system identity of the foundry resource
az role assignment create --assignee-object-id ${identity_principal_id} --role "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb" --scope /subscriptions/${subscription_id}/resourceGroups/${resource_group}/providers/Microsoft.CognitiveServices/accounts/${foundry_resource}
備註
由於 Foundry RBAC 角色最近被重新命名,請在程式碼中使用角色定義 ID(GUID)取代角色名稱,以避免在重新命名時出現問題:
-
Foundry 使用者:
53ca6127-db72-4b80-b1b0-d745d6d5456d
-
Foundry 擁有者:
c883944f-8b7b-4483-af10-35834be79c4a
-
Foundry 帳戶持有人:
e47c6f54-e4a2-4754-9501-8e0985b135e1
-
Foundry 專案管理者:
eadc314b-1a2d-4efa-be10-5d325db5065e
跨資源認證
當您使用資源覆寫時,無論您的驗證方式是 API 金鑰或 Microsoft Entra ID,都必須設有驗證設定。 您必須同時設定 Voice Live Foundry 資源與模型 Foundry 資源的權限。 執行以下指令來設定必要的權限:
export subscription_id_for_model=<your-subscription-id-for-model-resource>
export resource_group_for_model=<your-resource-group-for-model-resource>
export foundry_resource_for_model=<your-foundry-resource-for-model>
export subscription_id_for_voice_live=<your-subscription-id-for-voice-live-resource>
export resource_group_for_voice_live=<your-resource-group-for-voice-live-resource>
export foundry_resource_for_voice_live=<your-foundry-resource-for-voice-live>
# Enable system-assigned managed identity for the Voice Live Foundry resource
az cognitiveservices account identity assign \
--name ${foundry_resource_for_voice_live} \
--resource-group ${resource_group_for_voice_live} \
--subscription ${subscription_id_for_voice_live}
# Get the system-assigned managed identity object ID
# for the Voice Live resource
identity_principal_id=$(az cognitiveservices account show \
--name ${foundry_resource_for_voice_live} \
--resource-group ${resource_group_for_voice_live} \
--subscription ${subscription_id_for_voice_live} \
--query "identity.principalId" -o tsv)
# Assign the Foundry User role to the Voice Live resource's
# system identity on the model Foundry resource
az role assignment create \
--assignee-object-id ${identity_principal_id} \
--role "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb" \
--scope /subscriptions/${subscription_id_for_model}/resourceGroups/${resource_group_for_model}/providers/Microsoft.CognitiveServices/accounts/${foundry_resource_for_model}
選擇 BYOM 整合模式
語音直播 API 支援三種 BYOM 整合模式:
| Mode |
Description |
範例模型 |
byom-azure-openai-realtime |
Azure OpenAI 即時語音互動模型用於串流語音互動 |
gpt-realtime、gpt-realtime-mini |
byom-azure-openai-chat-completion |
Azure OpenAI 聊天完成模型用於文字互動。 也適用於其他 Foundry 型號 |
gpt-5.4、gpt-5.3-chat、grok-4 |
byom-foundry-anthropic-messages |
在 Azure Foundry 中部署的 Anthropic Claude 模型,使用 Messages API(預覽版) |
claude-sonnet-4.6、claude-haiku-4.5 |
備註
該 byom-foundry-anthropic-messages 模式目前仍在預覽階段。 預覽功能可能會有變動,且可用性可能有限。
整合 BYOM
更新 API 呼叫中的端點 URL,以包含您的 BYOM 設定:
wss://<your-foundry-resource>.services.ai.azure.com/voice-live/realtime?api-version=2026-04-10&profile=<your-byom-mode>&model=<your-model-deployment>
從 Foundry 門戶網站取得 <your-model-deployment> 值。 它對應於您在部署時為模型指定的名稱。
例如,要使用部署在 Azure Foundry 中的 Anthropic Claude 模型:
wss://<your-foundry-resource>.services.ai.azure.com/voice-live/realtime?api-version=2026-04-10&profile=byom-foundry-anthropic-messages&model=<your-claude-deployment-name>
若要從其他 Foundry 資源使用模型部署,請加入 foundry-resource-override 參數:
wss://<your-foundry-resource>.services.ai.azure.com/voice-live/realtime?api-version=2026-04-10&profile=<your-byom-mode>&model=<your-model-deployment>&foundry-resource-override=<foundry-resource>
這個 <foundry-resource> 值是沒有網域後綴的資源名稱。 例如,若 Foundry 資源端點為 https://my-foundry-resource.services.ai.azure.com,則使用 my-foundry-resource。
參考文件Package (PyPi) GitHub
使用 Python SDK 快速啟動碼 開始語音對話,並進行以下變更以啟用 BYOM:
在函式中 parse_arguments() ,新增 BYOM 設定檔類型的新引數:
parser.add_argument(
"--byom",
help="BYOM (Bring Your Own Model) profile type",
type=str,
choices=["byom-azure-openai-realtime", "byom-azure-openai-chat-completion", "byom-foundry-anthropic-messages"],
default=os.environ.get("VOICELIVE_BYOM_MODE", "byom-azure-openai-chat-completion"),
)
parser.add_argument(
"--foundry-resource-override",
help="Override the Foundry resource for cross-resource BYOM",
type=str,
default=os.environ.get("VOICELIVE_FOUNDRY_RESOURCE_OVERRIDE"),
)
在 main() 函數中,當建立語音助理時,新增 byom 欄位:
# Create and start voice assistant
assistant = BasicVoiceAssistant(
...
byom=args.byom,
foundry_resource_override=args.foundry_resource_override,
...
)
在類別 BasicVoiceAssistant 中,加入 byom 和 foundry_resource_override 欄位:
class BasicVoiceAssistant:
"""Basic voice assistant implementing the VoiceLive SDK patterns."""
def __init__(
self,
endpoint: str,
credential: Union[AzureKeyCredential, TokenCredential],
model: str,
voice: str,
instructions: str,
byom: Literal["byom-azure-openai-realtime", "byom-azure-openai-chat-completion", "byom-foundry-anthropic-messages"] | None = None,
foundry_resource_override: str | None = None
):
self.endpoint = endpoint
self.credential = credential
self.model = model
self.voice = voice
self.instructions = instructions
self.connection: Optional["VoiceLiveConnection"] = None
self.audio_processor: Optional[AudioProcessor] = None
self.session_ready = False
self.conversation_started = False
self.byom = byom
self.foundry_resource_override = foundry_resource_override
async def start(self):
"""Start the voice assistant session."""
try:
logger.info(f"Connecting to VoiceLive API with model {self.model}")
# Connect to VoiceLive WebSocket API
query_params = {"profile": self.byom} if self.byom else None
if query_params and self.foundry_resource_override:
query_params["foundry-resource-override"] = self.foundry_resource_override
async with connect(
endpoint=self.endpoint,
credential=self.credential,
model=self.model,
query=query_params
) as connection:
...
當您執行程式碼時,請指定 --byom 引數和 --model 引數,以指出您要使用的 BYOM 設定檔和模型部署。 例如:
python voice-live-quickstart.py --byom "byom-azure-openai-chat-completion" --model "your-model-name"
若要使用 Anthropic Claude 模型:
python voice-live-quickstart.py --byom "byom-foundry-anthropic-messages" --model "your-claude-deployment-name"
若要使用來自其他 Foundry 資源的模型,請加入 --foundry-resource-override 參數:
python voice-live-quickstart.py --byom "byom-azure-openai-chat-completion" --model "your-model-name" --foundry-resource-override "my-foundry-resource"
參考文件Package (NuGet) GitHub
使用 C# VoiceLive SDK 快速入門程式碼 開始語音交談,並進行下列變更以啟用 BYOM:
在檔案頂端新增 System.Web 和 System.Runtime.InteropServices using 陳述式:
using System.Web;
using System.Runtime.InteropServices;
在函數中 CreateRootCommand ,替換為以下程式碼以新增“byomOption”:
private static RootCommand CreateRootCommand()
{
var rootCommand = new RootCommand("Basic Voice Assistant using Azure VoiceLive SDK");
var apiKeyOption = new Option<string?>(
"--api-key",
"Azure VoiceLive API key. If not provided, will use AZURE_VOICELIVE_API_KEY environment variable.");
var endpointOption = new Option<string>(
"--endpoint",
() => "wss://api.voicelive.com/v1",
"Azure VoiceLive endpoint");
var modelOption = new Option<string>(
"--model",
() => "gpt-4o",
"VoiceLive model to use");
var byomOption = new Option<string>(
"--byom",
() => "byom-azure-openai-chat-completion",
"BYOM integration mode. Supported modes: byom-azure-openai-realtime, byom-azure-openai-chat-completion, byom-foundry-anthropic-messages");
var foundryResourceOverrideOption = new Option<string?>(
"--foundry-resource-override",
"Override the Foundry resource for cross-resource BYOM");
var voiceOption = new Option<string>(
"--voice",
() => "en-US-AvaNeural",
"Voice to use for the assistant");
var instructionsOption = new Option<string>(
"--instructions",
() => "You are a helpful AI assistant. Respond naturally and conversationally. Keep your responses concise but engaging. Always start the conversation in English.",
"System instructions for the AI assistant");
var useTokenCredentialOption = new Option<bool>(
"--use-token-credential",
"Use Azure token credential instead of API key");
var verboseOption = new Option<bool>(
"--verbose",
"Enable verbose logging");
rootCommand.AddOption(apiKeyOption);
rootCommand.AddOption(endpointOption);
rootCommand.AddOption(modelOption);
rootCommand.AddOption(byomOption);
rootCommand.AddOption(foundryResourceOverrideOption);
rootCommand.AddOption(voiceOption);
rootCommand.AddOption(instructionsOption);
rootCommand.AddOption(useTokenCredentialOption);
rootCommand.AddOption(verboseOption);
rootCommand.SetHandler(async (
string? apiKey,
string endpoint,
string model,
string byom,
string? foundryResourceOverride,
string voice,
string instructions,
bool useTokenCredential,
bool verbose) =>
{
await RunVoiceAssistantAsync(apiKey, endpoint, model, byom, foundryResourceOverride, voice, instructions, useTokenCredential, verbose).ConfigureAwait(false);
},
apiKeyOption,
endpointOption,
modelOption,
byomOption,
foundryResourceOverrideOption,
voiceOption,
instructionsOption,
useTokenCredentialOption,
verboseOption);
return rootCommand;
}
在函數 RunVoiceAssistantAsync中,新增「byom」參數和配置設定:
private static async Task RunVoiceAssistantAsync(
string? apiKey,
string endpoint,
string model,
string byom,
string? foundryResourceOverride,
string voice,
string instructions,
bool useTokenCredential,
bool verbose)
{
// Setup configuration
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true)
.AddEnvironmentVariables()
.Build();
// Override with command line values if provided
apiKey ??= configuration["VoiceLive:ApiKey"] ?? Environment.GetEnvironmentVariable("AZURE_VOICELIVE_API_KEY");
endpoint = configuration["VoiceLive:Endpoint"] ?? endpoint;
model = configuration["VoiceLive:Model"] ?? model;
byom = configuration["VoiceLive:Byom"] ?? byom;
foundryResourceOverride ??= configuration["VoiceLive:FoundryResourceOverride"];
voice = configuration["VoiceLive:Voice"] ?? voice;
instructions = configuration["VoiceLive:Instructions"] ?? instructions;
...
在函數 RunVoiceAssistantAsync 中,在建立用戶端之前,將BYOM設定檔引數附加至端點URL:
try
{
// Append BYOM profile parameter to the endpoint URL if provided
if (!string.IsNullOrEmpty(byom))
{
var uriBuilder = new UriBuilder(endpoint);
var query = HttpUtility.ParseQueryString(uriBuilder.Query);
query["profile"] = byom;
if (!string.IsNullOrEmpty(foundryResourceOverride))
{
query["foundry-resource-override"] = foundryResourceOverride;
}
uriBuilder.Query = query.ToString();
endpoint = uriBuilder.ToString();
logger.LogInformation("BYOM profile parameter added to endpoint: profile={Profile}", byom);
}
// Create client with appropriate credential
VoiceLiveClient client;
var endpointUri = new Uri(endpoint);
if (useTokenCredential)
{
var tokenCredential = new DefaultAzureCredential();
client = new VoiceLiveClient(endpointUri, tokenCredential, new VoiceLiveClientOptions());
logger.LogInformation("Using Azure token credential");
}
else
{
var keyCredential = new Azure.AzureKeyCredential(apiKey!);
client = new VoiceLiveClient(endpointUri, keyCredential, new VoiceLiveClientOptions());
logger.LogInformation("Using API key credential");
}
...
在功能 RunVoiceAssistantAsync中,將「byom」新增至語音助理設定:
...
// Create and start voice assistant
using var assistant = new BasicVoiceAssistant(
client,
model,
byom,
voice,
instructions,
loggerFactory);
...
在類別 BasicVoiceAssistant中,新增 _byom 欄位並更新建構函式:
public class BasicVoiceAssistant : IDisposable
{
private readonly VoiceLiveClient _client;
private readonly string _model;
private readonly string _byom;
private readonly string _voice;
private readonly string _instructions;
...
public BasicVoiceAssistant(
VoiceLiveClient client,
string model,
string byom,
string voice,
string instructions,
ILoggerFactory loggerFactory)
{
_client = client ?? throw new ArgumentNullException(nameof(client));
_model = model ?? throw new ArgumentNullException(nameof(model));
_byom = byom ?? throw new ArgumentNullException(nameof(byom));
_voice = voice ?? throw new ArgumentNullException(nameof(voice));
_instructions = instructions ?? throw new ArgumentNullException(nameof(instructions));
_loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
_logger = loggerFactory.CreateLogger<BasicVoiceAssistant>();
}
...
在函式 StartAsync 中,更新日誌記錄和工作階段啟動呼叫 (BYOM 設定檔已在端點中):
public async Task StartAsync(CancellationToken cancellationToken = default)
{
try
{
_logger.LogInformation("Connecting to VoiceLive API with model {Model} and BYOM mode {Byom}", _model, _byom);
// Start VoiceLive session (BYOM profile is already in the client endpoint)
_session = await _client.StartSessionAsync(_model, cancellationToken).ConfigureAwait(false);
...
當您執行程式碼時,請指定 --byom 引數和 --model 引數,以指出您要使用的 BYOM 設定檔和模型部署。 例如:
dotnet run --byom "byom-azure-openai-chat-completion" --model "your-model-name"
若要使用 Anthropic Claude 模型:
dotnet run --byom "byom-foundry-anthropic-messages" --model "your-claude-deployment-name"
若要使用來自其他 Foundry 資源的模型,請加入 --foundry-resource-override 參數:
dotnet run --byom "byom-azure-openai-chat-completion" --model "your-model-name" --foundry-resource-override "my-foundry-resource"
參考文件Package (Maven) GitHub
請使用 Java SDK 快速啟動碼 開始語音對話,並進行以下修改以啟用 BYOM:
在檔案頂端新增 java.net.URI and java.net.URISyntaxException import 的語句:
import java.net.URI;
import java.net.URISyntaxException;
在類別 Config 中,新增一個 byom 欄位並解析 --byom 命令列參數:
private static class Config {
String endpoint;
String apiKey;
String model = DEFAULT_MODEL;
String voice = DEFAULT_VOICE;
String instructions = DEFAULT_INSTRUCTIONS;
String byom = null;
boolean useTokenCredential = false;
static Config load(String[] args) {
Config config = new Config();
// 1. Load from application.properties first
Properties props = loadProperties();
if (props != null) {
config.endpoint = props.getProperty("azure.voicelive.endpoint");
config.apiKey = props.getProperty("azure.voicelive.api-key");
config.model = props.getProperty("azure.voicelive.model", DEFAULT_MODEL);
config.voice = props.getProperty("azure.voicelive.voice", DEFAULT_VOICE);
config.instructions = props.getProperty("azure.voicelive.instructions", DEFAULT_INSTRUCTIONS);
config.byom = props.getProperty("azure.voicelive.byom");
}
// 2. Override with environment variables if present
if (System.getenv(ENV_ENDPOINT) != null) {
config.endpoint = System.getenv(ENV_ENDPOINT);
}
if (System.getenv(ENV_API_KEY) != null) {
config.apiKey = System.getenv(ENV_API_KEY);
}
if (System.getenv("AZURE_VOICELIVE_MODEL") != null) {
config.model = System.getenv("AZURE_VOICELIVE_MODEL");
}
if (System.getenv("AZURE_VOICELIVE_VOICE") != null) {
config.voice = System.getenv("AZURE_VOICELIVE_VOICE");
}
if (System.getenv("AZURE_VOICELIVE_INSTRUCTIONS") != null) {
config.instructions = System.getenv("AZURE_VOICELIVE_INSTRUCTIONS");
}
if (System.getenv("VOICELIVE_BYOM_MODE") != null) {
config.byom = System.getenv("VOICELIVE_BYOM_MODE");
}
// 3. Parse command line arguments (highest priority)
for (int i = 0; i < args.length; i++) {
switch (args[i]) {
case "--endpoint":
if (i + 1 < args.length) config.endpoint = args[++i];
break;
case "--api-key":
if (i + 1 < args.length) config.apiKey = args[++i];
break;
case "--model":
if (i + 1 < args.length) config.model = args[++i];
break;
case "--voice":
if (i + 1 < args.length) config.voice = args[++i];
break;
case "--instructions":
if (i + 1 < args.length) config.instructions = args[++i];
break;
case "--byom":
if (i + 1 < args.length) config.byom = args[++i];
break;
case "--use-token-credential":
config.useTokenCredential = true;
break;
}
}
return config;
}
}
在此 runVoiceAssistantWithClient 方法中,在建立用戶端前,將 BYOM 設定檔查詢參數附加到端點 URL。 將這兩個 runVoiceAssistant 多載替換為可以處理端點修改的版本:
private static void runVoiceAssistant(Config config, KeyCredential credential) {
String endpoint = appendByomProfile(config.endpoint, config.byom);
System.out.println("Initializing VoiceLive client:");
System.out.println(" Endpoint: " + endpoint);
if (config.byom != null) {
System.out.println(" BYOM profile: " + config.byom);
}
VoiceLiveAsyncClient client = new VoiceLiveClientBuilder()
.endpoint(endpoint)
.credential(credential)
.serviceVersion(VoiceLiveServiceVersion.V2025_10_01)
.buildAsyncClient();
runVoiceAssistantWithClient(client, config);
}
private static void runVoiceAssistant(Config config, TokenCredential credential) {
String endpoint = appendByomProfile(config.endpoint, config.byom);
System.out.println("Initializing VoiceLive client:");
System.out.println(" Endpoint: " + endpoint);
if (config.byom != null) {
System.out.println(" BYOM profile: " + config.byom);
}
VoiceLiveAsyncClient client = new VoiceLiveClientBuilder()
.endpoint(endpoint)
.credential(credential)
.serviceVersion(VoiceLiveServiceVersion.V2025_10_01)
.buildAsyncClient();
runVoiceAssistantWithClient(client, config);
}
新增 appendByomProfile 一個輔助方法,將 BYOM 設定檔作為查詢參數附加到端點 URL:
private static String appendByomProfile(String endpoint, String byom) {
if (byom == null || byom.isEmpty()) {
return endpoint;
}
try {
URI uri = new URI(endpoint);
String existingQuery = uri.getQuery();
String newQuery = (existingQuery != null && !existingQuery.isEmpty())
? existingQuery + "&profile=" + byom
: "profile=" + byom;
URI newUri = new URI(
uri.getScheme(), uri.getAuthority(), uri.getPath(),
newQuery, uri.getFragment());
return newUri.toString();
} catch (URISyntaxException e) {
System.err.println("Failed to append BYOM profile to endpoint: "
+ e.getMessage());
return endpoint;
}
}
當您執行程式碼時,請指定 --byom 引數和 --model 引數,以指出您要使用的 BYOM 設定檔和模型部署。 例如:
mvn exec:java -Dexec.args="--byom byom-azure-openai-chat-completion --model your-model-name"
參考文件套件(npm)GitHub 上的額外範例
使用 JavaScript SDK 快速啟動程式碼 開始語音對話,並做出以下修改以啟用 BYOM:
在函數中 parseArguments() ,新增一個 --byom 參數:
const parsed = {
...
byom: process.env.VOICELIVE_BYOM_MODE ?? undefined,
...
};
for (let i = 0; i < argv.length; i++) {
const arg = argv[i];
switch (arg) {
...
case "--byom":
parsed.byom = argv[++i];
break;
...
}
}
在 main() 函式中,建立語音助理時傳遞 byom 值:
const assistant = new BasicModelVoiceAssistant({
...
byom: args.byom,
...
});
在類別 BasicModelVoiceAssistant 中,加入 byom 建構子中的欄位:
class BasicModelVoiceAssistant {
constructor(options) {
...
this.byom = options.byom;
...
}
...
在此 start() 方法中,在建立用戶端前,將 BYOM 設定檔查詢參數附加到端點網址後:
async start() {
let endpoint = this.endpoint;
// Append BYOM profile query parameter if provided
if (this.byom) {
const url = new URL(endpoint);
url.searchParams.set("profile", this.byom);
endpoint = url.toString();
console.log(`[init] BYOM profile added to endpoint: profile=${this.byom}`);
}
const client = new VoiceLiveClient(endpoint, this.credential);
const session = client.createSession({ model: this.model });
this._session = session;
...
當您執行程式碼時,請指定 --byom 引數和 --model 引數,以指出您要使用的 BYOM 設定檔和模型部署。 例如:
node model-quickstart.js --byom "byom-azure-openai-chat-completion" --model "your-model-name"
備註
使用byom-foundry-anthropic-messages模式時,usage中的response.done事件欄位只包含語音標記用量(用於語音識別和文字轉語音)。 Anthropic 模型中的 LLM 代幣使用情況會分別在回應元資料中報告。
資源覆寫
預設情況下,Voice Live API 在與 Voice Live 服務相同的 Foundry 資源中使用 LLM 部署。 如果你的模型部署在不同的 Foundry 資源中,請指定 foundry-resource-override 查詢參數將 API 導向到正確的資源。 這支援跨區域情境,當語音直播服務與模型部署位於不同區域時。
這個 foundry-resource-override 值是沒有網域後綴的資源名稱。 例如,若 Foundry 資源端點為 https://my-foundry-resource.services.ai.azure.com,則使用 my-foundry-resource。
請參閱 整合 BYOM 章節中的每個分頁以了解實作細節。
這很重要
使用資源覆寫時,無論你的認證方式(API 金鑰或 Microsoft Entra ID),都必須設定 跨資源認證。
相關內容