JavaScript 的 Azure VoiceLive 客户端库
Azure VoiceLive是一种管理服务,它能为语音代理提供低纬度,高质的语音对语音互动. 该服务将语音识别,基因AI,和文本对语音功能整合为单一,统一的界面,为创建无缝语音驱动体验提供端到端解决方案.
使用客户端库 :
- 创建实时语音助理和对话代理
- 用最小的空闲度构建语音对语音应用程序
- 整合噪音抑制和回声取消等高级对话特征
- 利用多种AI模型(GPT-Realtime,GPT-Realtime-Mini,Phi)用于不同的使用案例
- 实施功能调用和工具集成,以进行动态响应
- 创建可视化的语音交互
注意:此软件包支持浏览器和Node.js环境. WebSocket连接用于实时通信.
开始
目前得到支持的环境
- 节点.js的LTS版本
- Safari、Chrome、Edge和Firefox的最新版本
先决条件
- 一个 Azure 订阅
- 一个 Azure AI 创始资源 有语音 Live API 访问
安装软件包
使用 npm 安装 Azure VoiceLive 客户端库 :
npm install @azure/ai-voicelive
安装身份库
VoiceLive客户端通过Azure身份图书馆认证. 安装它:
npm install @azure/identity
配置类型脚本
TypeScript 用户需要安装节点类型定义 :
npm install @types/node
您还需要启用 compilerOptions.allowSyntheticDefaultImports 在你的Tsconfig.json中。 请注意, 如果您已启用 compilerOptions.esModuleInterop, (中文(简体) ), allowSyntheticDefaultImports 默认启用.
Java 脚本套装
要在浏览器中使用此客户端库,首先需要使用捆绑器. 关于如何做到这一点的详情,请参见我们 捆绑文件。 。 。 .
关键概念
语音流线
用于建立与Azure VoiceLive服务连接的主要接口. 使用此客户端认证并创建会话用于实时语音交互.
语音会议
代表了用于实时语音通信的活跃的WebSocket连接. 此类处理双向通信,允许您发送音频输入并接收音频输出,文本转录等实时事件.
会话配置
该服务使用会话配置来控制语音交互的各个方面:
- 旋转检测: 配置用户开始和停止发言时服务如何检测
- 音频处理: 启用噪声抑制和回声取消
- 语音选择: 从标准 Azure 声音、自定义声音、 avatar- sync 声音或预览 Azure 实时本地声音
- 模式选择: 选择最适合您需要的AI模式( GPT- Realtime, GPT- Realtime- Mini, Azure- Realtime, Phi 变体)
模型和能力
VoiceLive API支持多个具有不同能力的AI模型:
| 型号 | 说明 | 使用大小写 |
|---|---|---|
gpt-realtime | 实时音频处理模式 | 高质量对话AI |
gpt-realtime-mini | 轻型实时模型 | 快速有效的互动 |
azure-realtime | Azure- 本地实时模型 | 土著声音和WebRTC方案 |
phi4-mm-realtime | 支持多式联运的Phi模式 | 成本效益高的语音应用程序 |
对话增强
VoiceLive API提供Azure特定增强:
- Azure语义VAD: 删除填充词的高级语音活动检测
- 消除噪音:减少环境背景噪音
- 回声取消: 从模型本身的声音中删除回声
- 最终检测: 允许自然暂停而不过早中断
会话模式
VoiceLive 支持两种不同的创建会话模式:
模型模式( LLM 为主要演员)
在模型模式中,LLM模型是主要AI演员. 您指定一个模型名称, 并选择配置函数或 MCP 服务器等工具 .
import { DefaultAzureCredential } from "@azure/identity";
import { VoiceLiveClient } from "@azure/ai-voicelive";
const credential = new DefaultAzureCredential();
const endpoint = "https://your-resource.cognitiveservices.azure.com";
const client = new VoiceLiveClient(endpoint, credential);
// Model mode - LLM is the main actor
const session = await client.startSession("gpt-realtime");
代理模式( 代理为主代理)
在代理模式中,铸币局的代理是主要AI演员. 代理的配置(工具,指令,温度)在Azure AI Foundary门户网站中进行管理,而不是会话代码. 这是理想的:
- 允许语音的现有文本代理
- 应集中管理代理配置的情景
- 没有运行时间配置的简化集成
import { DefaultAzureCredential } from "@azure/identity";
import { VoiceLiveClient } from "@azure/ai-voicelive";
const credential = new DefaultAzureCredential();
const endpoint = "https://your-resource.cognitiveservices.azure.com";
const client = new VoiceLiveClient(endpoint, credential);
// Agent mode - Foundry agent is the main actor
const session = await client.startSession({
agent: {
agentName: "my-agent",
projectName: "my-foundry-project",
},
});
正在使用 Azure 活动目录认证
VoiceLive服务依赖Azure Active Directory来验证其API的请求. 这个 @azure/identity 软件包提供了各种证书类型,应用程序可用来做到这一点。 这个 读取 @azure/identity 提供更多细节和样本来启动.
为了与Azure VoiceLive服务互动,您需要创建实例 VoiceLiveClient 类, a 服务端点 和证书对象。 本文档中显示的示例使用命名为证书对象 DefaultAzureCredential,适用于大多数情景,包括当地发展和生产环境。 我们建议使用 管理身份 用于生产环境中的认证.
您可以在数据库中找到更多关于不同认证方式及其相应的证书类型的信息 Azure 身份证件。 。 。 .
这里有一个简单的例子。 第一,导入 DefaultAzureCredential 财务报告和审定财务报表 VoiceLiveClient数字 :
import { DefaultAzureCredential } from "@azure/identity";
import { VoiceLiveClient } from "@azure/ai-voicelive";
const credential = new DefaultAzureCredential();
// Build the URL to reach your AI Foundry resource
const endpoint = "https://your-resource.cognitiveservices.azure.com";
// Create the VoiceLive client
const client = new VoiceLiveClient(endpoint, credential);
使用 API 密钥进行认证
对于开发情景,您也可以使用 API 密钥进行认证 :
import { AzureKeyCredential } from "@azure/core-auth";
import { VoiceLiveClient } from "@azure/ai-voicelive";
const endpoint = "https://your-resource.cognitiveservices.azure.com";
const credential = new AzureKeyCredential("your-api-key");
const client = new VoiceLiveClient(endpoint, credential);
实例
以下各节提供代码片段,以使用Azure VoiceLive来覆盖一些常见的任务. 本文涵盖的情景包括:
创建基本的语音助理
这个例子显示了如何创建一个简单的语音助手,可以处理语音对语音的交互:
import { DefaultAzureCredential } from "@azure/identity";
import { VoiceLiveClient } from "@azure/ai-voicelive";
const credential = new DefaultAzureCredential();
const endpoint = "https://your-resource.cognitiveservices.azure.com";
// Create the client
const client = new VoiceLiveClient(endpoint, credential);
// Create and connect a session
const session = await client.startSession("gpt-realtime-mini");
// Configure session for voice conversation
await session.updateSession({
modalities: ["text", "audio"],
instructions: "You are a helpful AI assistant. Respond naturally and conversationally.",
voice: {
type: "azure-standard",
name: "en-US-AvaNeural",
},
turnDetection: {
type: "server_vad",
threshold: 0.5,
prefixPaddingInMs: 300,
silenceDurationInMs: 500,
},
inputAudioFormat: "pcm16",
outputAudioFormat: "pcm16",
});
创建代理驱动语音助理
这个例子说明了如何创建由创始人代理的语音助理. 在代理模式中,代理的配置在Azure AI Foundary门户网站中管理:
import { DefaultAzureCredential } from "@azure/identity";
import { VoiceLiveClient } from "@azure/ai-voicelive";
const credential = new DefaultAzureCredential();
const endpoint = "https://your-resource.cognitiveservices.azure.com";
// Create the client
const client = new VoiceLiveClient(endpoint, credential);
// Create and connect a session with an agent as the main actor
const session = await client.startSession({
agent: {
agentName: "your-agent-name",
projectName: "your-foundry-project",
},
});
// Subscribe to events - audio settings can still be configured
const subscription = session.subscribe({
onResponseAudioDelta: async (event, context) => {
// Handle audio from the agent
playAudioChunk(event.delta);
},
onResponseTextDelta: async (event, context) => {
console.log("Agent:", event.delta);
},
});
// Send audio data from microphone
function sendAudioChunk(audioBuffer: ArrayBuffer) {
session.sendAudio(audioBuffer);
}
配置会话选项
您可以自定义语音互动的各个方面 :
import { DefaultAzureCredential } from "@azure/identity";
import { VoiceLiveClient } from "@azure/ai-voicelive";
const credential = new DefaultAzureCredential();
const endpoint = "https://your-resource.cognitiveservices.azure.com";
const client = new VoiceLiveClient(endpoint, credential);
const session = await client.startSession("gpt-realtime");
// Advanced session configuration
await session.updateSession({
modalities: ["audio", "text"],
instructions: "You are a customer service representative. Be helpful and professional.",
voice: {
type: "azure-custom",
name: "your-custom-voice-name",
endpointId: "your-custom-voice-endpoint",
},
turnDetection: {
type: "server_vad",
threshold: 0.6,
prefixPaddingInMs: 200,
silenceDurationInMs: 300,
},
inputAudioFormat: "pcm16",
outputAudioFormat: "pcm16",
});
预览本地声音 azure-realtime 模式,使用专用语音类型:
import { DefaultAzureCredential } from "@azure/identity";
import { VoiceLiveClient } from "@azure/ai-voicelive";
const credential = new DefaultAzureCredential();
const endpoint = "https://your-resource.cognitiveservices.azure.com";
const client = new VoiceLiveClient(endpoint, credential);
const session = await client.startSession("azure-realtime");
await session.updateSession({
voice: {
type: "azure-realtime-native",
name: "ava",
},
});
文本输入流
与其发送音频,不如将文本逐步流入对话项目 input_text.delta 事件并用单个结束 input_text.done 活动。 当文本本身被逐一生成时(例如,从另一个模型中传输),这一点是有用的:
import { DefaultAzureCredential } from "@azure/identity";
import { VoiceLiveClient } from "@azure/ai-voicelive";
const credential = new DefaultAzureCredential();
const endpoint = "https://your-resource.cognitiveservices.azure.com";
const client = new VoiceLiveClient(endpoint, credential);
const session = await client.startSession("gpt-realtime-mini");
// Create the conversation item that the streamed text is appended to
const itemId = "user-message-1";
await session.addConversationItem({
type: "message",
role: "user",
id: itemId,
content: [{ type: "input_text", text: "" }],
});
// Stream the text in chunks as `input_text.delta` events
for (const chunk of ["Tell me ", "a fun fact ", "about the ocean."]) {
await session.sendEvent({
type: "input_text.delta",
id: itemId,
delta: chunk,
});
}
// Signal that the streamed text is complete with a single `input_text.done` event
await session.sendEvent({
type: "input_text.done",
id: itemId,
});
// Ask the model to respond to the streamed text
await session.sendEvent({ type: "response.create" });
处理实时事件
VoiceLive客户端提供事件驱动的实时交互通信:
import { DefaultAzureCredential } from "@azure/identity";
import { VoiceLiveClient } from "@azure/ai-voicelive";
const credential = new DefaultAzureCredential();
const endpoint = "https://your-resource.cognitiveservices.azure.com";
const client = new VoiceLiveClient(endpoint, credential);
const session = await client.startSession("gpt-realtime-mini");
// Set up event handlers using subscription pattern
const subscription = session.subscribe({
onResponseAudioDelta: async (event, context) => {
// Handle incoming audio chunks
const audioData = event.delta;
// Play audio using Web Audio API or other audio system
playAudioChunk(audioData);
},
onResponseTextDelta: async (event, context) => {
// Handle incoming text deltas
console.log("Assistant:", event.delta);
},
onConversationItemInputAudioTranscriptionCompleted: async (event, context) => {
// Handle user speech transcription
console.log("User said:", event.transcript);
},
});
// Send audio data from microphone
function sendAudioChunk(audioBuffer: ArrayBuffer) {
session.sendAudio(audioBuffer);
}
执行函数调用
允许您的语音助理调用外部函数和工具 :
import { DefaultAzureCredential } from "@azure/identity";
import { VoiceLiveClient } from "@azure/ai-voicelive";
const credential = new DefaultAzureCredential();
const endpoint = "https://your-resource.cognitiveservices.azure.com";
const client = new VoiceLiveClient(endpoint, credential);
const session = await client.startSession("gpt-realtime-mini");
// Define available functions
const tools = [
{
type: "function",
name: "get_weather",
description: "Get current weather for a location",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "The city and state or country",
},
},
required: ["location"],
},
},
];
// Configure session with tools
await session.updateSession({
modalities: ["audio", "text"],
instructions:
"You can help users with weather information. Use the get_weather function when needed.",
tools: tools,
toolChoice: "auto",
});
// Handle function calls
const subscription = session.subscribe({
onResponseFunctionCallArgumentsDone: async (event, context) => {
if (event.name === "get_weather") {
const args = JSON.parse(event.arguments);
const weatherData = await getWeatherData(args.location);
// Send function result back
await session.addConversationItem({
type: "function_call_output",
callId: event.callId,
output: JSON.stringify(weatherData),
});
// Request response generation
await session.sendEvent({
type: "response.create",
});
}
},
});
解决问题
常见错误和例外
认证错误: 如果您收到认证错误, 请确认:
- 您的 Azure AI 创建资源配置正确
- 您的 API 密钥或证书拥有必要的权限
- 端点 URL 正确且可访问
WebSocket 连接问题:VoiceLive使用WebSocket连接. 确保:
- 您的网络允许 WebSocket 连接
- 防火墙规则允许连接到
*.cognitiveservices.azure.com - 浏览器政策允许WebSocket和麦克风访问(用于浏览器使用)
音频问题: 与音频有关的问题:
- 检查浏览器中的麦克风权限
- 检查支持音频格式( PCM16, PCM24)
- 确保为播放设置适当的音频上下文
遥测/分布式追踪
语音Live SDK 支持 分布式追踪 通过 @azure/core-tracing 软件包。 追踪是 默认无操作 ——除非您通过注册一个与 OpenTeleometry 兼容的追踪提供者来选择,否则不会创建跨度 .
如何运作
当跟踪被启用时, SDK 自动为会话生命周期创建跨度 :
connect (parent span — open for the entire session lifetime)
├── send session.update
├── send conversation.item.create
├── send response.create
├── recv session.created
├── recv response.done ← turn count incremented, token usage recorded
├── send response.cancel ← interruption count incremented
├── recv error ← error event recorded
└── close ← session-level counters finalized
扩展属性跟随 OpenTeleometry GenAI 语义常规 (单位:千美元)gen_ai.system, (中文(简体) ), gen_ai.operation.name, (中文(简体) ), gen_ai.request.model等)外加"VoiceLive"特有外延(英语:gen_ai.voice.session_id, (中文(简体) ), gen_ai.voice.turn_count, (中文(简体) ), gen_ai.voice.audio_bytes_sent。)会话级衡量标准汇总到 connect 当会话结束.
启用追踪(Node.js, CommunityJS——建议)
对于普通JS应用程序,使用标准Azure SDK仪器桥:
npm install @azure/opentelemetry-instrumentation-azure-sdk @opentelemetry/instrumentation @opentelemetry/sdk-trace-node
const {
NodeTracerProvider,
SimpleSpanProcessor,
ConsoleSpanExporter,
} = require("@opentelemetry/sdk-trace-node");
const { registerInstrumentations } = require("@opentelemetry/instrumentation");
const { createAzureSdkInstrumentation } = require("@azure/opentelemetry-instrumentation-azure-sdk");
// 1. Configure an OpenTelemetry tracer provider
const provider = new NodeTracerProvider({
spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())],
});
provider.register();
// 2. Register the Azure SDK instrumentation BEFORE requiring @azure/ai-voicelive
registerInstrumentations({
instrumentations: [createAzureSdkInstrumentation()],
});
// 3. Use VoiceLive — spans are emitted automatically
const { VoiceLiveClient } = require("@azure/ai-voicelive");
const { DefaultAzureCredential } = require("@azure/identity");
const client = new VoiceLiveClient(endpoint, new DefaultAzureCredential());
const session = client.createSession("gpt-realtime");
await session.connect(); // creates "connect" span
启用跟踪(节点.js 无害环境管理和浏览器)
createAzureSdkInstrumentation 依赖CommonJS需要-hoks,当SDK被装入作为无害环境管理(即:. "type": "module" 软件包或Vite等浏览器捆绑器。 对于这些环境,登记最低 Instrumenter 直接通过 useInstrumenter 从 @azure/core-tracing数字 :
import { useInstrumenter } from "@azure/core-tracing";
import { trace, context } from "@opentelemetry/api";
useInstrumenter({
startSpan(name, spanOptions) {
const ctx = spanOptions.tracingContext ?? context.active();
const tracer = trace.getTracer(spanOptions.packageName ?? "@azure/ai-voicelive", spanOptions.packageVersion);
const span = tracer.startSpan(name, { attributes: spanOptions.spanAttributes }, ctx);
return {
span: {
end: () => span.end(),
setStatus: (s) => { if (s.status === "error") span.setStatus({ code: 2, message: String(s.error ?? "") }); },
setAttribute: (k, v) => span.setAttribute(k, v),
isRecording: () => span.isRecording(),
recordException: (e) => span.recordException(e),
},
tracingContext: trace.setSpan(ctx, span),
};
},
withContext: (ctx, fn, ...args) => context.with(ctx, fn, undefined, ...args),
parseTraceparentHeader: () => undefined,
createRequestHeaders: () => ({}),
});
这产生了与CommonJS桥相同的跨度.
完整、可操作的样本:
- 节点.js(ESM):
samples/telemetry/控制台出口商和Azure监测器变体.- 浏览器( Vite) :
samples/telemetry-browser/——页内跨度取景器.
扩展属性
SDK 设置属性如下 GenAI 语义学公约数字 :
| 属性 | 说明 |
|---|---|
az.namespace | 永远 Microsoft.CognitiveServices |
gen_ai.system | 永远 az.ai.voicelive |
gen_ai.operation.name | connect, (中文(简体) ), send, (中文(简体) ), recv,或 close |
gen_ai.request.model | 型号名称(例如, gpt-realtime(中文(简体) ) |
gen_ai.voice.session_id | 语音会议ID来自 session.created |
gen_ai.voice.turn_count | 已完成的响应回合总数(连接间距) |
gen_ai.voice.interruption_count | 数目 response.cancel 事件(连接间距) |
gen_ai.voice.audio_bytes_sent | 发送的音频字节总数( 连接间距) |
gen_ai.voice.audio_bytes_received | 收到音频字节总数( 连接间距) |
gen_ai.voice.first_token_latency_ms | 时间从 response.create 到第一个音频/文本三角洲 |
gen_ai.usage.input_tokens | 输入符数 response.done |
gen_ai.usage.output_tokens | 输出符数从 response.done |
日志
允许伐木可能有助于发现有关失败的有用信息。 为了查看WebSocket信件和回复的日志,设置 AZURE_LOG_LEVEL 环境变量改为 info。或者,可以在运行时拨打 setLogLevel 输入 @azure/logger数字 :
import { setLogLevel } from "@azure/logger";
setLogLevel("info");
关于如何启用日志的更详细指示,您可以查看 @ azure/ logger 包文件。 。 。 .
今后的步骤
您可以通过下列链接找到更多的代码样本:
捐款
如果您想为图书馆捐钱 请读一下 贡献指南 学习如何构建和测试密码.